normalize argument b in equate_normalized_inputs_output

This commit is contained in:
b-naber 2021-11-09 20:21:51 +01:00
parent d71ba74f0d
commit 26ca71fdb2
2 changed files with 41 additions and 24 deletions

View File

@ -7,13 +7,16 @@
//! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
//! contain revealed `impl Trait` values). //! contain revealed `impl Trait` values).
use crate::type_check::constraint_conversion::ConstraintConversion;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::traits::ObligationCause; use rustc_middle::ty::Ty;
use rustc_middle::ty::{self, Ty};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::query::normalize::AtExt; use rustc_span::DUMMY_SP;
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
use rustc_trait_selection::traits::query::Fallible;
use type_op::TypeOpOutput;
use crate::universal_regions::UniversalRegions; use crate::universal_regions::UniversalRegions;
@ -30,6 +33,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let (&normalized_output_ty, normalized_input_tys) = let (&normalized_output_ty, normalized_input_tys) =
normalized_inputs_and_output.split_last().unwrap(); normalized_inputs_and_output.split_last().unwrap();
debug!(?normalized_output_ty);
debug!(?normalized_input_tys);
let mir_def_id = body.source.def_id().expect_local(); let mir_def_id = body.source.def_id().expect_local();
// If the user explicitly annotated the input types, extract // If the user explicitly annotated the input types, extract
@ -75,10 +81,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.delay_span_bug(body.span, "found more normalized_input_ty than local_decls"); .delay_span_bug(body.span, "found more normalized_input_ty than local_decls");
break; break;
} }
// In MIR, argument N is stored in local N+1. // In MIR, argument N is stored in local N+1.
let local = Local::new(argument_index + 1); let local = Local::new(argument_index + 1);
let mir_input_ty = body.local_decls[local].ty; let mir_input_ty = body.local_decls[local].ty;
let mir_input_span = body.local_decls[local].source_info.span; let mir_input_span = body.local_decls[local].source_info.span;
self.equate_normalized_input_or_output( self.equate_normalized_input_or_output(
normalized_input_ty, normalized_input_ty,
@ -100,6 +108,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// If the user explicitly annotated the input types, enforce those. // If the user explicitly annotated the input types, enforce those.
let user_provided_input_ty = let user_provided_input_ty =
self.normalize(user_provided_input_ty, Locations::All(mir_input_span)); self.normalize(user_provided_input_ty, Locations::All(mir_input_span));
self.equate_normalized_input_or_output( self.equate_normalized_input_or_output(
user_provided_input_ty, user_provided_input_ty,
mir_input_ty, mir_input_ty,
@ -167,30 +176,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd
// like to normalize *before* inserting into `local_decls`, but // like to normalize *before* inserting into `local_decls`, but
// doing so ends up causing some other trouble. // doing so ends up causing some other trouble.
let b = match self let b = match self.normalize_and_add_constraints(b) {
.infcx Ok(n) => n,
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
.normalize(b)
{
Ok(n) => {
debug!("equate_inputs_and_outputs: {:?}", n);
if n.obligations.iter().all(|o| {
matches!(
o.predicate.kind().skip_binder(),
ty::PredicateKind::RegionOutlives(_)
| ty::PredicateKind::TypeOutlives(_)
)
}) {
n.value
} else {
b
}
}
Err(_) => { Err(_) => {
debug!("equate_inputs_and_outputs: NoSolution"); debug!("equate_inputs_and_outputs: NoSolution");
b b
} }
}; };
// Note: if we have to introduce new placeholders during normalization above, then we won't have // Note: if we have to introduce new placeholders during normalization above, then we won't have
// added those universes to the universe info, which we would want in `relate_tys`. // added those universes to the universe info, which we would want in `relate_tys`.
if let Err(terr) = if let Err(terr) =
@ -207,4 +200,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
} }
} }
pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible<Ty<'tcx>> {
let TypeOpOutput { output: norm_ty, constraints, .. } =
self.param_env.and(type_op::normalize::Normalize::new(t)).fully_perform(self.infcx)?;
debug!("{:?} normalized to {:?}", t, norm_ty);
for data in constraints.into_iter().collect::<Vec<_>>() {
ConstraintConversion::new(
self.infcx,
&self.borrowck_context.universal_regions,
&self.region_bound_pairs,
Some(self.implicit_region_bound),
self.param_env,
Locations::All(DUMMY_SP),
ConstraintCategory::Internal,
&mut self.borrowck_context.constraints,
)
.convert_all(&*data);
}
Ok(norm_ty)
}
} }

View File

@ -893,11 +893,11 @@ struct TypeChecker<'a, 'tcx> {
} }
struct BorrowCheckContext<'a, 'tcx> { struct BorrowCheckContext<'a, 'tcx> {
universal_regions: &'a UniversalRegions<'tcx>, pub(crate) universal_regions: &'a UniversalRegions<'tcx>,
location_table: &'a LocationTable, location_table: &'a LocationTable,
all_facts: &'a mut Option<AllFacts>, all_facts: &'a mut Option<AllFacts>,
borrow_set: &'a BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
upvars: &'a [Upvar<'tcx>], upvars: &'a [Upvar<'tcx>],
} }
@ -1157,6 +1157,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category) self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category)
} }
#[instrument(skip(self, category), level = "debug")]
fn eq_types( fn eq_types(
&mut self, &mut self,
expected: Ty<'tcx>, expected: Ty<'tcx>,