Skip to content

Commit 3bb9ec7

Browse files
committed
Add unsized_fn_params feature
1 parent 215f2d3 commit 3bb9ec7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+139
-69
lines changed

src/liballoc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
#![feature(unboxed_closures)]
119119
#![feature(unicode_internals)]
120120
#![feature(unsize)]
121+
#![cfg_attr(not(bootstrap), feature(unsized_fn_params))]
121122
#![feature(unsized_locals)]
122123
#![feature(allocator_internals)]
123124
#![feature(slice_partition_dedup)]

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
#![feature(track_caller)]
118118
#![feature(transparent_unions)]
119119
#![feature(unboxed_closures)]
120+
#![cfg_attr(not(bootstrap), feature(unsized_fn_params))]
120121
#![feature(unsized_locals)]
121122
#![feature(untagged_unions)]
122123
#![feature(unwind_attributes)]

src/librustc_feature/active.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,9 @@ declare_features! (
571571
/// Allows the use of `#[ffi_const]` on foreign functions.
572572
(active, ffi_const, "1.45.0", Some(58328), None),
573573

574+
/// Allows unsized fn parameters.
575+
(active, unsized_fn_params, "1.45.0", Some(48055), None),
576+
574577
// -------------------------------------------------------------------------
575578
// feature-group-end: actual feature gates
576579
// -------------------------------------------------------------------------

src/librustc_mir/borrow_check/type_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1729,7 +1729,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
17291729

17301730
// When `#![feature(unsized_locals)]` is not enabled,
17311731
// this check is done at `check_local`.
1732-
if self.tcx().features().unsized_locals {
1732+
if self.tcx().features().unsized_fn_params {
17331733
let span = term.source_info.span;
17341734
self.ensure_place_sized(dest_ty, span);
17351735
}

src/librustc_mir_build/build/expr/as_operand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
165165

166166
let tcx = this.hir.tcx();
167167

168-
if tcx.features().unsized_locals {
168+
if tcx.features().unsized_fn_params {
169169
let ty = expr.ty;
170170
let span = expr.span;
171171
let param_env = this.hir.param_env;

src/librustc_span/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ symbols! {
807807
unreachable_code,
808808
unrestricted_attribute_tokens,
809809
unsafe_no_drop_flag,
810+
unsized_fn_params,
810811
unsized_locals,
811812
unsized_tuple_coercion,
812813
unstable,

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,8 +1749,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
17491749
}
17501750
ObligationCauseCode::SizedArgumentType => {
17511751
err.note("all function arguments must have a statically known size");
1752-
if !self.tcx.features().unsized_locals {
1753-
err.help("unsized locals are gated as an unstable feature");
1752+
if !self.tcx.features().unsized_fn_params {
1753+
err.help("unsized fn params are gated as an unstable feature");
17541754
}
17551755
}
17561756
ObligationCauseCode::SizedReturnType => {

src/librustc_typeck/check/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
486486

487487
if let ty::FnDef(..) = ty.kind {
488488
let fn_sig = ty.fn_sig(tcx);
489-
if !tcx.features().unsized_locals {
489+
if !tcx.features().unsized_fn_params {
490490
// We want to remove some Sized bounds from std functions,
491491
// but don't want to expose the removal to stable Rust.
492492
// i.e., we don't want to allow

src/librustc_typeck/check/mod.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,8 @@ fn typeck_tables_of_with_fallback<'tcx>(
10531053
};
10541054

10551055
// Gather locals in statics (because of block expressions).
1056-
GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1056+
GatherLocalsVisitor { fcx: &fcx, parent_id: id, within_fn_param: false }
1057+
.visit_body(body);
10571058

10581059
fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
10591060

@@ -1156,6 +1157,10 @@ fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
11561157
struct GatherLocalsVisitor<'a, 'tcx> {
11571158
fcx: &'a FnCtxt<'a, 'tcx>,
11581159
parent_id: hir::HirId,
1160+
// params are special cases of pats, but we want to handle them as
1161+
// *distinct* cases. so track when we are hitting a pat *within* an fn
1162+
// param.
1163+
within_fn_param: bool,
11591164
}
11601165

11611166
impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
@@ -1226,13 +1231,25 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
12261231
intravisit::walk_local(self, local);
12271232
}
12281233

1234+
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
1235+
self.within_fn_param = true;
1236+
intravisit::walk_param(self, param);
1237+
self.within_fn_param = false;
1238+
}
1239+
12291240
// Add pattern bindings.
12301241
fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
12311242
if let PatKind::Binding(_, _, ident, _) = p.kind {
12321243
let var_ty = self.assign(p.span, p.hir_id, None);
12331244

1234-
if !self.fcx.tcx.features().unsized_locals {
1235-
self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1245+
if self.within_fn_param {
1246+
if !self.fcx.tcx.features().unsized_fn_params {
1247+
self.fcx.require_type_is_sized(var_ty, p.span, traits::SizedArgumentType);
1248+
}
1249+
} else {
1250+
if !self.fcx.tcx.features().unsized_locals {
1251+
self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1252+
}
12361253
}
12371254

12381255
debug!(
@@ -1332,7 +1349,8 @@ fn check_fn<'a, 'tcx>(
13321349

13331350
let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id());
13341351
let outer_hir_id = hir.as_local_hir_id(outer_def_id.expect_local());
1335-
GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1352+
GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, within_fn_param: false }
1353+
.visit_body(body);
13361354

13371355
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
13381356
// (as it's created inside the body itself, not passed in from outside).
@@ -1360,7 +1378,7 @@ fn check_fn<'a, 'tcx>(
13601378
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
13611379
// for simple cases like `fn foo(x: Trait)`,
13621380
// where we would error once on the parameter as a whole, and once on the binding `x`.
1363-
if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1381+
if param.pat.simple_ident().is_none() && !tcx.features().unsized_fn_params {
13641382
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
13651383
}
13661384

src/test/run-pass-valgrind/unsized-locals/long-live-the-unsized-temporary.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#![feature(unsized_locals)]
1+
#![allow(incomplete_features)]
2+
#![feature(unsized_locals, unsized_fn_params)]
23

34
use std::fmt;
45

@@ -45,11 +46,7 @@ fn main() {
4546

4647
{
4748
let x: fmt::Display = *gen_foo();
48-
let x = if true {
49-
x
50-
} else {
51-
*gen_foo()
52-
};
49+
let x = if true { x } else { *gen_foo() };
5350
foo(x);
5451
}
5552
}

src/test/ui/error-codes/E0277.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | fn f(p: Path) { }
77
= help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: required because it appears within the type `std::path::Path`
10-
= note: all local variables must have a statically known size
11-
= help: unsized locals are gated as an unstable feature
10+
= note: all function arguments must have a statically known size
11+
= help: unsized fn params are gated as an unstable feature
1212

1313
error[E0277]: the trait bound `i32: Foo` is not satisfied
1414
--> $DIR/E0277.rs:17:15
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#[repr(align(256))]
2+
#[allow(dead_code)]
3+
struct A {
4+
v: u8,
5+
}
6+
7+
trait Foo {
8+
fn foo(&self);
9+
}
10+
11+
impl Foo for A {
12+
fn foo(&self) {
13+
assert_eq!(self as *const A as usize % 256, 0);
14+
}
15+
}
16+
17+
fn foo(x: dyn Foo) {
18+
//~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time [E0277]
19+
x.foo()
20+
}
21+
22+
fn main() {
23+
let x: Box<dyn Foo> = Box::new(A { v: 22 });
24+
foo(*x);
25+
//~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time [E0277]
26+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
2+
--> $DIR/feature-gate-unsized_fn_params.rs:17:8
3+
|
4+
LL | fn foo(x: dyn Foo) {
5+
| ^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + 'static)`
8+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9+
= note: all function arguments must have a statically known size
10+
= help: unsized fn params are gated as an unstable feature
11+
12+
error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
13+
--> $DIR/feature-gate-unsized_fn_params.rs:24:5
14+
|
15+
LL | foo(*x);
16+
| ^^^ doesn't have a size known at compile-time
17+
|
18+
= help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + 'static)`
19+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
20+
= note: all function arguments must have a statically known size
21+
= help: unsized fn params are gated as an unstable feature
22+
23+
error: aborting due to 2 previous errors
24+
25+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/feature-gates/feature-gate-unsized_locals.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | fn f(f: dyn FnOnce()) {}
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce() + 'static)`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: all local variables must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
9+
= note: all function arguments must have a statically known size
10+
= help: unsized fn params are gated as an unstable feature
1111

1212
error: aborting due to previous error
1313

src/test/ui/fn/dyn-fn-alignment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-pass
22

3-
#![feature(unsized_locals)]
3+
#![feature(unsized_fn_params)]
44
#![allow(dead_code)]
55
#[repr(align(256))]
66
struct A {

src/test/ui/issues/issue-17651.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ LL | (|| Box::new(*(&[0][..])))();
1717
= help: the trait `std::marker::Sized` is not implemented for `[{integer}]`
1818
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
1919
= note: all function arguments must have a statically known size
20-
= help: unsized locals are gated as an unstable feature
20+
= help: unsized fn params are gated as an unstable feature
2121

2222
error: aborting due to 2 previous errors
2323

src/test/ui/issues/issue-27078.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | fn foo(self) -> &'static i32 {
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `Self`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: all local variables must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
9+
= note: all function arguments must have a statically known size
10+
= help: unsized fn params are gated as an unstable feature
1111
help: consider further restricting `Self`
1212
|
1313
LL | fn foo(self) -> &'static i32 where Self: std::marker::Sized {

src/test/ui/issues/issue-30355.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | &X(*Y)
77
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all function arguments must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
10+
= help: unsized fn params are gated as an unstable feature
1111

1212
error: aborting due to previous error
1313

src/test/ui/issues/issue-38954.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | fn _test(ref _p: str) {}
77
= help: the trait `std::marker::Sized` is not implemented for `str`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all function arguments must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
10+
= help: unsized fn params are gated as an unstable feature
1111

1212
error: aborting due to previous error
1313

src/test/ui/issues/issue-41229-ref-str.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | pub fn example(ref s: str) {}
77
= help: the trait `std::marker::Sized` is not implemented for `str`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all function arguments must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
10+
= help: unsized fn params are gated as an unstable feature
1111

1212
error: aborting due to previous error
1313

src/test/ui/issues/issue-42312.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | fn baz(_: Self::Target) where Self: Deref {}
77
= help: the trait `std::marker::Sized` is not implemented for `<Self as std::ops::Deref>::Target`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all function arguments must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
10+
= help: unsized fn params are gated as an unstable feature
1111
help: consider further restricting the associated type
1212
|
1313
LL | fn baz(_: Self::Target) where Self: Deref, <Self as std::ops::Deref>::Target: std::marker::Sized {}
@@ -22,7 +22,7 @@ LL | pub fn f(_: dyn ToString) {}
2222
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::string::ToString + 'static)`
2323
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
2424
= note: all function arguments must have a statically known size
25-
= help: unsized locals are gated as an unstable feature
25+
= help: unsized fn params are gated as an unstable feature
2626

2727
error: aborting due to 2 previous errors
2828

src/test/ui/issues/issue-5883.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | fn new_struct(r: dyn A + 'static)
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: all local variables must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
9+
= note: all function arguments must have a statically known size
10+
= help: unsized fn params are gated as an unstable feature
1111

1212
error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
1313
--> $DIR/issue-5883.rs:8:8

src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize, unsized_locals)]
1+
#![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize, unsized_locals, unsized_fn_params)]
22

33
// This tests a few edge-cases around `arbitrary_self_types`. Most specifically,
44
// it checks that the `ObjectCandidate` you get from method matching can't

src/test/ui/resolve/issue-5035-2.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | fn foo(_x: K) {}
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: all local variables must have a statically known size
10-
= help: unsized locals are gated as an unstable feature
9+
= note: all function arguments must have a statically known size
10+
= help: unsized fn params are gated as an unstable feature
1111

1212
error: aborting due to previous error
1313

src/test/ui/suggestions/path-by-value.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | fn f(p: Path) { }
77
= help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: required because it appears within the type `std::path::Path`
10-
= note: all local variables must have a statically known size
11-
= help: unsized locals are gated as an unstable feature
10+
= note: all function arguments must have a statically known size
11+
= help: unsized fn params are gated as an unstable feature
1212

1313
error: aborting due to previous error
1414

src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ LL | fn foo(_x: Foo + Send) {
1414
|
1515
= help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + std::marker::Send + 'static)`
1616
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
17-
= note: all local variables must have a statically known size
18-
= help: unsized locals are gated as an unstable feature
17+
= note: all function arguments must have a statically known size
18+
= help: unsized fn params are gated as an unstable feature
1919

2020
error: aborting due to previous error; 1 warning emitted
2121

src/test/ui/unsized-locals/autoderef.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-pass
22

3-
#![feature(unsized_locals)]
3+
#![feature(unsized_locals, unsized_fn_params)]
44

55
pub trait Foo {
66
fn foo(self) -> String;
@@ -24,7 +24,6 @@ impl Foo for dyn FnMut() -> String {
2424
}
2525
}
2626

27-
2827
fn main() {
2928
let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
3029
assert_eq!(&x.foo() as &str, "hello");
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
#![feature(unsized_locals)]
1+
#![feature(unsized_locals, unsized_fn_params)]
22

33
pub fn udrop<T: ?Sized>(_x: T) {}

src/test/ui/unsized-locals/borrow-after-move.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(unsized_locals)]
1+
#![feature(unsized_locals, unsized_fn_params)]
22

33
pub trait Foo {
44
fn foo(self) -> String;

0 commit comments

Comments
 (0)