Skip to content

Commit

Permalink
Auto merge of #43505 - eddyb:poly-const-eval-layout-of, r=nikomatsakis
Browse files Browse the repository at this point in the history
rustc_const_eval: always require Substs and a ParamEnv.

Fixes #43357 by tracking the `Substs` and `ParamEnv` for const-evaluation in generic contexts.
  • Loading branch information
bors committed Jul 28, 2017
2 parents 4d5150c + 60cf542 commit 7167843
Show file tree
Hide file tree
Showing 15 changed files with 199 additions and 136 deletions.
8 changes: 5 additions & 3 deletions src/librustc/middle/const_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ pub use rustc_const_math::ConstInt;
use hir;
use hir::def::Def;
use hir::def_id::DefId;
use ty::{TyCtxt, layout};
use traits::Reveal;
use ty::{self, TyCtxt, layout};
use ty::subst::Substs;
use util::common::ErrorReported;
use rustc_const_math::*;
Expand Down Expand Up @@ -229,8 +230,9 @@ pub fn eval_length(tcx: TyCtxt,
{
let count_expr = &tcx.hir.body(count).value;
let count_def_id = tcx.hir.body_owner_def_id(count);
let substs = Substs::empty();
match tcx.at(count_expr.span).const_eval((count_def_id, substs)) {
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
match tcx.at(count_expr.span).const_eval(param_env.and((count_def_id, substs))) {
Ok(Integral(Usize(count))) => {
let val = count.as_u64(tcx.sess.target.uint_type);
assert_eq!(val as usize as u64, val);
Expand Down
9 changes: 5 additions & 4 deletions src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,8 @@ impl<'tcx> QueryDescription for queries::reachable_set<'tcx> {
}

impl<'tcx> QueryDescription for queries::const_eval<'tcx> {
fn describe(tcx: TyCtxt, (def_id, _): (DefId, &'tcx Substs<'tcx>)) -> String {
format!("const-evaluating `{}`", tcx.item_path_str(def_id))
fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>) -> String {
format!("const-evaluating `{}`", tcx.item_path_str(key.value.0))
}
}

Expand Down Expand Up @@ -935,7 +935,7 @@ define_maps! { <'tcx>

/// Results of evaluating const items or constants embedded in
/// other items (such as enum variant explicit discriminants).
[] const_eval: const_eval_dep_node((DefId, &'tcx Substs<'tcx>))
[] const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
-> const_val::EvalResult<'tcx>,

/// Performs the privacy check and computes "access levels".
Expand Down Expand Up @@ -1032,8 +1032,9 @@ fn typeck_item_bodies_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::TypeckBodiesKrate
}

fn const_eval_dep_node<'tcx>((def_id, substs): (DefId, &'tcx Substs<'tcx>))
fn const_eval_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
-> DepConstructor<'tcx> {
let (def_id, substs) = key.value;
DepConstructor::ConstEval { def_id, substs }
}

Expand Down
10 changes: 6 additions & 4 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1582,14 +1582,15 @@ impl<'a, 'gcx, 'tcx> AdtDef {
#[inline]
pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
-> impl Iterator<Item=ConstInt> + 'a {
let param_env = ParamEnv::empty(traits::Reveal::UserFacing);
let repr_type = self.repr.discr_type();
let initial = repr_type.initial_discriminant(tcx.global_tcx());
let mut prev_discr = None::<ConstInt>;
self.variants.iter().map(move |v| {
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr());
if let VariantDiscr::Explicit(expr_did) = v.discr {
let substs = Substs::empty();
match tcx.const_eval((expr_did, substs)) {
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
match tcx.const_eval(param_env.and((expr_did, substs))) {
Ok(ConstVal::Integral(v)) => {
discr = v;
}
Expand Down Expand Up @@ -1617,6 +1618,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
variant_index: usize)
-> ConstInt {
let param_env = ParamEnv::empty(traits::Reveal::UserFacing);
let repr_type = self.repr.discr_type();
let mut explicit_value = repr_type.initial_discriminant(tcx.global_tcx());
let mut explicit_index = variant_index;
Expand All @@ -1627,8 +1629,8 @@ impl<'a, 'gcx, 'tcx> AdtDef {
explicit_index -= distance;
}
ty::VariantDiscr::Explicit(expr_did) => {
let substs = Substs::empty();
match tcx.const_eval((expr_did, substs)) {
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
match tcx.const_eval(param_env.and((expr_did, substs))) {
Ok(ConstVal::Integral(v)) => {
explicit_value = v;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ macro_rules! CopyImpls {
}
}

CopyImpls! { (), hir::Unsafety, abi::Abi }
CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId }

impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
Expand Down
15 changes: 11 additions & 4 deletions src/librustc_const_eval/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rustc::middle::mem_categorization::{cmt};
use rustc::middle::region::RegionMaps;
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
use rustc::lint;
use rustc_errors::{Diagnostic, Level, DiagnosticBuilder};

Expand Down Expand Up @@ -51,7 +52,8 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
tcx: self.tcx,
tables: self.tcx.body_tables(b),
region_maps: &self.tcx.region_maps(def_id),
param_env: self.tcx.param_env(def_id)
param_env: self.tcx.param_env(def_id),
identity_substs: Substs::identity_for_item(self.tcx, def_id),
}.visit_body(self.tcx.hir.body(b));
}
}
Expand All @@ -69,6 +71,7 @@ struct MatchVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
param_env: ty::ParamEnv<'tcx>,
identity_substs: &'tcx Substs<'tcx>,
region_maps: &'a RegionMaps,
}

Expand Down Expand Up @@ -110,7 +113,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
}
}

impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> {
impl<'a, 'tcx> PatternContext<'a, 'tcx> {
fn report_inlining_errors(&self, pat_span: Span) {
for error in &self.errors {
match *error {
Expand Down Expand Up @@ -162,7 +165,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {

let inlined_arms : Vec<(Vec<_>, _)> = arms.iter().map(|arm| (
arm.pats.iter().map(|pat| {
let mut patcx = PatternContext::new(self.tcx, self.tables);
let mut patcx = PatternContext::new(self.tcx,
self.param_env.and(self.identity_substs),
self.tables);
let pattern = expand_pattern(cx, patcx.lower_pattern(&pat));
if !patcx.errors.is_empty() {
patcx.report_inlining_errors(pat.span);
Expand Down Expand Up @@ -229,7 +234,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
fn check_irrefutable(&self, pat: &Pat, origin: &str) {
let module = self.tcx.hir.get_module_parent(pat.id);
MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
let mut patcx = PatternContext::new(self.tcx, self.tables);
let mut patcx = PatternContext::new(self.tcx,
self.param_env.and(self.identity_substs),
self.tables);
let pattern = patcx.lower_pattern(pat);
let pattern_ty = pattern.ty;
let pats : Matrix = vec![vec![
Expand Down
Loading

0 comments on commit 7167843

Please sign in to comment.