From f5cbf5d297c3f93caa3402abc773ae895dfcfc21 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Tue, 7 Apr 2026 10:51:20 +0200 Subject: [PATCH 01/20] add lang items for field projections via virtual places --- compiler/rustc_hir/src/lang_items.rs | 27 + compiler/rustc_span/src/symbol.rs | 25 + library/core/src/field.rs | 33 + library/core/src/ops/field_projections.rs | 220 +++++ library/core/src/ops/mod.rs | 6 + ...tr_offset.LowerIntrinsics.panic-abort.diff | 2 +- ...r_offset.LowerIntrinsics.panic-unwind.diff | 2 +- .../feature-gate-field-projections.rs | 209 +++- .../feature-gate-field-projections.stderr | 900 +++++++++++++++++- 9 files changed, 1406 insertions(+), 18 deletions(-) create mode 100644 library/core/src/ops/field_projections.rs diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 75c708e33929d..58d606feeb364 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -444,6 +444,33 @@ language_item_table! { FieldType, sym::field_type, field_type, Target::AssocTy, GenericRequirement::Exact(0); FieldOffset, sym::field_offset, field_offset, Target::AssocConst, GenericRequirement::Exact(0); + // Field projections lang-items. + Subplace, sym::subplace, subplace, Target::Trait, GenericRequirement::Exact(0); + SubplaceSource, sym::subplace_source, subplace_source, Target::AssocTy, GenericRequirement::Exact(0); + SubplaceTarget, sym::subplace_target, subplace_target, Target::AssocTy, GenericRequirement::Exact(0); + SubplaceOffset, sym::subplace_offset, subplace_offset, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0); + Place, sym::place, place, Target::Trait, GenericRequirement::Exact(0); + PlaceTarget, sym::place_target, place_target, Target::AssocTy, GenericRequirement::Exact(0); + PlaceRead, sym::place_read, place_read, Target::Trait, GenericRequirement::Exact(1); + PlaceReadSafety, sym::place_read_safety, place_read_safety, Target::AssocConst, GenericRequirement::Exact(1); + PlaceReadRead, sym::place_read_read, place_read_read, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + PlaceWrite, sym::place_write, place_write, Target::Trait, GenericRequirement::Exact(1); + PlaceWriteSafety, sym::place_write_safety, place_write_safety, Target::AssocConst, GenericRequirement::Exact(1); + PlaceWriteWrite, sym::place_write_write, place_write_write, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + PlaceMove, sym::place_move, place_move, Target::Trait, GenericRequirement::Exact(1); + PlaceDrop, sym::place_drop, place_drop, Target::Trait, GenericRequirement::Exact(1); + PlaceDropDrop, sym::place_drop_drop, place_drop_drop, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + DropHusk, sym::drop_husk, drop_husk, Target::Trait, GenericRequirement::Exact(0); + DropHuskDropHusk, sym::drop_husk_drop_husk, drop_husk_drop_husk, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0); + PlaceBorrow, sym::place_borrow, place_borrow, Target::Trait, GenericRequirement::Exact(2); + PlaceBorrowSafety, sym::place_borrow_safety, place_borrow_safety, Target::AssocConst, GenericRequirement::Exact(2); + PlaceBorrowBorrow, sym::place_borrow_borrow, place_borrow_borrow, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(2); + PlaceDeref, sym::place_deref, place_deref, Target::Trait, GenericRequirement::Exact(1); + PlaceDerefDeref, sym::place_deref_deref, place_deref_deref, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + PlaceWrapper, sym::place_wrapper, place_wrapper, Target::Trait, GenericRequirement::Exact(1); + PlaceWrapperWrapped, sym::place_wrapper_wrapped, place_wrapper_wrapped, Target::AssocTy, GenericRequirement::Exact(1); + PlaceWrapperWrap, sym::place_wrapper_wrap, place_wrapper_wrap, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + // Used to fallback `{float}` to `f32` when `f32: From<{float}>` From, sym::From, from_trait, Target::Trait, GenericRequirement::Exact(1); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9cd66bc1604d1..319dc498103be 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -832,6 +832,8 @@ symbols! { dreg_low8, dreg_low16, drop, + drop_husk, + drop_husk_drop_husk, drop_in_place, drop_types_in_const, dropck_eyepatch, @@ -1514,6 +1516,25 @@ symbols! { pin, pin_ergonomics, pin_v2, + place, + place_borrow, + place_borrow_borrow, + place_borrow_safety, + place_deref, + place_deref_deref, + place_drop, + place_drop_drop, + place_move, + place_read, + place_read_read, + place_read_safety, + place_target, + place_wrapper, + place_wrapper_wrap, + place_wrapper_wrapped, + place_write, + place_write_safety, + place_write_write, platform_intrinsics, plugin, plugin_registrar, @@ -1990,6 +2011,10 @@ symbols! { sub, sub_assign, sub_with_overflow, + subplace, + subplace_offset, + subplace_source, + subplace_target, suggestion, super_let, supertrait_item_shadowing, diff --git a/library/core/src/field.rs b/library/core/src/field.rs index 0e537e2f92fcf..dc0a747ce2396 100644 --- a/library/core/src/field.rs +++ b/library/core/src/field.rs @@ -1,6 +1,7 @@ //! Field Reflection use crate::marker::PhantomData; +use crate::ptr::Pointee; /// Field Representing Type #[unstable(feature = "field_representing_type_raw", issue = "none")] @@ -84,3 +85,35 @@ pub unsafe trait Field: Send + Sync + Copy { #[lang = "field_offset"] const OFFSET: usize = crate::intrinsics::field_offset::(); } + +/// A subplace of [`Self::Source`] with the type [`Self::Target`]. +/// +/// A subplace is always within the same allocation as the base place. Current subplaces are: +/// - field accesses, +/// - array/slice indexes. +/// +/// This represents an arbitrary chaining of these; it can also be empty. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[rustc_deny_explicit_impl] +#[rustc_dyn_incompatible_trait] +#[lang = "subplace"] +pub unsafe trait Subplace: Sized + Copy { + /// The type of the base place this subplace is a part of. + #[lang = "subplace_source"] + type Source: ?Sized; + + /// The type of this subplace. + #[lang = "subplace_target"] + type Target: ?Sized; + + /// The offset of this subplace. + #[lang = "subplace_offset"] + fn offset( + self, + metadata: ::Metadata, + ) -> (usize, ::Metadata); +} diff --git a/library/core/src/ops/field_projections.rs b/library/core/src/ops/field_projections.rs new file mode 100644 index 0000000000000..e5f6b2125ddb2 --- /dev/null +++ b/library/core/src/ops/field_projections.rs @@ -0,0 +1,220 @@ +use crate::field::Subplace; + +/// Marks a type as containing a place. +/// +/// This is the new trait for the dereference operator `*`; implementing it will allow writing `*x` +/// for `x: Self`, but not enable any operations on `*x`. For those, one of the other place +/// operation traits has to be implemented: +/// +/// - [`PlaceRead`] +/// - [`PlaceWrite`] +/// - [`PlaceDrop`] +/// - [`PlaceMove`] +/// - [`PlaceBorrow`] +/// - [`PlaceDeref`] +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place"] +pub trait Place { + /// The type of the contained place. + #[lang = "place_target"] + type Target: ?Sized; +} + +/// Reading a place `let val = *x;`. +/// +/// When `x: Self`, then `let val = *x;` will be desugared into [`PlaceRead::read`]. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place_read"] +pub unsafe trait PlaceRead: Place +where + S: Subplace, + S::Target: Sized, +{ + /// Whether the read operation is safe when used through the operator. + /// + /// When the compiler emits the call to `read`, the borrow checker guarantees that no other + /// operation is conflicting with this one. + #[lang = "place_read_safety"] + const SAFETY: bool; + + /// Reads the subplace pointed to by `this`. + /// + /// # Safety + /// + /// FIXME + #[lang = "place_read_read"] + unsafe fn read(this: *const Self, sub: S) -> S::Target; +} + +/// Writing a place `*x = val;`. +/// +/// When `x: Self`, then `*x = val;` will be desugared into [`PlaceWrite::write`]. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place_write"] +pub unsafe trait PlaceWrite: Place +where + S: Subplace, + S::Target: Sized, +{ + /// Whether the write operation is safe when used through the operator. + /// + /// When the compiler emits the call to `read`, the borrow checker guarantees that no other + /// operation is conflicting with this one. + #[lang = "place_write_safety"] + const SAFETY: bool; + + /// Writes to the subplace pointed to by `this`. + /// + /// # Safety + /// + /// FIXME + #[lang = "place_write_write"] + unsafe fn write(this: *const Self, sub: S, value: S::Target); +} + +/// Moving out of a place. +/// +/// When `x: Self` and one performs a [`PlaceRead::read`] where the target value is not [`Copy`], +/// then the compiler checks if this trait is implemented and if so, moves the value out by reading +/// it and adjusting the borrow checker state of the place. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place_move"] +pub unsafe trait PlaceMove: PlaceRead +where + S: Subplace, + S::Target: Sized, +{ +} + +/// Dropping a place. +/// +/// Emitted by the compiler when a place has been partially moved out and the pointer with ownership +/// is being dropped. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place_drop"] +pub unsafe trait PlaceDrop: Place +where + S: Subplace, +{ + /// Drop the subplace pointed to by `this`. + /// + /// # Safety + /// + /// FIXME + #[lang = "place_drop_drop"] + unsafe fn drop(this: *const Self, sub: S); +} + +/// Dropping a pointer that points at a fully moved-out place. +/// +/// This operation is emitted by the compiler when a pointer is being dropped that had some fields +/// moved out. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "drop_husk"] +pub unsafe trait DropHusk: Place { + /// Drops the + /// + /// # Safety + /// + /// FIXME + #[lang = "drop_husk_drop_husk"] + unsafe fn drop_husk(this: *const Self); +} + +/// Borrowing a place with `X`. +/// +/// When `y: Self`, then `let x = @ *y;` will be desugared into [`PlaceBorrow::borrow`]. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place_borrow"] +pub unsafe trait PlaceBorrow: Place +where + S: Subplace, + X: Place, +{ + /// Whether the borrow operation is safe when used through the operator. + /// + /// When the compiler emits the call to `read`, the borrow checker guarantees that no other + /// operation is conflicting with this one. + #[lang = "place_borrow_safety"] + const SAFETY: bool; + + /// Borrow the subplace pointed to by `this` with `X`. + /// + /// # Safety + /// + /// FIXME + #[lang = "place_borrow_borrow"] + unsafe fn borrow(this: *const Self, sub: S) -> X; +} + +/// Accessing a nested pointer. +/// +/// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a combination of the +/// corresponding operation and a [`PlaceDeref::deref`]. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place_deref"] +pub unsafe trait PlaceDeref: Place +where + S: Subplace, + S::Target: Place, +{ + /// Obtain a raw pointer to the subplace pointed to by `this`. + /// + /// # Safety + /// + /// FIXME + #[lang = "place_deref_deref"] + unsafe fn deref(this: *const Self, sub: S) -> *const S::Target; +} + +/// Forwards the subplace `S` of the place contained by this. +/// +/// When `x: Self` and `Self::Target` has a subplace `S` accessible via `.foo.bar`, then `x.foo.bar` +/// is also valid, has type `::Target` and any place operation on it uses +/// [Self::wrap]\(sub\) as the subplace instead of `S`. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "place_wrapper"] +pub unsafe trait PlaceWrapper: Place +where + S: Subplace, +{ + /// The subplace to use instead of `S` for any place operations on `Self`. + #[lang = "place_wrapper_wrapped"] + type Wrapped: Subplace; + + /// Turn a subplace of type `S` into [`Self::Wrapped`]. + #[lang = "place_wrapper_wrap"] + fn wrap(sub: S) -> Self::Wrapped; +} diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index ab1ad407ee282..6f4d5c1cc1369 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -145,6 +145,7 @@ mod control_flow; mod coroutine; mod deref; mod drop; +mod field_projections; mod function; mod index; mod index_range; @@ -177,6 +178,11 @@ pub use self::deref::Receiver; pub use self::deref::{Deref, DerefMut}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::drop::Drop; +#[unstable(feature = "field_projections", issue = "145383")] +pub use self::field_projections::{ + DropHusk, Place, PlaceBorrow, PlaceDeref, PlaceDrop, PlaceMove, PlaceRead, PlaceWrapper, + PlaceWrite, +}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::function::{Fn, FnMut, FnOnce}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-abort.diff index 62cce84f69560..437fb1d3cd4ef 100644 --- a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-abort.diff @@ -13,7 +13,7 @@ _3 = copy _1; StorageLive(_4); _4 = copy _2; -- _0 = offset::<*const i32, isize>(move _3, move _4) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::offset::<*const i32, isize>(move _3, move _4) -> [return: bb1, unwind unreachable]; + _0 = Offset(move _3, move _4); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-unwind.diff index 62cce84f69560..437fb1d3cd4ef 100644 --- a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-unwind.diff @@ -13,7 +13,7 @@ _3 = copy _1; StorageLive(_4); _4 = copy _2; -- _0 = offset::<*const i32, isize>(move _3, move _4) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::offset::<*const i32, isize>(move _3, move _4) -> [return: bb1, unwind unreachable]; + _0 = Offset(move _3, move _4); + goto -> bb1; } diff --git a/tests/ui/feature-gates/feature-gate-field-projections.rs b/tests/ui/feature-gates/feature-gate-field-projections.rs index 9cc219460c37b..ef50027687cc5 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.rs +++ b/tests/ui/feature-gates/feature-gate-field-projections.rs @@ -1,6 +1,19 @@ -use std::field::{Field, field_of}; //~ ERROR: use of unstable library feature `field_projections` [E0658] -//~^ ERROR: use of unstable library feature `field_projections` [E0658] +#![feature(ptr_metadata)] + +use std::field::Field; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::field::Subplace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::field::field_of; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::DropHusk; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::Place; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::PlaceBorrow; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::PlaceDeref; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::PlaceDrop; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::PlaceMove; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::PlaceRead; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::PlaceWrapper; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::PlaceWrite; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ptr; +use std::ptr::Pointee; fn project_ref( //~^ ERROR: use of unstable library feature `field_projections` [E0658] @@ -13,6 +26,198 @@ where unsafe { &*ptr::from_ref(r).byte_add(F::OFFSET).cast() } //~ ERROR: use of unstable library feature `field_projections` [E0658] } +struct MyPtr(*mut T); + +impl Place for MyPtr { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + type Target = T; //~ ERROR: use of unstable library feature `field_projections` [E0658] +} + +unsafe impl PlaceRead for MyPtr +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +where + T: ?Sized, + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: Sized, //~ ERROR: use of unstable library feature `field_projections` [E0658] +{ + const SAFETY: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] + + unsafe fn read(this: *const Self, sub: S) -> S::Target { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = (this, sub); + todo!() + } +} + +unsafe impl PlaceWrite for MyPtr +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +where + T: ?Sized, + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: Sized, //~ ERROR: use of unstable library feature `field_projections` [E0658] +{ + const SAFETY: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] + + unsafe fn write(this: *const Self, sub: S, value: S::Target) { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = (this, sub, value); + todo!() + } +} + +unsafe impl PlaceMove for MyPtr +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +where + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: Sized, //~ ERROR: use of unstable library feature `field_projections` [E0658] +{ +} + +unsafe impl PlaceDrop for MyPtr +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +where + T: ?Sized, + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] +{ + unsafe fn drop(this: *const Self, sub: S) { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = (this, sub); + todo!() + } +} + +unsafe impl DropHusk for MyPtr { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + + unsafe fn drop_husk(this: *const Self) { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = this; + todo!() + } +} + +unsafe impl PlaceBorrow> for MyPtr +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +//~^^ ERROR: use of unstable library feature `field_projections` [E0658] +where + T: ?Sized, + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] +{ + const SAFETY: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] + + unsafe fn borrow(this: *const Self, sub: S) -> MyPtr { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = (this, sub); + todo!() + } +} + +unsafe impl PlaceDeref for MyPtr +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +where + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: Place, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] +{ + unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = (this, sub); + todo!() + } +} + +unsafe fn using_place_ops(place: *const MyPtr, sub: S) +where + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + //~^^ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: Sized + Place, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] +{ + unsafe { + let value = PlaceRead::read(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] + PlaceWrite::write(place, sub, value); //~ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = PlaceBorrow::<_, MyPtr<_>>::borrow(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = PlaceDeref::deref(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] + PlaceDrop::drop(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] + DropHusk::drop_husk(place); //~ ERROR: use of unstable library feature `field_projections` [E0658] + } +} + +struct MyWrapper(T); + +impl Place for MyWrapper { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + type Target = T; //~ ERROR: use of unstable library feature `field_projections` [E0658] +} + +unsafe impl PlaceWrapper for MyWrapper +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +where + T: ?Sized, + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] +{ + type Wrapped = MyWrapped; //~ ERROR: use of unstable library feature `field_projections` [E0658] + + fn wrap(sub: S) -> MyWrapped { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + MyWrapped(sub) + } +} + +#[derive(Copy, Clone)] +struct MyWrapped(S); + +unsafe impl Subplace for MyWrapped +//~^ ERROR: use of unstable library feature `field_projections` [E0658] +//~^^ ERROR: explicit impls for the `Subplace` trait are not permitted [E0322] +where + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] +{ + type Source = MyWrapper; //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + type Target = MyWrapper; //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + + fn offset( + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + self, + metadata: ::Metadata, + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + ) -> (usize, ::Metadata) { + //~^ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = (self, metadata); + todo!() + } +} + +unsafe fn using_wrapper_ops(sub: S) +where + T: ?Sized, + S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + //~^ ERROR: use of unstable library feature `field_projections` [E0658] +{ + unsafe { + let _ = as PlaceWrapper>::wrap(sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] + } +} + fn main() { struct Foo(()); let _ = project_ref::(&Foo(())); //~ ERROR: use of unstable library feature `field_projections` [E0658] diff --git a/tests/ui/feature-gates/feature-gate-field-projections.stderr b/tests/ui/feature-gates/feature-gate-field-projections.stderr index 935e968c5b8ed..70607e52b6b9c 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.stderr +++ b/tests/ui/feature-gates/feature-gate-field-projections.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:18:27 + --> $DIR/feature-gate-field-projections.rs:223:27 | LL | let _ = project_ref::(&Foo(())); | ^^^^^^^^ @@ -9,27 +9,127 @@ LL | let _ = project_ref::(&Foo(())); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:1:18 + --> $DIR/feature-gate-field-projections.rs:3:5 | -LL | use std::field::{Field, field_of}; - | ^^^^^ +LL | use std::field::Field; + | ^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:1:25 + --> $DIR/feature-gate-field-projections.rs:4:5 | -LL | use std::field::{Field, field_of}; - | ^^^^^^^^ +LL | use std::field::Subplace; + | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:5:19 + --> $DIR/feature-gate-field-projections.rs:5:5 + | +LL | use std::field::field_of; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:6:5 + | +LL | use std::ops::DropHusk; + | ^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:7:5 + | +LL | use std::ops::Place; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:8:5 + | +LL | use std::ops::PlaceBorrow; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:9:5 + | +LL | use std::ops::PlaceDeref; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:10:5 + | +LL | use std::ops::PlaceDrop; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:11:5 + | +LL | use std::ops::PlaceMove; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:12:5 + | +LL | use std::ops::PlaceRead; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:13:5 + | +LL | use std::ops::PlaceWrapper; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:14:5 + | +LL | use std::ops::PlaceWrite; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:18:19 | LL | fn project_ref( | ^^^^^ @@ -39,7 +139,472 @@ LL | fn project_ref( = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:11:5 + --> $DIR/feature-gate-field-projections.rs:33:5 + | +LL | type Target = T; + | ^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:31:17 + | +LL | impl Place for MyPtr { + | ^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:45:5 + | +LL | const SAFETY: bool = true; + | ^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:47:5 + | +LL | unsafe fn read(this: *const Self, sub: S) -> S::Target { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:40:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:36:19 + | +LL | unsafe impl PlaceRead for MyPtr + | ^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:64:5 + | +LL | const SAFETY: bool = true; + | ^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:66:5 + | +LL | unsafe fn write(this: *const Self, sub: S, value: S::Target) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:59:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:55:19 + | +LL | unsafe impl PlaceWrite for MyPtr + | ^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:77:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:74:19 + | +LL | unsafe impl PlaceMove for MyPtr + | ^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:91:5 + | +LL | unsafe fn drop(this: *const Self, sub: S) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:88:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:84:19 + | +LL | unsafe impl PlaceDrop for MyPtr + | ^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:101:5 + | +LL | unsafe fn drop_husk(this: *const Self) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:98:16 + | +LL | unsafe impl DropHusk for MyPtr { + | ^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:117:5 + | +LL | const SAFETY: bool = true; + | ^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:119:5 + | +LL | unsafe fn borrow(this: *const Self, sub: S) -> MyPtr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:113:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:108:19 + | +LL | unsafe impl PlaceBorrow> for MyPtr + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:136:5 + | +LL | unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:130:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:133:16 + | +LL | S::Target: Place, + | ^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:127:19 + | +LL | unsafe impl PlaceDeref for MyPtr + | ^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:146:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:149:24 + | +LL | S::Target: Sized + Place, + | ^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:153:21 + | +LL | let value = PlaceRead::read(place, sub); + | ^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:154:9 + | +LL | PlaceWrite::write(place, sub, value); + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:155:17 + | +LL | let _ = PlaceBorrow::<_, MyPtr<_>>::borrow(place, sub); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:156:17 + | +LL | let _ = PlaceDeref::deref(place, sub); + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:157:9 + | +LL | PlaceDrop::drop(place, sub); + | ^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:158:9 + | +LL | DropHusk::drop_husk(place); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:166:5 + | +LL | type Target = T; + | ^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:164:17 + | +LL | impl Place for MyWrapper { + | ^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:176:5 + | +LL | type Wrapped = MyWrapped; + | ^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:178:5 + | +LL | fn wrap(sub: S) -> MyWrapped { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:173:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:169:19 + | +LL | unsafe impl PlaceWrapper for MyWrapper + | ^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:193:5 + | +LL | type Source = MyWrapper; + | ^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:195:5 + | +LL | type Target = MyWrapper; + | ^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:198:5 + | +LL | / fn offset( +LL | | +LL | | self, +LL | | metadata: ::Metadata, +LL | | +LL | | ) -> (usize, ::Metadata) { + | |_____________________________________________________^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:191:8 + | +LL | S: Subplace, + | ^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:187:16 + | +LL | unsafe impl Subplace for MyWrapped + | ^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:213:8 + | +LL | S: Subplace, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:217:17 + | +LL | let _ = as PlaceWrapper>::wrap(sub); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:24:5 | LL | F::Type: Sized, | ^^^^^^^ @@ -49,7 +614,7 @@ LL | F::Type: Sized, = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:7:9 + --> $DIR/feature-gate-field-projections.rs:20:9 | LL | r: &F::Base, | ^^^^^^^ @@ -59,7 +624,7 @@ LL | r: &F::Base, = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:8:7 + --> $DIR/feature-gate-field-projections.rs:21:7 | LL | ) -> &F::Type | ^^^^^^^ @@ -69,7 +634,313 @@ LL | ) -> &F::Type = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:13:42 + --> $DIR/feature-gate-field-projections.rs:40:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:47:50 + | +LL | unsafe fn read(this: *const Self, sub: S) -> S::Target { + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:59:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:66:55 + | +LL | unsafe fn write(this: *const Self, sub: S, value: S::Target) { + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:113:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:119:58 + | +LL | unsafe fn borrow(this: *const Self, sub: S) -> MyPtr { + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:130:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:136:58 + | +LL | unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:201:20 + | +LL | metadata: ::Metadata, + | ^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:203:19 + | +LL | ) -> (usize, ::Metadata) { + | ^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:40:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:43:5 + | +LL | S::Target: Sized, + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:59:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:62:5 + | +LL | S::Target: Sized, + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:77:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:77:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:80:5 + | +LL | S::Target: Sized, + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:88:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:113:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:108:40 + | +LL | unsafe impl PlaceBorrow> for MyPtr + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:130:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:133:5 + | +LL | S::Target: Place, + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:146:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:146:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:149:5 + | +LL | S::Target: Sized + Place, + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:173:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:193:29 + | +LL | type Source = MyWrapper; + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0322]: explicit impls for the `Subplace` trait are not permitted + --> $DIR/feature-gate-field-projections.rs:187:1 + | +LL | / unsafe impl Subplace for MyWrapped +LL | | +LL | | +LL | | where +LL | | S: Subplace, + | |________________^ impl of `Subplace` not allowed + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:195:29 + | +LL | type Target = MyWrapper; + | ^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:213:17 + | +LL | S: Subplace, + | ^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/feature-gate-field-projections.rs:26:42 | LL | unsafe { &*ptr::from_ref(r).byte_add(F::OFFSET).cast() } | ^^^^^^^^^ @@ -78,6 +949,7 @@ LL | unsafe { &*ptr::from_ref(r).byte_add(F::OFFSET).cast() } = help: add `#![feature(field_projections)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 8 previous errors +error: aborting due to 94 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0322, E0658. +For more information about an error, try `rustc --explain E0322`. From 785bea21c30bec8d0f4d5ad35bfb03383f236f64 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 08:23:41 +0200 Subject: [PATCH 02/20] TOSQUASH: better structure for our lang items --- compiler/rustc_hir/src/lang_items.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 58d606feeb364..85ce2f3eeb493 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -437,14 +437,16 @@ language_item_table! { Reborrow, sym::reborrow, reborrow, Target::Trait, GenericRequirement::Exact(0); CoerceShared, sym::coerce_shared, coerce_shared, Target::Trait, GenericRequirement::Exact(0); - // Field representing types. + // # Experimental lang-items for field projections . + + // ## Field representing types. FieldRepresentingType, sym::field_representing_type, field_representing_type, Target::Struct, GenericRequirement::Exact(3); Field, sym::field, field, Target::Trait, GenericRequirement::Exact(0); FieldBase, sym::field_base, field_base, Target::AssocTy, GenericRequirement::Exact(0); FieldType, sym::field_type, field_type, Target::AssocTy, GenericRequirement::Exact(0); FieldOffset, sym::field_offset, field_offset, Target::AssocConst, GenericRequirement::Exact(0); - // Field projections lang-items. + // ## Virtual places. Subplace, sym::subplace, subplace, Target::Trait, GenericRequirement::Exact(0); SubplaceSource, sym::subplace_source, subplace_source, Target::AssocTy, GenericRequirement::Exact(0); SubplaceTarget, sym::subplace_target, subplace_target, Target::AssocTy, GenericRequirement::Exact(0); From 7f7db8bd629f4b8a439d22a1e12a1be87388363a Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 08:01:19 +0200 Subject: [PATCH 03/20] TOSQUASH: improve SAFETY constant docs --- library/core/src/ops/field_projections.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/library/core/src/ops/field_projections.rs b/library/core/src/ops/field_projections.rs index e5f6b2125ddb2..5cce773f90850 100644 --- a/library/core/src/ops/field_projections.rs +++ b/library/core/src/ops/field_projections.rs @@ -36,8 +36,9 @@ where { /// Whether the read operation is safe when used through the operator. /// - /// When the compiler emits the call to `read`, the borrow checker guarantees that no other - /// operation is conflicting with this one. + /// When the operator is used, the borrow checker follows its usual rules to ensure that no + /// other operation conflicts with this one. If that alone is sufficient to make this operation + /// sound, then this should be `true`. #[lang = "place_read_safety"] const SAFETY: bool; @@ -66,8 +67,9 @@ where { /// Whether the write operation is safe when used through the operator. /// - /// When the compiler emits the call to `read`, the borrow checker guarantees that no other - /// operation is conflicting with this one. + /// When the operator is used, the borrow checker follows its usual rules to ensure that no + /// other operation conflicts with this one. If that alone is sufficient to make this operation + /// sound, then this should be `true`. #[lang = "place_write_safety"] const SAFETY: bool; @@ -157,8 +159,9 @@ where { /// Whether the borrow operation is safe when used through the operator. /// - /// When the compiler emits the call to `read`, the borrow checker guarantees that no other - /// operation is conflicting with this one. + /// When the operator is used, the borrow checker follows its usual rules to ensure that no + /// other operation conflicts with this one. If that alone is sufficient to make this operation + /// sound, then this should be `true`. #[lang = "place_borrow_safety"] const SAFETY: bool; From f03d083b078f326c0690aa1beaafbbc7601bfa70 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 08:02:33 +0200 Subject: [PATCH 04/20] TOSQUASH: add note regarding missing associated constants in `PlaceBorrow` --- library/core/src/ops/field_projections.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/core/src/ops/field_projections.rs b/library/core/src/ops/field_projections.rs index 5cce773f90850..e6ecaa4e9ab42 100644 --- a/library/core/src/ops/field_projections.rs +++ b/library/core/src/ops/field_projections.rs @@ -165,6 +165,9 @@ where #[lang = "place_borrow_safety"] const SAFETY: bool; + // FIXME: this is missing some associated items related to controlling the + // borrow checker. The details need to still be worked out in a-mir-formality. + /// Borrow the subplace pointed to by `this` with `X`. /// /// # Safety From a1068cae51aaf37ced8ce8d22001c9c84aec8ad0 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 08:03:23 +0200 Subject: [PATCH 05/20] TOSQUASH: move `ops/{field_projections.rs -> place.rs}` and make the module public --- library/core/src/ops/mod.rs | 8 ++------ library/core/src/ops/{field_projections.rs => place.rs} | 2 ++ 2 files changed, 4 insertions(+), 6 deletions(-) rename library/core/src/ops/{field_projections.rs => place.rs} (99%) diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index 6f4d5c1cc1369..c4d84a1faae4a 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -145,7 +145,6 @@ mod control_flow; mod coroutine; mod deref; mod drop; -mod field_projections; mod function; mod index; mod index_range; @@ -154,6 +153,8 @@ mod reborrow; mod try_trait; mod unsize; +#[unstable(feature = "field_projections", issue = "145383")] +pub mod place; #[stable(feature = "rust1", since = "1.0.0")] pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub}; #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -178,11 +179,6 @@ pub use self::deref::Receiver; pub use self::deref::{Deref, DerefMut}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::drop::Drop; -#[unstable(feature = "field_projections", issue = "145383")] -pub use self::field_projections::{ - DropHusk, Place, PlaceBorrow, PlaceDeref, PlaceDrop, PlaceMove, PlaceRead, PlaceWrapper, - PlaceWrite, -}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::function::{Fn, FnMut, FnOnce}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/ops/field_projections.rs b/library/core/src/ops/place.rs similarity index 99% rename from library/core/src/ops/field_projections.rs rename to library/core/src/ops/place.rs index e6ecaa4e9ab42..7c8e29cdc8447 100644 --- a/library/core/src/ops/field_projections.rs +++ b/library/core/src/ops/place.rs @@ -1,3 +1,5 @@ +//! Place Operations. + use crate::field::Subplace; /// Marks a type as containing a place. From 40187050f96e377e71dd1bdc5f0e75c6663bfdd9 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 10:13:40 +0200 Subject: [PATCH 06/20] TOSQUASH: move `Subplace` trait to `ops::place` --- library/core/src/field.rs | 33 --------------------------------- library/core/src/ops/place.rs | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/library/core/src/field.rs b/library/core/src/field.rs index dc0a747ce2396..0e537e2f92fcf 100644 --- a/library/core/src/field.rs +++ b/library/core/src/field.rs @@ -1,7 +1,6 @@ //! Field Reflection use crate::marker::PhantomData; -use crate::ptr::Pointee; /// Field Representing Type #[unstable(feature = "field_representing_type_raw", issue = "none")] @@ -85,35 +84,3 @@ pub unsafe trait Field: Send + Sync + Copy { #[lang = "field_offset"] const OFFSET: usize = crate::intrinsics::field_offset::(); } - -/// A subplace of [`Self::Source`] with the type [`Self::Target`]. -/// -/// A subplace is always within the same allocation as the base place. Current subplaces are: -/// - field accesses, -/// - array/slice indexes. -/// -/// This represents an arbitrary chaining of these; it can also be empty. -/// -/// # Safety -/// -/// FIXME -#[unstable(feature = "field_projections", issue = "145383")] -#[rustc_deny_explicit_impl] -#[rustc_dyn_incompatible_trait] -#[lang = "subplace"] -pub unsafe trait Subplace: Sized + Copy { - /// The type of the base place this subplace is a part of. - #[lang = "subplace_source"] - type Source: ?Sized; - - /// The type of this subplace. - #[lang = "subplace_target"] - type Target: ?Sized; - - /// The offset of this subplace. - #[lang = "subplace_offset"] - fn offset( - self, - metadata: ::Metadata, - ) -> (usize, ::Metadata); -} diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index 7c8e29cdc8447..91c732d795c0b 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -1,6 +1,38 @@ //! Place Operations. -use crate::field::Subplace; +use crate::ptr::Pointee; + +/// A subplace of [`Self::Source`] with the type [`Self::Target`]. +/// +/// A subplace is always within the same allocation as the base place. Current subplaces are: +/// - field accesses, +/// - array/slice indexes. +/// +/// This represents an arbitrary chaining of these; it can also be empty. +/// +/// # Safety +/// +/// FIXME +#[unstable(feature = "field_projections", issue = "145383")] +#[rustc_deny_explicit_impl] +#[rustc_dyn_incompatible_trait] +#[lang = "subplace"] +pub unsafe trait Subplace: Sized + Copy { + /// The type of the base place this subplace is a part of. + #[lang = "subplace_source"] + type Source: ?Sized; + + /// The type of this subplace. + #[lang = "subplace_target"] + type Target: ?Sized; + + /// The offset of this subplace. + #[lang = "subplace_offset"] + fn offset( + self, + metadata: ::Metadata, + ) -> (usize, ::Metadata); +} /// Marks a type as containing a place. /// From 4c3ce0693ff155b055ab7009642c121c8b77e97e Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 10:49:59 +0200 Subject: [PATCH 07/20] TOSQUASH: make `Subplace` not require `Copy` --- library/core/src/ops/place.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index 91c732d795c0b..6b1659117e8eb 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -17,7 +17,7 @@ use crate::ptr::Pointee; #[rustc_deny_explicit_impl] #[rustc_dyn_incompatible_trait] #[lang = "subplace"] -pub unsafe trait Subplace: Sized + Copy { +pub unsafe trait Subplace: Sized { /// The type of the base place this subplace is a part of. #[lang = "subplace_source"] type Source: ?Sized; @@ -29,7 +29,7 @@ pub unsafe trait Subplace: Sized + Copy { /// The offset of this subplace. #[lang = "subplace_offset"] fn offset( - self, + &self, metadata: ::Metadata, ) -> (usize, ::Metadata); } From ef19d2b90a4d7121943dc316f23e206ab7ab22ed Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 10:16:52 +0200 Subject: [PATCH 08/20] TOSQUASH: rename traits according to zulip discussion --- compiler/rustc_hir/src/lang_items.rs | 47 +++++++++------ compiler/rustc_span/src/symbol.rs | 37 ++++++------ library/core/src/ops/place.rs | 86 ++++++++++++++-------------- 3 files changed, 90 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 85ce2f3eeb493..01288f35fb2fd 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -451,27 +451,36 @@ language_item_table! { SubplaceSource, sym::subplace_source, subplace_source, Target::AssocTy, GenericRequirement::Exact(0); SubplaceTarget, sym::subplace_target, subplace_target, Target::AssocTy, GenericRequirement::Exact(0); SubplaceOffset, sym::subplace_offset, subplace_offset, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0); - Place, sym::place, place, Target::Trait, GenericRequirement::Exact(0); - PlaceTarget, sym::place_target, place_target, Target::AssocTy, GenericRequirement::Exact(0); - PlaceRead, sym::place_read, place_read, Target::Trait, GenericRequirement::Exact(1); - PlaceReadSafety, sym::place_read_safety, place_read_safety, Target::AssocConst, GenericRequirement::Exact(1); - PlaceReadRead, sym::place_read_read, place_read_read, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); - PlaceWrite, sym::place_write, place_write, Target::Trait, GenericRequirement::Exact(1); - PlaceWriteSafety, sym::place_write_safety, place_write_safety, Target::AssocConst, GenericRequirement::Exact(1); - PlaceWriteWrite, sym::place_write_write, place_write_write, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); - PlaceMove, sym::place_move, place_move, Target::Trait, GenericRequirement::Exact(1); - PlaceDrop, sym::place_drop, place_drop, Target::Trait, GenericRequirement::Exact(1); - PlaceDropDrop, sym::place_drop_drop, place_drop_drop, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + + DerefPlace, sym::deref_place, deref_place, Target::Trait, GenericRequirement::Exact(0); + DerefPlaceTarget, sym::deref_place_target, deref_place_target, Target::AssocTy, GenericRequirement::Exact(0); + + ReadPlace, sym::read_place, read_place, Target::Trait, GenericRequirement::Exact(1); + ReadPlaceSafety, sym::read_place_safety, read_place_safety, Target::AssocConst, GenericRequirement::Exact(1); + ReadPlaceRead, sym::read_place_read, read_place_read, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + + WritePlace, sym::write_place, write_place, Target::Trait, GenericRequirement::Exact(1); + WritePlaceSafety, sym::write_place_safety, write_place_safety, Target::AssocConst, GenericRequirement::Exact(1); + WritePlaceWrite, sym::write_place_write, write_place_write, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + + MovePlace, sym::move_place, move_place, Target::Trait, GenericRequirement::Exact(1); + + DropPlace, sym::drop_place, drop_place, Target::Trait, GenericRequirement::Exact(1); + DropPlaceDrop, sym::drop_place_drop, drop_place_drop, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + DropHusk, sym::drop_husk, drop_husk, Target::Trait, GenericRequirement::Exact(0); DropHuskDropHusk, sym::drop_husk_drop_husk, drop_husk_drop_husk, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0); - PlaceBorrow, sym::place_borrow, place_borrow, Target::Trait, GenericRequirement::Exact(2); - PlaceBorrowSafety, sym::place_borrow_safety, place_borrow_safety, Target::AssocConst, GenericRequirement::Exact(2); - PlaceBorrowBorrow, sym::place_borrow_borrow, place_borrow_borrow, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(2); - PlaceDeref, sym::place_deref, place_deref, Target::Trait, GenericRequirement::Exact(1); - PlaceDerefDeref, sym::place_deref_deref, place_deref_deref, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); - PlaceWrapper, sym::place_wrapper, place_wrapper, Target::Trait, GenericRequirement::Exact(1); - PlaceWrapperWrapped, sym::place_wrapper_wrapped, place_wrapper_wrapped, Target::AssocTy, GenericRequirement::Exact(1); - PlaceWrapperWrap, sym::place_wrapper_wrap, place_wrapper_wrap, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + + BorrowPlace, sym::borrow_place, borrow_place, Target::Trait, GenericRequirement::Exact(2); + BorrowPlaceSafety, sym::borrow_place_safety, borrow_place_safety, Target::AssocConst, GenericRequirement::Exact(2); + BorrowPlaceBorrow, sym::borrow_place_borrow, borrow_place_borrow, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(2); + + NestPlace, sym::nest_place, nest_place, Target::Trait, GenericRequirement::Exact(1); + NestPlaceNested, sym::nest_place_nested, nest_place_nested, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + + WrapPlace, sym::wrap_place, wrap_place, Target::Trait, GenericRequirement::Exact(1); + WrapPlaceWrapped, sym::wrap_place_wrapped, wrap_place_wrapped, Target::AssocTy, GenericRequirement::Exact(1); + WrapPlaceWrap, sym::wrap_place_wrap, wrap_place_wrap, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); // Used to fallback `{float}` to `f32` when `f32: From<{float}>` From, sym::From, from_trait, Target::Trait, GenericRequirement::Exact(1); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 319dc498103be..41e97cf1beb39 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -528,6 +528,9 @@ symbols! { block, blocking, bool, + borrow_place, + borrow_place_borrow, + borrow_place_safety, borrowck_graphviz_format, borrowck_graphviz_postflow, box_new, @@ -788,6 +791,8 @@ symbols! { deref_method, deref_mut, deref_patterns, + deref_place, + deref_place_target, deref_pure, deref_target, derive, @@ -835,6 +840,8 @@ symbols! { drop_husk, drop_husk_drop_husk, drop_in_place, + drop_place, + drop_place_drop, drop_types_in_const, dropck_eyepatch, dropck_parametricity, @@ -1320,6 +1327,7 @@ symbols! { more_qualified_paths, more_struct_aliases, movbe_target_feature, + move_place, move_ref_pattern, move_size_limit, movrs_target_feature, @@ -1355,6 +1363,8 @@ symbols! { negative_bounds, negative_impls, neon, + nest_place, + nest_place_nested, nested, never, never_patterns, @@ -1517,24 +1527,6 @@ symbols! { pin_ergonomics, pin_v2, place, - place_borrow, - place_borrow_borrow, - place_borrow_safety, - place_deref, - place_deref_deref, - place_drop, - place_drop_drop, - place_move, - place_read, - place_read_read, - place_read_safety, - place_target, - place_wrapper, - place_wrapper_wrap, - place_wrapper_wrapped, - place_write, - place_write_safety, - place_write_write, platform_intrinsics, plugin, plugin_registrar, @@ -1630,6 +1622,9 @@ symbols! { raw_identifiers, raw_ref_op, re_rebalance_coherence, + read_place, + read_place_read, + read_place_safety, read_via_copy, readonly, realloc, @@ -2285,6 +2280,9 @@ symbols! { windows_subsystem, with_negative_coherence, wrap_binder, + wrap_place, + wrap_place_wrap, + wrap_place_wrapped, wrapping_add, wrapping_div, wrapping_mul, @@ -2296,6 +2294,9 @@ symbols! { write_bytes, write_fmt, write_macro, + write_place, + write_place_safety, + write_place_write, write_str, write_via_move, writeln_macro, diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index 6b1659117e8eb..98c65375146a3 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -40,30 +40,30 @@ pub unsafe trait Subplace: Sized { /// for `x: Self`, but not enable any operations on `*x`. For those, one of the other place /// operation traits has to be implemented: /// -/// - [`PlaceRead`] -/// - [`PlaceWrite`] -/// - [`PlaceDrop`] -/// - [`PlaceMove`] -/// - [`PlaceBorrow`] -/// - [`PlaceDeref`] +/// - [`ReadPlace`] +/// - [`WritePlace`] +/// - [`BorrowPlace`] +/// - [`DropPlace`] +/// - [`MovePlace`] +/// - [`NestPlace`] #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place"] -pub trait Place { +#[lang = "deref_place"] +pub trait DerefPlace { /// The type of the contained place. - #[lang = "place_target"] + #[lang = "deref_place_target"] type Target: ?Sized; } /// Reading a place `let val = *x;`. /// -/// When `x: Self`, then `let val = *x;` will be desugared into [`PlaceRead::read`]. +/// When `x: Self`, then `let val = *x;` will be desugared into [`ReadPlace::read`]. /// /// # Safety /// /// FIXME #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place_read"] -pub unsafe trait PlaceRead: Place +#[lang = "read_place"] +pub unsafe trait ReadPlace: DerefPlace where S: Subplace, S::Target: Sized, @@ -73,7 +73,7 @@ where /// When the operator is used, the borrow checker follows its usual rules to ensure that no /// other operation conflicts with this one. If that alone is sufficient to make this operation /// sound, then this should be `true`. - #[lang = "place_read_safety"] + #[lang = "read_place_safety"] const SAFETY: bool; /// Reads the subplace pointed to by `this`. @@ -81,20 +81,20 @@ where /// # Safety /// /// FIXME - #[lang = "place_read_read"] + #[lang = "read_place_read"] unsafe fn read(this: *const Self, sub: S) -> S::Target; } /// Writing a place `*x = val;`. /// -/// When `x: Self`, then `*x = val;` will be desugared into [`PlaceWrite::write`]. +/// When `x: Self`, then `*x = val;` will be desugared into [`WritePlace::write`]. /// /// # Safety /// /// FIXME #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place_write"] -pub unsafe trait PlaceWrite: Place +#[lang = "write_place"] +pub unsafe trait WritePlace: DerefPlace where S: Subplace, S::Target: Sized, @@ -104,7 +104,7 @@ where /// When the operator is used, the borrow checker follows its usual rules to ensure that no /// other operation conflicts with this one. If that alone is sufficient to make this operation /// sound, then this should be `true`. - #[lang = "place_write_safety"] + #[lang = "write_place_safety"] const SAFETY: bool; /// Writes to the subplace pointed to by `this`. @@ -112,13 +112,13 @@ where /// # Safety /// /// FIXME - #[lang = "place_write_write"] + #[lang = "write_place_write"] unsafe fn write(this: *const Self, sub: S, value: S::Target); } /// Moving out of a place. /// -/// When `x: Self` and one performs a [`PlaceRead::read`] where the target value is not [`Copy`], +/// When `x: Self` and one performs a [`ReadPlace::read`] where the target value is not [`Copy`], /// then the compiler checks if this trait is implemented and if so, moves the value out by reading /// it and adjusting the borrow checker state of the place. /// @@ -126,8 +126,8 @@ where /// /// FIXME #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place_move"] -pub unsafe trait PlaceMove: PlaceRead +#[lang = "move_place"] +pub unsafe trait MovePlace: ReadPlace where S: Subplace, S::Target: Sized, @@ -143,8 +143,8 @@ where /// /// FIXME #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place_drop"] -pub unsafe trait PlaceDrop: Place +#[lang = "drop_place"] +pub unsafe trait DropPlace: DerefPlace where S: Subplace, { @@ -153,7 +153,7 @@ where /// # Safety /// /// FIXME - #[lang = "place_drop_drop"] + #[lang = "drop_place_drop"] unsafe fn drop(this: *const Self, sub: S); } @@ -167,7 +167,7 @@ where /// FIXME #[unstable(feature = "field_projections", issue = "145383")] #[lang = "drop_husk"] -pub unsafe trait DropHusk: Place { +pub unsafe trait DropHusk: DerefPlace { /// Drops the /// /// # Safety @@ -179,24 +179,24 @@ pub unsafe trait DropHusk: Place { /// Borrowing a place with `X`. /// -/// When `y: Self`, then `let x = @ *y;` will be desugared into [`PlaceBorrow::borrow`]. +/// When `y: Self`, then `let x = @ *y;` will be desugared into [`BorrowPlace::borrow`]. /// /// # Safety /// /// FIXME #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place_borrow"] -pub unsafe trait PlaceBorrow: Place +#[lang = "borrow_place"] +pub unsafe trait BorrowPlace: DerefPlace where S: Subplace, - X: Place, + X: DerefPlace, { /// Whether the borrow operation is safe when used through the operator. /// /// When the operator is used, the borrow checker follows its usual rules to ensure that no /// other operation conflicts with this one. If that alone is sufficient to make this operation /// sound, then this should be `true`. - #[lang = "place_borrow_safety"] + #[lang = "borrow_place_safety"] const SAFETY: bool; // FIXME: this is missing some associated items related to controlling the @@ -207,32 +207,32 @@ where /// # Safety /// /// FIXME - #[lang = "place_borrow_borrow"] + #[lang = "borrow_place_borrow"] unsafe fn borrow(this: *const Self, sub: S) -> X; } /// Accessing a nested pointer. /// /// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a combination of the -/// corresponding operation and a [`PlaceDeref::deref`]. +/// corresponding operation and a [`NestPlace::nested`]. /// /// # Safety /// /// FIXME #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place_deref"] -pub unsafe trait PlaceDeref: Place +#[lang = "nest_place"] +pub unsafe trait NestPlace: DerefPlace where S: Subplace, - S::Target: Place, + S::Target: DerefPlace, { - /// Obtain a raw pointer to the subplace pointed to by `this`. + /// Obtain a raw pointer to the subplace contained by `this`. /// /// # Safety /// /// FIXME - #[lang = "place_deref_deref"] - unsafe fn deref(this: *const Self, sub: S) -> *const S::Target; + #[lang = "nest_place_nested"] + unsafe fn nested(this: *const Self, sub: S) -> *const S::Target; } /// Forwards the subplace `S` of the place contained by this. @@ -245,16 +245,16 @@ where /// /// FIXME #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "place_wrapper"] -pub unsafe trait PlaceWrapper: Place +#[lang = "wrap_place"] +pub unsafe trait WrapPlace: DerefPlace where S: Subplace, { /// The subplace to use instead of `S` for any place operations on `Self`. - #[lang = "place_wrapper_wrapped"] + #[lang = "wrap_place_wrapped"] type Wrapped: Subplace; /// Turn a subplace of type `S` into [`Self::Wrapped`]. - #[lang = "place_wrapper_wrap"] + #[lang = "wrap_place_wrap"] fn wrap(sub: S) -> Self::Wrapped; } From 39e5a888c029a9815fdef5ad6f298c31e00a0882 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 10:05:09 +0200 Subject: [PATCH 09/20] TOSQUASH: write top-level documentation --- library/core/src/ops/place.rs | 125 +++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index 98c65375146a3..bff8c2487f6b2 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -1,4 +1,127 @@ -//! Place Operations. +//! Operations on places. +//! +//! # Operations on Places +//! +//! This module contains traits to customize the place operations of Rust: +//! - reading, +//! - writing, and +//! - borrowing. +//! +//! This is part of the language experiment for field projections +//! . The specific design that +//! is currently being implemented is explained in detail in the latest [design +//! meeting document](https://hackmd.io/H5d2-83ER2ymNPZVIWCYWg?view). Note that +//! several types and traits have been renamed. Further modifications pending +//! experiment results are expected to occur. +//! +//! ## Places +//! +//! A *place* in Rust is a particular location in memory. They are represented +//! by [*place expressions*][ref-place-exprs], which take on the following form: +//! - `$path`: paths that refer to locals variables (also parameters), statics, +//! constants, and functions. +//! - `|$args...| $body`: closure expressions, +//! - `$place as $ty`: certain `as`-casts of another place expression, +//! - `*$place`: dereferences of another place expression, +//! - `$place[$expr]`: indexing operation of another place expression, +//! - `$place.$ident`: field access of another place expression, +//! - `($place)`: parenthesized place expressions, +//! +//! Further reading: +//! - +//! - +//! +//! [ref-place-exprs]: https://doc.rust-lang.org/reference/expressions.html#r-expr.place-value.place-expr-kinds +//! +//! ## Operation Traits +//! +//! Place operations are implemented by types that reference/contain/represent a +//! place. This is because places are not part of the type system of Rust; a +//! place expression has the type of the values that are contained in the place. +//! The [`DerefPlace`] trait marks a type as containing a place; it also records +//! which type the values contained within the place have. +//! +//! When a type `X` implements [`DerefPlace`], values of type `X` can be +//! dereferenced, which results in a place that can be read from, written to, or +//! borrowed. Any of those place operations are implemented by the corresponding +//! place operation trait on the value the place originated from. This means +//! that the operations are only available if `X` implements the corresponding +//! place operation trait: +//! - reading [`ReadPlace`], +//! - writing [`WritePlace`], and +//! - borrowing [`BorrowPlace`]. +//! +//! Examples of types that implement some of these operations are smart & dumb +//! pointers like `Box`, `Arc`, [`&mut T`](primitive@reference), +//! [`*mut T`](primitive@pointer), and [`NonNull`](core::ptr::NonNull). +//! +//! ### Subplaces +//! +//! Place operations are allowed to target only a *subplace*. For example +//! `my_struct.field = 42;` writes to only the `field` subplace. However, +//! the operations traits are always applied to a type that references the +//! *entire* place, since there is no type system level construct that +//! represents only the subplace. For this reason, all operation traits have a +//! generic argument implementing the [`Subplace`] trait that specifies the +//! subplace that the operation should affect. +//! +//! This generic argument is supplied by the compiler when desugaring a place +//! operation into the corresponding place operation trait function call. There +//! is a direct translation from place expressions to types implementing the +//! [`Subplace`] trait (these are compiler-internal). +//! +//! ### Implicit Operations +//! +//! In addition to the three visible operations, there are several other +//! *implicit* operations that allow full customization of types implementing +//! [`DerefPlace`]: +//! - moving out of a subplace [`MovePlace`], +//! - dropping a subplace [`DropPlace`] and dropping a fully moved-out pointer +//! [`DropHusk`], and +//! - support for accessing a nested pointer [`NestPlace`]. +//! +//! ### Place Wrappers +//! +//! Place wrappers are types that implement the [`WrapPlace`] trait. They modify +//! subplaces contained by their value. For example [`MaybeUninit`] has all +//! fields that `T` has (it forwards all subplaces of `T`), but those subplaces +//! have `MaybeUninit` as the type instead of `U`. Given `Struct` with a +//! field of type `Field` called `field`, we can write `val.field` (this has +//! type `Field`) given `val: Struct`; we can also write `val.field` given `val: +//! MaybeUninit` and then `val.field: MaybeUninit`. +//! +//! [`MaybeUninit`]: crate::mem::MaybeUninit +//! +//! ### Safety +//! +//! All operation functions are `unsafe`, since they have raw pointer arguments. +//! The raw pointers are needed, because the values they point to might be +//! partially moved out or borrowed at the same time. +//! +//! The safety requirements for the operation functions have not been figured +//! out at this point in time. Since we expect several changes to the design, we +//! do not want to commit to writing down good safety documentation before +//! having finished the design. +//! +//! What is clear at the moment is that the safety requirements will heavily +//! interact with the borrow checker. It will ensure that simultaneous place +//! operations on the same value are allowed, since they either affect disjoint +//! subplaces, or because they both only require shared access. For example: +//! - reading `ptr.field.subfield` and borrowing `ptr.field` with `&T` are +//! allowed to happen at the same time, +//! - writing `ptr.field` and borrowing `ptr.field.subfield` at the same time is +//! not allowed. +//! +//! The safety of using the place operations via the operators will depend on +//! the value of the `SAFETY` constant in the operation traits. At the moment we +//! will only permit a literal value of `true` or `false` in implementations. It +//! will dictate if people have to write for example `unsafe { &*ptr }` or if +//! `*ptr` is allowed. It should be set to `true` when the borrow checker's +//! guarantees of either disjoint subplaces or "all concurrent operations are +//! shared" are enough to calling the operations' function correctly. If there +//! are additional requirements, such as "ptr is valid", then `SAFETY` should be +//! set to `false`. For example, `&mut T` will have `SAFETY = true` in +//! [`ReadPlace`], but `NonNull` will set it to `false`. use crate::ptr::Pointee; From 2c630114d7321e093cd056c7c5873bd456e7fddd Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 10:28:49 +0200 Subject: [PATCH 10/20] TOSQUASH: link to module-level safety docs --- library/core/src/ops/place.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index bff8c2487f6b2..d9a3006fd0e37 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -135,7 +135,7 @@ use crate::ptr::Pointee; /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[rustc_deny_explicit_impl] #[rustc_dyn_incompatible_trait] @@ -183,7 +183,7 @@ pub trait DerefPlace { /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "read_place"] pub unsafe trait ReadPlace: DerefPlace @@ -203,7 +203,7 @@ where /// /// # Safety /// - /// FIXME + /// See the module-level section on [safety](crate::ops::place#safety). #[lang = "read_place_read"] unsafe fn read(this: *const Self, sub: S) -> S::Target; } @@ -214,7 +214,7 @@ where /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "write_place"] pub unsafe trait WritePlace: DerefPlace @@ -234,7 +234,7 @@ where /// /// # Safety /// - /// FIXME + /// See the module-level section on [safety](crate::ops::place#safety). #[lang = "write_place_write"] unsafe fn write(this: *const Self, sub: S, value: S::Target); } @@ -247,7 +247,7 @@ where /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "move_place"] pub unsafe trait MovePlace: ReadPlace @@ -264,7 +264,7 @@ where /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "drop_place"] pub unsafe trait DropPlace: DerefPlace @@ -275,7 +275,7 @@ where /// /// # Safety /// - /// FIXME + /// See the module-level section on [safety](crate::ops::place#safety). #[lang = "drop_place_drop"] unsafe fn drop(this: *const Self, sub: S); } @@ -287,7 +287,7 @@ where /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "drop_husk"] pub unsafe trait DropHusk: DerefPlace { @@ -295,7 +295,7 @@ pub unsafe trait DropHusk: DerefPlace { /// /// # Safety /// - /// FIXME + /// See the module-level section on [safety](crate::ops::place#safety). #[lang = "drop_husk_drop_husk"] unsafe fn drop_husk(this: *const Self); } @@ -306,7 +306,7 @@ pub unsafe trait DropHusk: DerefPlace { /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "borrow_place"] pub unsafe trait BorrowPlace: DerefPlace @@ -329,7 +329,7 @@ where /// /// # Safety /// - /// FIXME + /// See the module-level section on [safety](crate::ops::place#safety). #[lang = "borrow_place_borrow"] unsafe fn borrow(this: *const Self, sub: S) -> X; } @@ -341,7 +341,7 @@ where /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "nest_place"] pub unsafe trait NestPlace: DerefPlace @@ -353,7 +353,7 @@ where /// /// # Safety /// - /// FIXME + /// See the module-level section on [safety](crate::ops::place#safety). #[lang = "nest_place_nested"] unsafe fn nested(this: *const Self, sub: S) -> *const S::Target; } @@ -366,7 +366,7 @@ where /// /// # Safety /// -/// FIXME +/// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "wrap_place"] pub unsafe trait WrapPlace: DerefPlace From 8c25087f2cafbf5439230229c9680afacb7ef30d Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 10:26:05 +0200 Subject: [PATCH 11/20] TOSQUASH: add more trait docs & format to 80 columns --- library/core/src/ops/place.rs | 80 ++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index d9a3006fd0e37..efc06312a1159 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -127,11 +127,12 @@ use crate::ptr::Pointee; /// A subplace of [`Self::Source`] with the type [`Self::Target`]. /// -/// A subplace is always within the same allocation as the base place. Current subplaces are: -/// - field accesses, +/// A subplace is always within the same allocation as the base place. A +/// subplace is described by a chain of +/// - field accesses, and /// - array/slice indexes. /// -/// This represents an arbitrary chaining of these; it can also be empty. +/// Note that a subplace can also be the entire original place. /// /// # Safety /// @@ -159,16 +160,21 @@ pub unsafe trait Subplace: Sized { /// Marks a type as containing a place. /// -/// This is the new trait for the dereference operator `*`; implementing it will allow writing `*x` -/// for `x: Self`, but not enable any operations on `*x`. For those, one of the other place -/// operation traits has to be implemented: -/// +/// Dereferencing a value of this type will result in a normal place expression +/// that can be read from, written to, or borrowed. Each of these operations is +/// only available if the corresponding trait is implemented: /// - [`ReadPlace`] /// - [`WritePlace`] /// - [`BorrowPlace`] +/// +/// Further implicit operation traits are also available: /// - [`DropPlace`] +/// - [`DropHusk`] /// - [`MovePlace`] /// - [`NestPlace`] +/// - [`WrapPlace`] +/// +/// Read the [module](self) description for more information. #[unstable(feature = "field_projections", issue = "145383")] #[lang = "deref_place"] pub trait DerefPlace { @@ -193,9 +199,9 @@ where { /// Whether the read operation is safe when used through the operator. /// - /// When the operator is used, the borrow checker follows its usual rules to ensure that no - /// other operation conflicts with this one. If that alone is sufficient to make this operation - /// sound, then this should be `true`. + /// When the operator is used, the borrow checker follows its usual rules to + /// ensure that no other operation conflicts with this one. If that alone is + /// sufficient to make this operation sound, then this should be `true`. #[lang = "read_place_safety"] const SAFETY: bool; @@ -210,7 +216,11 @@ where /// Writing a place `*x = val;`. /// -/// When `x: Self`, then `*x = val;` will be desugared into [`WritePlace::write`]. +/// When `x: Self`, then `*x = val;` will be desugared into +/// [`WritePlace::write`]. +/// +/// When a value already exists at the subplace, it is dropped with +/// [`DropPlace`] before it is written to. /// /// # Safety /// @@ -224,9 +234,9 @@ where { /// Whether the write operation is safe when used through the operator. /// - /// When the operator is used, the borrow checker follows its usual rules to ensure that no - /// other operation conflicts with this one. If that alone is sufficient to make this operation - /// sound, then this should be `true`. + /// When the operator is used, the borrow checker follows its usual rules to + /// ensure that no other operation conflicts with this one. If that alone is + /// sufficient to make this operation sound, then this should be `true`. #[lang = "write_place_safety"] const SAFETY: bool; @@ -241,9 +251,10 @@ where /// Moving out of a place. /// -/// When `x: Self` and one performs a [`ReadPlace::read`] where the target value is not [`Copy`], -/// then the compiler checks if this trait is implemented and if so, moves the value out by reading -/// it and adjusting the borrow checker state of the place. +/// When `x: Self` and one performs a [`ReadPlace::read`] where the target value +/// is not [`Copy`], then the compiler checks if this trait is implemented and +/// if so, moves the value out by reading it and adjusting the borrow checker +/// state of the place. /// /// # Safety /// @@ -259,8 +270,10 @@ where /// Dropping a place. /// -/// Emitted by the compiler when a place has been partially moved out and the pointer with ownership -/// is being dropped. +/// Emitted by the compiler before a new value is written ([`WritePlace`]) to +/// this subplace, or when a pointer to a partially moved out place is dropped. +/// See the documentation of [`DropHusk`] for more on the exact details of that +/// last case. /// /// # Safety /// @@ -282,8 +295,15 @@ where /// Dropping a pointer that points at a fully moved-out place. /// -/// This operation is emitted by the compiler when a pointer is being dropped that had some fields -/// moved out. +/// This operation is emitted by the compiler when a pointer is being dropped +/// that had all of its fields moved out. +/// +/// If no fields or only some fields have been moved out, all not yet moved out +/// fields are dropped with the [`DropPlace`] trait. After that this pointer is +/// dropped by calling [`DropHusk::drop_husk`]. +/// +/// Note that a write operation ([`WritePlace`]) can move a value into a +/// previously moved-out field. /// /// # Safety /// @@ -302,7 +322,8 @@ pub unsafe trait DropHusk: DerefPlace { /// Borrowing a place with `X`. /// -/// When `y: Self`, then `let x = @ *y;` will be desugared into [`BorrowPlace::borrow`]. +/// When `y: Self`, then `let x = @ *y;` will be desugared into +/// [`BorrowPlace::borrow`]. /// /// # Safety /// @@ -316,9 +337,9 @@ where { /// Whether the borrow operation is safe when used through the operator. /// - /// When the operator is used, the borrow checker follows its usual rules to ensure that no - /// other operation conflicts with this one. If that alone is sufficient to make this operation - /// sound, then this should be `true`. + /// When the operator is used, the borrow checker follows its usual rules to + /// ensure that no other operation conflicts with this one. If that alone is + /// sufficient to make this operation sound, then this should be `true`. #[lang = "borrow_place_safety"] const SAFETY: bool; @@ -336,8 +357,8 @@ where /// Accessing a nested pointer. /// -/// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a combination of the -/// corresponding operation and a [`NestPlace::nested`]. +/// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a +/// combination of the corresponding operation and a [`NestPlace::nested`]. /// /// # Safety /// @@ -360,8 +381,9 @@ where /// Forwards the subplace `S` of the place contained by this. /// -/// When `x: Self` and `Self::Target` has a subplace `S` accessible via `.foo.bar`, then `x.foo.bar` -/// is also valid, has type `::Target` and any place operation on it uses +/// When `x: Self` and `Self::Target` has a subplace `S` accessible via +/// `.foo.bar`, then `x.foo.bar` is also valid, has type `::Target` and any place operation on it uses /// [Self::wrap]\(sub\) as the subplace instead of `S`. /// /// # Safety From 3ee9a3674b071f05a10f11eacdf56ad7e50dbfad Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 16 Apr 2026 10:56:38 +0200 Subject: [PATCH 12/20] TOSQUASH: have consistent ordering with the traits --- library/core/src/ops/place.rs | 74 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index efc06312a1159..4018864e6310a 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -167,10 +167,10 @@ pub unsafe trait Subplace: Sized { /// - [`WritePlace`] /// - [`BorrowPlace`] /// -/// Further implicit operation traits are also available: +/// Further operation traits are also available: +/// - [`MovePlace`] /// - [`DropPlace`] /// - [`DropHusk`] -/// - [`MovePlace`] /// - [`NestPlace`] /// - [`WrapPlace`] /// @@ -249,6 +249,41 @@ where unsafe fn write(this: *const Self, sub: S, value: S::Target); } +/// Borrowing a place with `X`. +/// +/// When `y: Self`, then `let x = @ *y;` will be desugared into +/// [`BorrowPlace::borrow`]. +/// +/// # Safety +/// +/// See the module-level section on [safety](crate::ops::place#safety). +#[unstable(feature = "field_projections", issue = "145383")] +#[lang = "borrow_place"] +pub unsafe trait BorrowPlace: DerefPlace +where + S: Subplace, + X: DerefPlace, +{ + /// Whether the borrow operation is safe when used through the operator. + /// + /// When the operator is used, the borrow checker follows its usual rules to + /// ensure that no other operation conflicts with this one. If that alone is + /// sufficient to make this operation sound, then this should be `true`. + #[lang = "borrow_place_safety"] + const SAFETY: bool; + + // FIXME: this is missing some associated items related to controlling the + // borrow checker. The details need to still be worked out in a-mir-formality. + + /// Borrow the subplace pointed to by `this` with `X`. + /// + /// # Safety + /// + /// See the module-level section on [safety](crate::ops::place#safety). + #[lang = "borrow_place_borrow"] + unsafe fn borrow(this: *const Self, sub: S) -> X; +} + /// Moving out of a place. /// /// When `x: Self` and one performs a [`ReadPlace::read`] where the target value @@ -320,41 +355,6 @@ pub unsafe trait DropHusk: DerefPlace { unsafe fn drop_husk(this: *const Self); } -/// Borrowing a place with `X`. -/// -/// When `y: Self`, then `let x = @ *y;` will be desugared into -/// [`BorrowPlace::borrow`]. -/// -/// # Safety -/// -/// See the module-level section on [safety](crate::ops::place#safety). -#[unstable(feature = "field_projections", issue = "145383")] -#[lang = "borrow_place"] -pub unsafe trait BorrowPlace: DerefPlace -where - S: Subplace, - X: DerefPlace, -{ - /// Whether the borrow operation is safe when used through the operator. - /// - /// When the operator is used, the borrow checker follows its usual rules to - /// ensure that no other operation conflicts with this one. If that alone is - /// sufficient to make this operation sound, then this should be `true`. - #[lang = "borrow_place_safety"] - const SAFETY: bool; - - // FIXME: this is missing some associated items related to controlling the - // borrow checker. The details need to still be worked out in a-mir-formality. - - /// Borrow the subplace pointed to by `this` with `X`. - /// - /// # Safety - /// - /// See the module-level section on [safety](crate::ops::place#safety). - #[lang = "borrow_place_borrow"] - unsafe fn borrow(this: *const Self, sub: S) -> X; -} - /// Accessing a nested pointer. /// /// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a From 26d8e91993ee7e23fd4818df771bb78209e7fcc3 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Tue, 21 Apr 2026 08:02:41 +0200 Subject: [PATCH 13/20] TOSQUASH: fix feature gate test --- .../feature-gate-field-projections.rs | 58 +++++----- .../feature-gate-field-projections.stderr | 106 +++++++++--------- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/tests/ui/feature-gates/feature-gate-field-projections.rs b/tests/ui/feature-gates/feature-gate-field-projections.rs index ef50027687cc5..ac17f1fc6afc2 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.rs +++ b/tests/ui/feature-gates/feature-gate-field-projections.rs @@ -1,17 +1,17 @@ #![feature(ptr_metadata)] use std::field::Field; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::field::Subplace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::Subplace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::field::field_of; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::DropHusk; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::Place; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::PlaceBorrow; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::PlaceDeref; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::PlaceDrop; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::PlaceMove; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::PlaceRead; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::PlaceWrapper; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::PlaceWrite; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::DropHusk; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::DerefPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::BorrowPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::NestPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::DropPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::MovePlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::ReadPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::WrapPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::WritePlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ptr; use std::ptr::Pointee; @@ -28,12 +28,12 @@ where struct MyPtr(*mut T); -impl Place for MyPtr { +impl DerefPlace for MyPtr { //~^ ERROR: use of unstable library feature `field_projections` [E0658] type Target = T; //~ ERROR: use of unstable library feature `field_projections` [E0658] } -unsafe impl PlaceRead for MyPtr +unsafe impl ReadPlace for MyPtr //~^ ERROR: use of unstable library feature `field_projections` [E0658] where T: ?Sized, @@ -52,7 +52,7 @@ where } } -unsafe impl PlaceWrite for MyPtr +unsafe impl WritePlace for MyPtr //~^ ERROR: use of unstable library feature `field_projections` [E0658] where T: ?Sized, @@ -71,7 +71,7 @@ where } } -unsafe impl PlaceMove for MyPtr +unsafe impl MovePlace for MyPtr //~^ ERROR: use of unstable library feature `field_projections` [E0658] where S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] @@ -81,7 +81,7 @@ where { } -unsafe impl PlaceDrop for MyPtr +unsafe impl DropPlace for MyPtr //~^ ERROR: use of unstable library feature `field_projections` [E0658] where T: ?Sized, @@ -105,7 +105,7 @@ unsafe impl DropHusk for MyPtr { } } -unsafe impl PlaceBorrow> for MyPtr +unsafe impl BorrowPlace> for MyPtr //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] where @@ -124,16 +124,16 @@ where } } -unsafe impl PlaceDeref for MyPtr +unsafe impl NestPlace for MyPtr //~^ ERROR: use of unstable library feature `field_projections` [E0658] where S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] - S::Target: Place, //~ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: DerefPlace, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] { - unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { + unsafe fn nested(this: *const Self, sub: S) -> *const S::Target { //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] let _ = (this, sub); @@ -141,32 +141,32 @@ where } } -unsafe fn using_place_ops(place: *const MyPtr, sub: S) +unsafe fn using_place_ops(place: *const MyPtr, sub: impl Fn() -> S) where S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] - S::Target: Sized + Place, //~ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: Sized + DerefPlace, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] { unsafe { - let value = PlaceRead::read(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] - PlaceWrite::write(place, sub, value); //~ ERROR: use of unstable library feature `field_projections` [E0658] - let _ = PlaceBorrow::<_, MyPtr<_>>::borrow(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] - let _ = PlaceDeref::deref(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] - PlaceDrop::drop(place, sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] + let value = ReadPlace::read(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] + WritePlace::write(place, sub(), value); //~ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = BorrowPlace::<_, MyPtr<_>>::borrow(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = NestPlace::nested(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] + DropPlace::drop(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] DropHusk::drop_husk(place); //~ ERROR: use of unstable library feature `field_projections` [E0658] } } struct MyWrapper(T); -impl Place for MyWrapper { +impl DerefPlace for MyWrapper { //~^ ERROR: use of unstable library feature `field_projections` [E0658] type Target = T; //~ ERROR: use of unstable library feature `field_projections` [E0658] } -unsafe impl PlaceWrapper for MyWrapper +unsafe impl WrapPlace for MyWrapper //~^ ERROR: use of unstable library feature `field_projections` [E0658] where T: ?Sized, @@ -214,7 +214,7 @@ where //~^ ERROR: use of unstable library feature `field_projections` [E0658] { unsafe { - let _ = as PlaceWrapper>::wrap(sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = as WrapPlace>::wrap(sub); //~ ERROR: use of unstable library feature `field_projections` [E0658] } } diff --git a/tests/ui/feature-gates/feature-gate-field-projections.stderr b/tests/ui/feature-gates/feature-gate-field-projections.stderr index 70607e52b6b9c..379cf46684b79 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.stderr +++ b/tests/ui/feature-gates/feature-gate-field-projections.stderr @@ -21,8 +21,8 @@ LL | use std::field::Field; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:4:5 | -LL | use std::field::Subplace; - | ^^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::Subplace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -41,8 +41,8 @@ LL | use std::field::field_of; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:6:5 | -LL | use std::ops::DropHusk; - | ^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::DropHusk; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -51,8 +51,8 @@ LL | use std::ops::DropHusk; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:7:5 | -LL | use std::ops::Place; - | ^^^^^^^^^^^^^^^ +LL | use std::ops::place::DerefPlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -61,8 +61,8 @@ LL | use std::ops::Place; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:8:5 | -LL | use std::ops::PlaceBorrow; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::BorrowPlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -71,8 +71,8 @@ LL | use std::ops::PlaceBorrow; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:9:5 | -LL | use std::ops::PlaceDeref; - | ^^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::NestPlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -81,8 +81,8 @@ LL | use std::ops::PlaceDeref; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:10:5 | -LL | use std::ops::PlaceDrop; - | ^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::DropPlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -91,8 +91,8 @@ LL | use std::ops::PlaceDrop; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:11:5 | -LL | use std::ops::PlaceMove; - | ^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::MovePlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -101,8 +101,8 @@ LL | use std::ops::PlaceMove; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:12:5 | -LL | use std::ops::PlaceRead; - | ^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::ReadPlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -111,8 +111,8 @@ LL | use std::ops::PlaceRead; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:13:5 | -LL | use std::ops::PlaceWrapper; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::WrapPlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -121,8 +121,8 @@ LL | use std::ops::PlaceWrapper; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:14:5 | -LL | use std::ops::PlaceWrite; - | ^^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::WritePlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -151,8 +151,8 @@ LL | type Target = T; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:31:17 | -LL | impl Place for MyPtr { - | ^^^^^ +LL | impl DerefPlace for MyPtr { + | ^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -191,7 +191,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:36:19 | -LL | unsafe impl PlaceRead for MyPtr +LL | unsafe impl ReadPlace for MyPtr | ^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -231,7 +231,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:55:19 | -LL | unsafe impl PlaceWrite for MyPtr +LL | unsafe impl WritePlace for MyPtr | ^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -251,7 +251,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:74:19 | -LL | unsafe impl PlaceMove for MyPtr +LL | unsafe impl MovePlace for MyPtr | ^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -281,7 +281,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:84:19 | -LL | unsafe impl PlaceDrop for MyPtr +LL | unsafe impl DropPlace for MyPtr | ^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -341,7 +341,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:108:19 | -LL | unsafe impl PlaceBorrow> for MyPtr +LL | unsafe impl BorrowPlace> for MyPtr | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -351,8 +351,8 @@ LL | unsafe impl PlaceBorrow> for MyPtr error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:136:5 | -LL | unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe fn nested(this: *const Self, sub: S) -> *const S::Target { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -371,8 +371,8 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:133:16 | -LL | S::Target: Place, - | ^^^^^ +LL | S::Target: DerefPlace, + | ^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -381,8 +381,8 @@ LL | S::Target: Place, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:127:19 | -LL | unsafe impl PlaceDeref for MyPtr - | ^^^^^^^^^^^^^ +LL | unsafe impl NestPlace for MyPtr + | ^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -401,8 +401,8 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:149:24 | -LL | S::Target: Sized + Place, - | ^^^^^ +LL | S::Target: Sized + DerefPlace, + | ^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -411,7 +411,7 @@ LL | S::Target: Sized + Place, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:153:21 | -LL | let value = PlaceRead::read(place, sub); +LL | let value = ReadPlace::read(place, sub()); | ^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -421,7 +421,7 @@ LL | let value = PlaceRead::read(place, sub); error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:154:9 | -LL | PlaceWrite::write(place, sub, value); +LL | WritePlace::write(place, sub(), value); | ^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -431,8 +431,8 @@ LL | PlaceWrite::write(place, sub, value); error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:155:17 | -LL | let _ = PlaceBorrow::<_, MyPtr<_>>::borrow(place, sub); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = BorrowPlace::<_, MyPtr<_>>::borrow(place, sub()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -441,7 +441,7 @@ LL | let _ = PlaceBorrow::<_, MyPtr<_>>::borrow(place, sub); error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:156:17 | -LL | let _ = PlaceDeref::deref(place, sub); +LL | let _ = NestPlace::nested(place, sub()); | ^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -451,7 +451,7 @@ LL | let _ = PlaceDeref::deref(place, sub); error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:157:9 | -LL | PlaceDrop::drop(place, sub); +LL | DropPlace::drop(place, sub()); | ^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -481,8 +481,8 @@ LL | type Target = T; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:164:17 | -LL | impl Place for MyWrapper { - | ^^^^^ +LL | impl DerefPlace for MyWrapper { + | ^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -521,8 +521,8 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:169:19 | -LL | unsafe impl PlaceWrapper for MyWrapper - | ^^^^^^^^^^^^^^^ +LL | unsafe impl WrapPlace for MyWrapper + | ^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -596,8 +596,8 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:217:17 | -LL | let _ = as PlaceWrapper>::wrap(sub); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = as WrapPlace>::wrap(sub); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -704,10 +704,10 @@ LL | S: Subplace, = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:136:58 + --> $DIR/feature-gate-field-projections.rs:136:59 | -LL | unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { - | ^^^^^^^^^ +LL | unsafe fn nested(this: *const Self, sub: S) -> *const S::Target { + | ^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -830,7 +830,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:108:40 | -LL | unsafe impl PlaceBorrow> for MyPtr +LL | unsafe impl BorrowPlace> for MyPtr | ^^^^^^^^^ | = note: see issue #145383 for more information @@ -851,7 +851,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:133:5 | -LL | S::Target: Place, +LL | S::Target: DerefPlace, | ^^^^^^^^^ | = note: see issue #145383 for more information @@ -882,7 +882,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:149:5 | -LL | S::Target: Sized + Place, +LL | S::Target: Sized + DerefPlace, | ^^^^^^^^^ | = note: see issue #145383 for more information From 58cc5f4309c831703b8c454125d62c5f95bc0424 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Wed, 22 Apr 2026 20:07:18 +0200 Subject: [PATCH 14/20] TOSQUASH: apply Nadri's suggestions --- library/core/src/ops/place.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index 4018864e6310a..b4f11a0ae7041 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -94,9 +94,10 @@ //! //! ### Safety //! -//! All operation functions are `unsafe`, since they have raw pointer arguments. -//! The raw pointers are needed, because the values they point to might be -//! partially moved out or borrowed at the same time. +//! All operation functions are `unsafe`, since they have raw pointer arguments +//! that have safety preconditions. The arguments are raw pointers, because the +//! values they point to need not be in a valid state (they may be partially +//! moved out or borrowed). //! //! The safety requirements for the operation functions have not been figured //! out at this point in time. Since we expect several changes to the design, we From 55fc3d7ebbdf1a6dbda5e092c9d499f31b0480e5 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Wed, 22 Apr 2026 20:11:57 +0200 Subject: [PATCH 15/20] TOSQUASH: apply Tyler's suggestions --- library/core/src/ops/place.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index b4f11a0ae7041..de9d5cd4707bd 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -65,6 +65,9 @@ //! generic argument implementing the [`Subplace`] trait that specifies the //! subplace that the operation should affect. //! +//! Note that the [`Subplace`] trait also can represent the entire place in case +//! the operation affects the entire place (for example `let x = *ptr;`). +//! //! This generic argument is supplied by the compiler when desugaring a place //! operation into the corresponding place operation trait function call. There //! is a direct translation from place expressions to types implementing the @@ -385,7 +388,7 @@ where /// When `x: Self` and `Self::Target` has a subplace `S` accessible via /// `.foo.bar`, then `x.foo.bar` is also valid, has type `::Target` and any place operation on it uses -/// [Self::wrap]\(sub\) as the subplace instead of `S`. +/// [Self::wrap]\(sub\) as the subplace instead of `sub`. /// /// # Safety /// From 7554c7e2db1fa64dfc247a167ba2f6d468175e37 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 23 Apr 2026 20:19:26 +0200 Subject: [PATCH 16/20] TOSQUASH: rename DerefPlace to PlaceProxy --- compiler/rustc_hir/src/lang_items.rs | 4 +- compiler/rustc_span/src/symbol.rs | 4 +- library/core/src/ops/place.rs | 41 ++++++++++--------- .../feature-gate-field-projections.rs | 10 ++--- .../feature-gate-field-projections.stderr | 14 +++---- 5 files changed, 37 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 01288f35fb2fd..0c161605a168b 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -452,8 +452,8 @@ language_item_table! { SubplaceTarget, sym::subplace_target, subplace_target, Target::AssocTy, GenericRequirement::Exact(0); SubplaceOffset, sym::subplace_offset, subplace_offset, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0); - DerefPlace, sym::deref_place, deref_place, Target::Trait, GenericRequirement::Exact(0); - DerefPlaceTarget, sym::deref_place_target, deref_place_target, Target::AssocTy, GenericRequirement::Exact(0); + PlaceProxy, sym::place_proxy, place_proxy, Target::Trait, GenericRequirement::Exact(0); + PlaceProxyTarget, sym::place_proxy_target, place_proxy_target, Target::AssocTy, GenericRequirement::Exact(0); ReadPlace, sym::read_place, read_place, Target::Trait, GenericRequirement::Exact(1); ReadPlaceSafety, sym::read_place_safety, read_place_safety, Target::AssocConst, GenericRequirement::Exact(1); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 41e97cf1beb39..d1475adb35dcc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -791,8 +791,6 @@ symbols! { deref_method, deref_mut, deref_patterns, - deref_place, - deref_place_target, deref_pure, deref_target, derive, @@ -1527,6 +1525,8 @@ symbols! { pin_ergonomics, pin_v2, place, + place_proxy, + place_proxy_target, platform_intrinsics, plugin, plugin_registrar, diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index de9d5cd4707bd..5a9de271e7287 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -38,10 +38,10 @@ //! Place operations are implemented by types that reference/contain/represent a //! place. This is because places are not part of the type system of Rust; a //! place expression has the type of the values that are contained in the place. -//! The [`DerefPlace`] trait marks a type as containing a place; it also records +//! The [`PlaceProxy`] trait marks a type as containing a place; it also records //! which type the values contained within the place have. //! -//! When a type `X` implements [`DerefPlace`], values of type `X` can be +//! When a type `X` implements [`PlaceProxy`], values of type `X` can be //! dereferenced, which results in a place that can be read from, written to, or //! borrowed. Any of those place operations are implemented by the corresponding //! place operation trait on the value the place originated from. This means @@ -77,7 +77,7 @@ //! //! In addition to the three visible operations, there are several other //! *implicit* operations that allow full customization of types implementing -//! [`DerefPlace`]: +//! [`PlaceProxy`]: //! - moving out of a subplace [`MovePlace`], //! - dropping a subplace [`DropPlace`] and dropping a fully moved-out pointer //! [`DropHusk`], and @@ -162,16 +162,17 @@ pub unsafe trait Subplace: Sized { ) -> (usize, ::Metadata); } -/// Marks a type as containing a place. +/// Marks a type as a place proxy. /// -/// Dereferencing a value of this type will result in a normal place expression -/// that can be read from, written to, or borrowed. Each of these operations is -/// only available if the corresponding trait is implemented: +/// A place proxy can be dereferenced (`*val`). This results in a place for +/// which any place operation is implemented by this type instead. The operation +/// is available only if the corresponding place operation trait is implemented: /// - [`ReadPlace`] /// - [`WritePlace`] /// - [`BorrowPlace`] /// -/// Further operation traits are also available: +/// Furthermore, there are implicit place operations that can be supported by +/// types implementing this trait: /// - [`MovePlace`] /// - [`DropPlace`] /// - [`DropHusk`] @@ -180,10 +181,10 @@ pub unsafe trait Subplace: Sized { /// /// Read the [module](self) description for more information. #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "deref_place"] -pub trait DerefPlace { +#[lang = "place_proxy"] +pub trait PlaceProxy { /// The type of the contained place. - #[lang = "deref_place_target"] + #[lang = "place_proxy_target"] type Target: ?Sized; } @@ -196,7 +197,7 @@ pub trait DerefPlace { /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "read_place"] -pub unsafe trait ReadPlace: DerefPlace +pub unsafe trait ReadPlace: PlaceProxy where S: Subplace, S::Target: Sized, @@ -231,7 +232,7 @@ where /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "write_place"] -pub unsafe trait WritePlace: DerefPlace +pub unsafe trait WritePlace: PlaceProxy where S: Subplace, S::Target: Sized, @@ -263,10 +264,10 @@ where /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "borrow_place"] -pub unsafe trait BorrowPlace: DerefPlace +pub unsafe trait BorrowPlace: PlaceProxy where S: Subplace, - X: DerefPlace, + X: PlaceProxy, { /// Whether the borrow operation is safe when used through the operator. /// @@ -319,7 +320,7 @@ where /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "drop_place"] -pub unsafe trait DropPlace: DerefPlace +pub unsafe trait DropPlace: PlaceProxy where S: Subplace, { @@ -349,7 +350,7 @@ where /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "drop_husk"] -pub unsafe trait DropHusk: DerefPlace { +pub unsafe trait DropHusk: PlaceProxy { /// Drops the /// /// # Safety @@ -369,10 +370,10 @@ pub unsafe trait DropHusk: DerefPlace { /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "nest_place"] -pub unsafe trait NestPlace: DerefPlace +pub unsafe trait NestPlace: PlaceProxy where S: Subplace, - S::Target: DerefPlace, + S::Target: PlaceProxy, { /// Obtain a raw pointer to the subplace contained by `this`. /// @@ -395,7 +396,7 @@ where /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] #[lang = "wrap_place"] -pub unsafe trait WrapPlace: DerefPlace +pub unsafe trait WrapPlace: PlaceProxy where S: Subplace, { diff --git a/tests/ui/feature-gates/feature-gate-field-projections.rs b/tests/ui/feature-gates/feature-gate-field-projections.rs index ac17f1fc6afc2..d5f6451e7dd1a 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.rs +++ b/tests/ui/feature-gates/feature-gate-field-projections.rs @@ -4,7 +4,7 @@ use std::field::Field; //~ ERROR: use of unstable library feature `field_project use std::ops::place::Subplace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::field::field_of; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::DropHusk; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::place::DerefPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::PlaceProxy; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::BorrowPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::NestPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::DropPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] @@ -28,7 +28,7 @@ where struct MyPtr(*mut T); -impl DerefPlace for MyPtr { +impl PlaceProxy for MyPtr { //~^ ERROR: use of unstable library feature `field_projections` [E0658] type Target = T; //~ ERROR: use of unstable library feature `field_projections` [E0658] } @@ -130,7 +130,7 @@ where S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] - S::Target: DerefPlace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: PlaceProxy, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] { unsafe fn nested(this: *const Self, sub: S) -> *const S::Target { @@ -146,7 +146,7 @@ where S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] - S::Target: Sized + DerefPlace, //~ ERROR: use of unstable library feature `field_projections` [E0658] + S::Target: Sized + PlaceProxy, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] { unsafe { @@ -161,7 +161,7 @@ where struct MyWrapper(T); -impl DerefPlace for MyWrapper { +impl PlaceProxy for MyWrapper { //~^ ERROR: use of unstable library feature `field_projections` [E0658] type Target = T; //~ ERROR: use of unstable library feature `field_projections` [E0658] } diff --git a/tests/ui/feature-gates/feature-gate-field-projections.stderr b/tests/ui/feature-gates/feature-gate-field-projections.stderr index 379cf46684b79..da3aaaeaf717c 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.stderr +++ b/tests/ui/feature-gates/feature-gate-field-projections.stderr @@ -51,7 +51,7 @@ LL | use std::ops::place::DropHusk; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:7:5 | -LL | use std::ops::place::DerefPlace; +LL | use std::ops::place::PlaceProxy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -151,7 +151,7 @@ LL | type Target = T; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:31:17 | -LL | impl DerefPlace for MyPtr { +LL | impl PlaceProxy for MyPtr { | ^^^^^^^^^^ | = note: see issue #145383 for more information @@ -371,7 +371,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:133:16 | -LL | S::Target: DerefPlace, +LL | S::Target: PlaceProxy, | ^^^^^^^^^^ | = note: see issue #145383 for more information @@ -401,7 +401,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:149:24 | -LL | S::Target: Sized + DerefPlace, +LL | S::Target: Sized + PlaceProxy, | ^^^^^^^^^^ | = note: see issue #145383 for more information @@ -481,7 +481,7 @@ LL | type Target = T; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:164:17 | -LL | impl DerefPlace for MyWrapper { +LL | impl PlaceProxy for MyWrapper { | ^^^^^^^^^^ | = note: see issue #145383 for more information @@ -851,7 +851,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:133:5 | -LL | S::Target: DerefPlace, +LL | S::Target: PlaceProxy, | ^^^^^^^^^ | = note: see issue #145383 for more information @@ -882,7 +882,7 @@ LL | S: Subplace, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:149:5 | -LL | S::Target: Sized + DerefPlace, +LL | S::Target: Sized + PlaceProxy, | ^^^^^^^^^ | = note: see issue #145383 for more information From 80bd3083dc960c582cd5fbe96150a730c826f03f Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Thu, 23 Apr 2026 20:22:08 +0200 Subject: [PATCH 17/20] TOSQUASH: rename NestPlace to DerefPlace --- compiler/rustc_hir/src/lang_items.rs | 4 ++-- compiler/rustc_span/src/symbol.rs | 4 ++-- library/core/src/ops/place.rs | 14 ++++++------- .../feature-gate-field-projections.rs | 8 ++++---- .../feature-gate-field-projections.stderr | 20 +++++++++---------- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 0c161605a168b..164485aa03f01 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -475,8 +475,8 @@ language_item_table! { BorrowPlaceSafety, sym::borrow_place_safety, borrow_place_safety, Target::AssocConst, GenericRequirement::Exact(2); BorrowPlaceBorrow, sym::borrow_place_borrow, borrow_place_borrow, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(2); - NestPlace, sym::nest_place, nest_place, Target::Trait, GenericRequirement::Exact(1); - NestPlaceNested, sym::nest_place_nested, nest_place_nested, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); + DerefPlace, sym::deref_place, deref_place, Target::Trait, GenericRequirement::Exact(1); + DerefPlaceNested, sym::deref_place_deref, deref_place_deref, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); WrapPlace, sym::wrap_place, wrap_place, Target::Trait, GenericRequirement::Exact(1); WrapPlaceWrapped, sym::wrap_place_wrapped, wrap_place_wrapped, Target::AssocTy, GenericRequirement::Exact(1); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d1475adb35dcc..06813cb9d2c45 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -791,6 +791,8 @@ symbols! { deref_method, deref_mut, deref_patterns, + deref_place, + deref_place_deref, deref_pure, deref_target, derive, @@ -1361,8 +1363,6 @@ symbols! { negative_bounds, negative_impls, neon, - nest_place, - nest_place_nested, nested, never, never_patterns, diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index 5a9de271e7287..5edb17e2b730a 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -81,7 +81,7 @@ //! - moving out of a subplace [`MovePlace`], //! - dropping a subplace [`DropPlace`] and dropping a fully moved-out pointer //! [`DropHusk`], and -//! - support for accessing a nested pointer [`NestPlace`]. +//! - support for accessing a nested pointer [`DerefPlace`]. //! //! ### Place Wrappers //! @@ -176,7 +176,7 @@ pub unsafe trait Subplace: Sized { /// - [`MovePlace`] /// - [`DropPlace`] /// - [`DropHusk`] -/// - [`NestPlace`] +/// - [`DerefPlace`] /// - [`WrapPlace`] /// /// Read the [module](self) description for more information. @@ -363,14 +363,14 @@ pub unsafe trait DropHusk: PlaceProxy { /// Accessing a nested pointer. /// /// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a -/// combination of the corresponding operation and a [`NestPlace::nested`]. +/// combination of the corresponding operation and a [`DerefPlace::nested`]. /// /// # Safety /// /// See the module-level section on [safety](crate::ops::place#safety). #[unstable(feature = "field_projections", issue = "145383")] -#[lang = "nest_place"] -pub unsafe trait NestPlace: PlaceProxy +#[lang = "deref_place"] +pub unsafe trait DerefPlace: PlaceProxy where S: Subplace, S::Target: PlaceProxy, @@ -380,8 +380,8 @@ where /// # Safety /// /// See the module-level section on [safety](crate::ops::place#safety). - #[lang = "nest_place_nested"] - unsafe fn nested(this: *const Self, sub: S) -> *const S::Target; + #[lang = "deref_place_deref"] + unsafe fn deref(this: *const Self, sub: S) -> *const S::Target; } /// Forwards the subplace `S` of the place contained by this. diff --git a/tests/ui/feature-gates/feature-gate-field-projections.rs b/tests/ui/feature-gates/feature-gate-field-projections.rs index d5f6451e7dd1a..f1dec485bbb31 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.rs +++ b/tests/ui/feature-gates/feature-gate-field-projections.rs @@ -6,7 +6,7 @@ use std::field::field_of; //~ ERROR: use of unstable library feature `field_proj use std::ops::place::DropHusk; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::PlaceProxy; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::BorrowPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] -use std::ops::place::NestPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] +use std::ops::place::DerefPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::DropPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::MovePlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] use std::ops::place::ReadPlace; //~ ERROR: use of unstable library feature `field_projections` [E0658] @@ -124,7 +124,7 @@ where } } -unsafe impl NestPlace for MyPtr +unsafe impl DerefPlace for MyPtr //~^ ERROR: use of unstable library feature `field_projections` [E0658] where S: Subplace, //~ ERROR: use of unstable library feature `field_projections` [E0658] @@ -133,7 +133,7 @@ where S::Target: PlaceProxy, //~ ERROR: use of unstable library feature `field_projections` [E0658] //~^ ERROR: use of unstable library feature `field_projections` [E0658] { - unsafe fn nested(this: *const Self, sub: S) -> *const S::Target { + unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] let _ = (this, sub); @@ -153,7 +153,7 @@ where let value = ReadPlace::read(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] WritePlace::write(place, sub(), value); //~ ERROR: use of unstable library feature `field_projections` [E0658] let _ = BorrowPlace::<_, MyPtr<_>>::borrow(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] - let _ = NestPlace::nested(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] + let _ = DerefPlace::deref(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] DropPlace::drop(place, sub()); //~ ERROR: use of unstable library feature `field_projections` [E0658] DropHusk::drop_husk(place); //~ ERROR: use of unstable library feature `field_projections` [E0658] } diff --git a/tests/ui/feature-gates/feature-gate-field-projections.stderr b/tests/ui/feature-gates/feature-gate-field-projections.stderr index da3aaaeaf717c..bffcea1b769c2 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.stderr +++ b/tests/ui/feature-gates/feature-gate-field-projections.stderr @@ -71,8 +71,8 @@ LL | use std::ops::place::BorrowPlace; error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:9:5 | -LL | use std::ops::place::NestPlace; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | use std::ops::place::DerefPlace; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -351,8 +351,8 @@ LL | unsafe impl BorrowPlace> for MyPtr error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:136:5 | -LL | unsafe fn nested(this: *const Self, sub: S) -> *const S::Target { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -381,8 +381,8 @@ LL | S::Target: PlaceProxy, error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:127:19 | -LL | unsafe impl NestPlace for MyPtr - | ^^^^^^^^^^^^ +LL | unsafe impl DerefPlace for MyPtr + | ^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -441,7 +441,7 @@ LL | ... let _ = BorrowPlace::<_, MyPtr<_>>::borrow(place, sub()); error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:156:17 | -LL | let _ = NestPlace::nested(place, sub()); +LL | let _ = DerefPlace::deref(place, sub()); | ^^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information @@ -704,10 +704,10 @@ LL | S: Subplace, = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `field_projections` - --> $DIR/feature-gate-field-projections.rs:136:59 + --> $DIR/feature-gate-field-projections.rs:136:58 | -LL | unsafe fn nested(this: *const Self, sub: S) -> *const S::Target { - | ^^^^^^^^^ +LL | unsafe fn deref(this: *const Self, sub: S) -> *const S::Target { + | ^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable From 159ce3524e0e3a2268fd0899f54d6178645e3ebc Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Fri, 24 Apr 2026 13:32:00 +0200 Subject: [PATCH 18/20] TOSQUASH: rename `const SAFETY` to `const SAFE` --- compiler/rustc_hir/src/lang_items.rs | 6 +++--- compiler/rustc_span/src/symbol.rs | 6 +++--- library/core/src/ops/place.rs | 18 +++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 164485aa03f01..05c93d4aa57dc 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -456,11 +456,11 @@ language_item_table! { PlaceProxyTarget, sym::place_proxy_target, place_proxy_target, Target::AssocTy, GenericRequirement::Exact(0); ReadPlace, sym::read_place, read_place, Target::Trait, GenericRequirement::Exact(1); - ReadPlaceSafety, sym::read_place_safety, read_place_safety, Target::AssocConst, GenericRequirement::Exact(1); + ReadPlaceSafety, sym::read_place_safe, read_place_safe, Target::AssocConst, GenericRequirement::Exact(1); ReadPlaceRead, sym::read_place_read, read_place_read, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); WritePlace, sym::write_place, write_place, Target::Trait, GenericRequirement::Exact(1); - WritePlaceSafety, sym::write_place_safety, write_place_safety, Target::AssocConst, GenericRequirement::Exact(1); + WritePlaceSafety, sym::write_place_safe, write_place_safe, Target::AssocConst, GenericRequirement::Exact(1); WritePlaceWrite, sym::write_place_write, write_place_write, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1); MovePlace, sym::move_place, move_place, Target::Trait, GenericRequirement::Exact(1); @@ -472,7 +472,7 @@ language_item_table! { DropHuskDropHusk, sym::drop_husk_drop_husk, drop_husk_drop_husk, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0); BorrowPlace, sym::borrow_place, borrow_place, Target::Trait, GenericRequirement::Exact(2); - BorrowPlaceSafety, sym::borrow_place_safety, borrow_place_safety, Target::AssocConst, GenericRequirement::Exact(2); + BorrowPlaceSafety, sym::borrow_place_safe, borrow_place_safe, Target::AssocConst, GenericRequirement::Exact(2); BorrowPlaceBorrow, sym::borrow_place_borrow, borrow_place_borrow, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(2); DerefPlace, sym::deref_place, deref_place, Target::Trait, GenericRequirement::Exact(1); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 06813cb9d2c45..ec25ec4079963 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -530,7 +530,7 @@ symbols! { bool, borrow_place, borrow_place_borrow, - borrow_place_safety, + borrow_place_safe, borrowck_graphviz_format, borrowck_graphviz_postflow, box_new, @@ -1624,7 +1624,7 @@ symbols! { re_rebalance_coherence, read_place, read_place_read, - read_place_safety, + read_place_safe, read_via_copy, readonly, realloc, @@ -2295,7 +2295,7 @@ symbols! { write_fmt, write_macro, write_place, - write_place_safety, + write_place_safe, write_place_write, write_str, write_via_move, diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index 5edb17e2b730a..bb7d8296fade3 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -117,14 +117,14 @@ //! not allowed. //! //! The safety of using the place operations via the operators will depend on -//! the value of the `SAFETY` constant in the operation traits. At the moment we +//! the value of the `SAFE` constant in the operation traits. At the moment we //! will only permit a literal value of `true` or `false` in implementations. It //! will dictate if people have to write for example `unsafe { &*ptr }` or if //! `*ptr` is allowed. It should be set to `true` when the borrow checker's //! guarantees of either disjoint subplaces or "all concurrent operations are //! shared" are enough to calling the operations' function correctly. If there -//! are additional requirements, such as "ptr is valid", then `SAFETY` should be -//! set to `false`. For example, `&mut T` will have `SAFETY = true` in +//! are additional requirements, such as "ptr is valid", then `SAFE` should be +//! set to `false`. For example, `&mut T` will have `SAFE = true` in //! [`ReadPlace`], but `NonNull` will set it to `false`. use crate::ptr::Pointee; @@ -207,8 +207,8 @@ where /// When the operator is used, the borrow checker follows its usual rules to /// ensure that no other operation conflicts with this one. If that alone is /// sufficient to make this operation sound, then this should be `true`. - #[lang = "read_place_safety"] - const SAFETY: bool; + #[lang = "read_place_safe"] + const SAFE: bool; /// Reads the subplace pointed to by `this`. /// @@ -242,8 +242,8 @@ where /// When the operator is used, the borrow checker follows its usual rules to /// ensure that no other operation conflicts with this one. If that alone is /// sufficient to make this operation sound, then this should be `true`. - #[lang = "write_place_safety"] - const SAFETY: bool; + #[lang = "write_place_safe"] + const SAFE: bool; /// Writes to the subplace pointed to by `this`. /// @@ -274,8 +274,8 @@ where /// When the operator is used, the borrow checker follows its usual rules to /// ensure that no other operation conflicts with this one. If that alone is /// sufficient to make this operation sound, then this should be `true`. - #[lang = "borrow_place_safety"] - const SAFETY: bool; + #[lang = "borrow_place_safe"] + const SAFE: bool; // FIXME: this is missing some associated items related to controlling the // borrow checker. The details need to still be worked out in a-mir-formality. From 5f8769e161aa0abc75df7fcea1148ef8aaceff9e Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Fri, 24 Apr 2026 13:32:12 +0200 Subject: [PATCH 19/20] TOSQUASH: improve documentation --- library/core/src/ops/place.rs | 90 +++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/library/core/src/ops/place.rs b/library/core/src/ops/place.rs index bb7d8296fade3..babb652bb90a1 100644 --- a/library/core/src/ops/place.rs +++ b/library/core/src/ops/place.rs @@ -18,14 +18,14 @@ //! //! A *place* in Rust is a particular location in memory. They are represented //! by [*place expressions*][ref-place-exprs], which take on the following form: -//! - `$path`: paths that refer to locals variables (also parameters), statics, -//! constants, and functions. -//! - `|$args...| $body`: closure expressions, -//! - `$place as $ty`: certain `as`-casts of another place expression, +//! - `$path`: paths that refer to locals variables (also parameters) and +//! statics, //! - `*$place`: dereferences of another place expression, //! - `$place[$expr]`: indexing operation of another place expression, //! - `$place.$ident`: field access of another place expression, //! - `($place)`: parenthesized place expressions, +//! - `$value`: value expressions can be coerced to a temporary place whose +//! lifetime is determined from its context, //! //! Further reading: //! - @@ -33,20 +33,23 @@ //! //! [ref-place-exprs]: https://doc.rust-lang.org/reference/expressions.html#r-expr.place-value.place-expr-kinds //! -//! ## Operation Traits +//! ## Place Proxies //! -//! Place operations are implemented by types that reference/contain/represent a -//! place. This is because places are not part of the type system of Rust; a -//! place expression has the type of the values that are contained in the place. -//! The [`PlaceProxy`] trait marks a type as containing a place; it also records -//! which type the values contained within the place have. +//! Places and place expressions are not part of the type system of Rust and +//! therefore cannot implement traits. To still be able to customize place +//! operations via traits, they are implemented for types that act as a proxy +//! for the place. Such types are called *place proxies* and they implement the +//! [`PlaceProxy`] trait. Elements of a place proxy type denote/represent one +//! specific place. Such an element can be dereferenced, which results in a +//! place expression denoting the represented place. This is a normal place +//! expression that can be used to perform place operations or can be composed +//! into a bigger place expression. +//! +//! Place operations performed on the represented place are implemented by the +//! corresponding place operation trait of this module. This trait must be +//! implemented for the place's proxy type, otherwise the compiler will emit an +//! error: //! -//! When a type `X` implements [`PlaceProxy`], values of type `X` can be -//! dereferenced, which results in a place that can be read from, written to, or -//! borrowed. Any of those place operations are implemented by the corresponding -//! place operation trait on the value the place originated from. This means -//! that the operations are only available if `X` implements the corresponding -//! place operation trait: //! - reading [`ReadPlace`], //! - writing [`WritePlace`], and //! - borrowing [`BorrowPlace`]. @@ -58,12 +61,11 @@ //! ### Subplaces //! //! Place operations are allowed to target only a *subplace*. For example -//! `my_struct.field = 42;` writes to only the `field` subplace. However, -//! the operations traits are always applied to a type that references the -//! *entire* place, since there is no type system level construct that -//! represents only the subplace. For this reason, all operation traits have a -//! generic argument implementing the [`Subplace`] trait that specifies the -//! subplace that the operation should affect. +//! `my_struct.field = 42;` writes to only the `field` subplace. Since places +//! are operated upon through their proxy, which represents the *entire* place, +//! each operation has a generic parameter denoting the subplace the operation +//! is targeting. This generic implements the [`Subplace`] trait, which contains +//! all the information describing the targeted subplace. //! //! Note that the [`Subplace`] trait also can represent the entire place in case //! the operation affects the entire place (for example `let x = *ptr;`). @@ -71,13 +73,13 @@ //! This generic argument is supplied by the compiler when desugaring a place //! operation into the corresponding place operation trait function call. There //! is a direct translation from place expressions to types implementing the -//! [`Subplace`] trait (these are compiler-internal). +//! [`Subplace`] trait. //! //! ### Implicit Operations //! //! In addition to the three visible operations, there are several other -//! *implicit* operations that allow full customization of types implementing -//! [`PlaceProxy`]: +//! *implicit* operations that can be implemented for place proxies: +//! //! - moving out of a subplace [`MovePlace`], //! - dropping a subplace [`DropPlace`] and dropping a fully moved-out pointer //! [`DropHusk`], and @@ -85,13 +87,14 @@ //! //! ### Place Wrappers //! -//! Place wrappers are types that implement the [`WrapPlace`] trait. They modify -//! subplaces contained by their value. For example [`MaybeUninit`] has all -//! fields that `T` has (it forwards all subplaces of `T`), but those subplaces -//! have `MaybeUninit` as the type instead of `U`. Given `Struct` with a -//! field of type `Field` called `field`, we can write `val.field` (this has -//! type `Field`) given `val: Struct`; we can also write `val.field` given `val: -//! MaybeUninit` and then `val.field: MaybeUninit`. +//! Place wrappers are a special kind of place proxy. They "physically contain" +//! the place they are proxying for. A good example is [`MaybeUninit`]. To +//! support subplaces of these place wrappers, the [`WrapPlace`] trait exists. +//! It allows forwarding subplaces to the proxy and changing the subplace access +//! information. With [`MaybeUninit`], this allows accessing any subplace +//! under the transformation that it's type is wrapped in `MaybeUninit`. So +//! Given `&MaybeUninit`, the `field` subplace can be borrowed using `&` +//! and it has type `&MaybeUninit`. //! //! [`MaybeUninit`]: crate::mem::MaybeUninit //! @@ -165,14 +168,16 @@ pub unsafe trait Subplace: Sized { /// Marks a type as a place proxy. /// /// A place proxy can be dereferenced (`*val`). This results in a place for -/// which any place operation is implemented by this type instead. The operation -/// is available only if the corresponding place operation trait is implemented: +/// which any place operation is implemented by this type. The operation is +/// available only if the corresponding place operation trait is implemented: +/// /// - [`ReadPlace`] /// - [`WritePlace`] /// - [`BorrowPlace`] /// /// Furthermore, there are implicit place operations that can be supported by /// types implementing this trait: +/// /// - [`MovePlace`] /// - [`DropPlace`] /// - [`DropHusk`] @@ -333,10 +338,10 @@ where unsafe fn drop(this: *const Self, sub: S); } -/// Dropping a pointer that points at a fully moved-out place. +/// Dropping an empty place proxy. /// -/// This operation is emitted by the compiler when a pointer is being dropped -/// that had all of its fields moved out. +/// This operation is emitted by the compiler when a place proxy is being +/// dropped where all fields of the represented place were moved out. /// /// If no fields or only some fields have been moved out, all not yet moved out /// fields are dropped with the [`DropPlace`] trait. After that this pointer is @@ -345,6 +350,11 @@ where /// Note that a write operation ([`WritePlace`]) can move a value into a /// previously moved-out field. /// +/// This trait cannot be implemented at the same time as [`Drop`], since it +/// generalizes it. When this trait is implemented, dropping a value of type +/// `Self` is done by first dropping the represented place using [`DropPlace`] +/// and then calling drop_husk. +/// /// # Safety /// /// See the module-level section on [safety](crate::ops::place#safety). @@ -360,10 +370,10 @@ pub unsafe trait DropHusk: PlaceProxy { unsafe fn drop_husk(this: *const Self); } -/// Accessing a nested pointer. +/// Accessing a nested proxy. /// -/// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a -/// combination of the corresponding operation and a [`DerefPlace::nested`]. +/// When `x: Self`, then nested dereferences `let _ = **x;` are desugared into a +/// combination of the corresponding operation and [`DerefPlace::deref`]. /// /// # Safety /// From ded037a463a7734bc361b6eeb55b38a932b2f863 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Fri, 24 Apr 2026 13:50:37 +0200 Subject: [PATCH 20/20] fixup! TOSQUASH: rename `const SAFETY` to `const SAFE` --- .../feature-gates/feature-gate-field-projections.rs | 6 +++--- .../feature-gate-field-projections.stderr | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/ui/feature-gates/feature-gate-field-projections.rs b/tests/ui/feature-gates/feature-gate-field-projections.rs index f1dec485bbb31..a5123987a8541 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.rs +++ b/tests/ui/feature-gates/feature-gate-field-projections.rs @@ -42,7 +42,7 @@ where //~^^ ERROR: use of unstable library feature `field_projections` [E0658] S::Target: Sized, //~ ERROR: use of unstable library feature `field_projections` [E0658] { - const SAFETY: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] + const SAFE: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] unsafe fn read(this: *const Self, sub: S) -> S::Target { //~^ ERROR: use of unstable library feature `field_projections` [E0658] @@ -61,7 +61,7 @@ where //~^^ ERROR: use of unstable library feature `field_projections` [E0658] S::Target: Sized, //~ ERROR: use of unstable library feature `field_projections` [E0658] { - const SAFETY: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] + const SAFE: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] unsafe fn write(this: *const Self, sub: S, value: S::Target) { //~^ ERROR: use of unstable library feature `field_projections` [E0658] @@ -114,7 +114,7 @@ where //~^ ERROR: use of unstable library feature `field_projections` [E0658] //~^^ ERROR: use of unstable library feature `field_projections` [E0658] { - const SAFETY: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] + const SAFE: bool = true; //~ ERROR: use of unstable library feature `field_projections` [E0658] unsafe fn borrow(this: *const Self, sub: S) -> MyPtr { //~^ ERROR: use of unstable library feature `field_projections` [E0658] diff --git a/tests/ui/feature-gates/feature-gate-field-projections.stderr b/tests/ui/feature-gates/feature-gate-field-projections.stderr index bffcea1b769c2..e67bc79ca070e 100644 --- a/tests/ui/feature-gates/feature-gate-field-projections.stderr +++ b/tests/ui/feature-gates/feature-gate-field-projections.stderr @@ -161,8 +161,8 @@ LL | impl PlaceProxy for MyPtr { error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:45:5 | -LL | const SAFETY: bool = true; - | ^^^^^^^^^^^^^^^^^^ +LL | const SAFE: bool = true; + | ^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -201,8 +201,8 @@ LL | unsafe impl ReadPlace for MyPtr error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:64:5 | -LL | const SAFETY: bool = true; - | ^^^^^^^^^^^^^^^^^^ +LL | const SAFE: bool = true; + | ^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable @@ -311,8 +311,8 @@ LL | unsafe impl DropHusk for MyPtr { error[E0658]: use of unstable library feature `field_projections` --> $DIR/feature-gate-field-projections.rs:117:5 | -LL | const SAFETY: bool = true; - | ^^^^^^^^^^^^^^^^^^ +LL | const SAFE: bool = true; + | ^^^^^^^^^^^^^^^^ | = note: see issue #145383 for more information = help: add `#![feature(field_projections)]` to the crate attributes to enable