Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 708fc3b

Browse files
committed
Add unsized_fn_params feature
1 parent 2a71e45 commit 708fc3b

Some content is hidden

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

46 files changed

+165
-86
lines changed

compiler/rustc_feature/src/active.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,9 @@ declare_features! (
607607
/// Allow anonymous constants from an inline `const` block
608608
(active, inline_const, "1.49.0", Some(76001), None),
609609

610+
/// Allows unsized fn parameters.
611+
(active, unsized_fn_params, "1.49.0", Some(48055), None),
612+
610613
// -------------------------------------------------------------------------
611614
// feature-group-end: actual feature gates
612615
// -------------------------------------------------------------------------

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
14561456
}
14571457

14581458
self.check_rvalue(body, rv, location);
1459-
if !self.tcx().features().unsized_locals {
1459+
if !(self.tcx().features().unsized_locals
1460+
|| self.tcx().features().unsized_fn_params)
1461+
{
14601462
let trait_ref = ty::TraitRef {
14611463
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
14621464
substs: tcx.mk_substs_trait(place_ty, &[]),
@@ -1717,9 +1719,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
17171719
);
17181720
}
17191721

1720-
// When `#![feature(unsized_locals)]` is not enabled,
1722+
// When `unsized_fn_params` or `unsized_locals` is not enabled,
17211723
// this check is done at `check_local`.
1722-
if self.tcx().features().unsized_locals {
1724+
if self.tcx().features().unsized_locals || self.tcx().features().unsized_fn_params {
17231725
let span = term.source_info.span;
17241726
self.ensure_place_sized(dest_ty, span);
17251727
}
@@ -1880,9 +1882,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18801882
LocalKind::Var | LocalKind::Temp => {}
18811883
}
18821884

1883-
// When `#![feature(unsized_locals)]` is enabled, only function calls
1885+
// When `unsized_fn_params` or `unsized_locals` is enabled, only function calls
18841886
// and nullary ops are checked in `check_call_dest`.
1885-
if !self.tcx().features().unsized_locals {
1887+
if !(self.tcx().features().unsized_locals || self.tcx().features().unsized_fn_params) {
18861888
let span = local_decl.source_info.span;
18871889
let ty = local_decl.ty;
18881890
self.ensure_place_sized(ty, span);
@@ -2024,7 +2026,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20242026

20252027
Rvalue::NullaryOp(_, ty) => {
20262028
// Even with unsized locals cannot box an unsized value.
2027-
if self.tcx().features().unsized_locals {
2029+
if self.tcx().features().unsized_locals || self.tcx().features().unsized_fn_params {
20282030
let span = body.source_info(location).span;
20292031
self.ensure_place_sized(ty, span);
20302032
}

compiler/rustc_mir_build/src/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;

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,7 @@ symbols! {
11611161
unsafe_cell,
11621162
unsafe_no_drop_flag,
11631163
unsize,
1164+
unsized_fn_params,
11641165
unsized_locals,
11651166
unsized_tuple_coercion,
11661167
unstable,

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,9 +1845,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18451845
err.note("all function arguments must have a statically known size");
18461846
}
18471847
if tcx.sess.opts.unstable_features.is_nightly_build()
1848-
&& !self.tcx.features().unsized_locals
1848+
&& !self.tcx.features().unsized_fn_params
18491849
{
1850-
err.help("unsized locals are gated as an unstable feature");
1850+
err.help("unsized fn params are gated as an unstable feature");
18511851
}
18521852
}
18531853
ObligationCauseCode::SizedReturnType => {

compiler/rustc_typeck/src/check/check.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub(super) fn check_fn<'a, 'tcx>(
105105

106106
let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
107107
let outer_hir_id = hir.local_def_id_to_hir_id(outer_def_id);
108-
GatherLocalsVisitor::new(&fcx, outer_hir_id).visit_body(body);
108+
GatherLocalsVisitor::new(&fcx, outer_hir_id, false).visit_body(body);
109109

110110
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
111111
// (as it's created inside the body itself, not passed in from outside).
@@ -131,7 +131,7 @@ pub(super) fn check_fn<'a, 'tcx>(
131131
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
132132
// for simple cases like `fn foo(x: Trait)`,
133133
// where we would error once on the parameter as a whole, and once on the binding `x`.
134-
if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
134+
if param.pat.simple_ident().is_none() && !tcx.features().unsized_fn_params {
135135
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
136136
}
137137

compiler/rustc_typeck/src/check/expr.rs

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

477477
if let ty::FnDef(..) = ty.kind() {
478478
let fn_sig = ty.fn_sig(tcx);
479-
if !tcx.features().unsized_locals {
479+
if !tcx.features().unsized_fn_params {
480480
// We want to remove some Sized bounds from std functions,
481481
// but don't want to expose the removal to stable Rust.
482482
// i.e., we don't want to allow

compiler/rustc_typeck/src/check/gather_locals.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,19 @@ use rustc_trait_selection::traits;
1010
pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
1111
fcx: &'a FnCtxt<'a, 'tcx>,
1212
parent_id: hir::HirId,
13+
// params are special cases of pats, but we want to handle them as
14+
// *distinct* cases. so track when we are hitting a pat *within* an fn
15+
// param.
16+
within_fn_param: bool,
1317
}
1418

1519
impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
16-
pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>, parent_id: hir::HirId) -> Self {
17-
Self { fcx, parent_id }
20+
pub(super) fn new(
21+
fcx: &'a FnCtxt<'a, 'tcx>,
22+
parent_id: hir::HirId,
23+
within_fn_param: bool,
24+
) -> Self {
25+
Self { fcx, parent_id, within_fn_param }
1826
}
1927

2028
fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
@@ -88,13 +96,29 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
8896
intravisit::walk_local(self, local);
8997
}
9098

99+
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
100+
self.within_fn_param = true;
101+
intravisit::walk_param(self, param);
102+
self.within_fn_param = false;
103+
}
104+
91105
// Add pattern bindings.
92106
fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
93107
if let PatKind::Binding(_, _, ident, _) = p.kind {
94108
let var_ty = self.assign(p.span, p.hir_id, None);
95109

96-
if !self.fcx.tcx.features().unsized_locals {
97-
self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
110+
if self.within_fn_param {
111+
if !self.fcx.tcx.features().unsized_fn_params {
112+
self.fcx.require_type_is_sized(
113+
var_ty,
114+
p.span,
115+
traits::SizedArgumentType(Some(p.span)),
116+
);
117+
}
118+
} else {
119+
if !self.fcx.tcx.features().unsized_locals {
120+
self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
121+
}
98122
}
99123

100124
debug!(

compiler/rustc_typeck/src/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ fn typeck_with_fallback<'tcx>(
553553
};
554554

555555
// Gather locals in statics (because of block expressions).
556-
GatherLocalsVisitor::new(&fcx, id).visit_body(body);
556+
GatherLocalsVisitor::new(&fcx, id, false).visit_body(body);
557557

558558
fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
559559

library/alloc/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@
130130
#![feature(unicode_internals)]
131131
#![feature(unsafe_block_in_unsafe_fn)]
132132
#![feature(unsize)]
133-
#![feature(unsized_locals)]
133+
#![cfg_attr(not(bootstrap), feature(unsized_fn_params))]
134+
#![cfg_attr(bootstrap, feature(unsized_locals))]
134135
#![feature(allocator_internals)]
135136
#![feature(slice_partition_dedup)]
136137
#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]

0 commit comments

Comments
 (0)