diff options
Diffstat (limited to 'tests/ui/async-await/in-trait')
12 files changed, 185 insertions, 6 deletions
diff --git a/tests/ui/async-await/in-trait/async-associated-types.rs b/tests/ui/async-await/in-trait/async-associated-types.rs index 974f5aaff..3e2739a16 100644 --- a/tests/ui/async-await/in-trait/async-associated-types.rs +++ b/tests/ui/async-await/in-trait/async-associated-types.rs @@ -2,7 +2,6 @@ // edition: 2021 #![feature(async_fn_in_trait)] -#![feature(impl_trait_projections)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs index 81e1e59a3..3505690f1 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs @@ -2,14 +2,14 @@ // edition: 2021 #![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait)] +#![feature(return_position_impl_trait_in_trait, lint_reasons)] #![allow(incomplete_features)] use std::future::Future; use std::pin::Pin; use std::task::Poll; -trait MyTrait { +pub trait MyTrait { async fn foo(&self) -> i32; } @@ -27,8 +27,7 @@ impl Future for MyFuture { } impl MyTrait for i32 { - // FIXME: this should eventually require `#[refine]` to compile, because it also provides - // `Clone`. + #[expect(refining_impl_trait)] fn foo(&self) -> impl Future<Output = i32> + Clone { MyFuture(*self) } diff --git a/tests/ui/async-await/in-trait/async-example-desugared.rs b/tests/ui/async-await/in-trait/async-example-desugared.rs index fb92ec786..0a5023176 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared.rs @@ -12,7 +12,7 @@ trait MyTrait { } impl MyTrait for i32 { - fn foo(&self) -> impl Future<Output = i32> + '_ { + fn foo(&self) -> impl Future<Output = i32> { async { *self } } } diff --git a/tests/ui/async-await/in-trait/auxiliary/foreign-async-fn.rs b/tests/ui/async-await/in-trait/auxiliary/foreign-async-fn.rs new file mode 100644 index 000000000..bba886f17 --- /dev/null +++ b/tests/ui/async-await/in-trait/auxiliary/foreign-async-fn.rs @@ -0,0 +1,7 @@ +// edition:2021 + +#![feature(async_fn_in_trait)] + +pub trait Foo { + async fn test(); +} diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs new file mode 100644 index 000000000..2fe6b473d --- /dev/null +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs @@ -0,0 +1,38 @@ +// edition: 2021 +// build-fail +//~^^ ERROR cycle detected when computing layout of + +#![feature(async_fn_in_trait)] + +fn main() { + let _ = async { + A.first().await.second().await; + }; +} + +pub trait First { + type Second: Second; + async fn first(self) -> Self::Second; +} + +struct A; + +impl First for A { + type Second = A; + async fn first(self) -> Self::Second { + A + } +} + +pub trait Second { + async fn second(self); +} + +impl<C> Second for C +where + C: First, +{ + async fn second(self) { + self.first().await.second().await; + } +} diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr new file mode 100644 index 000000000..41e84466a --- /dev/null +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr @@ -0,0 +1,10 @@ +error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}` + | + = note: ...which requires computing layout of `<<A as First>::Second as Second>::{opaque#0}`... + = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}`, completing the cycle + = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:8:13: 10:6}` + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/async-await/in-trait/missing-send-bound.stderr b/tests/ui/async-await/in-trait/missing-send-bound.stderr index 18185b755..7e59d94d4 100644 --- a/tests/ui/async-await/in-trait/missing-send-bound.stderr +++ b/tests/ui/async-await/in-trait/missing-send-bound.stderr @@ -15,6 +15,11 @@ note: required by a bound in `assert_is_send` | LL | fn assert_is_send(_: impl Send) {} | ^^^^ required by this bound in `assert_is_send` +help: `Send` can be made part of the associated future's guarantees for all implementations of `Foo::bar` + | +LL - async fn bar(); +LL + fn bar() -> impl std::future::Future<Output = ()> + Send; + | error: aborting due to previous error diff --git a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.fixed b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.fixed new file mode 100644 index 000000000..33c005874 --- /dev/null +++ b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.fixed @@ -0,0 +1,20 @@ +// run-rustfix +// edition: 2021 + +#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] +#![allow(unused)] + +trait Foo { + fn test() -> impl std::future::Future<Output = ()> + Send { async {} } + fn test2() -> impl std::future::Future<Output = i32> + Send {async { 1 + 2 } } +} + +fn bar<T: Foo>() { + fn needs_send(_: impl Send) {} + needs_send(T::test()); + //~^ ERROR `impl Future<Output = ()>` cannot be sent between threads safely + needs_send(T::test2()); + //~^ ERROR `impl Future<Output = i32>` cannot be sent between threads safely +} + +fn main() {} diff --git a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.rs b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.rs new file mode 100644 index 000000000..96b623d69 --- /dev/null +++ b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.rs @@ -0,0 +1,20 @@ +// run-rustfix +// edition: 2021 + +#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] +#![allow(unused)] + +trait Foo { + async fn test() -> () {} + async fn test2() -> i32 { 1 + 2 } +} + +fn bar<T: Foo>() { + fn needs_send(_: impl Send) {} + needs_send(T::test()); + //~^ ERROR `impl Future<Output = ()>` cannot be sent between threads safely + needs_send(T::test2()); + //~^ ERROR `impl Future<Output = i32>` cannot be sent between threads safely +} + +fn main() {} diff --git a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.stderr b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.stderr new file mode 100644 index 000000000..4319a1411 --- /dev/null +++ b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.stderr @@ -0,0 +1,43 @@ +error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely + --> $DIR/send-on-async-fn-in-trait.rs:14:16 + | +LL | needs_send(T::test()); + | ---------- ^^^^^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `impl Future<Output = ()>` +note: required by a bound in `needs_send` + --> $DIR/send-on-async-fn-in-trait.rs:13:27 + | +LL | fn needs_send(_: impl Send) {} + | ^^^^ required by this bound in `needs_send` +help: `Send` can be made part of the associated future's guarantees for all implementations of `Foo::test` + | +LL - async fn test() -> () {} +LL + fn test() -> impl std::future::Future<Output = ()> + Send { async {} } + | + +error[E0277]: `impl Future<Output = i32>` cannot be sent between threads safely + --> $DIR/send-on-async-fn-in-trait.rs:16:16 + | +LL | needs_send(T::test2()); + | ---------- ^^^^^^^^^^ `impl Future<Output = i32>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `impl Future<Output = i32>` +note: required by a bound in `needs_send` + --> $DIR/send-on-async-fn-in-trait.rs:13:27 + | +LL | fn needs_send(_: impl Send) {} + | ^^^^ required by this bound in `needs_send` +help: `Send` can be made part of the associated future's guarantees for all implementations of `Foo::test2` + | +LL - async fn test2() -> i32 { 1 + 2 } +LL + fn test2() -> impl std::future::Future<Output = i32> + Send {async { 1 + 2 } } + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.rs b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.rs new file mode 100644 index 000000000..83b69d72a --- /dev/null +++ b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.rs @@ -0,0 +1,15 @@ +// aux-build:foreign-async-fn.rs +// edition:2021 + +#![feature(async_fn_in_trait)] + +extern crate foreign_async_fn; +use foreign_async_fn::Foo; + +fn bar<T: Foo>() { + fn needs_send(_: impl Send) {} + needs_send(T::test()); + //~^ ERROR `impl Future<Output = ()>` cannot be sent between threads safely +} + +fn main() {} diff --git a/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.stderr b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.stderr new file mode 100644 index 000000000..f337a04ba --- /dev/null +++ b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.stderr @@ -0,0 +1,23 @@ +error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely + --> $DIR/send-on-foreign-async-fn-in-trait.rs:11:16 + | +LL | needs_send(T::test()); + | ---------- ^^^^^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `impl Future<Output = ()>` +note: `<T as Foo>::test` is an `async fn` in trait, which does not automatically imply that its future is `Send` + --> $DIR/auxiliary/foreign-async-fn.rs:6:5 + | +LL | async fn test(); + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_send` + --> $DIR/send-on-foreign-async-fn-in-trait.rs:10:27 + | +LL | fn needs_send(_: impl Send) {} + | ^^^^ required by this bound in `needs_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |