only normalize operand types when in an ADT constructor
This commit is contained in:
parent
527a5dd251
commit
b588edc413
@ -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`.
|
||||
|
@ -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. =)
|
||||
|
Loading…
x
Reference in New Issue
Block a user