|
11 | 11 | //! This pass type-checks the MIR to ensure it is not broken.
|
12 | 12 | #![allow(unreachable_code)]
|
13 | 13 |
|
| 14 | +use rustc::hir::def_id::DefId; |
| 15 | +use rustc::hir::map::DefPathData; |
14 | 16 | use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
|
15 | 17 | use rustc::infer::region_constraints::RegionConstraintData;
|
16 | 18 | use rustc::traits::{self, FulfillmentContext};
|
@@ -41,8 +43,9 @@ pub fn type_check<'a, 'gcx, 'tcx>(
|
41 | 43 | body_id: ast::NodeId,
|
42 | 44 | param_env: ty::ParamEnv<'gcx>,
|
43 | 45 | mir: &Mir<'tcx>,
|
| 46 | + mir_def_id: DefId, |
44 | 47 | ) -> MirTypeckRegionConstraints<'tcx> {
|
45 |
| - let mut checker = TypeChecker::new(infcx, body_id, param_env); |
| 48 | + let mut checker = TypeChecker::new(infcx, body_id, param_env, mir_def_id); |
46 | 49 | let errors_reported = {
|
47 | 50 | let mut verifier = TypeVerifier::new(&mut checker, mir);
|
48 | 51 | verifier.visit_mir(mir);
|
@@ -408,6 +411,11 @@ pub struct TypeChecker<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
408 | 411 | body_id: ast::NodeId,
|
409 | 412 | reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
|
410 | 413 | constraints: MirTypeckRegionConstraints<'tcx>,
|
| 414 | + |
| 415 | + // FIXME(#45940) - True if this is a MIR shim or ADT constructor |
| 416 | + // (e.g., for a tuple struct.) In that case, the internal types of |
| 417 | + // operands and things require normalization. |
| 418 | + is_adt_constructor: bool, |
411 | 419 | }
|
412 | 420 |
|
413 | 421 | /// A collection of region constraints that must be satisfied for the
|
@@ -459,14 +467,22 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
459 | 467 | infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
460 | 468 | body_id: ast::NodeId,
|
461 | 469 | param_env: ty::ParamEnv<'gcx>,
|
| 470 | + mir_def_id: DefId, |
462 | 471 | ) -> Self {
|
| 472 | + let def_key = infcx.tcx.def_key(mir_def_id); |
| 473 | + let is_adt_constructor = match def_key.disambiguated_data.data { |
| 474 | + DefPathData::StructCtor => true, |
| 475 | + _ => false, |
| 476 | + }; |
| 477 | + |
463 | 478 | TypeChecker {
|
464 | 479 | infcx,
|
465 | 480 | last_span: DUMMY_SP,
|
466 | 481 | body_id,
|
467 | 482 | param_env,
|
468 | 483 | reported_errors: FxHashSet(),
|
469 | 484 | constraints: MirTypeckRegionConstraints::default(),
|
| 485 | + is_adt_constructor, |
470 | 486 | }
|
471 | 487 | }
|
472 | 488 |
|
@@ -1086,7 +1102,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
1086 | 1102 | };
|
1087 | 1103 | let op_ty = match op {
|
1088 | 1104 | Operand::Consume(lv) => {
|
1089 |
| - self.normalize(&lv.ty(mir, tcx), location).to_ty(tcx) |
| 1105 | + let lv_ty = lv.ty(mir, tcx).to_ty(tcx); |
| 1106 | + if self.is_adt_constructor { |
| 1107 | + self.normalize(&lv_ty, location) |
| 1108 | + } else { |
| 1109 | + lv_ty |
| 1110 | + } |
1090 | 1111 | }
|
1091 | 1112 | Operand::Constant(c) => c.ty,
|
1092 | 1113 | };
|
@@ -1178,7 +1199,7 @@ impl MirPass for TypeckMir {
|
1178 | 1199 | }
|
1179 | 1200 | let param_env = tcx.param_env(def_id);
|
1180 | 1201 | tcx.infer_ctxt().enter(|infcx| {
|
1181 |
| - let _region_constraint_sets = type_check(&infcx, id, param_env, mir); |
| 1202 | + let _region_constraint_sets = type_check(&infcx, id, param_env, mir, def_id); |
1182 | 1203 |
|
1183 | 1204 | // For verification purposes, we just ignore the resulting
|
1184 | 1205 | // region constraint sets. Not our problem. =)
|
|
0 commit comments