Skip to content

Commit 8f0b4f3

Browse files
committed
Unimplement unsized_locals
1 parent fe5c95d commit 8f0b4f3

File tree

85 files changed

+456
-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

+456
-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
@@ -373,8 +373,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
373373
}
374374

375375
fn unsized_feature_enabled(&self) -> bool {
376-
let features = self.tcx().features();
377-
features.unsized_locals() || features.unsized_fn_params()
376+
self.tcx().features().unsized_fn_params()
378377
}
379378

380379
/// Equate the inferred type and the annotated type for user type annotations
@@ -957,7 +956,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
957956
}
958957
}
959958

960-
// When `unsized_fn_params` or `unsized_locals` is enabled, only function calls
959+
// When `unsized_fn_params` is enabled, only function calls
961960
// and nullary ops are checked in `check_call_dest`.
962961
if !self.unsized_feature_enabled() {
963962
match self.body.local_kind(local) {
@@ -1941,7 +1940,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19411940
);
19421941
}
19431942

1944-
// When `unsized_fn_params` and `unsized_locals` are both not enabled,
1943+
// When `unsized_fn_params` is not enabled,
19451944
// this check is done at `check_local`.
19461945
if self.unsized_feature_enabled() {
19471946
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
@@ -263,6 +263,8 @@ declare_features! (
263263
/// Allows unnamed fields of struct and union type
264264
(removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign"), 131045),
265265
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
266+
/// Allows unsized rvalues at arguments and parameters.
267+
(removed, unsized_locals, "CURRENT_RUSTC_VERSION", Some(48055), Some("removed due to implementation concerns; see https://github.com/rust-lang/rust/issues/111942")),
266268
(removed, unsized_tuple_coercion, "1.87.0", Some(42877),
267269
Some("The feature restricts possible layouts for tuples, and this restriction is not worth it."), 137728),
268270
/// 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
@@ -665,8 +665,6 @@ declare_features! (
665665
(incomplete, unsized_const_params, "1.82.0", Some(95174)),
666666
/// Allows unsized fn parameters.
667667
(internal, unsized_fn_params, "1.49.0", Some(48055)),
668-
/// Allows unsized rvalues at arguments and parameters.
669-
(incomplete, unsized_locals, "1.30.0", Some(48055)),
670668
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
671669
(unstable, used_with_arg, "1.60.0", Some(93798)),
672670
/// 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
@@ -1662,9 +1662,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
16621662
blk_id,
16631663
expression,
16641664
);
1665-
if !fcx.tcx.features().unsized_locals() {
1666-
unsized_return = self.is_return_ty_definitely_unsized(fcx);
1667-
}
1665+
unsized_return = self.is_return_ty_definitely_unsized(fcx);
16681666
}
16691667
ObligationCauseCode::ReturnValue(return_expr_id) => {
16701668
err = self.report_return_mismatched_types(
@@ -1676,9 +1674,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
16761674
return_expr_id,
16771675
expression,
16781676
);
1679-
if !fcx.tcx.features().unsized_locals() {
1680-
unsized_return = self.is_return_ty_definitely_unsized(fcx);
1681-
}
1677+
unsized_return = self.is_return_ty_definitely_unsized(fcx);
16821678
}
16831679
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
16841680
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
@@ -1417,9 +1417,9 @@ fn check_field_tys_sized<'tcx>(
14171417
coroutine_layout: &CoroutineLayout<'tcx>,
14181418
def_id: LocalDefId,
14191419
) {
1420-
// No need to check if unsized_locals/unsized_fn_params is disabled,
1420+
// No need to check if unsized_fn_params is disabled,
14211421
// since we will error during typeck.
1422-
if !tcx.features().unsized_locals() && !tcx.features().unsized_fn_params() {
1422+
if !tcx.features().unsized_fn_params() {
14231423
return;
14241424
}
14251425

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
@@ -2995,9 +2995,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
29952995
if local {
29962996
err.note("all local variables must have a statically known size");
29972997
}
2998-
if !tcx.features().unsized_locals() {
2999-
err.help("unsized locals are gated as an unstable feature");
3000-
}
30012998
}
30022999
ObligationCauseCode::SizedArgumentType(hir_id) => {
30033000
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)