diff --git a/src/test/ui/async-await/in-trait/async-associated-types.rs b/src/test/ui/async-await/in-trait/async-associated-types.rs new file mode 100644 index 00000000000..0269f00bbab --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-associated-types.rs @@ -0,0 +1,24 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +trait MyTrait<'a, 'b, T> where Self: 'a, T: Debug + Sized + 'b { + type MyAssoc;// = (&'a T, &'b U); + + async fn foo(&'a self, key: &'b T) -> Self::MyAssoc; +} + +impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U { + type MyAssoc = (&'a U, &'b T); + + async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + (self, key) + } +} +//~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements +//~| ERROR cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-associated-types.stderr b/src/test/ui/async-await/in-trait/async-associated-types.stderr new file mode 100644 index 00000000000..c1c66f9023b --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-associated-types.stderr @@ -0,0 +1,57 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/async-associated-types.rs:17:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + | ^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined here... + --> $DIR/async-associated-types.rs:14:6 + | +LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U { + | ^^ +note: ...so that the types are compatible + --> $DIR/async-associated-types.rs:17:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + | ^^^^^^^^^^^^^^ + = note: expected `(&'a U, &'b T)` + found `(&U, &T)` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the types are compatible + --> $DIR/async-associated-types.rs:17:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + | ^^^^^^^^^^^^^^ + = note: expected `MyTrait<'static, 'static, T>` + found `MyTrait<'_, '_, T>` + +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements + --> $DIR/async-associated-types.rs:17:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + | ^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime `'b` as defined here... + --> $DIR/async-associated-types.rs:14:10 + | +LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U { + | ^^ +note: ...so that the types are compatible + --> $DIR/async-associated-types.rs:17:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + | ^^^^^^^^^^^^^^ + = note: expected `(&'a U, &'b T)` + found `(&U, &T)` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the types are compatible + --> $DIR/async-associated-types.rs:17:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + | ^^^^^^^^^^^^^^ + = note: expected `MyTrait<'static, 'static, T>` + found `MyTrait<'_, '_, T>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/async-await/in-trait/async-associated-types2-desugared.rs b/src/test/ui/async-await/in-trait/async-associated-types2-desugared.rs new file mode 100644 index 00000000000..85d29eb703e --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-associated-types2-desugared.rs @@ -0,0 +1,31 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +use std::future::Future; + +trait MyTrait { + type Fut<'a>: Future + where + Self: 'a; + + async fn foo(&self) -> Self::Fut<'a>; + //~^ ERROR use of undeclared lifetime name `'a` + //~| ERROR the parameter type `Self` may not live long enough +} + +impl MyTrait for i32 { + type Fut<'a> = impl Future + 'a + where + Self: 'a; + //~^^^ ERROR `impl Trait` in type aliases is unstable + + fn foo<'a>(&'a self) -> Self::Fut<'a> { + async { + *self + } + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-associated-types2-desugared.stderr b/src/test/ui/async-await/in-trait/async-associated-types2-desugared.stderr new file mode 100644 index 00000000000..6bc553b2635 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-associated-types2-desugared.stderr @@ -0,0 +1,42 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/async-associated-types2-desugared.rs:13:38 + | +LL | async fn foo(&self) -> Self::Fut<'a>; + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | async fn foo<'a>(&self) -> Self::Fut<'a>; + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait MyTrait<'a> { + | ++++ + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/async-associated-types2-desugared.rs:19:20 + | +LL | type Fut<'a> = impl Future + 'a + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error[E0310]: the parameter type `Self` may not live long enough + --> $DIR/async-associated-types2-desugared.rs:13:28 + | +LL | async fn foo(&self) -> Self::Fut<'a>; + | ^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `Self: 'static`... + = note: ...so that the type `Self` will meet its required lifetime bounds... +note: ...that is required by this bound + --> $DIR/async-associated-types2-desugared.rs:11:15 + | +LL | Self: 'a; + | ^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0261, E0310, E0658. +For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/async-await/in-trait/async-associated-types2.rs b/src/test/ui/async-await/in-trait/async-associated-types2.rs new file mode 100644 index 00000000000..c2133b04bc8 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-associated-types2.rs @@ -0,0 +1,32 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +use std::future::Future; + +trait MyTrait { + type Fut<'a>: Future + where + Self: 'a; + + fn foo(&self) -> Self::Fut<'a>; + //~^ ERROR use of undeclared lifetime name `'a` +} + +impl MyTrait for i32 { + type Fut<'a> = impl Future + 'a + where + Self: 'a; + //~^^^ ERROR `impl Trait` in type aliases is unstable + //~| ERROR expected `::Fut<'a>` to be a future that resolves to `i32`, but it resolves to `<::Fut<'a> as Future>::Output` + + fn foo<'a>(&'a self) -> Self::Fut<'a> { + //~^ ERROR `impl` item signature doesn't match `trait` item signature + async { + *self + } + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-associated-types2.stderr b/src/test/ui/async-await/in-trait/async-associated-types2.stderr new file mode 100644 index 00000000000..f3343852fa0 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-associated-types2.stderr @@ -0,0 +1,63 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/async-associated-types2.rs:13:32 + | +LL | fn foo(&self) -> Self::Fut<'a>; + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn foo<'a>(&self) -> Self::Fut<'a>; + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait MyTrait<'a> { + | ++++ + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/async-associated-types2.rs:18:20 + | +LL | type Fut<'a> = impl Future + 'a + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error[E0271]: expected `::Fut<'a>` to be a future that resolves to `i32`, but it resolves to `<::Fut<'a> as Future>::Output` + --> $DIR/async-associated-types2.rs:18:20 + | +LL | type Fut<'a> = impl Future + 'a + | ^^^^^^^^^^^^^^^^ expected `i32`, found associated type + | + = note: expected type `i32` + found associated type `<::Fut<'a> as Future>::Output` +note: required by a bound in `MyTrait::Fut` + --> $DIR/async-associated-types2.rs:9:26 + | +LL | type Fut<'a>: Future + | ^^^^^^^^^^^^ required by this bound in `MyTrait::Fut` +help: consider constraining the associated type `<::Fut<'a> as Future>::Output` to `i32` + | +LL | type Fut<'a> = impl Future + 'a + | ++++++++++++++ + +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/async-associated-types2.rs:24:5 + | +LL | fn foo(&self) -> Self::Fut<'a>; + | ------------------------------- expected `fn(&'1 i32) -> ::Fut<'static>` +... +LL | fn foo<'a>(&'a self) -> Self::Fut<'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 i32) -> ::Fut<'1>` + | + = note: expected `fn(&'1 i32) -> ::Fut<'static>` + found `fn(&'1 i32) -> ::Fut<'1>` +help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + --> $DIR/async-associated-types2.rs:13:22 + | +LL | fn foo(&self) -> Self::Fut<'a>; + | ^^^^ consider borrowing this type parameter in the trait + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0261, E0271, E0658. +For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/async-await/in-trait/async-example.rs b/src/test/ui/async-await/in-trait/async-example.rs new file mode 100644 index 00000000000..2c2297c6b58 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-example.rs @@ -0,0 +1,17 @@ +// check-pass +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +trait MyTrait { + async fn foo(&self) -> i32; +} + +impl MyTrait for i32 { + async fn foo(&self) -> i32 { + *self + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs b/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs new file mode 100644 index 00000000000..d748430c5ee --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs @@ -0,0 +1,21 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; +use std::hash::Hash; + +trait MyTrait { + async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; +} +//~^^ ERROR the parameter type `U` may not live long enough +//~| ERROR the parameter type `T` may not live long enough + +impl MyTrait for (T, U) { + async fn foo(&self) -> &(T, U) { + self + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr new file mode 100644 index 00000000000..8975ec21a01 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -0,0 +1,37 @@ +error[E0311]: the parameter type `U` may not live long enough + --> $DIR/async-generics-and-bounds.rs:10:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + | +note: the parameter type `U` must be valid for the anonymous lifetime as defined here... + --> $DIR/async-generics-and-bounds.rs:10:18 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics-and-bounds.rs:10:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/async-generics-and-bounds.rs:10:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime as defined here... + --> $DIR/async-generics-and-bounds.rs:10:18 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics-and-bounds.rs:10:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0311`. diff --git a/src/test/ui/async-await/in-trait/async-generics.rs b/src/test/ui/async-await/in-trait/async-generics.rs new file mode 100644 index 00000000000..3e6f70cd49f --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-generics.rs @@ -0,0 +1,18 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +trait MyTrait { + async fn foo(&self) -> &(T, U); +} +//~^^ ERROR the parameter type `U` may not live long enough +//~| ERROR the parameter type `T` may not live long enough + +impl MyTrait for (T, U) { + async fn foo(&self) -> &(T, U) { + self + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-generics.stderr b/src/test/ui/async-await/in-trait/async-generics.stderr new file mode 100644 index 00000000000..84c7b309536 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-generics.stderr @@ -0,0 +1,37 @@ +error[E0311]: the parameter type `U` may not live long enough + --> $DIR/async-generics.rs:7:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + | +note: the parameter type `U` must be valid for the anonymous lifetime as defined here... + --> $DIR/async-generics.rs:7:18 + | +LL | async fn foo(&self) -> &(T, U); + | ^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics.rs:7:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/async-generics.rs:7:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime as defined here... + --> $DIR/async-generics.rs:7:18 + | +LL | async fn foo(&self) -> &(T, U); + | ^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics.rs:7:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0311`. diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs new file mode 100644 index 00000000000..6a2276c96c8 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs @@ -0,0 +1,20 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +trait MyTrait<'a, 'b, T> { + async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized; +} +//~^^ ERROR the parameter type `Self` may not live long enough +//~| ERROR the parameter type `T` may not live long enough + +impl<'a, 'b, T, U> MyTrait<'a, 'b, T> for U { + async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + (self, key) + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr new file mode 100644 index 00000000000..d74f80917a4 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr @@ -0,0 +1,23 @@ +error[E0309]: the parameter type `Self` may not live long enough + --> $DIR/async-lifetimes-and-bounds.rs:9:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized; + | ^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `Self: 'a`... + = note: ...so that the reference type `&'a Self` does not outlive the data it points at + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/async-lifetimes-and-bounds.rs:9:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized; + | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | trait MyTrait<'a, 'b, T: 'b> { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.rs b/src/test/ui/async-await/in-trait/async-lifetimes.rs new file mode 100644 index 00000000000..1032a343547 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-lifetimes.rs @@ -0,0 +1,18 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +trait MyTrait<'a, 'b, T> { + async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T); +} +//~^^ ERROR the parameter type `Self` may not live long enough +//~| ERROR the parameter type `T` may not live long enough + +impl<'a, 'b, T, U> MyTrait<'a, 'b, T> for U { + async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { + (self, key) + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.stderr b/src/test/ui/async-await/in-trait/async-lifetimes.stderr new file mode 100644 index 00000000000..780f75cf683 --- /dev/null +++ b/src/test/ui/async-await/in-trait/async-lifetimes.stderr @@ -0,0 +1,23 @@ +error[E0309]: the parameter type `Self` may not live long enough + --> $DIR/async-lifetimes.rs:7:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T); + | ^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `Self: 'a`... + = note: ...so that the reference type `&'a Self` does not outlive the data it points at + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/async-lifetimes.rs:7:43 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T); + | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | trait MyTrait<'a, 'b, T: 'b> { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err.rs b/src/test/ui/async-await/in-trait/fn-not-async-err.rs new file mode 100644 index 00000000000..f94d32145a2 --- /dev/null +++ b/src/test/ui/async-await/in-trait/fn-not-async-err.rs @@ -0,0 +1,17 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +trait MyTrait { + async fn foo(&self) -> i32; +} + +impl MyTrait for i32 { + fn foo(&self) -> i32 { + //~^ ERROR: `i32` is not a future [E0277] + *self + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err.stderr b/src/test/ui/async-await/in-trait/fn-not-async-err.stderr new file mode 100644 index 00000000000..03321dc5b5a --- /dev/null +++ b/src/test/ui/async-await/in-trait/fn-not-async-err.stderr @@ -0,0 +1,17 @@ +error[E0277]: `i32` is not a future + --> $DIR/fn-not-async-err.rs:11:22 + | +LL | fn foo(&self) -> i32 { + | ^^^ `i32` is not a future + | + = help: the trait `Future` is not implemented for `i32` + = note: i32 must be a future or must implement `IntoFuture` to be awaited +note: required by a bound in `MyTrait::foo::{opaque#0}` + --> $DIR/fn-not-async-err.rs:7:28 + | +LL | async fn foo(&self) -> i32; + | ^^^ required by this bound in `MyTrait::foo::{opaque#0}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err2.rs b/src/test/ui/async-await/in-trait/fn-not-async-err2.rs new file mode 100644 index 00000000000..f617a19ab34 --- /dev/null +++ b/src/test/ui/async-await/in-trait/fn-not-async-err2.rs @@ -0,0 +1,21 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +use std::future::Future; + +trait MyTrait { + async fn foo(&self) -> i32; +} + +impl MyTrait for i32 { + fn foo(&self) -> impl Future { + //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return [E0562] + async { + *self + } + } +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr b/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr new file mode 100644 index 00000000000..f591f184772 --- /dev/null +++ b/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr @@ -0,0 +1,12 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return + --> $DIR/fn-not-async-err2.rs:13:22 + | +LL | fn foo(&self) -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`.