about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs11
-rw-r--r--src/test/ui/hrtb/issue-88446.rs35
2 files changed, 43 insertions, 3 deletions
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<M2, T>(
+        _: for<'a> fn(
+            capture: T,
+            std::marker::PhantomData<&'a ()>,
+        ) -> <M2::Yokeable as Yokeable<'a>>::Output,
+    ) -> DataPayload<'static, M2>
+    where
+        M2: DataMarker<'static>,
+    {
+        todo!()
+    }
+}
+
+fn main() {
+    let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!());
+}