mirror of
https://github.com/rust-lang/rust
synced 2024-10-05 08:10:32 +00:00
rustc: expose monomorphic const_eval through on-demand.
This commit is contained in:
parent
8854164d0c
commit
63064ec190
2
src/Cargo.lock
generated
2
src/Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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 @@ pub fn report(&self,
|
|||
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<usize, ErrorReported>
|
||||
{
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
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 @@ pub fn compare_lit_exprs(&self,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// 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<usize, ErrorReported>
|
||||
{
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
diag.emit();
|
||||
Err(ErrorReported)
|
||||
}
|
||||
}
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
monomorphic_const_eval,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
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 @@ macro_rules! try_with_f {
|
|||
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);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
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")
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
|
|||
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
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
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 @@ fn check_expr_kind(&self,
|
|||
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 {
|
||||
|
|
|
@ -59,14 +59,12 @@
|
|||
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
|
||||
|
|
|
@ -94,7 +94,6 @@
|
|||
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;
|
||||
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -1715,7 +1715,7 @@ fn clean(&self, cx: &DocContext) -> Type {
|
|||
}
|
||||
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())
|
||||
},
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue