Skip to content

Commit efea88a

Browse files
authored
Rollup merge of #111864 - Jules-Bertholet:sized-closures, r=compiler-errors
Always require closure parameters to be `Sized` The `rust-call` ABI isn't compatible with `#![feature(unsized_fn_params)]`, so trying to use that feature with closures leads to an ICE (#67981). This turns that ICE into a type-check error. `@rustbot` label A-closures F-unsized_fn_params
2 parents 224b651 + 5cd02ea commit efea88a

File tree

5 files changed

+29
-2
lines changed

5 files changed

+29
-2
lines changed

compiler/rustc_hir_typeck/src/check.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub(super) fn check_fn<'a, 'tcx>(
3232
fn_def_id: LocalDefId,
3333
body: &'tcx hir::Body<'tcx>,
3434
can_be_generator: Option<hir::Movability>,
35+
params_can_be_unsized: bool,
3536
) -> Option<GeneratorTypes<'tcx>> {
3637
let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id);
3738

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

compiler/rustc_hir_typeck/src/closure.rs

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8989
expr_def_id,
9090
body,
9191
closure.movability,
92+
// Closure "rust-call" ABI doesn't support unsized params
93+
false,
9294
);
9395

9496
let parent_substs = InternalSubsts::identity_for_item(

compiler/rustc_hir_typeck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ fn typeck_with_fallback<'tcx>(
212212
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
213213
let fn_sig = fcx.normalize(body.value.span, fn_sig);
214214

215-
check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
215+
check_fn(&mut fcx, fn_sig, decl, def_id, body, None, tcx.features().unsized_fn_params);
216216
} else {
217217
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
218218
Some(fcx.next_ty_var(TypeVariableOrigin {
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(unsized_fn_params)]
2+
3+
fn main() {
4+
let f: fn([u8]) = |_| {};
5+
//~^ERROR the size for values of type `[u8]` cannot be known at compilation time
6+
let slice: Box<[u8]> = Box::new([1; 8]);
7+
8+
f(*slice);
9+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2+
--> $DIR/issue-67981.rs:4:24
3+
|
4+
LL | let f: fn([u8]) = |_| {};
5+
| ^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `[u8]`
8+
help: function arguments must have a statically known size, borrowed types always have a known size
9+
|
10+
LL | let f: fn([u8]) = |&_| {};
11+
| +
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)