Skip to content

Commit

Permalink
Unrolled build for rust-lang#134933
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#134933 - compiler-errors:async-fn-future-sized, r=lqd

Make sure we check the future type is `Sized` in `AsyncFn*`

Fixes rust-lang#134817
  • Loading branch information
rust-timer authored Dec 31, 2024
2 parents 80f5a81 + ed9a4cf commit d8fee1e
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
23 changes: 20 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(..) => {
Expand All @@ -907,14 +911,21 @@ 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,
sig.output().map_bound(|output_ty| {
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))
}
Expand All @@ -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())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit d8fee1e

Please sign in to comment.