about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-07-13 23:17:21 +0000
committerMichael Goulet <michael@errs.io>2025-07-15 16:02:26 +0000
commit78fa79e7a642c8817b67d1c10d782c4c7b661a00 (patch)
treefd15b0d3a45e3d85a7c43204ed6cc9b649fdfb92
parent512cf3ae88b26f50a92ebfcb69c24ca39acd72e6 (diff)
downloadrust-78fa79e7a642c8817b67d1c10d782c4c7b661a00.tar.gz
rust-78fa79e7a642c8817b67d1c10d782c4c7b661a00.zip
Add tests, some of them fail...
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-1.no_assumptions.stderr38
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-1.rs48
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-10.assumptions.stderr21
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-10.no_assumptions.stderr21
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-10.rs35
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-11.assumptions.stderr20
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-11.no_assumptions.stderr20
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-11.rs31
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-12.no_assumptions.stderr18
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-12.rs40
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-13.assumptions.stderr41
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-13.no_assumptions.stderr60
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-13.rs68
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr33
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-14.rs29
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-15.no_assumptions.stderr21
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-15.rs21
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-16.assumptions.stderr25
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-16.no_assumptions.stderr25
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-16.rs23
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-17.no_assumptions.stderr29
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-17.rs30
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr49
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-2.rs23
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr12
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-3.rs72
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-4.no_assumptions.stderr10
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-4.rs34
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-5.no_assumptions.stderr13
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-5.rs54
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr50
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-6.rs59
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr8
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-7.rs33
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-8.no_assumptions.stderr10
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-8.rs27
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-9.no_assumptions.stderr11
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-9.rs44
38 files changed, 1206 insertions, 0 deletions
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-1.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-1.no_assumptions.stderr
new file mode 100644
index 00000000000..b298a3bf215
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-1.no_assumptions.stderr
@@ -0,0 +1,38 @@
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-auto-trait-1.rs:37:5
+   |
+LL | /     async {
+LL | |         let _y = &();
+LL | |         let _x = filter(FilterMap {
+LL | |             f: || async move { *_y },
+...  |
+LL | |         drop(_x);
+LL | |     }
+   | |_____^ one type is more general than the other
+   |
+   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}`
+              found `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}`
+   = note: no two async blocks, even if identical, have the same type
+   = help: consider pinning your async block and casting it to a trait object
+
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-auto-trait-1.rs:37:5
+   |
+LL | /     async {
+LL | |         let _y = &();
+LL | |         let _x = filter(FilterMap {
+LL | |             f: || async move { *_y },
+...  |
+LL | |         drop(_x);
+LL | |     }
+   | |_____^ one type is more general than the other
+   |
+   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}`
+              found `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}`
+   = note: no two async blocks, even if identical, have the same type
+   = help: consider pinning your async block and casting it to a trait object
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-1.rs b/tests/ui/async-await/higher-ranked-auto-trait-1.rs
new file mode 100644
index 00000000000..740f7e29245
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-1.rs
@@ -0,0 +1,48 @@
+// Repro for <https://github.com/rust-lang/rust/issues/79648#issuecomment-749127947>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+use std::future::Future;
+use std::marker::PhantomData;
+
+trait Stream {
+    type Item;
+}
+
+struct Filter<St: Stream> {
+    pending_item: St::Item,
+}
+
+fn filter<St: Stream>(_: St) -> Filter<St> {
+    unimplemented!();
+}
+
+struct FilterMap<Fut, F> {
+    f: F,
+    pending: PhantomData<Fut>,
+}
+
+impl<Fut, F> Stream for FilterMap<Fut, F>
+where
+    F: FnMut() -> Fut,
+    Fut: Future,
+{
+    type Item = ();
+}
+
+pub fn get_foo() -> impl Future + Send {
+    async {
+        let _y = &();
+        let _x = filter(FilterMap {
+            f: || async move { *_y },
+            pending: PhantomData,
+        });
+        async {}.await;
+        drop(_x);
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-10.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-10.assumptions.stderr
new file mode 100644
index 00000000000..6fcf1b1eac1
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-10.assumptions.stderr
@@ -0,0 +1,21 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/higher-ranked-auto-trait-10.rs:32:5
+   |
+LL |     Box::new(async move { get_foo(x).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2`
+
+error: implementation of `Foo` is not general enough
+  --> $DIR/higher-ranked-auto-trait-10.rs:32:5
+   |
+LL |     Box::new(async move { get_foo(x).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-10.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-10.no_assumptions.stderr
new file mode 100644
index 00000000000..6fcf1b1eac1
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-10.no_assumptions.stderr
@@ -0,0 +1,21 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/higher-ranked-auto-trait-10.rs:32:5
+   |
+LL |     Box::new(async move { get_foo(x).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2`
+
+error: implementation of `Foo` is not general enough
+  --> $DIR/higher-ranked-auto-trait-10.rs:32:5
+   |
+LL |     Box::new(async move { get_foo(x).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-10.rs b/tests/ui/async-await/higher-ranked-auto-trait-10.rs
new file mode 100644
index 00000000000..4bfa27961ab
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-10.rs
@@ -0,0 +1,35 @@
+// Repro for <https://github.com/rust-lang/rust/issues/92415#issue-1090723521>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] known-bug: unknown
+//@[no_assumptions] known-bug: #110338
+
+use std::any::Any;
+use std::future::Future;
+
+trait Foo<'a>: Sized {
+    type Error;
+    fn foo(x: &'a str) -> Result<Self, Self::Error>;
+}
+
+impl<'a> Foo<'a> for &'a str {
+    type Error = ();
+
+    fn foo(x: &'a str) -> Result<Self, Self::Error> {
+        Ok(x)
+    }
+}
+
+async fn get_foo<'a, T>(x: &'a str) -> Result<T, <T as Foo<'a>>::Error>
+where
+    T: Foo<'a>,
+{
+    Foo::foo(x)
+}
+
+fn bar<'a>(x: &'a str) -> Box<dyn Future<Output = Result<&'a str, ()>> + Send + 'a> {
+    Box::new(async move { get_foo(x).await })
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-11.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-11.assumptions.stderr
new file mode 100644
index 00000000000..d39843f628c
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-11.assumptions.stderr
@@ -0,0 +1,20 @@
+error: lifetime may not live long enough
+  --> $DIR/higher-ranked-auto-trait-11.rs:27:9
+   |
+LL | impl<'a, T> Foo<'a> for MyType<T>
+   |      -- lifetime `'a` defined here
+...
+LL |         Box::pin(async move { <T as Foo<'a>>::foo().await })
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'a` must outlive `'static`
+
+error: implementation of `Send` is not general enough
+  --> $DIR/higher-ranked-auto-trait-11.rs:27:9
+   |
+LL |         Box::pin(async move { <T as Foo<'a>>::foo().await })
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Send` is not general enough
+   |
+   = note: `Send` would have to be implemented for the type `<T as Foo<'0>>::Future`, for any lifetime `'0`...
+   = note: ...but `Send` is actually implemented for the type `<T as Foo<'1>>::Future`, for some specific lifetime `'1`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-11.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-11.no_assumptions.stderr
new file mode 100644
index 00000000000..d39843f628c
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-11.no_assumptions.stderr
@@ -0,0 +1,20 @@
+error: lifetime may not live long enough
+  --> $DIR/higher-ranked-auto-trait-11.rs:27:9
+   |
+LL | impl<'a, T> Foo<'a> for MyType<T>
+   |      -- lifetime `'a` defined here
+...
+LL |         Box::pin(async move { <T as Foo<'a>>::foo().await })
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'a` must outlive `'static`
+
+error: implementation of `Send` is not general enough
+  --> $DIR/higher-ranked-auto-trait-11.rs:27:9
+   |
+LL |         Box::pin(async move { <T as Foo<'a>>::foo().await })
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Send` is not general enough
+   |
+   = note: `Send` would have to be implemented for the type `<T as Foo<'0>>::Future`, for any lifetime `'0`...
+   = note: ...but `Send` is actually implemented for the type `<T as Foo<'1>>::Future`, for some specific lifetime `'1`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-11.rs b/tests/ui/async-await/higher-ranked-auto-trait-11.rs
new file mode 100644
index 00000000000..3aebdd8224d
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-11.rs
@@ -0,0 +1,31 @@
+// Repro for <https://github.com/rust-lang/rust/issues/60658#issuecomment-1509321859>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] known-bug: unknown
+//@[no_assumptions] known-bug: #110338
+
+use core::pin::Pin;
+use std::future::Future;
+
+pub trait Foo<'a> {
+    type Future: Future<Output = ()>;
+
+    fn foo() -> Self::Future;
+}
+
+struct MyType<T>(T);
+
+impl<'a, T> Foo<'a> for MyType<T>
+where
+    T: Foo<'a>,
+    T::Future: Send,
+{
+    type Future = Pin<Box<dyn Future<Output = ()> + Send + 'a>>;
+
+    fn foo() -> Self::Future {
+        Box::pin(async move { <T as Foo<'a>>::foo().await })
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-12.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-12.no_assumptions.stderr
new file mode 100644
index 00000000000..63e71cbc40c
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-12.no_assumptions.stderr
@@ -0,0 +1,18 @@
+error: implementation of `Robot` is not general enough
+  --> $DIR/higher-ranked-auto-trait-12.rs:31:20
+   |
+LL |       let _my_task = this_is_send(async move {
+   |  ____________________^
+LL | |         let _my_iter = IRobot {
+LL | |             id: 32,
+LL | |             robot: source,
+LL | |         };
+LL | |         yield_now().await;
+LL | |     });
+   | |______^ implementation of `Robot` is not general enough
+   |
+   = note: `Box<(dyn Robot<Id = u32> + Send + '0)>` must implement `Robot`, for any lifetime `'0`...
+   = note: ...but `Robot` is actually implemented for the type `Box<(dyn Robot<Id = u32> + Send + 'static)>`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-12.rs b/tests/ui/async-await/higher-ranked-auto-trait-12.rs
new file mode 100644
index 00000000000..b1cca5cbb00
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-12.rs
@@ -0,0 +1,40 @@
+// Repro for <https://github.com/rust-lang/rust/issues/71671#issuecomment-848994782>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+pub trait Robot {
+    type Id;
+}
+
+pub type DynRobot = Box<dyn Robot<Id = u32> + Send>;
+
+impl Robot for DynRobot {
+    type Id = u32;
+}
+
+struct IRobot<R: Robot> {
+    id: R::Id,
+    robot: R,
+}
+
+// stand-in for tokio::spawn
+fn this_is_send<T: Send>(value: T) -> T {
+    value
+}
+
+async fn yield_now() {}
+
+fn test(source: DynRobot) {
+    let _my_task = this_is_send(async move {
+        let _my_iter = IRobot {
+            id: 32,
+            robot: source,
+        };
+        yield_now().await;
+    });
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-13.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-13.assumptions.stderr
new file mode 100644
index 00000000000..f69218740dc
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-13.assumptions.stderr
@@ -0,0 +1,41 @@
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-13.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-13.no_assumptions.stderr
new file mode 100644
index 00000000000..cfbdaa8ad4b
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-13.no_assumptions.stderr
@@ -0,0 +1,60 @@
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `Callable` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Callable` is not general enough
+   |
+   = note: `Callable<'_>` would have to be implemented for the type `ConstructableImpl<'0>`, for any lifetime `'0`...
+   = note: ...but `Callable<'1>` is actually implemented for the type `ConstructableImpl<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `Getter` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough
+   |
+   = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `Callable` is not general enough
+  --> $DIR/higher-ranked-auto-trait-13.rs:65:5
+   |
+LL |     assert_send(my_send_async_method(struct_with_lifetime, data));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Callable` is not general enough
+   |
+   = note: `Callable<'_>` would have to be implemented for the type `ConstructableImpl<'0>`, for any lifetime `'0`...
+   = note: ...but `Callable<'1>` is actually implemented for the type `ConstructableImpl<'1>`, for some specific lifetime `'1`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-13.rs b/tests/ui/async-await/higher-ranked-auto-trait-13.rs
new file mode 100644
index 00000000000..4bce0f5197f
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-13.rs
@@ -0,0 +1,68 @@
+// Repro for <https://github.com/rust-lang/rust/issues/114046#issue-1819720359>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] known-bug: unknown
+//@[no_assumptions] known-bug: #110338
+
+use std::marker::PhantomData;
+
+trait Callable<'a>: Send + Sync {
+    fn callable(data: &'a [u8]);
+}
+
+trait Getter<'a>: Send + Sync {
+    type ItemSize: Send + Sync;
+
+    fn get(data: &'a [u8]);
+}
+
+struct List<'a, A: Getter<'a>> {
+    data: &'a [u8],
+    item_size: A::ItemSize, // Removing this member causes the code to compile
+    phantom: PhantomData<A>,
+}
+
+struct GetterImpl<'a, T: Callable<'a> + 'a> {
+    p: PhantomData<&'a T>,
+}
+
+impl<'a, T: Callable<'a> + 'a> Getter<'a> for GetterImpl<'a, T> {
+    type ItemSize = ();
+
+    fn get(data: &'a [u8]) {
+        <T>::callable(data);
+    }
+}
+
+struct ConstructableImpl<'a> {
+    _data: &'a [u8],
+}
+
+impl<'a> Callable<'a> for ConstructableImpl<'a> {
+    fn callable(_: &'a [u8]) {}
+}
+
+struct StructWithLifetime<'a> {
+    marker: &'a PhantomData<u8>,
+}
+
+async fn async_method() {}
+
+fn assert_send(_: impl Send + Sync) {}
+
+// This async method ought to be send, but is not
+async fn my_send_async_method(_struct_with_lifetime: &mut StructWithLifetime<'_>, data: &Vec<u8>) {
+    let _named =
+        List::<'_, GetterImpl<ConstructableImpl<'_>>> { data, item_size: (), phantom: PhantomData };
+    // Moving the await point above the constructed of _named, causes
+    // the method to become send, even though _named is Send + Sync
+    async_method().await;
+    assert_send(_named);
+}
+
+fn dummy(struct_with_lifetime: &mut StructWithLifetime<'_>, data: &Vec<u8>) {
+    assert_send(my_send_async_method(struct_with_lifetime, data));
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr
new file mode 100644
index 00000000000..b47db2b19ff
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr
@@ -0,0 +1,33 @@
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-14.rs:20:5
+   |
+LL | /     async move {
+LL | |         let xs = unique_x.union(&cached)
+LL | |             // .copied() // works
+LL | |             .map(|x| *x) // error
+LL | |             ;
+LL | |         let blah = val.blah(xs.into_iter()).await;
+LL | |     }
+   | |_____^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&u32,)>`
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-14.rs:20:5
+   |
+LL | /     async move {
+LL | |         let xs = unique_x.union(&cached)
+LL | |             // .copied() // works
+LL | |             .map(|x| *x) // error
+LL | |             ;
+LL | |         let blah = val.blah(xs.into_iter()).await;
+LL | |     }
+   | |_____^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&u32,)>`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-14.rs b/tests/ui/async-await/higher-ranked-auto-trait-14.rs
new file mode 100644
index 00000000000..5ed12cd6e38
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-14.rs
@@ -0,0 +1,29 @@
+// Repro for <https://github.com/rust-lang/rust/issues/124757#issue-2279603232>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+use std::collections::HashSet;
+use std::future::Future;
+
+trait MyTrait {
+    fn blah(&self, x: impl Iterator<Item = u32>) -> impl Future<Output = ()> + Send;
+}
+
+fn foo<T: MyTrait + Send + Sync>(
+    val: T,
+    unique_x: HashSet<u32>,
+) -> impl Future<Output = ()> + Send {
+    let cached = HashSet::new();
+    async move {
+        let xs = unique_x.union(&cached)
+            // .copied() // works
+            .map(|x| *x) // error
+            ;
+        let blah = val.blah(xs.into_iter()).await;
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-15.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-15.no_assumptions.stderr
new file mode 100644
index 00000000000..b4f3570d9f2
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-15.no_assumptions.stderr
@@ -0,0 +1,21 @@
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-15.rs:20:5
+   |
+LL |     require_send(future);
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'0 Vec<i32>) -> std::slice::Iter<'_, i32>` must implement `FnOnce<(&'1 Vec<i32>,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&Vec<i32>,)>`
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-15.rs:20:5
+   |
+LL |     require_send(future);
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'0 Vec<i32>) -> std::slice::Iter<'_, i32>` must implement `FnOnce<(&'1 Vec<i32>,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&Vec<i32>,)>`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-15.rs b/tests/ui/async-await/higher-ranked-auto-trait-15.rs
new file mode 100644
index 00000000000..153fcac4c3a
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-15.rs
@@ -0,0 +1,21 @@
+// Repro for <https://github.com/rust-lang/rust/issues/126044#issuecomment-2154313449>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+async fn listen() {
+    let things: Vec<Vec<i32>> = vec![];
+    for _ in things.iter().map(|n| n.iter()).flatten() {
+        // comment this line and everything compiles
+        async {}.await;
+    }
+}
+
+fn require_send<T: Send>(_x: T) {}
+
+fn main() {
+    let future = listen();
+    require_send(future);
+}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-16.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-16.assumptions.stderr
new file mode 100644
index 00000000000..412c31b1bd8
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-16.assumptions.stderr
@@ -0,0 +1,25 @@
+error: implementation of `AsyncFnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-16.rs:18:5
+   |
+LL | /     assert_send(async {
+LL | |         commit_if_ok(&mut ctxt, async |_| todo!()).await;
+LL | |     });
+   | |______^ implementation of `AsyncFnOnce` is not general enough
+   |
+   = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>`
+
+error: implementation of `AsyncFnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-16.rs:18:5
+   |
+LL | /     assert_send(async {
+LL | |         commit_if_ok(&mut ctxt, async |_| todo!()).await;
+LL | |     });
+   | |______^ implementation of `AsyncFnOnce` is not general enough
+   |
+   = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-16.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-16.no_assumptions.stderr
new file mode 100644
index 00000000000..412c31b1bd8
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-16.no_assumptions.stderr
@@ -0,0 +1,25 @@
+error: implementation of `AsyncFnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-16.rs:18:5
+   |
+LL | /     assert_send(async {
+LL | |         commit_if_ok(&mut ctxt, async |_| todo!()).await;
+LL | |     });
+   | |______^ implementation of `AsyncFnOnce` is not general enough
+   |
+   = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>`
+
+error: implementation of `AsyncFnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-16.rs:18:5
+   |
+LL | /     assert_send(async {
+LL | |         commit_if_ok(&mut ctxt, async |_| todo!()).await;
+LL | |     });
+   | |______^ implementation of `AsyncFnOnce` is not general enough
+   |
+   = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-16.rs b/tests/ui/async-await/higher-ranked-auto-trait-16.rs
new file mode 100644
index 00000000000..2b206f0a4c5
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-16.rs
@@ -0,0 +1,23 @@
+// Repro for <https://github.com/rust-lang/rust/issues/126350#issue-2349492101>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] known-bug: unknown
+//@[no_assumptions] known-bug: #110338
+
+fn assert_send<T: Send>(_: T) {}
+
+#[derive(Clone)]
+struct Ctxt<'a>(&'a ());
+
+async fn commit_if_ok<'a>(ctxt: &mut Ctxt<'a>, f: impl AsyncFnOnce(&mut Ctxt<'a>)) {
+    f(&mut ctxt.clone()).await;
+}
+
+fn operation(mut ctxt: Ctxt<'_>) {
+    assert_send(async {
+        commit_if_ok(&mut ctxt, async |_| todo!()).await;
+    });
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-17.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-17.no_assumptions.stderr
new file mode 100644
index 00000000000..152900ca1ae
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-17.no_assumptions.stderr
@@ -0,0 +1,29 @@
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-17.rs:12:5
+   |
+LL | /     async move {
+LL | |         let iter = Adaptor::new(a.iter().map(|_: &()| {}));
+LL | |         std::future::pending::<()>().await;
+LL | |         drop(iter);
+LL | |     }
+   | |_____^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'0 ())` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&(),)>`
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/higher-ranked-auto-trait-17.rs:12:5
+   |
+LL | /     async move {
+LL | |         let iter = Adaptor::new(a.iter().map(|_: &()| {}));
+LL | |         std::future::pending::<()>().await;
+LL | |         drop(iter);
+LL | |     }
+   | |_____^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'0 ())` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `FnOnce<(&(),)>`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-17.rs b/tests/ui/async-await/higher-ranked-auto-trait-17.rs
new file mode 100644
index 00000000000..152432466c0
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-17.rs
@@ -0,0 +1,30 @@
+// Repro for <https://github.com/rust-lang/rust/issues/114177#issue-1826550174>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+// Using `impl Future` instead of `async to ensure that the Future is Send.
+//
+// In the original code `a` would be `&[T]`. For more minimization I've removed the reference.
+fn foo(a: [(); 0]) -> impl std::future::Future<Output = ()> + Send {
+    async move {
+        let iter = Adaptor::new(a.iter().map(|_: &()| {}));
+        std::future::pending::<()>().await;
+        drop(iter);
+    }
+}
+
+struct Adaptor<T: Iterator> {
+    iter: T,
+    v: T::Item,
+}
+
+impl<T: Iterator> Adaptor<T> {
+    pub fn new(_: T) -> Self {
+        Self { iter: todo!(), v: todo!() }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr
new file mode 100644
index 00000000000..2fc44412b9d
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr
@@ -0,0 +1,49 @@
+error: lifetime bound not satisfied
+  --> $DIR/higher-ranked-auto-trait-2.rs:16:9
+   |
+LL | /         async move {
+LL | |             // asks for an unspecified lifetime to outlive itself? weird diagnostics
+LL | |             self.run(t).await;
+LL | |         }
+   | |_________^
+   |
+   = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: lifetime bound not satisfied
+  --> $DIR/higher-ranked-auto-trait-2.rs:16:9
+   |
+LL | /         async move {
+LL | |             // asks for an unspecified lifetime to outlive itself? weird diagnostics
+LL | |             self.run(t).await;
+LL | |         }
+   | |_________^
+   |
+   = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: lifetime bound not satisfied
+  --> $DIR/higher-ranked-auto-trait-2.rs:16:9
+   |
+LL | /         async move {
+LL | |             // asks for an unspecified lifetime to outlive itself? weird diagnostics
+LL | |             self.run(t).await;
+LL | |         }
+   | |_________^
+   |
+   = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: lifetime bound not satisfied
+  --> $DIR/higher-ranked-auto-trait-2.rs:16:9
+   |
+LL | /         async move {
+LL | |             // asks for an unspecified lifetime to outlive itself? weird diagnostics
+LL | |             self.run(t).await;
+LL | |         }
+   | |_________^
+   |
+   = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-2.rs b/tests/ui/async-await/higher-ranked-auto-trait-2.rs
new file mode 100644
index 00000000000..6c75597265b
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-2.rs
@@ -0,0 +1,23 @@
+// Repro for <https://github.com/rust-lang/rust/issues/111105#issue-1692860759>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+use std::future::Future;
+
+pub trait Foo: Sync {
+    fn run<'a, 'b: 'a, T: Sync>(&'a self, _: &'b T) -> impl Future<Output = ()> + 'a + Send;
+}
+
+pub trait FooExt: Foo {
+    fn run_via<'a, 'b: 'a, T: Sync>(&'a self, t: &'b T) -> impl Future<Output = ()> + 'a + Send {
+        async move {
+            // asks for an unspecified lifetime to outlive itself? weird diagnostics
+            self.run(t).await;
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr
new file mode 100644
index 00000000000..c5c98ac807e
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr
@@ -0,0 +1,12 @@
+error: lifetime bound not satisfied
+  --> $DIR/higher-ranked-auto-trait-3.rs:66:9
+   |
+LL | /         async {
+LL | |             self.fi_2.get_iter(cx).await;
+LL | |         }
+   | |_________^
+   |
+   = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.rs b/tests/ui/async-await/higher-ranked-auto-trait-3.rs
new file mode 100644
index 00000000000..d42d4236680
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-3.rs
@@ -0,0 +1,72 @@
+// Repro for <https://github.com/rust-lang/rust/issues/100013#issue-1323807923>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+#![feature(impl_trait_in_assoc_type)]
+
+use std::future::Future;
+
+pub trait FutureIterator: 'static {
+    type Iterator;
+
+    type Future<'s, 'cx>: Future<Output = Self::Iterator> + Send + 'cx
+    where
+        's: 'cx;
+
+    fn get_iter<'s, 'cx>(&'s self, info: &'cx ()) -> Self::Future<'s, 'cx>;
+}
+
+trait IterCaller: 'static {
+    type Future1<'cx>: Future<Output = ()> + Send + 'cx;
+    type Future2<'cx>: Future<Output = ()> + Send + 'cx;
+
+    fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
+    where
+        's: 'cx;
+    fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
+    where
+        's: 'cx;
+}
+
+struct UseIter<FI1, FI2> {
+    fi_1: FI1,
+    fi_2: FI2,
+}
+
+impl<FI1, FI2> IterCaller for UseIter<FI1, FI2>
+where
+    FI1: FutureIterator + 'static + Send + Sync,
+    for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
+    FI2: FutureIterator + 'static + Send + Sync,
+{
+    type Future1<'cx> = impl Future<Output = ()> + Send + 'cx
+    where
+        Self: 'cx;
+
+    type Future2<'cx> = impl Future<Output = ()> + Send + 'cx
+    where
+        Self: 'cx;
+
+    fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
+    where
+        's: 'cx,
+    {
+        async {
+            self.fi_1.get_iter(cx).await;
+        }
+    }
+
+    fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
+    where
+        's: 'cx,
+    {
+        async {
+            self.fi_2.get_iter(cx).await;
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-4.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-4.no_assumptions.stderr
new file mode 100644
index 00000000000..5aa5b83655a
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-4.no_assumptions.stderr
@@ -0,0 +1,10 @@
+error: higher-ranked lifetime error
+  --> $DIR/higher-ranked-auto-trait-4.rs:29:5
+   |
+LL | /     async {
+LL | |         let _ = evil_function::<dyn BoringTrait, _>().await;
+LL | |     }
+   | |_____^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-4.rs b/tests/ui/async-await/higher-ranked-auto-trait-4.rs
new file mode 100644
index 00000000000..0586af41e9e
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-4.rs
@@ -0,0 +1,34 @@
+// Repro for <https://github.com/rust-lang/rust/issues/102211#issuecomment-2891975128>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+use std::future::Future;
+
+trait BoringTrait {}
+
+trait TraitWithAssocType<I> {
+    type Assoc;
+}
+
+impl<T> TraitWithAssocType<()> for T
+where
+    T: ?Sized + 'static,
+{
+    type Assoc = ();
+}
+
+fn evil_function<T: TraitWithAssocType<I> + ?Sized, I>()
+-> impl Future<Output = Result<(), T::Assoc>> {
+    async { Ok(()) }
+}
+
+fn fails_to_compile() -> impl std::future::Future<Output = ()> + Send {
+    async {
+        let _ = evil_function::<dyn BoringTrait, _>().await;
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-5.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-5.no_assumptions.stderr
new file mode 100644
index 00000000000..8fa3c7483c8
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-5.no_assumptions.stderr
@@ -0,0 +1,13 @@
+error: implementation of `Send` is not general enough
+  --> $DIR/higher-ranked-auto-trait-5.rs:13:5
+   |
+LL | /     assert_send(async {
+LL | |         call_me.call().await;
+LL | |     });
+   | |______^ implementation of `Send` is not general enough
+   |
+   = note: `Send` would have to be implemented for the type `&'0 str`, for any lifetime `'0`...
+   = note: ...but `Send` is actually implemented for the type `&'1 str`, for some specific lifetime `'1`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-5.rs b/tests/ui/async-await/higher-ranked-auto-trait-5.rs
new file mode 100644
index 00000000000..9a8b3f4357c
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-5.rs
@@ -0,0 +1,54 @@
+// Repro for <https://github.com/rust-lang/rust/issues/130113#issue-2512517191>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+use std::future::Future;
+
+fn main() {
+    let call_me = Wrap(CallMeImpl { value: "test" });
+
+    assert_send(async {
+        call_me.call().await;
+    });
+}
+
+pub fn assert_send<F>(_future: F)
+where
+    F: Future + Send,
+{
+}
+
+pub trait CallMe {
+    fn call(&self) -> impl Future<Output = ()> + Send;
+}
+
+struct Wrap<T>(T);
+
+impl<S> CallMe for Wrap<S>
+where
+    S: CallMe + Send,
+{
+    // adding `+ Send` to this RPIT fixes the issue
+    fn call(&self) -> impl Future<Output = ()> {
+        self.0.call()
+    }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct CallMeImpl<T> {
+    value: T,
+}
+
+impl<T> CallMe for CallMeImpl<T>
+where
+    // Can replace `Send` by `ToString`, `Clone`, whatever. When removing the
+    // `Send` bound, the compiler produces a higher-ranked lifetime error.
+    T: Send + 'static,
+{
+    fn call(&self) -> impl Future<Output = ()> {
+        async {}
+    }
+}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr
new file mode 100644
index 00000000000..d1f2d9a0753
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr
@@ -0,0 +1,50 @@
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-auto-trait-6.rs:16:5
+   |
+LL |     Box::new(async { new(|| async { f().await }).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+              found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+   = note: no two async blocks, even if identical, have the same type
+   = help: consider pinning your async block and casting it to a trait object
+
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-auto-trait-6.rs:16:5
+   |
+LL |     Box::new(async { new(|| async { f().await }).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+              found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+   = note: no two async blocks, even if identical, have the same type
+   = help: consider pinning your async block and casting it to a trait object
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-auto-trait-6.rs:16:5
+   |
+LL |     Box::new(async { new(|| async { f().await }).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+              found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+   = note: no two async blocks, even if identical, have the same type
+   = help: consider pinning your async block and casting it to a trait object
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-auto-trait-6.rs:16:5
+   |
+LL |     Box::new(async { new(|| async { f().await }).await })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+              found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
+   = note: no two async blocks, even if identical, have the same type
+   = help: consider pinning your async block and casting it to a trait object
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-6.rs b/tests/ui/async-await/higher-ranked-auto-trait-6.rs
new file mode 100644
index 00000000000..2c6adf8938d
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-6.rs
@@ -0,0 +1,59 @@
+// Repro for <https://github.com/rust-lang/rust/issues/82921#issue-825114180>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+use core::future::Future;
+use core::marker::PhantomData;
+use core::pin::Pin;
+use core::task::{Context, Poll};
+
+async fn f() {}
+
+pub fn fail<'a>() -> Box<dyn Future<Output = ()> + Send + 'a> {
+    Box::new(async { new(|| async { f().await }).await })
+}
+
+fn new<A, B>(_a: A) -> F<A, B>
+where
+    A: Fn() -> B,
+{
+    F { _i: PhantomData }
+}
+
+trait Stream {
+    type Item;
+}
+
+struct T<A, B> {
+    _a: PhantomData<A>,
+    _b: PhantomData<B>,
+}
+
+impl<A, B> Stream for T<A, B>
+where
+    A: Fn() -> B,
+{
+    type Item = B;
+}
+
+struct F<A, B>
+where
+    A: Fn() -> B,
+{
+    _i: PhantomData<<T<A, B> as Stream>::Item>,
+}
+
+impl<A, B> Future for F<A, B>
+where
+    A: Fn() -> B,
+{
+    type Output = ();
+    fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
+        unimplemented!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr
new file mode 100644
index 00000000000..dcb8075566e
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr
@@ -0,0 +1,8 @@
+error: `S` does not live long enough
+  --> $DIR/higher-ranked-auto-trait-7.rs:26:5
+   |
+LL |     future::<'a, S, _>(async move {
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-7.rs b/tests/ui/async-await/higher-ranked-auto-trait-7.rs
new file mode 100644
index 00000000000..abded5a88d3
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-7.rs
@@ -0,0 +1,33 @@
+// Repro for <https://github.com/rust-lang/rust/issues/90696#issuecomment-963375847>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+#![allow(dropping_copy_types)]
+
+use std::{future::Future, marker::PhantomData};
+
+trait Trait {
+    type Associated<'a>: Send
+    where
+        Self: 'a;
+}
+
+fn future<'a, S: Trait + 'a, F>(f: F) -> F
+where
+    F: Future<Output = ()> + Send,
+{
+    f
+}
+
+fn foo<'a, S: Trait + 'a>() {
+    future::<'a, S, _>(async move {
+        let result: PhantomData<S::Associated<'a>> = PhantomData;
+        async {}.await;
+        drop(result);
+    });
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-8.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-8.no_assumptions.stderr
new file mode 100644
index 00000000000..6208675117b
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-8.no_assumptions.stderr
@@ -0,0 +1,10 @@
+error: higher-ranked lifetime error
+  --> $DIR/higher-ranked-auto-trait-8.rs:26:5
+   |
+LL |     needs_send(use_my_struct(second_struct)); // ERROR
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: could not prove `impl Future<Output = ()>: Send`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-8.rs b/tests/ui/async-await/higher-ranked-auto-trait-8.rs
new file mode 100644
index 00000000000..91cef204e44
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-8.rs
@@ -0,0 +1,27 @@
+// Repro for <https://github.com/rust-lang/rust/issues/64552#issuecomment-532801232>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+fn needs_send<T: Send>(_val: T) {}
+async fn use_async<T>(_val: T) {}
+
+struct MyStruct<'a, T: 'a> {
+    val: &'a T,
+}
+
+unsafe impl<'a, T: 'a> Send for MyStruct<'a, T> {}
+
+async fn use_my_struct(val: MyStruct<'static, &'static u8>) {
+    use_async(val).await;
+}
+
+fn main() {
+    let first_struct: MyStruct<'static, &'static u8> = MyStruct { val: &&26 };
+    let second_struct: MyStruct<'static, &'static u8> = MyStruct { val: &&27 };
+
+    needs_send(first_struct);
+    needs_send(use_my_struct(second_struct)); // ERROR
+}
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-9.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-9.no_assumptions.stderr
new file mode 100644
index 00000000000..809cbcf0cad
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-9.no_assumptions.stderr
@@ -0,0 +1,11 @@
+error: implementation of `Debug` is not general enough
+  --> $DIR/higher-ranked-auto-trait-9.rs:43:50
+   |
+LL |     let fut: &(dyn Future<Output = ()> + Send) = &fut as _;
+   |                                                  ^^^^^^^^^ implementation of `Debug` is not general enough
+   |
+   = note: `(dyn Any + '0)` must implement `Debug`, for any lifetime `'0`...
+   = note: ...but `Debug` is actually implemented for the type `(dyn Any + 'static)`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-9.rs b/tests/ui/async-await/higher-ranked-auto-trait-9.rs
new file mode 100644
index 00000000000..66edbf23f2b
--- /dev/null
+++ b/tests/ui/async-await/higher-ranked-auto-trait-9.rs
@@ -0,0 +1,44 @@
+// Repro for <https://github.com/rust-lang/rust/issues/87425#issue-952059416>.
+//@ edition: 2021
+//@ revisions: assumptions no_assumptions
+//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
+//@[assumptions] check-pass
+//@[no_assumptions] known-bug: #110338
+
+use std::any::Any;
+use std::fmt;
+use std::future::Future;
+
+pub trait Foo {
+    type Item;
+}
+
+impl<F, I> Foo for F
+where
+    Self: FnOnce() -> I,
+    I: fmt::Debug,
+{
+    type Item = I;
+}
+
+async fn foo_item<F: Foo>(_: F) -> F::Item {
+    unimplemented!()
+}
+
+fn main() {
+    let fut = async {
+        let callback = || -> Box<dyn Any> { unimplemented!() };
+
+        // Using plain fn instead of a closure fixes the error,
+        // though you obviously can't capture any state...
+        // fn callback() -> Box<dyn Any> {
+        //     todo!()
+        // }
+
+        foo_item(callback).await;
+    };
+
+    // Removing `+ Send` bound also fixes the error,
+    // though at the cost of loosing `Send`ability...
+    let fut: &(dyn Future<Output = ()> + Send) = &fut as _;
+}