Skip to content

Commit b588edc

Browse files
committed
only normalize operand types when in an ADT constructor
1 parent 527a5dd commit b588edc

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

src/librustc_mir/transform/nll/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub fn compute_regions<'a, 'gcx, 'tcx>(
4747

4848
// Run the MIR type-checker.
4949
let mir_node_id = infcx.tcx.hir.as_local_node_id(def_id).unwrap();
50-
let constraint_sets = &type_check::type_check(infcx, mir_node_id, param_env, mir);
50+
let constraint_sets = &type_check::type_check(infcx, mir_node_id, param_env, mir, def_id);
5151

5252
// Create the region inference context, taking ownership of the region inference
5353
// data that was contained in `infcx`.

src/librustc_mir/transform/type_check.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//! This pass type-checks the MIR to ensure it is not broken.
1212
#![allow(unreachable_code)]
1313

14+
use rustc::hir::def_id::DefId;
15+
use rustc::hir::map::DefPathData;
1416
use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
1517
use rustc::infer::region_constraints::RegionConstraintData;
1618
use rustc::traits::{self, FulfillmentContext};
@@ -41,8 +43,9 @@ pub fn type_check<'a, 'gcx, 'tcx>(
4143
body_id: ast::NodeId,
4244
param_env: ty::ParamEnv<'gcx>,
4345
mir: &Mir<'tcx>,
46+
mir_def_id: DefId,
4447
) -> 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);
4649
let errors_reported = {
4750
let mut verifier = TypeVerifier::new(&mut checker, mir);
4851
verifier.visit_mir(mir);
@@ -408,6 +411,11 @@ pub struct TypeChecker<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
408411
body_id: ast::NodeId,
409412
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
410413
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,
411419
}
412420

413421
/// A collection of region constraints that must be satisfied for the
@@ -459,14 +467,22 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
459467
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
460468
body_id: ast::NodeId,
461469
param_env: ty::ParamEnv<'gcx>,
470+
mir_def_id: DefId,
462471
) -> 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+
463478
TypeChecker {
464479
infcx,
465480
last_span: DUMMY_SP,
466481
body_id,
467482
param_env,
468483
reported_errors: FxHashSet(),
469484
constraints: MirTypeckRegionConstraints::default(),
485+
is_adt_constructor,
470486
}
471487
}
472488

@@ -1086,7 +1102,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10861102
};
10871103
let op_ty = match op {
10881104
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+
}
10901111
}
10911112
Operand::Constant(c) => c.ty,
10921113
};
@@ -1178,7 +1199,7 @@ impl MirPass for TypeckMir {
11781199
}
11791200
let param_env = tcx.param_env(def_id);
11801201
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);
11821203

11831204
// For verification purposes, we just ignore the resulting
11841205
// region constraint sets. Not our problem. =)

0 commit comments

Comments
 (0)