about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/transform/nll/mod.rs2
-rw-r--r--src/librustc_mir/transform/type_check.rs27
2 files changed, 25 insertions, 4 deletions
diff --git a/src/librustc_mir/transform/nll/mod.rs b/src/librustc_mir/transform/nll/mod.rs
index 147f061ad11..63cbc637547 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);
+    let constraint_sets = &type_check::type_check(infcx, mir_node_id, param_env, mir, def_id);
 
     // 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 6888225de75..cdfa506a3c2 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -11,6 +11,8 @@
 //! 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};
@@ -41,8 +43,9 @@ 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);
+    let mut checker = TypeChecker::new(infcx, body_id, param_env, mir_def_id);
     let errors_reported = {
         let mut verifier = TypeVerifier::new(&mut checker, mir);
         verifier.visit_mir(mir);
@@ -408,6 +411,11 @@ 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
@@ -459,7 +467,14 @@ 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,
@@ -467,6 +482,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             param_env,
             reported_errors: FxHashSet(),
             constraints: MirTypeckRegionConstraints::default(),
+            is_adt_constructor,
         }
     }
 
@@ -1086,7 +1102,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                             };
                             let op_ty = match op {
                                 Operand::Consume(lv) => {
-                                    self.normalize(&lv.ty(mir, tcx), location).to_ty(tcx)
+                                    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,
                             };
@@ -1178,7 +1199,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);
+            let _region_constraint_sets = type_check(&infcx, id, param_env, mir, def_id);
 
             // For verification purposes, we just ignore the resulting
             // region constraint sets. Not our problem. =)