diff options
Diffstat (limited to 'tests/ui/async-await/issues')
71 files changed, 1405 insertions, 0 deletions
diff --git a/tests/ui/async-await/issues/auxiliary/issue-60674.rs b/tests/ui/async-await/issues/auxiliary/issue-60674.rs new file mode 100644 index 000000000..680c6e55e --- /dev/null +++ b/tests/ui/async-await/issues/auxiliary/issue-60674.rs @@ -0,0 +1,12 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn attr(_args: TokenStream, input: TokenStream) -> TokenStream { + println!("{}", input); + TokenStream::new() +} diff --git a/tests/ui/async-await/issues/auxiliary/issue_67893.rs b/tests/ui/async-await/issues/auxiliary/issue_67893.rs new file mode 100644 index 000000000..387966a50 --- /dev/null +++ b/tests/ui/async-await/issues/auxiliary/issue_67893.rs @@ -0,0 +1,10 @@ +// edition:2018 + +use std::sync::{Arc, Mutex}; + +pub async fn f(_: ()) {} + +pub async fn run() { + let x: Arc<Mutex<()>> = unimplemented!(); + f(*x.lock().unwrap()).await; +} diff --git a/tests/ui/async-await/issues/issue-102206.rs b/tests/ui/async-await/issues/issue-102206.rs new file mode 100644 index 000000000..a3a2ebc58 --- /dev/null +++ b/tests/ui/async-await/issues/issue-102206.rs @@ -0,0 +1,8 @@ +// edition:2021 + +async fn foo() {} + +fn main() { + std::mem::size_of_val(foo()); + //~^ ERROR: mismatched types +} diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr new file mode 100644 index 000000000..2ab790ac7 --- /dev/null +++ b/tests/ui/async-await/issues/issue-102206.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/issue-102206.rs:6:27 + | +LL | std::mem::size_of_val(foo()); + | --------------------- ^^^^^ + | | | + | | expected reference, found opaque type + | | help: consider borrowing here: `&foo()` + | arguments to this function are incorrect + | +note: while checking the return type of the `async fn` + --> $DIR/issue-102206.rs:3:16 + | +LL | async fn foo() {} + | ^ checked the `Output` of this `async fn`, found opaque type + = note: expected reference `&_` + found opaque type `impl Future<Output = ()>` +note: function defined here + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/issues/issue-51719.rs b/tests/ui/async-await/issues/issue-51719.rs new file mode 100644 index 000000000..09241f982 --- /dev/null +++ b/tests/ui/async-await/issues/issue-51719.rs @@ -0,0 +1,12 @@ +// edition:2018 +// +// Tests that the .await syntax can't be used to make a generator + +async fn foo() {} + +fn make_generator() { + let _gen = || foo().await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-51719.stderr b/tests/ui/async-await/issues/issue-51719.stderr new file mode 100644 index 000000000..f3ce5d1c8 --- /dev/null +++ b/tests/ui/async-await/issues/issue-51719.stderr @@ -0,0 +1,11 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-51719.rs:8:24 + | +LL | let _gen = || foo().await; + | -- ^^^^^^ only allowed inside `async` functions and blocks + | | + | this is not `async` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0728`. diff --git a/tests/ui/async-await/issues/issue-51751.rs b/tests/ui/async-await/issues/issue-51751.rs new file mode 100644 index 000000000..bc85a96ce --- /dev/null +++ b/tests/ui/async-await/issues/issue-51751.rs @@ -0,0 +1,11 @@ +// edition:2018 + +async fn inc(limit: i64) -> i64 { + limit + 1 +} + +fn main() { + let result = inc(10000); + let finished = result.await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks +} diff --git a/tests/ui/async-await/issues/issue-51751.stderr b/tests/ui/async-await/issues/issue-51751.stderr new file mode 100644 index 000000000..8696a5b79 --- /dev/null +++ b/tests/ui/async-await/issues/issue-51751.stderr @@ -0,0 +1,12 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-51751.rs:9:26 + | +LL | fn main() { + | ---- this is not `async` +LL | let result = inc(10000); +LL | let finished = result.await; + | ^^^^^^ only allowed inside `async` functions and blocks + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0728`. diff --git a/tests/ui/async-await/issues/issue-53249.rs b/tests/ui/async-await/issues/issue-53249.rs new file mode 100644 index 000000000..3a33af2d2 --- /dev/null +++ b/tests/ui/async-await/issues/issue-53249.rs @@ -0,0 +1,47 @@ +// check-pass +// edition:2018 + +#![feature(arbitrary_self_types)] + +use std::task::{self, Poll}; +use std::future::Future; +use std::marker::Unpin; +use std::pin::Pin; + +// This is a regression test for an ICE/unbounded recursion issue relating to async-await. + +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Lazy<F> { + f: Option<F> +} + +impl<F> Unpin for Lazy<F> {} + +pub fn lazy<F, R>(f: F) -> Lazy<F> + where F: FnOnce(&mut task::Context) -> R, +{ + Lazy { f: Some(f) } +} + +impl<R, F> Future for Lazy<F> + where F: FnOnce(&mut task::Context) -> R, +{ + type Output = R; + + fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<R> { + Poll::Ready((self.f.take().unwrap())(cx)) + } +} + +async fn __receive<WantFn, Fut>(want: WantFn) -> () + where Fut: Future<Output = ()>, WantFn: Fn(&Box<dyn Send + 'static>) -> Fut, +{ + lazy(|_| ()).await; +} + +pub fn basic_spawn_receive() { + async { __receive(|_| async { () }).await }; +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-54752-async-block.rs b/tests/ui/async-await/issues/issue-54752-async-block.rs new file mode 100644 index 000000000..a8165ae6c --- /dev/null +++ b/tests/ui/async-await/issues/issue-54752-async-block.rs @@ -0,0 +1,7 @@ +// run-pass + +// edition:2018 +// pp-exact + +fn main() { let _a = (async { }); } +//~^ WARNING unnecessary parentheses around assigned value diff --git a/tests/ui/async-await/issues/issue-54752-async-block.stderr b/tests/ui/async-await/issues/issue-54752-async-block.stderr new file mode 100644 index 000000000..8cc849dd9 --- /dev/null +++ b/tests/ui/async-await/issues/issue-54752-async-block.stderr @@ -0,0 +1,15 @@ +warning: unnecessary parentheses around assigned value + --> $DIR/issue-54752-async-block.rs:6:22 + | +LL | fn main() { let _a = (async { }); } + | ^ ^ + | + = note: `#[warn(unused_parens)]` on by default +help: remove these parentheses + | +LL - fn main() { let _a = (async { }); } +LL + fn main() { let _a = async { }; } + | + +warning: 1 warning emitted + diff --git a/tests/ui/async-await/issues/issue-54974.rs b/tests/ui/async-await/issues/issue-54974.rs new file mode 100644 index 000000000..b602ef153 --- /dev/null +++ b/tests/ui/async-await/issues/issue-54974.rs @@ -0,0 +1,14 @@ +// check-pass +// edition:2018 + +use std::sync::Arc; + +trait SomeTrait: Send + Sync + 'static { + fn do_something(&self); +} + +async fn my_task(obj: Arc<dyn SomeTrait>) { + unimplemented!() +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-55324.rs b/tests/ui/async-await/issues/issue-55324.rs new file mode 100644 index 000000000..9ecb3b129 --- /dev/null +++ b/tests/ui/async-await/issues/issue-55324.rs @@ -0,0 +1,11 @@ +// check-pass +// edition:2018 + +use std::future::Future; + +async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 { + let y = future.await; + *x + y +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-55809.rs b/tests/ui/async-await/issues/issue-55809.rs new file mode 100644 index 000000000..3b271775a --- /dev/null +++ b/tests/ui/async-await/issues/issue-55809.rs @@ -0,0 +1,28 @@ +// edition:2018 +// run-pass + +trait Foo { } + +impl Foo for () { } + +impl<'a, T> Foo for &'a mut T where T: Foo { } + +async fn foo_async<T>(_v: T) -> u8 where T: Foo { + 0 +} + +async fn bad<T>(v: T) -> u8 where T: Foo { + foo_async(v).await +} + +async fn async_main() { + let mut v = (); + + let _ = bad(&mut v).await; + let _ = foo_async(&mut v).await; + let _ = bad(v).await; +} + +fn main() { + let _ = async_main(); +} diff --git a/tests/ui/async-await/issues/issue-58885.rs b/tests/ui/async-await/issues/issue-58885.rs new file mode 100644 index 000000000..11920b072 --- /dev/null +++ b/tests/ui/async-await/issues/issue-58885.rs @@ -0,0 +1,19 @@ +// check-pass +// edition:2018 + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + &'a self, foo: &'a dyn Foo + ) -> bool + { + true + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-59001.rs b/tests/ui/async-await/issues/issue-59001.rs new file mode 100644 index 000000000..4ddebcf20 --- /dev/null +++ b/tests/ui/async-await/issues/issue-59001.rs @@ -0,0 +1,14 @@ +// check-pass +// edition:2018 + +use std::future::Future; + +async fn enter<'a, F, R>(mut callback: F) +where + F: FnMut(&'a mut i32) -> R, + R: Future<Output = ()> + 'a, +{ + unimplemented!() +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-59972.rs b/tests/ui/async-await/issues/issue-59972.rs new file mode 100644 index 000000000..c2e24a96b --- /dev/null +++ b/tests/ui/async-await/issues/issue-59972.rs @@ -0,0 +1,34 @@ +// Incorrect handling of uninhabited types could cause us to mark generator +// types as entirely uninhabited, when they were in fact constructible. This +// caused us to hit "unreachable" code (illegal instruction on x86). + +// run-pass + +// compile-flags: --edition=2018 -Aunused + +pub enum Uninhabited { } + +fn uninhabited_async() -> Uninhabited { + unreachable!() +} + +async fn noop() { } + +async fn contains_never() { + let error = uninhabited_async(); + noop().await; + let error2 = error; +} + +async fn overlap_never() { + let error1 = uninhabited_async(); + noop().await; + let error2 = uninhabited_async(); + drop(error1); + noop().await; + drop(error2); +} + +#[allow(unused_must_use)] +fn main() { +} diff --git a/tests/ui/async-await/issues/issue-60518.rs b/tests/ui/async-await/issues/issue-60518.rs new file mode 100644 index 000000000..69bbdd0e8 --- /dev/null +++ b/tests/ui/async-await/issues/issue-60518.rs @@ -0,0 +1,10 @@ +// check-pass +// edition:2018 + +// This is a regression test to ensure that simple bindings (where replacement arguments aren't +// created during async fn lowering) that have their DefId used during HIR lowering (such as impl +// trait) are visited during def collection and thus have a DefId. + +async fn foo(ws: impl Iterator<Item = ()>) {} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-60655-latebound-regions.rs b/tests/ui/async-await/issues/issue-60655-latebound-regions.rs new file mode 100644 index 000000000..66a3b07c3 --- /dev/null +++ b/tests/ui/async-await/issues/issue-60655-latebound-regions.rs @@ -0,0 +1,30 @@ +// Test that opaque `impl Trait` types are allowed to contain late-bound regions. + +// check-pass +// edition:2018 + +#![feature(type_alias_impl_trait)] + +use std::future::Future; + +pub type Func = impl Sized; + +// Late bound region should be allowed to escape the function, since it's bound +// in the type. +fn null_function_ptr() -> Func { + None::<for<'a> fn(&'a ())> +} + +async fn async_nop(_: &u8) {} + +pub type ServeFut = impl Future<Output=()>; + +// Late bound regions occur in the generator witness type here. +fn serve() -> ServeFut { + async move { + let x = 5; + async_nop(&x).await + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-60674.rs b/tests/ui/async-await/issues/issue-60674.rs new file mode 100644 index 000000000..c0e34a8df --- /dev/null +++ b/tests/ui/async-await/issues/issue-60674.rs @@ -0,0 +1,19 @@ +// aux-build:issue-60674.rs +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +// This is a regression test that ensures that `mut` patterns are not lost when provided as input +// to a proc macro. + +extern crate issue_60674; + +#[issue_60674::attr] +async fn f(mut x: u8) {} + +#[issue_60674::attr] +async fn g((mut x, y, mut z): (u8, u8, u8)) {} + +#[issue_60674::attr] +async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) {} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-60674.stdout b/tests/ui/async-await/issues/issue-60674.stdout new file mode 100644 index 000000000..6f980e606 --- /dev/null +++ b/tests/ui/async-await/issues/issue-60674.stdout @@ -0,0 +1,3 @@ +async fn f(mut x : u8) {} +async fn g((mut x, y, mut z) : (u8, u8, u8)) {} +async fn g(mut x : u8, (a, mut b, c) : (u8, u8, u8), y : u8) {} diff --git a/tests/ui/async-await/issues/issue-61187.rs b/tests/ui/async-await/issues/issue-61187.rs new file mode 100644 index 000000000..8585a4251 --- /dev/null +++ b/tests/ui/async-await/issues/issue-61187.rs @@ -0,0 +1,7 @@ +// edition:2018 + +fn main() {} + +async fn response(data: Vec<u8>) { + data.reverse(); //~ ERROR E0596 +} diff --git a/tests/ui/async-await/issues/issue-61187.stderr b/tests/ui/async-await/issues/issue-61187.stderr new file mode 100644 index 000000000..e58f74546 --- /dev/null +++ b/tests/ui/async-await/issues/issue-61187.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `data` as mutable, as it is not declared as mutable + --> $DIR/issue-61187.rs:6:5 + | +LL | data.reverse(); + | ^^^^^^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | async fn response(mut data: Vec<u8>) { + | +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/async-await/issues/issue-61986.rs b/tests/ui/async-await/issues/issue-61986.rs new file mode 100644 index 000000000..879bc6912 --- /dev/null +++ b/tests/ui/async-await/issues/issue-61986.rs @@ -0,0 +1,19 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 +// +// Tests that we properly handle StorageDead/StorageLives for temporaries +// created in async loop bodies. + +async fn bar() -> Option<()> { + Some(()) +} + +async fn listen() { + while let Some(_) = bar().await { + String::new(); + } +} + +fn main() { + listen(); +} diff --git a/tests/ui/async-await/issues/issue-62009-1.rs b/tests/ui/async-await/issues/issue-62009-1.rs new file mode 100644 index 000000000..40ccf2571 --- /dev/null +++ b/tests/ui/async-await/issues/issue-62009-1.rs @@ -0,0 +1,15 @@ +// edition:2018 + +async fn print_dur() {} + +fn main() { + async { let (); }.await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks + async { + let task1 = print_dur().await; + }.await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks + (|_| 2333).await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks + //~| ERROR is not a future +} diff --git a/tests/ui/async-await/issues/issue-62009-1.stderr b/tests/ui/async-await/issues/issue-62009-1.stderr new file mode 100644 index 000000000..222afb2c7 --- /dev/null +++ b/tests/ui/async-await/issues/issue-62009-1.stderr @@ -0,0 +1,43 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009-1.rs:6:22 + | +LL | fn main() { + | ---- this is not `async` +LL | async { let (); }.await; + | ^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009-1.rs:10:6 + | +LL | fn main() { + | ---- this is not `async` +... +LL | }.await; + | ^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009-1.rs:12:15 + | +LL | fn main() { + | ---- this is not `async` +... +LL | (|_| 2333).await; + | ^^^^^^ only allowed inside `async` functions and blocks + +error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future + --> $DIR/issue-62009-1.rs:12:15 + | +LL | (|_| 2333).await; + | ^^^^^^ + | | + | `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future + | help: remove the `.await` + | + = help: the trait `Future` is not implemented for closure `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` + = note: [closure@$DIR/issue-62009-1.rs:12:6: 12:9] must be a future or must implement `IntoFuture` to be awaited + = note: required for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` to implement `IntoFuture` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0728. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/async-await/issues/issue-62009-2.rs b/tests/ui/async-await/issues/issue-62009-2.rs new file mode 100644 index 000000000..cb7336e61 --- /dev/null +++ b/tests/ui/async-await/issues/issue-62009-2.rs @@ -0,0 +1,10 @@ +// edition:2018 + +#![feature(async_closure)] + +async fn print_dur() {} + +fn main() { + (async || 2333)().await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks +} diff --git a/tests/ui/async-await/issues/issue-62009-2.stderr b/tests/ui/async-await/issues/issue-62009-2.stderr new file mode 100644 index 000000000..92e9a8a69 --- /dev/null +++ b/tests/ui/async-await/issues/issue-62009-2.stderr @@ -0,0 +1,11 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009-2.rs:8:22 + | +LL | fn main() { + | ---- this is not `async` +LL | (async || 2333)().await; + | ^^^^^^ only allowed inside `async` functions and blocks + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0728`. diff --git a/tests/ui/async-await/issues/issue-62097.rs b/tests/ui/async-await/issues/issue-62097.rs new file mode 100644 index 000000000..a24c84cff --- /dev/null +++ b/tests/ui/async-await/issues/issue-62097.rs @@ -0,0 +1,21 @@ +// edition:2018 +async fn foo<F>(fun: F) +where + F: FnOnce() + 'static +{ + fun() +} + +struct Struct; + +impl Struct { + pub async fn run_dummy_fn(&self) { + foo(|| self.bar()).await; + //~^ ERROR closure may outlive the current function + //~| ERROR borrowed data escapes outside of associated function + } + + pub fn bar(&self) {} +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-62097.stderr b/tests/ui/async-await/issues/issue-62097.stderr new file mode 100644 index 000000000..786f62132 --- /dev/null +++ b/tests/ui/async-await/issues/issue-62097.stderr @@ -0,0 +1,36 @@ +error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function + --> $DIR/issue-62097.rs:13:13 + | +LL | foo(|| self.bar()).await; + | ^^ ---- `self` is borrowed here + | | + | may outlive borrowed value `self` + | +note: function requires argument type to outlive `'static` + --> $DIR/issue-62097.rs:13:9 + | +LL | foo(|| self.bar()).await; + | ^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword + | +LL | foo(move || self.bar()).await; + | ++++ + +error[E0521]: borrowed data escapes outside of associated function + --> $DIR/issue-62097.rs:13:9 + | +LL | pub async fn run_dummy_fn(&self) { + | ----- + | | + | `self` is a reference that is only valid in the associated function body + | let's call the lifetime of this reference `'1` +LL | foo(|| self.bar()).await; + | ^^^^^^^^^^^^^^^^^^ + | | + | `self` escapes the associated function body here + | argument requires that `'1` must outlive `'static` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0373, E0521. +For more information about an error, try `rustc --explain E0373`. diff --git a/tests/ui/async-await/issues/issue-62517-1.rs b/tests/ui/async-await/issues/issue-62517-1.rs new file mode 100644 index 000000000..4689ce36a --- /dev/null +++ b/tests/ui/async-await/issues/issue-62517-1.rs @@ -0,0 +1,21 @@ +// Regression test for #62517. We used to ICE when you had an `async +// fn` with an `impl Trait` return that mentioned a `dyn Bar` with no +// explicit lifetime bound. +// +// edition:2018 +// check-pass + +trait FirstTrait {} +trait SecondTrait { + type Item: ?Sized; +} + +async fn foo(x: &str) -> impl SecondTrait<Item = dyn FirstTrait> { +} + + +impl<T> SecondTrait for T { + type Item = dyn FirstTrait; +} + +fn main() { } diff --git a/tests/ui/async-await/issues/issue-62517-2.rs b/tests/ui/async-await/issues/issue-62517-2.rs new file mode 100644 index 000000000..aaf28d6c1 --- /dev/null +++ b/tests/ui/async-await/issues/issue-62517-2.rs @@ -0,0 +1,16 @@ +// Regression test for #62517. We used to ICE when you had an `async +// fn` with an `impl Trait` return that mentioned a `dyn Bar` with no +// explicit lifetime bound. +// +// edition:2018 +// check-pass + +trait Object {} + +trait Alpha<Param: ?Sized> {} + +async fn foo<'a>(_: &'a ()) -> impl Alpha<dyn Object> {} + +impl<T> Alpha<dyn Object> for T { } + +fn main() { } diff --git a/tests/ui/async-await/issues/issue-63388-1.rs b/tests/ui/async-await/issues/issue-63388-1.rs new file mode 100644 index 000000000..32bcbb111 --- /dev/null +++ b/tests/ui/async-await/issues/issue-63388-1.rs @@ -0,0 +1,19 @@ +// edition:2018 + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + &'a self, foo: &dyn Foo + ) -> &dyn Foo + { + //~^ ERROR explicit lifetime required in the type of `foo` [E0621] + foo + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr new file mode 100644 index 000000000..88542315e --- /dev/null +++ b/tests/ui/async-await/issues/issue-63388-1.stderr @@ -0,0 +1,15 @@ +error[E0621]: explicit lifetime required in the type of `foo` + --> $DIR/issue-63388-1.rs:13:5 + | +LL | &'a self, foo: &dyn Foo + | -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)` +LL | ) -> &dyn Foo +LL | / { +LL | | +LL | | foo +LL | | } + | |_____^ lifetime `'a` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/tests/ui/async-await/issues/issue-63388-2.rs b/tests/ui/async-await/issues/issue-63388-2.rs new file mode 100644 index 000000000..90b59f96e --- /dev/null +++ b/tests/ui/async-await/issues/issue-63388-2.rs @@ -0,0 +1,19 @@ +// edition:2018 + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + foo: &dyn Foo, bar: &'a dyn Foo + ) -> &dyn Foo //~ ERROR missing lifetime specifier + { + //~^ ERROR explicit lifetime required in the type of `foo` [E0621] + foo + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-63388-2.stderr b/tests/ui/async-await/issues/issue-63388-2.stderr new file mode 100644 index 000000000..e515f227c --- /dev/null +++ b/tests/ui/async-await/issues/issue-63388-2.stderr @@ -0,0 +1,30 @@ +error[E0106]: missing lifetime specifier + --> $DIR/issue-63388-2.rs:12:10 + | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | -------- ----------- +LL | ) -> &dyn Foo + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` +help: consider using the `'a` lifetime + | +LL | ) -> &'a dyn Foo + | ++ + +error[E0621]: explicit lifetime required in the type of `foo` + --> $DIR/issue-63388-2.rs:13:5 + | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)` +LL | ) -> &dyn Foo +LL | / { +LL | | +LL | | foo +LL | | } + | |_____^ lifetime `'a` required + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0621. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/async-await/issues/issue-63388-3.rs b/tests/ui/async-await/issues/issue-63388-3.rs new file mode 100644 index 000000000..1a9822e02 --- /dev/null +++ b/tests/ui/async-await/issues/issue-63388-3.rs @@ -0,0 +1,17 @@ +// edition:2018 +// check-pass + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth( + &self, foo: &dyn Foo + ) { + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-63388-4.rs b/tests/ui/async-await/issues/issue-63388-4.rs new file mode 100644 index 000000000..58f9dacb3 --- /dev/null +++ b/tests/ui/async-await/issues/issue-63388-4.rs @@ -0,0 +1,10 @@ +// check-pass +// edition:2018 + +struct A; + +impl A { + async fn foo(&self, f: &u32) -> &A { self } +} + +fn main() { } diff --git a/tests/ui/async-await/issues/issue-64391-2.rs b/tests/ui/async-await/issues/issue-64391-2.rs new file mode 100644 index 000000000..eef2c1fb2 --- /dev/null +++ b/tests/ui/async-await/issues/issue-64391-2.rs @@ -0,0 +1,20 @@ +// Regression test for #64391 +// +// As described on the issue, the (spurious) `DROP` inserted for the +// `"".to_string()` value was causing a (spurious) unwind path that +// led us to believe that the future might be dropped after `config` +// had been dropped. This cannot, in fact, happen. +// +// check-pass +// edition:2018 + +async fn connect() { + let config = 666; + connect2(&config, "".to_string()).await +} + +async fn connect2(_config: &u32, _tls: String) { + unimplemented!() +} + +fn main() { } diff --git a/tests/ui/async-await/issues/issue-64433.rs b/tests/ui/async-await/issues/issue-64433.rs new file mode 100644 index 000000000..d900f8ed9 --- /dev/null +++ b/tests/ui/async-await/issues/issue-64433.rs @@ -0,0 +1,30 @@ +// Regression test for issue #64433. +// +// See issue-64391-2.rs for more details, as that was fixed by the +// same PR. +// +// check-pass +// edition:2018 + +#[derive(Debug)] +struct A<'a> { + inner: Vec<&'a str>, +} + +struct B {} + +impl B { + async fn something_with_a(&mut self, a: A<'_>) -> Result<(), String> { + println!("{:?}", a); + Ok(()) + } +} + +async fn can_error(some_string: &str) -> Result<(), String> { + let a = A { inner: vec![some_string, "foo"] }; + let mut b = B {}; + Ok(b.something_with_a(a).await.map(drop)?) +} + +fn main() { +} diff --git a/tests/ui/async-await/issues/issue-64477-2.rs b/tests/ui/async-await/issues/issue-64477-2.rs new file mode 100644 index 000000000..2360b57cc --- /dev/null +++ b/tests/ui/async-await/issues/issue-64477-2.rs @@ -0,0 +1,22 @@ +// Another regression test for #64477. +// +// In the past, the code generated by `format!` produced temporaries in the surrounding scope that +// borrowed the arguments through `&dyn Trait`. These temporaries do not implement `Send`, which +// meant that when `format!` was used in an async block, the resulting generator was not `Send`. +// See https://github.com/rust-lang/rust/issues/64477#issuecomment-534669068 for details +// and https://github.com/rust-lang/rust/issues/64477#issuecomment-531882958 for an example. +// +// check-pass +// edition:2018 + +async fn foo(_: String) {} + +fn bar() -> impl Send { + async move { + foo(format!("{}:{}", 1, 2)).await; + } +} + +fn main() { + let _ = bar(); +} diff --git a/tests/ui/async-await/issues/issue-64477.rs b/tests/ui/async-await/issues/issue-64477.rs new file mode 100644 index 000000000..5bd52d44a --- /dev/null +++ b/tests/ui/async-await/issues/issue-64477.rs @@ -0,0 +1,20 @@ +// Regression test for #64477. +// +// We were incorrectly claiming that the `f(x).await` future captured +// a value of type `T`, and hence that `T: Send` would have to hold. +// +// check-pass +// edition:2018 + +use std::future::Future; +use std::pin::Pin; + +fn f<T>(_: &T) -> Pin<Box<dyn Future<Output = ()> + Send>> { + unimplemented!() +} + +pub fn g<T: Sync>(x: &'static T) -> impl Future<Output = ()> + Send { + async move { f(x).await } +} + +fn main() { } diff --git a/tests/ui/async-await/issues/issue-64964.rs b/tests/ui/async-await/issues/issue-64964.rs new file mode 100644 index 000000000..6d6eff486 --- /dev/null +++ b/tests/ui/async-await/issues/issue-64964.rs @@ -0,0 +1,23 @@ +// check-pass +// incremental +// compile-flags: -Z query-dep-graph +// edition:2018 + +// Regression test for ICE related to `await`ing in a method + incr. comp. (#64964) + +struct Body; +impl Body { + async fn next(&mut self) { + async {}.await + } +} + +// Another reproduction: `await`ing with a variable from for-loop. + +async fn bar() { + for x in 0..10 { + async { Some(x) }.await.unwrap(); + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-65159.rs b/tests/ui/async-await/issues/issue-65159.rs new file mode 100644 index 000000000..df2ca0257 --- /dev/null +++ b/tests/ui/async-await/issues/issue-65159.rs @@ -0,0 +1,11 @@ +// Regression test for #65159. We used to ICE. +// +// edition:2018 + +async fn copy() -> Result<()> +//~^ ERROR this enum takes 2 generic arguments +{ + Ok(()) +} + +fn main() { } diff --git a/tests/ui/async-await/issues/issue-65159.stderr b/tests/ui/async-await/issues/issue-65159.stderr new file mode 100644 index 000000000..40c0e72b2 --- /dev/null +++ b/tests/ui/async-await/issues/issue-65159.stderr @@ -0,0 +1,16 @@ +error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied + --> $DIR/issue-65159.rs:5:20 + | +LL | async fn copy() -> Result<()> + | ^^^^^^ -- supplied 1 generic argument + | | + | expected 2 generic arguments + | +help: add missing generic argument + | +LL | async fn copy() -> Result<(), E> + | +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs new file mode 100644 index 000000000..ade386a60 --- /dev/null +++ b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs @@ -0,0 +1,46 @@ +// issue 65419 - Attempting to run an async fn after completion mentions generators when it should +// be talking about `async fn`s instead. + +// run-fail +// error-pattern: thread 'main' panicked at '`async fn` resumed after completion' +// edition:2018 +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +#![feature(generators, generator_trait)] + +async fn foo() { +} + +fn main() { + let mut future = Box::pin(foo()); + executor::block_on(future.as_mut()); + executor::block_on(future.as_mut()); +} + +mod executor { + use core::{ + future::Future, + pin::Pin, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + }; + + pub fn block_on<F: Future>(mut future: F) -> F::Output { + let mut future = unsafe { Pin::new_unchecked(&mut future) }; + + static VTABLE: RawWakerVTable = RawWakerVTable::new( + |_| unimplemented!("clone"), + |_| unimplemented!("wake"), + |_| unimplemented!("wake_by_ref"), + |_| (), + ); + let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut context = Context::from_waker(&waker); + + loop { + if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + break val; + } + } + } +} diff --git a/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs new file mode 100644 index 000000000..b4ea4c9f6 --- /dev/null +++ b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs @@ -0,0 +1,52 @@ +// issue 65419 - Attempting to run an async fn after completion mentions generators when it should +// be talking about `async fn`s instead. Should also test what happens when it panics. + +// run-fail +// needs-unwind +// error-pattern: thread 'main' panicked at '`async fn` resumed after panicking' +// edition:2018 +// ignore-wasm no panic or subprocess support + +#![feature(generators, generator_trait)] + +use std::panic; + +async fn foo() { + panic!(); +} + +fn main() { + let mut future = Box::pin(foo()); + panic::catch_unwind(panic::AssertUnwindSafe(|| { + executor::block_on(future.as_mut()); + })); + + executor::block_on(future.as_mut()); +} + +mod executor { + use core::{ + future::Future, + pin::Pin, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + }; + + pub fn block_on<F: Future>(mut future: F) -> F::Output { + let mut future = unsafe { Pin::new_unchecked(&mut future) }; + + static VTABLE: RawWakerVTable = RawWakerVTable::new( + |_| unimplemented!("clone"), + |_| unimplemented!("wake"), + |_| unimplemented!("wake_by_ref"), + |_| (), + ); + let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut context = Context::from_waker(&waker); + + loop { + if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + break val; + } + } + } +} diff --git a/tests/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs b/tests/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs new file mode 100644 index 000000000..9fc5667d6 --- /dev/null +++ b/tests/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs @@ -0,0 +1,25 @@ +// issue 65419 - Attempting to run an `async fn` after completion mentions generators when it should +// be talking about `async fn`s instead. Regression test added to make sure generators still +// panic when resumed after completion. + +// run-fail +// error-pattern:generator resumed after completion +// edition:2018 +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +#![feature(generators, generator_trait)] + +use std::{ + ops::Generator, + pin::Pin, +}; + +fn main() { + let mut g = || { + yield; + }; + Pin::new(&mut g).resume(()); // Yields once. + Pin::new(&mut g).resume(()); // Completes here. + Pin::new(&mut g).resume(()); // Panics here. +} diff --git a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr new file mode 100644 index 000000000..1033fa6cc --- /dev/null +++ b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr @@ -0,0 +1,32 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-65436-raw-ptr-not-send.rs:16:17 + | +LL | assert_send(async { + | _________________^ +LL | | +LL | | bar(Foo(std::ptr::null())).await; +LL | | }) + | |_____^ future created by async block is not `Send` + | + = help: within `[async block@$DIR/issue-65436-raw-ptr-not-send.rs:16:17: 19:6]`, the trait `Send` is not implemented for `*const u8` +note: future is not `Send` as this value is used across an await + --> $DIR/issue-65436-raw-ptr-not-send.rs:18:35 + | +LL | bar(Foo(std::ptr::null())).await; + | ---------------- ^^^^^^- `std::ptr::null()` is later dropped here + | | | + | | await occurs here, with `std::ptr::null()` maybe used later + | has type `*const u8` which is not `Send` +help: consider moving this into a `let` binding to create a shorter lived borrow + --> $DIR/issue-65436-raw-ptr-not-send.rs:18:13 + | +LL | bar(Foo(std::ptr::null())).await; + | ^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `assert_send` + --> $DIR/issue-65436-raw-ptr-not-send.rs:13:19 + | +LL | fn assert_send<T: Send>(_: T) {} + | ^^^^ required by this bound in `assert_send` + +error: aborting due to previous error + diff --git a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs new file mode 100644 index 000000000..91edbc10d --- /dev/null +++ b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs @@ -0,0 +1,20 @@ +// edition:2018 +// revisions: no_drop_tracking drop_tracking +// [drop_tracking] check-pass +// [drop_tracking] compile-flags: -Zdrop-tracking=yes +// [no_drop_tracking] compile-flags: -Zdrop-tracking=no + +struct Foo(*const u8); + +unsafe impl Send for Foo {} + +async fn bar(_: Foo) {} + +fn assert_send<T: Send>(_: T) {} + +fn main() { + assert_send(async { + //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely + bar(Foo(std::ptr::null())).await; + }) +} diff --git a/tests/ui/async-await/issues/issue-66695-static-refs.rs b/tests/ui/async-await/issues/issue-66695-static-refs.rs new file mode 100644 index 000000000..f0609713b --- /dev/null +++ b/tests/ui/async-await/issues/issue-66695-static-refs.rs @@ -0,0 +1,24 @@ +// build-pass +// edition:2018 + +static A: [i32; 5] = [1, 2, 3, 4, 5]; + +async fn fun() { + let u = A[async { 1 }.await]; + match A { + i if async { true }.await => (), + _ => (), + } +} + +fn main() { + async { + let u = A[async { 1 }.await]; + }; + async { + match A { + i if async { true }.await => (), + _ => (), + } + }; +} diff --git a/tests/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs b/tests/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs new file mode 100644 index 000000000..b7a976a0a --- /dev/null +++ b/tests/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs @@ -0,0 +1,15 @@ +// edition:2018 + +struct Ia<S>(S); + +impl<S> Ia<S> { + fn partial(_: S) {} + fn full(self) {} + + async fn crash(self) { + Self::partial(self.0); + Self::full(self); //~ ERROR use of partially moved value: `self` + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr b/tests/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr new file mode 100644 index 000000000..e2a735398 --- /dev/null +++ b/tests/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of partially moved value: `self` + --> $DIR/issue-66958-non-copy-infered-type-arg.rs:11:20 + | +LL | Self::partial(self.0); + | ------ value partially moved here +LL | Self::full(self); + | ^^^^ value used here after partial move + | + = note: partial move occurs because `self.0` has type `S`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs new file mode 100644 index 000000000..dda4a151d --- /dev/null +++ b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs @@ -0,0 +1,33 @@ +// build-pass +// edition:2018 + +static mut A: [i32; 5] = [1, 2, 3, 4, 5]; + +fn is_send_sync<T: Send + Sync>(_: T) {} + +async fn fun() { + let u = unsafe { A[async { 1 }.await] }; + unsafe { + match A { + i if async { true }.await => (), + _ => (), + } + } +} + +fn main() { + let index_block = async { + let u = unsafe { A[async { 1 }.await] }; + }; + let match_block = async { + unsafe { + match A { + i if async { true }.await => (), + _ => (), + } + } + }; + is_send_sync(index_block); + is_send_sync(match_block); + is_send_sync(fun()); +} diff --git a/tests/ui/async-await/issues/issue-67893.rs b/tests/ui/async-await/issues/issue-67893.rs new file mode 100644 index 000000000..d73772e5f --- /dev/null +++ b/tests/ui/async-await/issues/issue-67893.rs @@ -0,0 +1,11 @@ +// aux-build: issue_67893.rs +// edition:2018 + +extern crate issue_67893; + +fn g(_: impl Send) {} + +fn main() { + g(issue_67893::run()) + //~^ ERROR future cannot be sent between threads safely +} diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr new file mode 100644 index 000000000..2ce68a782 --- /dev/null +++ b/tests/ui/async-await/issues/issue-67893.stderr @@ -0,0 +1,23 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-67893.rs:9:7 + | +LL | g(issue_67893::run()) + | ^^^^^^^^^^^^^^^^^^ future is not `Send` + | + = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` +note: future is not `Send` as this value is used across an await + --> $DIR/auxiliary/issue_67893.rs:9:26 + | +LL | f(*x.lock().unwrap()).await; + | ----------------- ^^^^^^- `x.lock().unwrap()` is later dropped here + | | | + | | await occurs here, with `x.lock().unwrap()` maybe used later + | has type `MutexGuard<'_, ()>` which is not `Send` +note: required by a bound in `g` + --> $DIR/issue-67893.rs:6:14 + | +LL | fn g(_: impl Send) {} + | ^^^^ required by this bound in `g` + +error: aborting due to previous error + diff --git a/tests/ui/async-await/issues/issue-69307-nested.rs b/tests/ui/async-await/issues/issue-69307-nested.rs new file mode 100644 index 000000000..b7cdf3987 --- /dev/null +++ b/tests/ui/async-await/issues/issue-69307-nested.rs @@ -0,0 +1,30 @@ +// Regression test for #69307 +// +// Having a `async { .. foo.await .. }` block appear inside of a `+=` +// expression was causing an ICE due to a failure to save/restore +// state in the AST numbering pass when entering a nested body. +// +// check-pass +// edition:2018 + +fn block_on<F>(_: F) -> usize { + 0 +} + +fn main() {} + +async fn bar() { + let mut sum = 0; + sum += { + block_on(async { + baz().await; + let mut inner = 1; + inner += block_on(async { + baz().await; + 0 + }) + }) + }; +} + +async fn baz() {} diff --git a/tests/ui/async-await/issues/issue-69307.rs b/tests/ui/async-await/issues/issue-69307.rs new file mode 100644 index 000000000..59309a7f2 --- /dev/null +++ b/tests/ui/async-await/issues/issue-69307.rs @@ -0,0 +1,23 @@ +// Regression test for #69307 +// +// Having an `async { .. foo.await .. }` block appear inside of a `+=` +// expression was causing an ICE due to a failure to save/restore +// state in the AST numbering pass when entering a nested body. +// +// check-pass +// edition:2018 + +fn block_on<F>(_: F) -> usize { + 0 +} + +fn main() {} + +async fn bar() { + let mut sum = 0; + sum += block_on(async { + baz().await; + }); +} + +async fn baz() {} diff --git a/tests/ui/async-await/issues/issue-72312.rs b/tests/ui/async-await/issues/issue-72312.rs new file mode 100644 index 000000000..74122cf00 --- /dev/null +++ b/tests/ui/async-await/issues/issue-72312.rs @@ -0,0 +1,21 @@ +// edition:2018 +fn require_static<T: 'static>(val: T) -> T { + val +} + +struct Problem; + +impl Problem { + pub async fn start(&self) { + //~^ NOTE let's call + //~| NOTE `self` is a reference + require_static(async move { + //~^ ERROR borrowed data escapes + //~| NOTE `self` escapes + //~| NOTE argument requires + &self; + }); + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-72312.stderr b/tests/ui/async-await/issues/issue-72312.stderr new file mode 100644 index 000000000..aa947b690 --- /dev/null +++ b/tests/ui/async-await/issues/issue-72312.stderr @@ -0,0 +1,23 @@ +error[E0521]: borrowed data escapes outside of associated function + --> $DIR/issue-72312.rs:12:9 + | +LL | pub async fn start(&self) { + | ----- + | | + | `self` is a reference that is only valid in the associated function body + | let's call the lifetime of this reference `'1` +... +LL | / require_static(async move { +LL | | +LL | | +LL | | +LL | | &self; +LL | | }); + | | ^ + | | | + | |__________`self` escapes the associated function body here + | argument requires that `'1` must outlive `'static` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/async-await/issues/issue-78600.rs b/tests/ui/async-await/issues/issue-78600.rs new file mode 100644 index 000000000..8aaeaecf3 --- /dev/null +++ b/tests/ui/async-await/issues/issue-78600.rs @@ -0,0 +1,12 @@ +// edition:2018 + +struct S<'a>(&'a i32); + +impl<'a> S<'a> { + async fn new(i: &'a i32) -> Result<Self, ()> { + //~^ ERROR: `async fn` + Ok(S(&22)) + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-78600.stderr b/tests/ui/async-await/issues/issue-78600.stderr new file mode 100644 index 000000000..37eafa996 --- /dev/null +++ b/tests/ui/async-await/issues/issue-78600.stderr @@ -0,0 +1,14 @@ +error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope + --> $DIR/issue-78600.rs:6:33 + | +LL | async fn new(i: &'a i32) -> Result<Self, ()> { + | ^^^^^^^----^^^^^ + | | + | help: consider spelling out the type instead: `S<'a>` + | + = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information + = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/issues/issue-78654.full.stderr b/tests/ui/async-await/issues/issue-78654.full.stderr new file mode 100644 index 000000000..0d12a948c --- /dev/null +++ b/tests/ui/async-await/issues/issue-78654.full.stderr @@ -0,0 +1,19 @@ +error[E0573]: expected type, found built-in attribute `feature` + --> $DIR/issue-78654.rs:9:15 + | +LL | impl<const H: feature> Foo { + | ^^^^^^^ not a type + +error[E0207]: the const parameter `H` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-78654.rs:9:6 + | +LL | impl<const H: feature> Foo { + | ^^^^^^^^^^^^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0207, E0573. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/async-await/issues/issue-78654.min.stderr b/tests/ui/async-await/issues/issue-78654.min.stderr new file mode 100644 index 000000000..0d12a948c --- /dev/null +++ b/tests/ui/async-await/issues/issue-78654.min.stderr @@ -0,0 +1,19 @@ +error[E0573]: expected type, found built-in attribute `feature` + --> $DIR/issue-78654.rs:9:15 + | +LL | impl<const H: feature> Foo { + | ^^^^^^^ not a type + +error[E0207]: the const parameter `H` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-78654.rs:9:6 + | +LL | impl<const H: feature> Foo { + | ^^^^^^^^^^^^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0207, E0573. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/async-await/issues/issue-78654.rs b/tests/ui/async-await/issues/issue-78654.rs new file mode 100644 index 000000000..cc6dc3834 --- /dev/null +++ b/tests/ui/async-await/issues/issue-78654.rs @@ -0,0 +1,15 @@ +// edition:2018 +// revisions: full min + +#![cfg_attr(full, feature(adt_const_params))] +#![cfg_attr(full, allow(incomplete_features))] + +struct Foo; + +impl<const H: feature> Foo { +//~^ ERROR: expected type, found built-in attribute `feature` +//~^^ ERROR: the const parameter `H` is not constrained by the impl trait, self type, or predicates + async fn biz() {} +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-78938-async-block.rs b/tests/ui/async-await/issues/issue-78938-async-block.rs new file mode 100644 index 000000000..36f716019 --- /dev/null +++ b/tests/ui/async-await/issues/issue-78938-async-block.rs @@ -0,0 +1,33 @@ +// edition:2018 + +use std::{sync::Arc, future::Future, pin::Pin, task::{Context, Poll}}; + +async fn f() { + let room_ref = Arc::new(Vec::new()); + + let gameloop_handle = spawn(async { //~ ERROR E0373 + game_loop(Arc::clone(&room_ref)) + }); + gameloop_handle.await; +} + +fn game_loop(v: Arc<Vec<usize>>) {} + +fn spawn<F>(future: F) -> JoinHandle +where + F: Future + Send + 'static, + F::Output: Send + 'static, +{ + loop {} +} + +struct JoinHandle; + +impl Future for JoinHandle { + type Output = (); + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { + loop {} + } +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-78938-async-block.stderr b/tests/ui/async-await/issues/issue-78938-async-block.stderr new file mode 100644 index 000000000..c1a4b467f --- /dev/null +++ b/tests/ui/async-await/issues/issue-78938-async-block.stderr @@ -0,0 +1,19 @@ +error[E0373]: async block may outlive the current function, but it borrows `room_ref`, which is owned by the current function + --> $DIR/issue-78938-async-block.rs:8:33 + | +LL | let gameloop_handle = spawn(async { + | _________________________________^ +LL | | game_loop(Arc::clone(&room_ref)) + | | -------- `room_ref` is borrowed here +LL | | }); + | |_____^ may outlive borrowed value `room_ref` + | + = note: async blocks are not executed immediately and must either take a reference or ownership of outside variables they use +help: to force the async block to take ownership of `room_ref` (and any other referenced variables), use the `move` keyword + | +LL | let gameloop_handle = spawn(async move { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0373`. diff --git a/tests/ui/async-await/issues/issue-95307.rs b/tests/ui/async-await/issues/issue-95307.rs new file mode 100644 index 000000000..f7e48070c --- /dev/null +++ b/tests/ui/async-await/issues/issue-95307.rs @@ -0,0 +1,13 @@ +// edition:2018 + +// Regression test for #95307. +// The ICE occurred on all the editions, specifying edition:2018 to reduce diagnostics. + +pub trait C { + async fn new() -> [u8; _]; + //~^ ERROR: functions in traits cannot be declared `async` + //~| ERROR: using `_` for array lengths is unstable + //~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment +} + +fn main() {} diff --git a/tests/ui/async-await/issues/issue-95307.stderr b/tests/ui/async-await/issues/issue-95307.stderr new file mode 100644 index 000000000..a497cebe3 --- /dev/null +++ b/tests/ui/async-await/issues/issue-95307.stderr @@ -0,0 +1,32 @@ +error[E0706]: functions in traits cannot be declared `async` + --> $DIR/issue-95307.rs:7:5 + | +LL | async fn new() -> [u8; _]; + | -----^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable + +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/issue-95307.rs:7:28 + | +LL | async fn new() -> [u8; _]; + | ^ `_` not allowed here + +error[E0658]: using `_` for array lengths is unstable + --> $DIR/issue-95307.rs:7:28 + | +LL | async fn new() -> [u8; _]; + | ^ + | + = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information + = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0658, E0706. +For more information about an error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/issues/non-async-enclosing-span.rs b/tests/ui/async-await/issues/non-async-enclosing-span.rs new file mode 100644 index 000000000..d47c21377 --- /dev/null +++ b/tests/ui/async-await/issues/non-async-enclosing-span.rs @@ -0,0 +1,11 @@ +// edition:2018 + +async fn do_the_thing() -> u8 { + 8 +} +// #63398: point at the enclosing scope and not the previously seen closure +fn main() { //~ NOTE this is not `async` + let x = move || {}; + let y = do_the_thing().await; //~ ERROR `await` is only allowed inside `async` functions + //~^ NOTE only allowed inside `async` functions and blocks +} diff --git a/tests/ui/async-await/issues/non-async-enclosing-span.stderr b/tests/ui/async-await/issues/non-async-enclosing-span.stderr new file mode 100644 index 000000000..20b827479 --- /dev/null +++ b/tests/ui/async-await/issues/non-async-enclosing-span.stderr @@ -0,0 +1,12 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/non-async-enclosing-span.rs:9:27 + | +LL | fn main() { + | ---- this is not `async` +LL | let x = move || {}; +LL | let y = do_the_thing().await; + | ^^^^^^ only allowed inside `async` functions and blocks + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0728`. |