From 0a3c6bb887dcd06730b0fe635d1c40067bf0e852 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Thu, 9 Sep 2021 18:04:59 -0400 Subject: [PATCH 1/2] In relate_tys, when creating new universes, insert missing universes as other --- .../src/type_check/relate_tys.rs | 11 ++++-- src/test/ui/hrtb/issue-88446.rs | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/hrtb/issue-88446.rs diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 0b9c33ccb77..827e3814259 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -80,10 +80,15 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { } fn create_next_universe(&mut self) -> ty::UniverseIndex { - let info_universe = - self.borrowck_context.constraints.universe_causes.push(self.universe_info.clone()); let universe = self.infcx.create_next_universe(); - assert_eq!(info_universe, universe); + // FIXME: If we relate tys after normalizing with late-bound regions, there will + // be extra universes. A proper solution would be to somehow track those universes + // during projection, but here we just treat those as "other" + self.borrowck_context + .constraints + .universe_causes + .ensure_contains_elem(universe, || UniverseInfo::other()); + self.borrowck_context.constraints.universe_causes[universe] = self.universe_info.clone(); universe } diff --git a/src/test/ui/hrtb/issue-88446.rs b/src/test/ui/hrtb/issue-88446.rs new file mode 100644 index 00000000000..571b8531757 --- /dev/null +++ b/src/test/ui/hrtb/issue-88446.rs @@ -0,0 +1,35 @@ +// check-pass + +trait Yokeable<'a> { + type Output: 'a; +} +impl<'a> Yokeable<'a> for () { + type Output = (); +} + +trait DataMarker<'data> { + type Yokeable: for<'a> Yokeable<'a>; +} +impl<'data> DataMarker<'data> for () { + type Yokeable = (); +} + +struct DataPayload<'data, M>(&'data M); + +impl DataPayload<'static, ()> { + pub fn map_project_with_capture( + _: for<'a> fn( + capture: T, + std::marker::PhantomData<&'a ()>, + ) -> >::Output, + ) -> DataPayload<'static, M2> + where + M2: DataMarker<'static>, + { + todo!() + } +} + +fn main() { + let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!()); +} From 47035e4d084d3ca57acd3c8a68371b866407d149 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Thu, 9 Sep 2021 23:28:20 -0400 Subject: [PATCH 2/2] Use FxHashMap --- compiler/rustc_borrowck/src/region_infer/mod.rs | 6 +++--- .../rustc_borrowck/src/type_check/canonical.rs | 14 +++++++++----- .../rustc_borrowck/src/type_check/input_output.rs | 2 ++ compiler/rustc_borrowck/src/type_check/mod.rs | 10 ++++++---- .../rustc_borrowck/src/type_check/relate_tys.rs | 6 +----- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 48e45a9b1ce..1c06690be3c 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -85,7 +85,7 @@ pub struct RegionInferenceContext<'tcx> { FxHashMap>, /// Map universe indexes to information on why we created it. - universe_causes: IndexVec>, + universe_causes: FxHashMap>, /// Contains the minimum universe of any variable within the same /// SCC. We will ensure that no SCC contains values that are not @@ -256,7 +256,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, >, - universe_causes: IndexVec>, + universe_causes: FxHashMap>, type_tests: Vec>, liveness_constraints: LivenessValues, elements: &Rc, @@ -2149,7 +2149,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } crate fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { - self.universe_causes[universe].clone() + self.universe_causes[&universe].clone() } } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 7a8c0a3da1f..18070164e82 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -50,9 +50,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { None => UniverseInfo::other(), }; for u in old_universe..universe { - let info_universe = - self.borrowck_context.constraints.universe_causes.push(universe_info.clone()); - assert_eq!(u.as_u32() + 1, info_universe.as_u32()); + self.borrowck_context + .constraints + .universe_causes + .insert(u + 1, universe_info.clone()); } } @@ -70,9 +71,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let (instantiated, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); - for _ in 0..canonical.max_universe.as_u32() { + for u in 0..canonical.max_universe.as_u32() { let info = UniverseInfo::other(); - self.borrowck_context.constraints.universe_causes.push(info); + self.borrowck_context + .constraints + .universe_causes + .insert(ty::UniverseIndex::from_u32(u), info); } instantiated diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 9d6f6f60a94..46d30a188ed 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -194,6 +194,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { b } }; + // 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`. if let Err(terr) = self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 2c8ff45b00d..3e757827a5e 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -136,6 +136,8 @@ pub(crate) fn type_check<'mir, 'tcx>( upvars: &[Upvar<'tcx>], ) -> 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(), @@ -144,7 +146,7 @@ pub(crate) fn type_check<'mir, 'tcx>( member_constraints: MemberConstraintSet::default(), closure_bounds_mapping: Default::default(), type_tests: Vec::default(), - universe_causes: IndexVec::from_elem_n(UniverseInfo::other(), 1), + universe_causes, }; let CreateResult { @@ -159,9 +161,9 @@ pub(crate) fn type_check<'mir, 'tcx>( &mut constraints, ); - for _ in ty::UniverseIndex::ROOT..infcx.universe() { + for u in ty::UniverseIndex::ROOT..infcx.universe() { let info = UniverseInfo::other(); - constraints.universe_causes.push(info); + constraints.universe_causes.insert(u, info); } let mut borrowck_context = BorrowCheckContext { @@ -924,7 +926,7 @@ crate struct MirTypeckRegionConstraints<'tcx> { crate closure_bounds_mapping: FxHashMap>, - crate universe_causes: IndexVec>, + crate universe_causes: FxHashMap>, crate type_tests: Vec>, } diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 827e3814259..de86d39cc37 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -81,14 +81,10 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { fn create_next_universe(&mut self) -> ty::UniverseIndex { let universe = self.infcx.create_next_universe(); - // FIXME: If we relate tys after normalizing with late-bound regions, there will - // be extra universes. A proper solution would be to somehow track those universes - // during projection, but here we just treat those as "other" self.borrowck_context .constraints .universe_causes - .ensure_contains_elem(universe, || UniverseInfo::other()); - self.borrowck_context.constraints.universe_causes[universe] = self.universe_info.clone(); + .insert(universe, self.universe_info.clone()); universe }