mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Make sure we check the future type is Sized in AsyncFn*
This commit is contained in:
parent
93722f7ed5
commit
ed9a4cfdeb
@ -896,6 +896,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
sig.tupled_inputs_ty,
|
||||
])
|
||||
});
|
||||
|
||||
// Note that unlike below, we don't need to check `Future + Sized` for
|
||||
// the output coroutine because they are `Future + Sized` by construction.
|
||||
|
||||
(trait_ref, args.kind_ty())
|
||||
}
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
@ -907,7 +911,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
])
|
||||
});
|
||||
|
||||
// We must additionally check that the return type impls `Future`.
|
||||
// We must additionally check that the return type impls `Future + Sized`.
|
||||
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
|
||||
nested.push(obligation.with(
|
||||
tcx,
|
||||
@ -915,6 +919,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
ty::TraitRef::new(tcx, future_trait_def_id, [output_ty])
|
||||
}),
|
||||
));
|
||||
let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
|
||||
nested.push(obligation.with(
|
||||
tcx,
|
||||
sig.output().map_bound(|output_ty| {
|
||||
ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
|
||||
}),
|
||||
));
|
||||
|
||||
(trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
|
||||
}
|
||||
@ -928,14 +939,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
])
|
||||
});
|
||||
|
||||
// We must additionally check that the return type impls `Future`.
|
||||
// See FIXME in last branch for why we instantiate the binder eagerly.
|
||||
// We must additionally check that the return type impls `Future + Sized`.
|
||||
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
|
||||
let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
|
||||
nested.push(obligation.with(
|
||||
tcx,
|
||||
ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]),
|
||||
));
|
||||
let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
|
||||
nested.push(obligation.with(
|
||||
tcx,
|
||||
sig.output().map_bound(|output_ty| {
|
||||
ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
|
||||
}),
|
||||
));
|
||||
|
||||
(trait_ref, args.kind_ty())
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
//@ edition: 2021
|
||||
|
||||
// Ensure that the output of a `fn` pointer that implements `AsyncFn*` is `Sized`,
|
||||
// like other built-in impls of an fn pointer, like `Fn*`.
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
fn foo() -> fn() -> dyn Future<Output = ()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn is_async_fn(f: impl AsyncFn()) {
|
||||
f().await;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
is_async_fn(foo());
|
||||
//~^ ERROR the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
|
||||
//~| ERROR the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
error[E0277]: the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
|
||||
--> $DIR/async-future-out-must-be-sized.rs:17:17
|
||||
|
|
||||
LL | is_async_fn(foo());
|
||||
| ----------- ^^^^^ doesn't have a size known at compile-time
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn Future<Output = ()>`
|
||||
note: required by a bound in `is_async_fn`
|
||||
--> $DIR/async-future-out-must-be-sized.rs:12:30
|
||||
|
|
||||
LL | async fn is_async_fn(f: impl AsyncFn()) {
|
||||
| ^^^^^^^^^ required by this bound in `is_async_fn`
|
||||
|
||||
error[E0277]: the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
|
||||
--> $DIR/async-future-out-must-be-sized.rs:17:5
|
||||
|
|
||||
LL | is_async_fn(foo());
|
||||
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn Future<Output = ()>`
|
||||
note: required by a bound in `is_async_fn`
|
||||
--> $DIR/async-future-out-must-be-sized.rs:12:30
|
||||
|
|
||||
LL | async fn is_async_fn(f: impl AsyncFn()) {
|
||||
| ^^^^^^^^^ required by this bound in `is_async_fn`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user