Skip to content

Commit 63064ec

Browse files
committed
rustc: expose monomorphic const_eval through on-demand.
1 parent 8854164 commit 63064ec

File tree

13 files changed

+61
-55
lines changed

13 files changed

+61
-55
lines changed

src/Cargo.lock

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc/middle/const_val.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
use self::ConstVal::*;
1212
pub use rustc_const_math::ConstInt;
1313

14+
use hir;
15+
use hir::def::Def;
1416
use hir::def_id::DefId;
15-
use ty::TyCtxt;
17+
use ty::{self, TyCtxt};
1618
use ty::subst::Substs;
19+
use util::common::ErrorReported;
1720
use rustc_const_math::*;
1821

1922
use graphviz::IntoCow;
@@ -215,3 +218,35 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
215218
self.struct_error(tcx, primary_span, primary_kind).emit();
216219
}
217220
}
221+
222+
/// Returns the value of the length-valued expression
223+
pub fn eval_length(tcx: TyCtxt,
224+
count: hir::BodyId,
225+
reason: &str)
226+
-> Result<usize, ErrorReported>
227+
{
228+
let count_expr = &tcx.hir.body(count).value;
229+
let count_def_id = tcx.hir.body_owner_def_id(count);
230+
match ty::queries::monomorphic_const_eval::get(tcx, count_expr.span, count_def_id) {
231+
Ok(Integral(Usize(count))) => {
232+
let val = count.as_u64(tcx.sess.target.uint_type);
233+
assert_eq!(val as usize as u64, val);
234+
Ok(val as usize)
235+
},
236+
Ok(_) |
237+
Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported),
238+
Err(err) => {
239+
let mut diag = err.struct_error(tcx, count_expr.span, reason);
240+
241+
if let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = count_expr.node {
242+
if let Def::Local(..) = path.def {
243+
diag.note(&format!("`{}` is a variable",
244+
tcx.hir.node_to_pretty_string(count_expr.id)));
245+
}
246+
}
247+
248+
diag.emit();
249+
Err(ErrorReported)
250+
}
251+
}
252+
}

src/librustc_const_eval/eval.rs

+15-34
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc::traits;
1818
use rustc::hir::def::Def;
1919
use rustc::hir::def_id::DefId;
2020
use rustc::ty::{self, Ty, TyCtxt};
21+
use rustc::ty::maps::Providers;
2122
use rustc::ty::util::IntTypeExt;
2223
use rustc::ty::subst::{Substs, Subst};
2324
use rustc::traits::Reveal;
@@ -163,12 +164,6 @@ pub struct ConstContext<'a, 'tcx: 'a> {
163164
}
164165

165166
impl<'a, 'tcx> ConstContext<'a, 'tcx> {
166-
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, body: hir::BodyId) -> Self {
167-
let def_id = tcx.hir.body_owner_def_id(body);
168-
ty::queries::mir_const_qualif::get(tcx, DUMMY_SP, def_id);
169-
ConstContext::with_tables(tcx, tcx.item_tables(def_id))
170-
}
171-
172167
pub fn with_tables(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &'a ty::TypeckTables<'tcx>) -> Self {
173168
ConstContext {
174169
tcx: tcx,
@@ -799,34 +794,20 @@ impl<'a, 'tcx> ConstContext<'a, 'tcx> {
799794
}
800795
}
801796

797+
pub fn provide(providers: &mut Providers) {
798+
*providers = Providers {
799+
monomorphic_const_eval,
800+
..*providers
801+
};
802+
}
802803

803-
/// Returns the value of the length-valued expression
804-
pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
805-
count: hir::BodyId,
806-
reason: &str)
807-
-> Result<usize, ErrorReported>
808-
{
809-
let count_expr = &tcx.hir.body(count).value;
810-
match ConstContext::new(tcx, count).eval(count_expr) {
811-
Ok(Integral(Usize(count))) => {
812-
let val = count.as_u64(tcx.sess.target.uint_type);
813-
assert_eq!(val as usize as u64, val);
814-
Ok(val as usize)
815-
},
816-
Ok(_) |
817-
Err(ConstEvalErr { kind: TypeckError, .. }) => Err(ErrorReported),
818-
Err(err) => {
819-
let mut diag = err.struct_error(tcx, count_expr.span, reason);
820-
821-
if let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = count_expr.node {
822-
if let Def::Local(..) = path.def {
823-
diag.note(&format!("`{}` is a variable",
824-
tcx.hir.node_to_pretty_string(count_expr.id)));
825-
}
826-
}
804+
fn monomorphic_const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
805+
def_id: DefId)
806+
-> EvalResult<'tcx> {
807+
ty::queries::mir_const_qualif::get(tcx, DUMMY_SP, def_id);
808+
let cx = ConstContext::with_tables(tcx, tcx.item_tables(def_id));
827809

828-
diag.emit();
829-
Err(ErrorReported)
830-
}
831-
}
810+
let id = tcx.hir.as_local_node_id(def_id).unwrap();
811+
let body = tcx.hir.body_owned_by(id);
812+
cx.eval(&tcx.hir.body(body).value)
832813
}

src/librustc_driver/driver.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use rustc_plugin::registry::Registry;
3737
use rustc_plugin as plugin;
3838
use rustc_passes::{ast_validation, no_asm, loops, consts,
3939
static_recursion, hir_stats, mir_stats};
40-
use rustc_const_eval::check_match;
40+
use rustc_const_eval::{self, check_match};
4141
use super::Compilation;
4242

4343
use serialize::json;
@@ -895,6 +895,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
895895
typeck::provide(&mut local_providers);
896896
ty::provide(&mut local_providers);
897897
reachable::provide(&mut local_providers);
898+
rustc_const_eval::provide(&mut local_providers);
898899

899900
let mut extern_providers = ty::maps::Providers::default();
900901
cstore::provide(&mut extern_providers);

src/librustc_mir/hair/cx/expr.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use hair::cx::to_ref::ToRef;
1717
use rustc::hir::map;
1818
use rustc::hir::def::{Def, CtorKind};
1919
use rustc::middle::const_val::ConstVal;
20-
use rustc_const_eval::ConstContext;
2120
use rustc::ty::{self, AdtKind, VariantDef, Ty};
2221
use rustc::ty::cast::CastKind as TyCastKind;
2322
use rustc::hir;
@@ -592,9 +591,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
592591

593592
// Now comes the rote stuff:
594593
hir::ExprRepeat(ref v, count) => {
595-
let tcx = cx.tcx.global_tcx();
596594
let c = &cx.tcx.hir.body(count).value;
597-
let count = match ConstContext::new(tcx, count).eval(c) {
595+
let def_id = cx.tcx.hir.body_owner_def_id(count);
596+
let count = match ty::queries::monomorphic_const_eval::get(cx.tcx, c.span, def_id) {
598597
Ok(ConstVal::Integral(ConstInt::Usize(u))) => u,
599598
Ok(other) => bug!("constant evaluation of repeat count yielded {:?}", other),
600599
Err(s) => cx.fatal_const_eval_err(&s, c.span, "expression")

src/librustc_typeck/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ arena = { path = "../libarena" }
1616
fmt_macros = { path = "../libfmt_macros" }
1717
rustc = { path = "../librustc" }
1818
rustc_back = { path = "../librustc_back" }
19-
rustc_const_eval = { path = "../librustc_const_eval" }
2019
rustc_const_math = { path = "../librustc_const_math" }
2120
rustc_data_structures = { path = "../librustc_data_structures" }
2221
rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }

src/librustc_typeck/astconv.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//! representation. The main routine here is `ast_ty_to_ty()`: each use
1313
//! is parameterized by an instance of `AstConv`.
1414
15-
use rustc_const_eval::eval_length;
15+
use rustc::middle::const_val::eval_length;
1616
use rustc_data_structures::accumulate_vec::AccumulateVec;
1717
use hir;
1818
use hir::def::Def;
@@ -1208,7 +1208,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
12081208
self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
12091209
}
12101210
hir::TyArray(ref ty, length) => {
1211-
if let Ok(length) = eval_length(tcx.global_tcx(), length, "array length") {
1211+
if let Ok(length) = eval_length(tcx, length, "array length") {
12121212
tcx.mk_array(self.ast_ty_to_ty(&ty), length)
12131213
} else {
12141214
self.tcx().types.err

src/librustc_typeck/check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
126126
use rustc::hir::{self, PatKind};
127127
use rustc::middle::lang_items;
128128
use rustc_back::slice;
129-
use rustc_const_eval::eval_length;
129+
use rustc::middle::const_val::eval_length;
130130
use rustc_const_math::ConstInt;
131131

132132
mod assoc;
@@ -3634,7 +3634,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
36343634
tcx.mk_array(element_ty, args.len())
36353635
}
36363636
hir::ExprRepeat(ref element, count) => {
3637-
let count = eval_length(self.tcx.global_tcx(), count, "repeat count")
3637+
let count = eval_length(self.tcx, count, "repeat count")
36383638
.unwrap_or(0);
36393639

36403640
let uty = match expected {

src/librustc_typeck/collect.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,12 @@ use constrained_type_params as ctp;
5959
use middle::lang_items::SizedTraitLangItem;
6060
use middle::const_val::ConstVal;
6161
use middle::resolve_lifetime as rl;
62-
use rustc_const_eval::ConstContext;
6362
use rustc::ty::subst::Substs;
6463
use rustc::ty::{ToPredicate, ReprOptions};
6564
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
6665
use rustc::ty::maps::Providers;
6766
use rustc::ty::util::IntTypeExt;
6867
use rustc::dep_graph::DepNode;
69-
use util::common::MemoizationMap;
7068
use util::nodemap::{NodeMap, FxHashMap};
7169

7270
use rustc_const_math::ConstInt;
@@ -600,9 +598,7 @@ fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
600598
let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr());
601599
prev_discr = Some(if let Some(e) = variant.node.disr_expr {
602600
let expr_did = tcx.hir.local_def_id(e.node_id);
603-
let result = tcx.maps.monomorphic_const_eval.memoize(expr_did, || {
604-
ConstContext::new(tcx, e).eval(&tcx.hir.body(e).value)
605-
});
601+
let result = ty::queries::monomorphic_const_eval::get(tcx, variant.span, expr_did);
606602

607603
// enum variant evaluation happens before the global constant check
608604
// so we need to report the real error

src/librustc_typeck/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ extern crate fmt_macros;
9494
extern crate rustc_platform_intrinsics as intrinsics;
9595
extern crate rustc_back;
9696
extern crate rustc_const_math;
97-
extern crate rustc_const_eval;
9897
extern crate rustc_data_structures;
9998
extern crate rustc_errors as errors;
10099

src/librustdoc/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ env_logger = { version = "0.4", default-features = false }
1414
log = "0.3"
1515
rustc = { path = "../librustc" }
1616
rustc_back = { path = "../librustc_back" }
17-
rustc_const_eval = { path = "../librustc_const_eval" }
1817
rustc_data_structures = { path = "../librustc_data_structures" }
1918
rustc_driver = { path = "../librustc_driver" }
2019
rustc_errors = { path = "../librustc_errors" }

src/librustdoc/clean/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1715,7 +1715,7 @@ impl Clean<Type> for hir::Ty {
17151715
}
17161716
TySlice(ref ty) => Vector(box ty.clean(cx)),
17171717
TyArray(ref ty, length) => {
1718-
use rustc_const_eval::eval_length;
1718+
use rustc::middle::const_val::eval_length;
17191719
let n = eval_length(cx.tcx, length, "array length").unwrap();
17201720
FixedVector(box ty.clean(cx), n.to_string())
17211721
},

src/librustdoc/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ extern crate getopts;
3333
extern crate env_logger;
3434
extern crate libc;
3535
extern crate rustc;
36-
extern crate rustc_const_eval;
3736
extern crate rustc_data_structures;
3837
extern crate rustc_trans;
3938
extern crate rustc_driver;

0 commit comments

Comments
 (0)