Skip to content

Commit a93bef6

Browse files
authored
Rollup merge of #134933 - compiler-errors:async-fn-future-sized, r=lqd
Make sure we check the future type is `Sized` in `AsyncFn*` Fixes #134817
2 parents e49929e + ed9a4cf commit a93bef6

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
896896
sig.tupled_inputs_ty,
897897
])
898898
});
899+
900+
// Note that unlike below, we don't need to check `Future + Sized` for
901+
// the output coroutine because they are `Future + Sized` by construction.
902+
899903
(trait_ref, args.kind_ty())
900904
}
901905
ty::FnDef(..) | ty::FnPtr(..) => {
@@ -907,14 +911,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
907911
])
908912
});
909913

910-
// We must additionally check that the return type impls `Future`.
914+
// We must additionally check that the return type impls `Future + Sized`.
911915
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
912916
nested.push(obligation.with(
913917
tcx,
914918
sig.output().map_bound(|output_ty| {
915919
ty::TraitRef::new(tcx, future_trait_def_id, [output_ty])
916920
}),
917921
));
922+
let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
923+
nested.push(obligation.with(
924+
tcx,
925+
sig.output().map_bound(|output_ty| {
926+
ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
927+
}),
928+
));
918929

919930
(trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
920931
}
@@ -928,14 +939,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
928939
])
929940
});
930941

931-
// We must additionally check that the return type impls `Future`.
932-
// See FIXME in last branch for why we instantiate the binder eagerly.
942+
// We must additionally check that the return type impls `Future + Sized`.
933943
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
934944
let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
935945
nested.push(obligation.with(
936946
tcx,
937947
ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]),
938948
));
949+
let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
950+
nested.push(obligation.with(
951+
tcx,
952+
sig.output().map_bound(|output_ty| {
953+
ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
954+
}),
955+
));
939956

940957
(trait_ref, args.kind_ty())
941958
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ edition: 2021
2+
3+
// Ensure that the output of a `fn` pointer that implements `AsyncFn*` is `Sized`,
4+
// like other built-in impls of an fn pointer, like `Fn*`.
5+
6+
use std::future::Future;
7+
8+
fn foo() -> fn() -> dyn Future<Output = ()> {
9+
todo!()
10+
}
11+
12+
async fn is_async_fn(f: impl AsyncFn()) {
13+
f().await;
14+
}
15+
16+
fn main() {
17+
is_async_fn(foo());
18+
//~^ ERROR the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
19+
//~| ERROR the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0277]: the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
2+
--> $DIR/async-future-out-must-be-sized.rs:17:17
3+
|
4+
LL | is_async_fn(foo());
5+
| ----------- ^^^^^ doesn't have a size known at compile-time
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `Sized` is not implemented for `dyn Future<Output = ()>`
10+
note: required by a bound in `is_async_fn`
11+
--> $DIR/async-future-out-must-be-sized.rs:12:30
12+
|
13+
LL | async fn is_async_fn(f: impl AsyncFn()) {
14+
| ^^^^^^^^^ required by this bound in `is_async_fn`
15+
16+
error[E0277]: the size for values of type `dyn Future<Output = ()>` cannot be known at compilation time
17+
--> $DIR/async-future-out-must-be-sized.rs:17:5
18+
|
19+
LL | is_async_fn(foo());
20+
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
21+
|
22+
= help: the trait `Sized` is not implemented for `dyn Future<Output = ()>`
23+
note: required by a bound in `is_async_fn`
24+
--> $DIR/async-future-out-must-be-sized.rs:12:30
25+
|
26+
LL | async fn is_async_fn(f: impl AsyncFn()) {
27+
| ^^^^^^^^^ required by this bound in `is_async_fn`
28+
29+
error: aborting due to 2 previous errors
30+
31+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)