From c52e51dfb7a3d2b9027a36ba93ec73a5c1b7f00a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 20 Nov 2017 13:08:52 -0500 Subject: [PATCH] normalize types in ADT constructor Fixes #45940 --- src/librustc_mir/shim.rs | 10 ++++++-- src/librustc_mir/transform/nll/mod.rs | 2 +- src/librustc_mir/transform/type_check.rs | 32 +++--------------------- 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index d31f3812e9a1..15c68954230b 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -825,10 +825,16 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, -> Mir<'tcx> { let tcx = infcx.tcx; + let gcx = tcx.global_tcx(); let def_id = tcx.hir.local_def_id(ctor_id); - let sig = tcx.no_late_bound_regions(&tcx.fn_sig(def_id)) + let sig = gcx.no_late_bound_regions(&gcx.fn_sig(def_id)) .expect("LBR in ADT constructor signature"); - let sig = tcx.erase_regions(&sig); + let sig = gcx.erase_regions(&sig); + let param_env = gcx.param_env(def_id); + + // Normalize the sig now that we have liberated the late-bound + // regions. + let sig = gcx.normalize_associated_type_in_env(&sig, param_env); let (adt_def, substs) = match sig.output().sty { ty::TyAdt(adt_def, substs) => (adt_def, substs), diff --git a/src/librustc_mir/transform/nll/mod.rs b/src/librustc_mir/transform/nll/mod.rs index 63cbc637547d..147f061ad113 100644 --- a/src/librustc_mir/transform/nll/mod.rs +++ b/src/librustc_mir/transform/nll/mod.rs @@ -47,7 +47,7 @@ pub fn compute_regions<'a, 'gcx, 'tcx>( // Run the MIR type-checker. let mir_node_id = infcx.tcx.hir.as_local_node_id(def_id).unwrap(); - let constraint_sets = &type_check::type_check(infcx, mir_node_id, param_env, mir, def_id); + let constraint_sets = &type_check::type_check(infcx, mir_node_id, param_env, mir); // Create the region inference context, taking ownership of the region inference // data that was contained in `infcx`. diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index ebf894af180d..ade5cf8b70c2 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -11,8 +11,6 @@ //! This pass type-checks the MIR to ensure it is not broken. #![allow(unreachable_code)] -use rustc::hir::def_id::DefId; -use rustc::hir::map::DefPathData; use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult}; use rustc::infer::region_constraints::RegionConstraintData; use rustc::traits::{self, FulfillmentContext}; @@ -43,9 +41,8 @@ pub fn type_check<'a, 'gcx, 'tcx>( body_id: ast::NodeId, param_env: ty::ParamEnv<'gcx>, mir: &Mir<'tcx>, - mir_def_id: DefId, ) -> MirTypeckRegionConstraints<'tcx> { - let mut checker = TypeChecker::new(infcx, body_id, param_env, mir_def_id); + let mut checker = TypeChecker::new(infcx, body_id, param_env); let errors_reported = { let mut verifier = TypeVerifier::new(&mut checker, mir); verifier.visit_mir(mir); @@ -411,11 +408,6 @@ pub struct TypeChecker<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { body_id: ast::NodeId, reported_errors: FxHashSet<(Ty<'tcx>, Span)>, constraints: MirTypeckRegionConstraints<'tcx>, - - // FIXME(#45940) - True if this is a MIR shim or ADT constructor - // (e.g., for a tuple struct.) In that case, the internal types of - // operands and things require normalization. - is_adt_constructor: bool, } /// A collection of region constraints that must be satisfied for the @@ -467,14 +459,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, body_id: ast::NodeId, param_env: ty::ParamEnv<'gcx>, - mir_def_id: DefId, ) -> Self { - let def_key = infcx.tcx.def_key(mir_def_id); - let is_adt_constructor = match def_key.disambiguated_data.data { - DefPathData::StructCtor => true, - _ => false, - }; - TypeChecker { infcx, last_span: DUMMY_SP, @@ -482,7 +467,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { param_env, reported_errors: FxHashSet(), constraints: MirTypeckRegionConstraints::default(), - is_adt_constructor, } } @@ -1099,17 +1083,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { continue; } }; - let op_ty = match op { - Operand::Consume(lv) => { - let lv_ty = lv.ty(mir, tcx).to_ty(tcx); - if self.is_adt_constructor { - self.normalize(&lv_ty, location) - } else { - lv_ty - } - } - Operand::Constant(c) => c.ty, - }; + let op_ty = op.ty(mir, tcx); if let Err(terr) = self.sub_types( op_ty, field_ty, @@ -1198,7 +1172,7 @@ impl MirPass for TypeckMir { } let param_env = tcx.param_env(def_id); tcx.infer_ctxt().enter(|infcx| { - let _region_constraint_sets = type_check(&infcx, id, param_env, mir, def_id); + let _region_constraint_sets = type_check(&infcx, id, param_env, mir); // For verification purposes, we just ignore the resulting // region constraint sets. Not our problem. =)