Add some tests
This commit is contained in:
parent
881b6b5149
commit
37184e86ea
24 changed files with 402 additions and 9 deletions
|
@ -394,13 +394,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
coroutine_captures_by_ref_ty,
|
coroutine_captures_by_ref_ty,
|
||||||
);
|
);
|
||||||
|
|
||||||
let ty::Coroutine(_, args) = *self.typeck_results.borrow().expr_ty(body.value).kind()
|
let ty::Coroutine(_, coroutine_args) =
|
||||||
|
*self.typeck_results.borrow().expr_ty(body.value).kind()
|
||||||
else {
|
else {
|
||||||
bug!();
|
bug!();
|
||||||
};
|
};
|
||||||
self.demand_eqtype(
|
self.demand_eqtype(
|
||||||
span,
|
span,
|
||||||
args.as_coroutine().kind_ty(),
|
coroutine_args.as_coroutine().kind_ty(),
|
||||||
Ty::from_closure_kind(self.tcx, closure_kind),
|
Ty::from_closure_kind(self.tcx, closure_kind),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,9 +371,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
obligation: &PolyTraitObligation<'tcx>,
|
obligation: &PolyTraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) {
|
) {
|
||||||
if let Some(closure_kind) = obligation.self_ty().skip_binder().to_opt_closure_kind()
|
let self_ty = obligation.self_ty().skip_binder();
|
||||||
&& let Some(goal_kind) =
|
let target_kind_ty = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
|
||||||
obligation.predicate.skip_binder().trait_ref.args.type_at(1).to_opt_closure_kind()
|
|
||||||
|
// `to_opt_closure_kind` is kind of ICEy when it sees non-int types.
|
||||||
|
if !(self_ty.is_integral() || self_ty.is_ty_var()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if !(target_kind_ty.is_integral() || self_ty.is_ty_var()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(closure_kind) = self_ty.to_opt_closure_kind()
|
||||||
|
&& let Some(goal_kind) = target_kind_ty.to_opt_closure_kind()
|
||||||
{
|
{
|
||||||
if closure_kind.extends(goal_kind) {
|
if closure_kind.extends(goal_kind) {
|
||||||
candidates.vec.push(AsyncFnKindHelperCandidate);
|
candidates.vec.push(AsyncFnKindHelperCandidate);
|
||||||
|
|
15
tests/ui/async-await/async-closures/arg-mismatch.rs
Normal file
15
tests/ui/async-await/async-closures/arg-mismatch.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let c = async |x| {};
|
||||||
|
c(1i32).await;
|
||||||
|
c(2usize).await;
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
});
|
||||||
|
}
|
21
tests/ui/async-await/async-closures/arg-mismatch.stderr
Normal file
21
tests/ui/async-await/async-closures/arg-mismatch.stderr
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/arg-mismatch.rs:12:11
|
||||||
|
|
|
||||||
|
LL | c(2usize).await;
|
||||||
|
| - ^^^^^^ expected `i32`, found `usize`
|
||||||
|
| |
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
note: closure parameter defined here
|
||||||
|
--> $DIR/arg-mismatch.rs:10:24
|
||||||
|
|
|
||||||
|
LL | let c = async |x| {};
|
||||||
|
| ^
|
||||||
|
help: change the type of the numeric literal from `usize` to `i32`
|
||||||
|
|
|
||||||
|
LL | c(2i32).await;
|
||||||
|
| ~~~
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -0,0 +1,23 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
// FIXME(async_closures): When `fn_sig_for_fn_abi` is fixed, remove this.
|
||||||
|
// ignore-pass (test emits codegen-time warnings)
|
||||||
|
|
||||||
|
#![feature(async_closure, async_fn_traits)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
use std::ops::AsyncFnOnce;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let x = async || {};
|
||||||
|
|
||||||
|
async fn needs_async_fn_once(x: impl AsyncFnOnce()) {
|
||||||
|
x().await;
|
||||||
|
}
|
||||||
|
needs_async_fn_once(x).await;
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
WARN rustc_codegen_ssa::mir::locals Unexpected initial operand type: expected std::pin::Pin<&ReErased mut Coroutine(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), [i32, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), []), ()])>, found std::pin::Pin<&ReErased mut Coroutine(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), [i8, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), []), ()])>.See <https://github.com/rust-lang/rust/issues/114858>.
|
||||||
|
WARN rustc_codegen_ssa::mir::locals Unexpected initial operand type: expected *mut Coroutine(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), [i8, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), []), ()]), found *mut Coroutine(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), [i32, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#1}), []), ()]).See <https://github.com/rust-lang/rust/issues/114858>.
|
20
tests/ui/async-await/async-closures/auxiliary/block-on.rs
Normal file
20
tests/ui/async-await/async-closures/auxiliary/block-on.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// edition: 2021
|
||||||
|
|
||||||
|
#![feature(async_closure, noop_waker, async_fn_traits)]
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::pin;
|
||||||
|
use std::task::*;
|
||||||
|
|
||||||
|
pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
|
||||||
|
let mut fut = pin!(fut);
|
||||||
|
// Poll loop, just to test the future...
|
||||||
|
let ctx = &mut Context::from_waker(Waker::noop());
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match unsafe { fut.as_mut().poll(ctx) } {
|
||||||
|
Poll::Pending => {}
|
||||||
|
Poll::Ready(t) => break t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let x = async |x: &str| -> String { x.to_owned() };
|
||||||
|
let mut s = x("hello, world").await;
|
||||||
|
s.truncate(4);
|
||||||
|
println!("{s}");
|
||||||
|
});
|
||||||
|
}
|
26
tests/ui/async-await/async-closures/brand.rs
Normal file
26
tests/ui/async-await/async-closures/brand.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
// build-pass
|
||||||
|
|
||||||
|
#![feature(async_closure, async_fn_traits)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ops::AsyncFn;
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
struct B<'b>(PhantomData<&'b mut &'b mut ()>);
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
async fn q<F: AsyncFn(B<'_>)>(self, f: F) {
|
||||||
|
f(B(PhantomData)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
S.q(async |b: B<'_>| { println!("...") }).await;
|
||||||
|
});
|
||||||
|
}
|
18
tests/ui/async-await/async-closures/higher-ranked-return.rs
Normal file
18
tests/ui/async-await/async-closures/higher-ranked-return.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
// known-bug: unknown
|
||||||
|
// Borrow checking doesn't like that higher-ranked output...
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let x = async move |x: &str| -> &str {
|
||||||
|
x
|
||||||
|
};
|
||||||
|
let s = x("hello!").await;
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/higher-ranked-return.rs:13:46
|
||||||
|
|
|
||||||
|
LL | let x = async move |x: &str| -> &str {
|
||||||
|
| ________________________________-________----_^
|
||||||
|
| | | |
|
||||||
|
| | | return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:13:46: 15:10}` contains a lifetime `'2`
|
||||||
|
| | let's call the lifetime of this reference `'1`
|
||||||
|
LL | | x
|
||||||
|
LL | | };
|
||||||
|
| |_________^ returning this value requires that `'1` must outlive `'2`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
// edition:2021
|
// edition:2021
|
||||||
// check-pass
|
// build-pass
|
||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = async move |x: &str| {
|
block_on::block_on(async {
|
||||||
println!("{x}");
|
let x = async move |x: &str| {
|
||||||
};
|
println!("{x}");
|
||||||
|
};
|
||||||
|
x("hello!").await;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
12
tests/ui/async-await/async-closures/is-not-fn.rs
Normal file
12
tests/ui/async-await/async-closures/is-not-fn.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
fn needs_fn(x: impl FnOnce()) {}
|
||||||
|
needs_fn(async || {});
|
||||||
|
//~^ ERROR expected a `FnOnce()` closure, found `{coroutine-closure@
|
||||||
|
// FIXME(async_closures): This should explain in more detail how async fns don't
|
||||||
|
// implement the regular `Fn` traits. Or maybe we should just fix it and make them
|
||||||
|
// when there are no upvars or whatever.
|
||||||
|
}
|
19
tests/ui/async-await/async-closures/is-not-fn.stderr
Normal file
19
tests/ui/async-await/async-closures/is-not-fn.stderr
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0277]: expected a `FnOnce()` closure, found `{coroutine-closure@$DIR/is-not-fn.rs:7:14: 7:22}`
|
||||||
|
--> $DIR/is-not-fn.rs:7:14
|
||||||
|
|
|
||||||
|
LL | needs_fn(async || {});
|
||||||
|
| -------- ^^^^^^^^^^^ expected an `FnOnce()` closure, found `{coroutine-closure@$DIR/is-not-fn.rs:7:14: 7:22}`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `FnOnce<()>` is not implemented for `{coroutine-closure@$DIR/is-not-fn.rs:7:14: 7:22}`
|
||||||
|
= note: wrap the `{coroutine-closure@$DIR/is-not-fn.rs:7:14: 7:22}` in a closure with no arguments: `|| { /* code */ }`
|
||||||
|
note: required by a bound in `needs_fn`
|
||||||
|
--> $DIR/is-not-fn.rs:6:25
|
||||||
|
|
|
||||||
|
LL | fn needs_fn(x: impl FnOnce()) {}
|
||||||
|
| ^^^^^^^^ required by this bound in `needs_fn`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,20 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
struct NoCopy;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let s = NoCopy;
|
||||||
|
let x = async move || {
|
||||||
|
drop(s);
|
||||||
|
};
|
||||||
|
x().await;
|
||||||
|
x().await;
|
||||||
|
//~^ ERROR use of moved value: `x`
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0382]: use of moved value: `x`
|
||||||
|
--> $DIR/move-consuming-capture.rs:17:9
|
||||||
|
|
|
||||||
|
LL | let x = async move || {
|
||||||
|
| - move occurs because `x` has type `{coroutine-closure@$DIR/move-consuming-capture.rs:13:17: 13:30}`, which does not implement the `Copy` trait
|
||||||
|
...
|
||||||
|
LL | x().await;
|
||||||
|
| --- `x` moved due to this method call
|
||||||
|
LL | x().await;
|
||||||
|
| ^ value used here after move
|
||||||
|
|
|
||||||
|
note: `async_call_once` takes ownership of the receiver `self`, which moves `x`
|
||||||
|
--> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0382`.
|
21
tests/ui/async-await/async-closures/move-is-async-fn.rs
Normal file
21
tests/ui/async-await/async-closures/move-is-async-fn.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
// build-pass
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let s = String::from("hello, world");
|
||||||
|
let c = async move || {
|
||||||
|
println!("{s}");
|
||||||
|
};
|
||||||
|
c().await;
|
||||||
|
c().await;
|
||||||
|
|
||||||
|
fn is_static<T: 'static>(_: T) {}
|
||||||
|
is_static(c);
|
||||||
|
});
|
||||||
|
}
|
19
tests/ui/async-await/async-closures/mutate.rs
Normal file
19
tests/ui/async-await/async-closures/mutate.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let mut prefix = String::from("Hello");
|
||||||
|
let mut c = async move |x: &str| {
|
||||||
|
prefix.push(',');
|
||||||
|
println!("{prefix} {x}!")
|
||||||
|
};
|
||||||
|
c("world").await;
|
||||||
|
c("rust").await;
|
||||||
|
});
|
||||||
|
}
|
21
tests/ui/async-await/async-closures/not-lending.rs
Normal file
21
tests/ui/async-await/async-closures/not-lending.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
// Make sure that we can't make an async closure that evaluates to a self-borrow.
|
||||||
|
// i.e. that the generator may reference captures, but the future's return type can't.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let s = String::new();
|
||||||
|
let x = async move || -> &String { &s };
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
|
|
||||||
|
let s = String::new();
|
||||||
|
let x = async move || { &s };
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
|
});
|
||||||
|
}
|
24
tests/ui/async-await/async-closures/not-lending.stderr
Normal file
24
tests/ui/async-await/async-closures/not-lending.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/not-lending.rs:14:42
|
||||||
|
|
|
||||||
|
LL | let x = async move || -> &String { &s };
|
||||||
|
| ------------------------ ^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||||
|
| | |
|
||||||
|
| | return type of async closure `{async closure body@$DIR/not-lending.rs:14:42: 14:48}` contains a lifetime `'2`
|
||||||
|
| lifetime `'1` represents this closure's body
|
||||||
|
|
|
||||||
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
|
||||||
|
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/not-lending.rs:18:31
|
||||||
|
|
|
||||||
|
LL | let x = async move || { &s };
|
||||||
|
| ------------- ^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||||
|
| | |
|
||||||
|
| | return type of async closure `{async closure body@$DIR/not-lending.rs:18:31: 18:37}` contains a lifetime `'2`
|
||||||
|
| lifetime `'1` represents this closure's body
|
||||||
|
|
|
||||||
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
14
tests/ui/async-await/async-closures/return-type-mismatch.rs
Normal file
14
tests/ui/async-await/async-closures/return-type-mismatch.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// aux-build:block-on.rs
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
extern crate block_on;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
block_on::block_on(async {
|
||||||
|
let x = async || -> i32 { 0 };
|
||||||
|
let y: usize = x().await;
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/return-type-mismatch.rs:11:24
|
||||||
|
|
|
||||||
|
LL | let y: usize = x().await;
|
||||||
|
| ^^^^^^^^^ expected `usize`, found `i32`
|
||||||
|
|
|
||||||
|
help: you can convert an `i32` to a `usize` and panic if the converted value doesn't fit
|
||||||
|
|
|
||||||
|
LL | let y: usize = x().await.try_into().unwrap();
|
||||||
|
| ++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
18
tests/ui/async-await/async-closures/wrong-fn-kind.rs
Normal file
18
tests/ui/async-await/async-closures/wrong-fn-kind.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
// FIXME(async_closures): This needs a better error message!
|
||||||
|
|
||||||
|
#![feature(async_closure, async_fn_traits)]
|
||||||
|
|
||||||
|
use std::ops::AsyncFn;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
fn needs_async_fn(_: impl AsyncFn()) {}
|
||||||
|
|
||||||
|
let mut x = 1;
|
||||||
|
needs_async_fn(async || {
|
||||||
|
//~^ ERROR i16: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>
|
||||||
|
// FIXME: Should say "closure is AsyncFnMut but it needs AsyncFn" or sth.
|
||||||
|
x += 1;
|
||||||
|
});
|
||||||
|
}
|
22
tests/ui/async-await/async-closures/wrong-fn-kind.stderr
Normal file
22
tests/ui/async-await/async-closures/wrong-fn-kind.stderr
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
error[E0277]: the trait bound `i16: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not satisfied
|
||||||
|
--> $DIR/wrong-fn-kind.rs:13:20
|
||||||
|
|
|
||||||
|
LL | needs_async_fn(async || {
|
||||||
|
| _____--------------_^
|
||||||
|
| | |
|
||||||
|
| | required by a bound introduced by this call
|
||||||
|
LL | |
|
||||||
|
LL | | // FIXME: Should say "closure is AsyncFnMut but it needs AsyncFn" or sth.
|
||||||
|
LL | | x += 1;
|
||||||
|
LL | | });
|
||||||
|
| |_____^ the trait `ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not implemented for `i16`
|
||||||
|
|
|
||||||
|
note: required by a bound in `needs_async_fn`
|
||||||
|
--> $DIR/wrong-fn-kind.rs:10:31
|
||||||
|
|
|
||||||
|
LL | fn needs_async_fn(_: impl AsyncFn()) {}
|
||||||
|
| ^^^^^^^^^ required by this bound in `needs_async_fn`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue