Skip to content

Commit 9376cd8

Browse files
committed
Unimplement unsized_locals
1 parent aa5832b commit 9376cd8

File tree

85 files changed

+455
-822
lines changed

Some content is hidden

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

85 files changed

+455
-822
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
377377
}
378378

379379
fn unsized_feature_enabled(&self) -> bool {
380-
let features = self.tcx().features();
381-
features.unsized_locals() || features.unsized_fn_params()
380+
self.tcx().features().unsized_fn_params()
382381
}
383382

384383
/// Equate the inferred type and the annotated type for user type annotations
@@ -961,7 +960,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
961960
}
962961
}
963962

964-
// When `unsized_fn_params` or `unsized_locals` is enabled, only function calls
963+
// When `unsized_fn_params` is enabled, only function calls
965964
// and nullary ops are checked in `check_call_dest`.
966965
if !self.unsized_feature_enabled() {
967966
match self.body.local_kind(local) {
@@ -1951,7 +1950,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19511950
);
19521951
}
19531952

1954-
// When `unsized_fn_params` and `unsized_locals` are both not enabled,
1953+
// When `unsized_fn_params` is not enabled,
19551954
// this check is done at `check_local`.
19561955
if self.unsized_feature_enabled() {
19571956
let span = term.source_info.span;

compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
3232
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
3333

3434
trait Trait {
35-
// This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
36-
// without unsized_locals), but wrappers around `Self` currently are not.
37-
// FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented
38-
// fn wrapper(self: Wrapper<Self>) -> i32;
3935
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
4036
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
4137
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;

compiler/rustc_codegen_gcc/example/arbitrary_self_types_pointers_and_wrappers.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
3737

3838

3939
trait Trait {
40-
// This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
41-
// without unsized_locals), but wrappers around `Self` currently are not.
42-
// FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented
43-
// fn wrapper(self: Wrapper<Self>) -> i32;
4440
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
4541
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
4642
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;

compiler/rustc_feature/src/removed.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ declare_features! (
247247
/// Allows unnamed fields of struct and union type
248248
(removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign")),
249249
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
250+
/// Allows unsized rvalues at arguments and parameters.
251+
(removed, unsized_locals, "CURRENT_RUSTC_VERSION", Some(48055), Some("removed due to soundness issues; see https://github.com/rust-lang/rust/issues/111942")),
250252
(removed, unsized_tuple_coercion, "1.87.0", Some(42877),
251253
Some("The feature restricts possible layouts for tuples, and this restriction is not worth it.")),
252254
/// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.

compiler/rustc_feature/src/unstable.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,6 @@ declare_features! (
669669
(incomplete, unsized_const_params, "1.82.0", Some(95174)),
670670
/// Allows unsized fn parameters.
671671
(internal, unsized_fn_params, "1.49.0", Some(48055)),
672-
/// Allows unsized rvalues at arguments and parameters.
673-
(incomplete, unsized_locals, "1.30.0", Some(48055)),
674672
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
675673
(unstable, used_with_arg, "1.60.0", Some(93798)),
676674
/// Allows use of attributes in `where` clauses.

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,9 +1663,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
16631663
blk_id,
16641664
expression,
16651665
);
1666-
if !fcx.tcx.features().unsized_locals() {
1667-
unsized_return = self.is_return_ty_definitely_unsized(fcx);
1668-
}
1666+
unsized_return = self.is_return_ty_definitely_unsized(fcx);
16691667
}
16701668
ObligationCauseCode::ReturnValue(return_expr_id) => {
16711669
err = self.report_return_mismatched_types(
@@ -1677,9 +1675,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
16771675
return_expr_id,
16781676
expression,
16791677
);
1680-
if !fcx.tcx.features().unsized_locals() {
1681-
unsized_return = self.is_return_ty_definitely_unsized(fcx);
1682-
}
1678+
unsized_return = self.is_return_ty_definitely_unsized(fcx);
16831679
}
16841680
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
16851681
arm_span,

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -809,9 +809,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
809809
);
810810
}
811811
}
812-
// Here we want to prevent struct constructors from returning unsized types.
813-
// There were two cases this happened: fn pointer coercion in stable
814-
// and usual function call in presence of unsized_locals.
812+
// Here we want to prevent struct constructors from returning unsized types,
813+
// which can happen with fn pointer coercion on stable.
815814
// Also, as we just want to check sizedness, instead of introducing
816815
// placeholder lifetimes with probing, we just replace higher lifetimes
817816
// with fresh vars.

compiler/rustc_hir_typeck/src/gather_locals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
202202
),
203203
);
204204
}
205-
} else if !self.fcx.tcx.features().unsized_locals() {
205+
} else {
206206
self.fcx.require_type_is_sized(
207207
var_ty,
208208
p.span,

compiler/rustc_hir_typeck/src/upvar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
492492
let final_upvar_tys = self.final_upvar_tys(closure_def_id);
493493
debug!(?closure_hir_id, ?args, ?final_upvar_tys);
494494

495-
if self.tcx.features().unsized_locals() || self.tcx.features().unsized_fn_params() {
495+
if self.tcx.features().unsized_fn_params() {
496496
for capture in
497497
self.typeck_results.borrow().closure_min_captures_flattened(closure_def_id)
498498
{

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,13 +1133,6 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
11331133
/// Each local naturally corresponds to the place `Place { local, projection: [] }`. This place has
11341134
/// the address of the local's allocation and the type of the local.
11351135
///
1136-
/// **Needs clarification:** Unsized locals seem to present a bit of an issue. Their allocation
1137-
/// can't actually be created on `StorageLive`, because it's unclear how big to make the allocation.
1138-
/// Furthermore, MIR produces assignments to unsized locals, although that is not permitted under
1139-
/// `#![feature(unsized_locals)]` in Rust. Besides just putting "unsized locals are special and
1140-
/// different" in a bunch of places, I (JakobDegen) don't know how to incorporate this behavior into
1141-
/// the current MIR semantics in a clean way - possibly this needs some design work first.
1142-
///
11431136
/// For places that are not locals, ie they have a non-empty list of projections, we define the
11441137
/// values as a function of the parent place, that is the place with its last [`ProjectionElem`]
11451138
/// stripped. The way this is computed of course depends on the kind of that last projection

compiler/rustc_middle/src/ty/instance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub enum InstanceKind<'tcx> {
7979
Intrinsic(DefId),
8080

8181
/// `<T as Trait>::method` where `method` receives unsizeable `self: Self` (part of the
82-
/// `unsized_locals` feature).
82+
/// `unsized_fn_params` feature).
8383
///
8484
/// The generated shim will take `Self` via `*mut Self` - conceptually this is `&owned Self` -
8585
/// and dereference the argument to call the original function.

compiler/rustc_mir_build/src/builder/expr/as_operand.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5555
/// local variable of unsized type. For example, consider this program:
5656
///
5757
/// ```
58-
/// #![feature(unsized_locals, unsized_fn_params)]
58+
/// #![feature(unsized_fn_params)]
5959
/// # use core::fmt::Debug;
60-
/// fn foo(p: dyn Debug) { dbg!(p); }
60+
/// fn foo(_p: dyn Debug) { /* ... */ }
6161
///
6262
/// fn bar(box_p: Box<dyn Debug>) { foo(*box_p); }
6363
/// ```
@@ -84,7 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8484
/// will actually provide a pointer to the interior of the box, and not move the `dyn Debug`
8585
/// value to the stack.
8686
///
87-
/// See #68304 for more details.
87+
/// See <https://github.com/rust-lang/rust/issues/68304> for more details.
8888
pub(crate) fn as_local_call_operand(
8989
&mut self,
9090
block: BasicBlock,

compiler/rustc_mir_transform/src/coroutine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,9 +1414,9 @@ fn check_field_tys_sized<'tcx>(
14141414
coroutine_layout: &CoroutineLayout<'tcx>,
14151415
def_id: LocalDefId,
14161416
) {
1417-
// No need to check if unsized_locals/unsized_fn_params is disabled,
1417+
// No need to check if unsized_fn_params is disabled,
14181418
// since we will error during typeck.
1419-
if !tcx.features().unsized_locals() && !tcx.features().unsized_fn_params() {
1419+
if !tcx.features().unsized_fn_params() {
14201420
return;
14211421
}
14221422

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,6 @@ struct VnState<'body, 'tcx> {
240240
next_opaque: usize,
241241
/// Cache the deref values.
242242
derefs: Vec<VnIndex>,
243-
/// Cache the value of the `unsized_locals` features, to avoid fetching it repeatedly in a loop.
244-
feature_unsized_locals: bool,
245243
ssa: &'body SsaLocals,
246244
dominators: Dominators<BasicBlock>,
247245
reused_locals: DenseBitSet<Local>,
@@ -273,7 +271,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
273271
evaluated: IndexVec::with_capacity(num_values),
274272
next_opaque: 1,
275273
derefs: Vec::new(),
276-
feature_unsized_locals: tcx.features().unsized_locals(),
277274
ssa,
278275
dominators,
279276
reused_locals: DenseBitSet::new_empty(local_decls.len()),
@@ -329,13 +326,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
329326
fn assign(&mut self, local: Local, value: VnIndex) {
330327
debug_assert!(self.ssa.is_ssa(local));
331328
self.locals[local] = Some(value);
332-
333-
// Only register the value if its type is `Sized`, as we will emit copies of it.
334-
let is_sized = !self.feature_unsized_locals
335-
|| self.local_decls[local].ty.is_sized(self.tcx, self.typing_env());
336-
if is_sized {
337-
self.rev_locals[value].push(local);
338-
}
329+
self.rev_locals[value].push(local);
339330
}
340331

341332
fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex {

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,9 +2993,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
29932993
if local {
29942994
err.note("all local variables must have a statically known size");
29952995
}
2996-
if !tcx.features().unsized_locals() {
2997-
err.help("unsized locals are gated as an unstable feature");
2998-
}
29992996
}
30002997
ObligationCauseCode::SizedArgumentType(hir_id) => {
30012998
let mut ty = None;

compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,8 @@ fn virtual_call_violations_for_method<'tcx>(
414414

415415
let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0));
416416

417-
// Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on.
418-
// However, this is already considered dyn compatible. We allow it as a special case here.
417+
// `self: Self` can't be dispatched on.
418+
// However, this is considered dyn compatible. We allow it as a special case here.
419419
// FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
420420
// `Receiver: Unsize<Receiver[Self => dyn Trait]>`.
421421
if receiver_ty != tcx.types.self_param {

library/core/src/mem/mod.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,32 @@ pub const fn forget<T>(t: T) {
149149

150150
/// Like [`forget`], but also accepts unsized values.
151151
///
152-
/// This function is just a shim intended to be removed when the `unsized_locals` feature gets
153-
/// stabilized.
152+
/// While Rust does not permit unsized locals since its removal in [#111942] it is
153+
/// still possible to call functions with unsized values from a function argument
154+
/// or in-place construction.
155+
///
156+
/// ```rust
157+
/// #![feature(unsized_fn_params, forget_unsized)]
158+
/// #![allow(internal_features)]
159+
///
160+
/// use std::mem::forget_unsized;
161+
///
162+
/// pub fn in_place() {
163+
/// forget_unsized(*Box::new("str"));
164+
/// }
165+
///
166+
/// pub fn param(x: str) {
167+
/// forget_unsized(x);
168+
/// }
169+
/// ```
170+
///
171+
/// This works because the compiler will alter these functions to pass the parameter
172+
/// by reference instead. This trick is necessary to support `Box<dyn FnOnce()>: FnOnce()`.
173+
/// See [#68304] and [#71170] for more information.
174+
///
175+
/// [#111942]: https://github.com/rust-lang/rust/issues/111942
176+
/// [#68304]: https://github.com/rust-lang/rust/issues/68304
177+
/// [#71170]: https://github.com/rust-lang/rust/pull/71170
154178
#[inline]
155179
#[unstable(feature = "forget_unsized", issue = "none")]
156180
pub fn forget_unsized<T: ?Sized>(t: T) {

library/coretests/tests/ptr.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,6 @@ fn thin_box() {
653653
// if `{size,align}_of_for_meta<T: ?Sized>(T::Metadata)` are added.
654654
// * Constructing a `ThinBox` without consuming and deallocating a `Box`
655655
// requires either the unstable `Unsize` marker trait,
656-
// or the unstable `unsized_locals` language feature,
657656
// or taking `&dyn T` and restricting to `T: Copy`.
658657

659658
use std::alloc::*;

src/doc/rustc-dev-guide/src/implementing_new_features.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ a new unstable feature:
156156
[`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features
157157

158158
```rust ignore
159-
/// Allows unsized rvalues at arguments and parameters.
160-
(incomplete, unsized_locals, "CURRENT_RUSTC_VERSION", Some(48055), None),
159+
/// Allows deref patterns.
160+
(incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None),
161161
```
162162

163163
To avoid [semantic merge conflicts], please use `CURRENT_RUSTC_VERSION` instead of `1.70` or

0 commit comments

Comments
 (0)