Add tests, some of them fail...

This commit is contained in:
Michael Goulet 2025-07-13 23:17:21 +00:00
parent 512cf3ae88
commit 78fa79e7a6
38 changed files with 1206 additions and 0 deletions

View file

@ -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`.

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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 {}
}
}

View file

@ -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`.

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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 _;
}