Skip to content

Commit 09ec036

Browse files
authored
Unrolled build for #145726
Rollup merge of #145726 - aapoalas:reborrow-lang-experiment, r=petrochenkov Experiment: Reborrow trait Tracking issue: #145612 Starting off really small here: just introduce the unstable feature and the feature gate, and one of the two traits that the Reborrow experiment deals with. ### Cliff-notes explanation The `Reborrow` trait is conceptually a close cousin of `Copy` with the exception that it disables the source (`self`) for the lifetime of the target / result of the reborrow action. It can be viewed as a method of `fn reborrow(self: Self<'a>) -> Self<'a>` with the compiler adding tracking of the resulting `Self<'a>` (or any value derived from it that retains the `'a` lifetime) to keep the `self` disabled for reads and writes. No method is planned to be surfaced to the user, however, as reborrowing cannot be seen in code (except for method calls [`a.foo()` reborrows `a`] and explicit reborrows [`&*a`]) and thus triggering user-code in it could be viewed as "spooky action at a distance". Furthermore, the added compiler tracking cannot be seen on the method itself, violating the Golden Rule. Note that the userland "reborrow" method is not True Reborrowing, but rather a form of a "Fancy Deref": ```rust fn reborrow(&'short self: Self<'long>) -> Self<'short>; ``` The lifetime shortening is the issue here: a reborrowed `Self` or any value derived from it is bound to the method that called `reborrow`, since `&'short` is effectively a local variable. True Reborrowing does not shorten the lifetime of the result. To avoid having to introduce new kinds of references, new kinds of lifetime annotations, or a blessed trait method, no method will be introduced at all. Instead, the `Reborrow` trait is intended to be a derived trait that effectively reborrows each field individually; `Copy` fields end up just copying, while fields that themselves `Reborrow` get disabled in the source, usually leading to the source itself being disabled (some differences may appear with structs that contain multiple reborrowable fields). The goal of the experiment is to determine how the actual implementation here will shape out, and what the "bottom case" for the recursive / deriving `Reborrow` is. `Reborrow` has a friend trait, `CoerceShared`, which is equivalent to a `&'a mut T -> &'a T` conversion. This is needed as a different trait and different operation due to the different semantics it enforces on the source: a `CoerceShared` operation only disables the source for writes / exclusive access for the lifetime of the result. That trait is not yet introduced in this PR, though there is no particular reason why it could not be introduced.
2 parents 78b89eb + fd44708 commit 09ec036

File tree

7 files changed

+30
-0
lines changed

7 files changed

+30
-0
lines changed

compiler/rustc_feature/src/unstable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ declare_features! (
614614
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
615615
/// Allows the use of raw-dylibs on ELF platforms
616616
(incomplete, raw_dylib_elf, "1.87.0", Some(135694)),
617+
(unstable, reborrow, "CURRENT_RUSTC_VERSION", Some(145612)),
617618
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
618619
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
619620
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant

compiler/rustc_hir/src/lang_items.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,9 @@ language_item_table! {
437437
DefaultTrait1, sym::default_trait1, default_trait1_trait, Target::Trait, GenericRequirement::None;
438438

439439
ContractCheckEnsures, sym::contract_check_ensures, contract_check_ensures_fn, Target::Fn, GenericRequirement::None;
440+
441+
// Reborrowing related lang-items
442+
Reborrow, sym::reborrow, reborrow, Target::Trait, GenericRequirement::Exact(0);
440443
}
441444

442445
/// The requirement imposed on the generics of a lang item

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,7 @@ symbols! {
17541754
readonly,
17551755
realloc,
17561756
reason,
1757+
reborrow,
17571758
receiver,
17581759
receiver_target,
17591760
recursion_limit,

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
#![feature(no_core)]
173173
#![feature(optimize_attribute)]
174174
#![feature(prelude_import)]
175+
#![feature(reborrow)]
175176
#![feature(repr_simd)]
176177
#![feature(rustc_allow_const_fn_unstable)]
177178
#![feature(rustc_attrs)]

library/core/src/marker.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,3 +1365,11 @@ pub macro CoercePointee($item:item) {
13651365
pub trait CoercePointeeValidated {
13661366
/* compiler built-in */
13671367
}
1368+
1369+
/// Allows value to be reborrowed as exclusive, creating a copy of the value
1370+
/// that disables the source for reads and writes for the lifetime of the copy.
1371+
#[lang = "reborrow"]
1372+
#[unstable(feature = "reborrow", issue = "145612")]
1373+
pub trait Reborrow {
1374+
// Empty.
1375+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
use std::marker::Reborrow; //~ ERROR use of unstable library feature `reborrow`
2+
3+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0658]: use of unstable library feature `reborrow`
2+
--> $DIR/feature-gate-reborrow.rs:1:5
3+
|
4+
LL | use std::marker::Reborrow;
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #145612 <https://github.com/rust-lang/rust/issues/145612> for more information
8+
= help: add `#![feature(reborrow)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)