Skip to content

Commit

Permalink
Always require closure parameters to be Sized
Browse files Browse the repository at this point in the history
The `rust-call` ABI isn't compatible with
`#![feature(unsized_fn_params)]`, so trying to use that feature with
closures leads to an ICE (rust-lang#67981). This turns that ICE into a
type-check error.
  • Loading branch information
Jules-Bertholet committed May 23, 2023
1 parent 8b4b208 commit 5cd02ea
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 2 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub(super) fn check_fn<'a, 'tcx>(
fn_def_id: LocalDefId,
body: &'tcx hir::Body<'tcx>,
can_be_generator: Option<hir::Movability>,
params_can_be_unsized: bool,
) -> Option<GeneratorTypes<'tcx>> {
let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id);

Expand Down Expand Up @@ -94,7 +95,7 @@ pub(super) fn check_fn<'a, 'tcx>(
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
// for simple cases like `fn foo(x: Trait)`,
// where we would error once on the parameter as a whole, and once on the binding `x`.
if param.pat.simple_ident().is_none() && !tcx.features().unsized_fn_params {
if param.pat.simple_ident().is_none() && !params_can_be_unsized {
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr_def_id,
body,
closure.movability,
// Closure "rust-call" ABI doesn't support unsized params
false,
);

let parent_substs = InternalSubsts::identity_for_item(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ fn typeck_with_fallback<'tcx>(
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
let fn_sig = fcx.normalize(body.value.span, fn_sig);

check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
check_fn(&mut fcx, fn_sig, decl, def_id, body, None, tcx.features().unsized_fn_params);
} else {
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
Some(fcx.next_ty_var(TypeVariableOrigin {
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/unsized-locals/issue-67981.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(unsized_fn_params)]

fn main() {
let f: fn([u8]) = |_| {};
//~^ERROR the size for values of type `[u8]` cannot be known at compilation time
let slice: Box<[u8]> = Box::new([1; 8]);

f(*slice);
}
15 changes: 15 additions & 0 deletions tests/ui/unsized-locals/issue-67981.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-67981.rs:4:24
|
LL | let f: fn([u8]) = |_| {};
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | let f: fn([u8]) = |&_| {};
| +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

0 comments on commit 5cd02ea

Please sign in to comment.