From 4eae7a1599bbac86e16715f0c09353204d697596 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 27 Jul 2022 20:54:59 +0300 Subject: [PATCH] don't ICE when normalizing closure input tys `normalize_and_add_constraints` doesn't add entries in `universe_causes` when creating new universes, causing an ICE. Remove it! Add spans to track normalization constraints. Fix couple places where `universe_causes` is not updated correctly to track newly added universes. --- .../src/type_check/canonical.rs | 17 ++--- .../src/type_check/free_region_relations.rs | 8 +-- .../src/type_check/input_output.rs | 39 +--------- compiler/rustc_borrowck/src/type_check/mod.rs | 9 +-- ...-malformed-projection-input-issue-99665.rs | 52 ++++++++++++++ ...formed-projection-input-issue-99665.stderr | 71 +++++++++++++++++++ 6 files changed, 138 insertions(+), 58 deletions(-) create mode 100644 src/test/ui/nll/closure-malformed-projection-input-issue-99665.rs create mode 100644 src/test/ui/nll/closure-malformed-projection-input-issue-99665.stderr diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 6cfe5efb68886..dc07f3a08aa50 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -50,11 +50,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Some(error_info) => error_info.to_universe_info(old_universe), None => UniverseInfo::other(), }; - for u in old_universe..universe { - self.borrowck_context - .constraints - .universe_causes - .insert(u + 1, universe_info.clone()); + for u in (old_universe + 1)..=universe { + self.borrowck_context.constraints.universe_causes.insert(u, universe_info.clone()); } } @@ -69,15 +66,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { where T: TypeFoldable<'tcx>, { + let old_universe = self.infcx.universe(); + let (instantiated, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); - for u in 0..canonical.max_universe.as_u32() { - let info = UniverseInfo::other(); - self.borrowck_context - .constraints - .universe_causes - .insert(ty::UniverseIndex::from_u32(u), info); + for u in (old_universe + 1)..=self.infcx.universe() { + self.borrowck_context.constraints.universe_causes.insert(u, UniverseInfo::other()); } instantiated diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index fe66821ad752b..c633617a38082 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -7,7 +7,6 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::OutlivesBound; use rustc_middle::ty::{self, RegionVid, Ty}; -use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; use std::rc::Rc; use type_op::TypeOpOutput; @@ -233,6 +232,7 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> { impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { pub(crate) fn create(mut self) -> CreateResult<'tcx> { + let span = self.infcx.tcx.def_span(self.universal_regions.defining_ty.def_id()); let unnormalized_input_output_tys = self .universal_regions .unnormalized_input_tys @@ -265,7 +265,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { self.infcx .tcx .sess - .delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty)); + .delay_span_bug(span, &format!("failed to normalize {:?}", ty)); TypeOpOutput { output: self.infcx.tcx.ty_error(), constraints: None, @@ -315,8 +315,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { &self.region_bound_pairs, self.implicit_region_bound, self.param_env, - Locations::All(DUMMY_SP), - DUMMY_SP, + Locations::All(span), + span, ConstraintCategory::Internal, &mut self.constraints, ) diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 4431a2e8ec60d..a66ddd27dbb2e 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,16 +7,11 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). -use crate::type_check::constraint_conversion::ConstraintConversion; use rustc_index::vec::Idx; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::*; use rustc_middle::ty::Ty; use rustc_span::Span; -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; @@ -185,7 +180,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - #[instrument(skip(self, span), level = "debug")] + #[instrument(skip(self), level = "debug")] fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span) { if let Err(_) = self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) @@ -194,13 +189,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd // like to normalize *before* inserting into `local_decls`, but // doing so ends up causing some other trouble. - let b = match self.normalize_and_add_constraints(b) { - Ok(n) => n, - Err(_) => { - debug!("equate_inputs_and_outputs: NoSolution"); - b - } - }; + let b = self.normalize(b, Locations::All(span)); // 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`. @@ -218,28 +207,4 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } - - pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible> { - 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 { - ConstraintConversion::new( - self.infcx, - &self.borrowck_context.universal_regions, - &self.region_bound_pairs, - self.implicit_region_bound, - self.param_env, - Locations::All(DUMMY_SP), - DUMMY_SP, - ConstraintCategory::Internal, - &mut self.borrowck_context.constraints, - ) - .convert_all(&*data); - } - - Ok(norm_ty) - } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cf2140097e6da..828d4a459dec4 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -137,8 +137,6 @@ pub(crate) fn type_check<'mir, 'tcx>( use_polonius: bool, ) -> MirTypeckResults<'tcx> { let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body)); - let mut universe_causes = FxHashMap::default(); - universe_causes.insert(ty::UniverseIndex::from_u32(0), UniverseInfo::other()); let mut constraints = MirTypeckRegionConstraints { placeholder_indices: PlaceholderIndices::default(), placeholder_index_to_region: IndexVec::default(), @@ -147,7 +145,7 @@ pub(crate) fn type_check<'mir, 'tcx>( member_constraints: MemberConstraintSet::default(), closure_bounds_mapping: Default::default(), type_tests: Vec::default(), - universe_causes, + universe_causes: FxHashMap::default(), }; let CreateResult { @@ -164,9 +162,8 @@ pub(crate) fn type_check<'mir, 'tcx>( debug!(?normalized_inputs_and_output); - for u in ty::UniverseIndex::ROOT..infcx.universe() { - let info = UniverseInfo::other(); - constraints.universe_causes.insert(u, info); + for u in ty::UniverseIndex::ROOT..=infcx.universe() { + constraints.universe_causes.insert(u, UniverseInfo::other()); } let mut borrowck_context = BorrowCheckContext { diff --git a/src/test/ui/nll/closure-malformed-projection-input-issue-99665.rs b/src/test/ui/nll/closure-malformed-projection-input-issue-99665.rs new file mode 100644 index 0000000000000..532b5466ce6ef --- /dev/null +++ b/src/test/ui/nll/closure-malformed-projection-input-issue-99665.rs @@ -0,0 +1,52 @@ +// Regression test for #99665 +// +// Here we are generating region constraints +// when normalizing input types of the closure. + +// check-fail + +pub trait MyComponent { + type Properties; +} + +struct Ty1(T); +struct Ty2(T); + +impl MyComponent for Ty1 +where + M: 'static, +{ + type Properties = (); +} + +impl MyComponent for Ty2 +where + M: 'static, +{ + type Properties = &'static M; +} + +fn fail() { + // This should fail because `Ty1<&u8>` is inferred to be higher-ranked. + // So effectively we're trying to prove `for<'a> Ty1<&'a u8>: MyComponent`. + |_: as MyComponent>::Properties| {}; + //~^ ERROR lifetime may not live long enough + //~| ERROR higher-ranked subtype error + //~| ERROR higher-ranked lifetime error + //~| ERROR higher-ranked lifetime error + //~| ERROR higher-ranked lifetime error + + |_: as MyComponent>::Properties| {}; + //~^ ERROR higher-ranked subtype error + //~| ERROR higher-ranked lifetime error + //~| ERROR higher-ranked lifetime error + //~| ERROR higher-ranked lifetime error +} + +fn pass() { + // Here both are not higher-ranked, so they sould pass. + || -> as MyComponent>::Properties { panic!() }; + || -> as MyComponent>::Properties { panic!() }; +} + +fn main() {} diff --git a/src/test/ui/nll/closure-malformed-projection-input-issue-99665.stderr b/src/test/ui/nll/closure-malformed-projection-input-issue-99665.stderr new file mode 100644 index 0000000000000..378c6d54554db --- /dev/null +++ b/src/test/ui/nll/closure-malformed-projection-input-issue-99665.stderr @@ -0,0 +1,71 @@ +error: lifetime may not live long enough + --> $DIR/closure-malformed-projection-input-issue-99665.rs:32:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | || + | |has type ` as MyComponent>::Properties` + | requires that `'1` must outlive `'static` + +error: higher-ranked subtype error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:32:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked lifetime error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:32:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: could not normalize `&[closure@$DIR/closure-malformed-projection-input-issue-99665.rs:32:5: 32:47]` + +error: higher-ranked subtype error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:39:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked lifetime error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:39:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: could not normalize `&[closure@$DIR/closure-malformed-projection-input-issue-99665.rs:39:5: 39:47]` + +error: higher-ranked lifetime error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:32:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: could not normalize `[closure@$DIR/closure-malformed-projection-input-issue-99665.rs:32:5: 32:47]` + +error: higher-ranked lifetime error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:32:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: could not normalize `[closure@$DIR/closure-malformed-projection-input-issue-99665.rs:32:5: 32:47]` + +error: higher-ranked lifetime error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:39:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: could not normalize `[closure@$DIR/closure-malformed-projection-input-issue-99665.rs:39:5: 39:47]` + +error: higher-ranked lifetime error + --> $DIR/closure-malformed-projection-input-issue-99665.rs:39:5 + | +LL | |_: as MyComponent>::Properties| {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: could not normalize `[closure@$DIR/closure-malformed-projection-input-issue-99665.rs:39:5: 39:47]` + +error: aborting due to 9 previous errors +