Add tests, some of them fail...
This commit is contained in:
parent
512cf3ae88
commit
78fa79e7a6
38 changed files with 1206 additions and 0 deletions
|
|
@ -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`.
|
||||
48
tests/ui/async-await/higher-ranked-auto-trait-1.rs
Normal file
48
tests/ui/async-await/higher-ranked-auto-trait-1.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
35
tests/ui/async-await/higher-ranked-auto-trait-10.rs
Normal file
35
tests/ui/async-await/higher-ranked-auto-trait-10.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
31
tests/ui/async-await/higher-ranked-auto-trait-11.rs
Normal file
31
tests/ui/async-await/higher-ranked-auto-trait-11.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
40
tests/ui/async-await/higher-ranked-auto-trait-12.rs
Normal file
40
tests/ui/async-await/higher-ranked-auto-trait-12.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
68
tests/ui/async-await/higher-ranked-auto-trait-13.rs
Normal file
68
tests/ui/async-await/higher-ranked-auto-trait-13.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
29
tests/ui/async-await/higher-ranked-auto-trait-14.rs
Normal file
29
tests/ui/async-await/higher-ranked-auto-trait-14.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
21
tests/ui/async-await/higher-ranked-auto-trait-15.rs
Normal file
21
tests/ui/async-await/higher-ranked-auto-trait-15.rs
Normal 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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
23
tests/ui/async-await/higher-ranked-auto-trait-16.rs
Normal file
23
tests/ui/async-await/higher-ranked-auto-trait-16.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
30
tests/ui/async-await/higher-ranked-auto-trait-17.rs
Normal file
30
tests/ui/async-await/higher-ranked-auto-trait-17.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
23
tests/ui/async-await/higher-ranked-auto-trait-2.rs
Normal file
23
tests/ui/async-await/higher-ranked-auto-trait-2.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
72
tests/ui/async-await/higher-ranked-auto-trait-3.rs
Normal file
72
tests/ui/async-await/higher-ranked-auto-trait-3.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
34
tests/ui/async-await/higher-ranked-auto-trait-4.rs
Normal file
34
tests/ui/async-await/higher-ranked-auto-trait-4.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
54
tests/ui/async-await/higher-ranked-auto-trait-5.rs
Normal file
54
tests/ui/async-await/higher-ranked-auto-trait-5.rs
Normal 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 {}
|
||||
}
|
||||
}
|
||||
|
|
@ -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`.
|
||||
59
tests/ui/async-await/higher-ranked-auto-trait-6.rs
Normal file
59
tests/ui/async-await/higher-ranked-auto-trait-6.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
33
tests/ui/async-await/higher-ranked-auto-trait-7.rs
Normal file
33
tests/ui/async-await/higher-ranked-auto-trait-7.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
|
||||
27
tests/ui/async-await/higher-ranked-auto-trait-8.rs
Normal file
27
tests/ui/async-await/higher-ranked-auto-trait-8.rs
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
44
tests/ui/async-await/higher-ranked-auto-trait-9.rs
Normal file
44
tests/ui/async-await/higher-ranked-auto-trait-9.rs
Normal 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 _;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue