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
}

0 commit comments

Comments
 (0)