From 63064ec190fef7947c3eabfcdfeaeb293c9a91dd Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 14 Apr 2017 19:00:08 +0300 Subject: [PATCH] rustc: expose monomorphic const_eval through on-demand. --- src/Cargo.lock | 2 -- src/librustc/middle/const_val.rs | 37 +++++++++++++++++++++++- src/librustc_const_eval/eval.rs | 49 ++++++++++---------------------- src/librustc_driver/driver.rs | 3 +- src/librustc_mir/hair/cx/expr.rs | 5 ++-- src/librustc_typeck/Cargo.toml | 1 - src/librustc_typeck/astconv.rs | 4 +-- src/librustc_typeck/check/mod.rs | 4 +-- src/librustc_typeck/collect.rs | 6 +--- src/librustc_typeck/lib.rs | 1 - src/librustdoc/Cargo.toml | 1 - src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/lib.rs | 1 - 13 files changed, 61 insertions(+), 55 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index c4b5366d4a324..62b853480394f 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -760,7 +760,6 @@ dependencies = [ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_back 0.0.0", - "rustc_const_eval 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", @@ -781,7 +780,6 @@ dependencies = [ "pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_back 0.0.0", - "rustc_const_eval 0.0.0", "rustc_data_structures 0.0.0", "rustc_driver 0.0.0", "rustc_errors 0.0.0", diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 9315f7f58081a..b4c5af9401944 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -11,9 +11,12 @@ use self::ConstVal::*; pub use rustc_const_math::ConstInt; +use hir; +use hir::def::Def; use hir::def_id::DefId; -use ty::TyCtxt; +use ty::{self, TyCtxt}; use ty::subst::Substs; +use util::common::ErrorReported; use rustc_const_math::*; use graphviz::IntoCow; @@ -215,3 +218,35 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { self.struct_error(tcx, primary_span, primary_kind).emit(); } } + +/// Returns the value of the length-valued expression +pub fn eval_length(tcx: TyCtxt, + count: hir::BodyId, + reason: &str) + -> Result +{ + let count_expr = &tcx.hir.body(count).value; + let count_def_id = tcx.hir.body_owner_def_id(count); + match ty::queries::monomorphic_const_eval::get(tcx, count_expr.span, count_def_id) { + Ok(Integral(Usize(count))) => { + let val = count.as_u64(tcx.sess.target.uint_type); + assert_eq!(val as usize as u64, val); + Ok(val as usize) + }, + Ok(_) | + Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported), + Err(err) => { + let mut diag = err.struct_error(tcx, count_expr.span, reason); + + if let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = count_expr.node { + if let Def::Local(..) = path.def { + diag.note(&format!("`{}` is a variable", + tcx.hir.node_to_pretty_string(count_expr.id))); + } + } + + diag.emit(); + Err(ErrorReported) + } + } +} diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index b928bae620b6c..bf8085be31c44 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -18,6 +18,7 @@ use rustc::traits; use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::maps::Providers; use rustc::ty::util::IntTypeExt; use rustc::ty::subst::{Substs, Subst}; use rustc::traits::Reveal; @@ -163,12 +164,6 @@ pub struct ConstContext<'a, 'tcx: 'a> { } impl<'a, 'tcx> ConstContext<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, body: hir::BodyId) -> Self { - let def_id = tcx.hir.body_owner_def_id(body); - ty::queries::mir_const_qualif::get(tcx, DUMMY_SP, def_id); - ConstContext::with_tables(tcx, tcx.item_tables(def_id)) - } - pub fn with_tables(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &'a ty::TypeckTables<'tcx>) -> Self { ConstContext { tcx: tcx, @@ -799,34 +794,20 @@ impl<'a, 'tcx> ConstContext<'a, 'tcx> { } } +pub fn provide(providers: &mut Providers) { + *providers = Providers { + monomorphic_const_eval, + ..*providers + }; +} -/// Returns the value of the length-valued expression -pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - count: hir::BodyId, - reason: &str) - -> Result -{ - let count_expr = &tcx.hir.body(count).value; - match ConstContext::new(tcx, count).eval(count_expr) { - Ok(Integral(Usize(count))) => { - let val = count.as_u64(tcx.sess.target.uint_type); - assert_eq!(val as usize as u64, val); - Ok(val as usize) - }, - Ok(_) | - Err(ConstEvalErr { kind: TypeckError, .. }) => Err(ErrorReported), - Err(err) => { - let mut diag = err.struct_error(tcx, count_expr.span, reason); - - if let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = count_expr.node { - if let Def::Local(..) = path.def { - diag.note(&format!("`{}` is a variable", - tcx.hir.node_to_pretty_string(count_expr.id))); - } - } +fn monomorphic_const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId) + -> EvalResult<'tcx> { + ty::queries::mir_const_qualif::get(tcx, DUMMY_SP, def_id); + let cx = ConstContext::with_tables(tcx, tcx.item_tables(def_id)); - diag.emit(); - Err(ErrorReported) - } - } + let id = tcx.hir.as_local_node_id(def_id).unwrap(); + let body = tcx.hir.body_owned_by(id); + cx.eval(&tcx.hir.body(body).value) } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 48d9719e76c4d..c856ea505ffe8 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -37,7 +37,7 @@ use rustc_plugin::registry::Registry; use rustc_plugin as plugin; use rustc_passes::{ast_validation, no_asm, loops, consts, static_recursion, hir_stats, mir_stats}; -use rustc_const_eval::check_match; +use rustc_const_eval::{self, check_match}; use super::Compilation; use serialize::json; @@ -895,6 +895,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, typeck::provide(&mut local_providers); ty::provide(&mut local_providers); reachable::provide(&mut local_providers); + rustc_const_eval::provide(&mut local_providers); let mut extern_providers = ty::maps::Providers::default(); cstore::provide(&mut extern_providers); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 595748c8c6fdc..b7de50efe3442 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -17,7 +17,6 @@ use hair::cx::to_ref::ToRef; use rustc::hir::map; use rustc::hir::def::{Def, CtorKind}; use rustc::middle::const_val::ConstVal; -use rustc_const_eval::ConstContext; use rustc::ty::{self, AdtKind, VariantDef, Ty}; use rustc::ty::cast::CastKind as TyCastKind; use rustc::hir; @@ -592,9 +591,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Now comes the rote stuff: hir::ExprRepeat(ref v, count) => { - let tcx = cx.tcx.global_tcx(); let c = &cx.tcx.hir.body(count).value; - let count = match ConstContext::new(tcx, count).eval(c) { + let def_id = cx.tcx.hir.body_owner_def_id(count); + let count = match ty::queries::monomorphic_const_eval::get(cx.tcx, c.span, def_id) { Ok(ConstVal::Integral(ConstInt::Usize(u))) => u, Ok(other) => bug!("constant evaluation of repeat count yielded {:?}", other), Err(s) => cx.fatal_const_eval_err(&s, c.span, "expression") diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 07998aa4a30ea..194d37dcb81c2 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -16,7 +16,6 @@ arena = { path = "../libarena" } fmt_macros = { path = "../libfmt_macros" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } -rustc_const_eval = { path = "../librustc_const_eval" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 66c4a81a5c0f2..9426d601dfcce 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -12,7 +12,7 @@ //! representation. The main routine here is `ast_ty_to_ty()`: each use //! is parameterized by an instance of `AstConv`. -use rustc_const_eval::eval_length; +use rustc::middle::const_val::eval_length; use rustc_data_structures::accumulate_vec::AccumulateVec; use hir; use hir::def::Def; @@ -1208,7 +1208,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0 } hir::TyArray(ref ty, length) => { - if let Ok(length) = eval_length(tcx.global_tcx(), length, "array length") { + if let Ok(length) = eval_length(tcx, length, "array length") { tcx.mk_array(self.ast_ty_to_ty(&ty), length) } else { self.tcx().types.err diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5e7325275b819..d2c9fd119d72b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -126,7 +126,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::{self, PatKind}; use rustc::middle::lang_items; use rustc_back::slice; -use rustc_const_eval::eval_length; +use rustc::middle::const_val::eval_length; use rustc_const_math::ConstInt; mod assoc; @@ -3634,7 +3634,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.mk_array(element_ty, args.len()) } hir::ExprRepeat(ref element, count) => { - let count = eval_length(self.tcx.global_tcx(), count, "repeat count") + let count = eval_length(self.tcx, count, "repeat count") .unwrap_or(0); let uty = match expected { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4c7979ea3765c..73e3de0cc76dd 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -59,14 +59,12 @@ use constrained_type_params as ctp; use middle::lang_items::SizedTraitLangItem; use middle::const_val::ConstVal; use middle::resolve_lifetime as rl; -use rustc_const_eval::ConstContext; use rustc::ty::subst::Substs; use rustc::ty::{ToPredicate, ReprOptions}; use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::maps::Providers; use rustc::ty::util::IntTypeExt; use rustc::dep_graph::DepNode; -use util::common::MemoizationMap; use util::nodemap::{NodeMap, FxHashMap}; use rustc_const_math::ConstInt; @@ -600,9 +598,7 @@ fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr()); prev_discr = Some(if let Some(e) = variant.node.disr_expr { let expr_did = tcx.hir.local_def_id(e.node_id); - let result = tcx.maps.monomorphic_const_eval.memoize(expr_did, || { - ConstContext::new(tcx, e).eval(&tcx.hir.body(e).value) - }); + let result = ty::queries::monomorphic_const_eval::get(tcx, variant.span, expr_did); // enum variant evaluation happens before the global constant check // so we need to report the real error diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 12db76bf91c34..e9d52c5eb98d9 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -94,7 +94,6 @@ extern crate fmt_macros; extern crate rustc_platform_intrinsics as intrinsics; extern crate rustc_back; extern crate rustc_const_math; -extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors as errors; diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 52f5d99838dc7..e81acf7bdba82 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -14,7 +14,6 @@ env_logger = { version = "0.4", default-features = false } log = "0.3" rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } -rustc_const_eval = { path = "../librustc_const_eval" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_driver = { path = "../librustc_driver" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3d233463bba3a..47e1d0b7edb2a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1715,7 +1715,7 @@ impl Clean for hir::Ty { } TySlice(ref ty) => Vector(box ty.clean(cx)), TyArray(ref ty, length) => { - use rustc_const_eval::eval_length; + use rustc::middle::const_val::eval_length; let n = eval_length(cx.tcx, length, "array length").unwrap(); FixedVector(box ty.clean(cx), n.to_string()) }, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 447d60018d912..d5b997001bb9d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -33,7 +33,6 @@ extern crate getopts; extern crate env_logger; extern crate libc; extern crate rustc; -extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_trans; extern crate rustc_driver;