Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d4e4f9a
Use print instead of po in debuginfo path test
fallofpheonix May 20, 2026
1521455
Add share_trait feature gate
P8L1 May 21, 2026
e5a6796
Add unstable Share trait
P8L1 May 21, 2026
02109ee
Implement Share for shared references
P8L1 May 21, 2026
d082ac9
Tighten initial Share trait implementation
P8L1 May 21, 2026
fc33b6d
Add Share impl for Rc
P8L1 May 21, 2026
78b0f9d
Add Share impl for Arc
P8L1 May 21, 2026
4b32cb2
Add Share impl for mpsc Sender
P8L1 May 21, 2026
4a32c28
Add Share impl for mpsc SyncSender
P8L1 May 21, 2026
71bcc49
Update Share non-implementor diagnostics
P8L1 May 21, 2026
65f4151
Fix reborrow_info early return skipping field validation
ikow May 21, 2026
9b3cd57
Remove provisional Share trait FIXME notes
P8L1 May 22, 2026
c01e320
Document unstable Share trait semantics
P8L1 May 22, 2026
3a6cb05
Add `#[doc(alias = "phi")]` for float GOLDEN_RATIO constants
okaneco May 22, 2026
501ab4e
Clarify Share trait docs
P8L1 May 22, 2026
fb2751b
float_literal_f32_fallback: Don't suggest invalid code
SpecificProtagonist May 22, 2026
2f953da
Remove unnecessary Share feature gate plumbing
P8L1 May 23, 2026
6ed5bf2
Remove po checks from debuginfo path test
fallofpheonix May 23, 2026
0ff74c9
Fix Pieter-Louis Schoeman mailmap entry
P8L1 May 23, 2026
4474668
Rollup merge of #156769 - fallofpheonix:fix-path-lldb-macos, r=jieyouxu
JonathanBrouwer May 24, 2026
f38e177
Rollup merge of #156784 - ikow:fix/reborrow-early-return, r=dingxiang…
JonathanBrouwer May 24, 2026
e938cd8
Rollup merge of #156827 - SpecificProtagonist:float_literal_f32_fallb…
JonathanBrouwer May 24, 2026
eb68b36
Rollup merge of #156828 - P8L1:share-trait-core-bootstrap, r=SimonSapin
JonathanBrouwer May 24, 2026
e8d2321
Rollup merge of #156830 - okaneco:phi_doc_alias, r=SimonSapin
JonathanBrouwer May 24, 2026
2843641
Rollup merge of #156860 - P8L1:fix/pieter-louis-schoeman-mailmap, r=j…
JonathanBrouwer May 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ Philipp Matthias Schäfer <philipp.matthias.schaefer@posteo.de>
phosphorus <steepout@qq.com>
Pierre Krieger <pierre.krieger1708@gmail.com>
pierwill <pierwill@users.noreply.github.com> <19642016+pierwill@users.noreply.github.com>
Pieter-Louis Schoeman <pl.schoeman44@gmail.com> <127837395+P8L1@users.noreply.github.com>
Pietro Albini <pietro@pietroalbini.org> <pietro@pietroalbini.io>
Pietro Albini <pietro@pietroalbini.org> <pietro.albini@ferrous-systems.com>
Pradyumna Rahul <prkinformed@gmail.com>
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,8 @@ pub(crate) fn reborrow_info<'tcx>(
)
.is_ok()
{
// Field implements Reborrow.
return Ok(());
// Field implements Reborrow, check remaining fields.
continue;
}

// Field does not implement Reborrow: it must be Copy.
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_hir_typeck/src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,13 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
.inspect(|vid| {
let origin = self.float_var_origin(*vid);
// Show the entire literal in the suggestion to make it clearer.
let literal = self.tcx.sess.source_map().span_to_snippet(origin.span).ok();
let mut literal = self.tcx.sess.source_map().span_to_snippet(origin.span).ok();
// A `.` at the end of the literal is no longer necessary if `f32` is explicitly specified
if let Some(ref mut literal) = literal
&& literal.ends_with('.')
{
literal.pop();
}
self.tcx.emit_node_span_lint(
FLOAT_LITERAL_F32_FALLBACK,
origin.lint_id.unwrap_or(CRATE_HIR_ID),
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
#![feature(ptr_metadata)]
#![feature(rev_into_inner)]
#![feature(set_ptr_value)]
#![feature(share_trait)]
#![feature(sized_type_properties)]
#![feature(slice_from_ptr_range)]
#![feature(slice_index_methods)]
Expand Down
5 changes: 4 additions & 1 deletion library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ use core::any::Any;
use core::cell::{Cell, CloneFromCell};
#[cfg(not(no_global_oom_handling))]
use core::clone::TrivialClone;
use core::clone::{CloneToUninit, UseCloned};
use core::clone::{CloneToUninit, Share, UseCloned};
use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
use core::intrinsics::abort;
Expand Down Expand Up @@ -2525,6 +2525,9 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Rc<T, A> {
#[unstable(feature = "ergonomic_clones", issue = "132290")]
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Rc<T, A> {}

#[unstable(feature = "share_trait", issue = "156756")]
impl<T: ?Sized, A: Allocator + Clone> Share for Rc<T, A> {}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Rc<T> {
Expand Down
5 changes: 4 additions & 1 deletion library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use core::any::Any;
use core::cell::CloneFromCell;
#[cfg(not(no_global_oom_handling))]
use core::clone::TrivialClone;
use core::clone::{CloneToUninit, UseCloned};
use core::clone::{CloneToUninit, Share, UseCloned};
use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
use core::intrinsics::abort;
Expand Down Expand Up @@ -2436,6 +2436,9 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Arc<T, A> {
#[unstable(feature = "ergonomic_clones", issue = "132290")]
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Arc<T, A> {}

#[unstable(feature = "share_trait", issue = "156756")]
impl<T: ?Sized, A: Allocator + Clone> Share for Arc<T, A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized, A: Allocator> Deref for Arc<T, A> {
type Target = T;
Expand Down
89 changes: 88 additions & 1 deletion library/core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,90 @@ pub macro Clone($item:item) {
/* compiler built-in */
}

/// A trait for types whose [`Clone`] operation creates another alias to the same
/// logical resource or shared state.
///
/// `Share` marks types where cloning creates another handle, reference, or alias
/// to the same logical resource or shared state, rather than an independent owned
/// value. The distinction is semantic, not cost-based: implementing `Share` does
/// not merely mean that cloning is cheap, constant-time, allocation-free, or
/// convenient.
///
/// Calling [`share`](Share::share) is equivalent to calling [`clone`](Clone::clone)
/// for implementors, but communicates that the resulting value aliases the same
/// underlying resource.
///
/// Shared references, `Rc<T>`, `Arc<T>`, `Sender<T>`, and `SyncSender<T>` are
/// examples of types that can be shared this way. Types such as `Vec<T>`,
/// `String`, and `Box<T>` are not `Share` even though they implement `Clone`,
/// because cloning them creates another owned value rather than another handle
/// to the same logical resource.
///
/// # Examples
///
/// ```
/// #![feature(share_trait)]
///
/// use std::cell::Cell;
/// use std::clone::Share;
/// use std::rc::Rc;
/// use std::sync::{
/// Arc,
/// atomic::{AtomicUsize, Ordering},
/// };
///
/// let value = 1;
/// let reference = &value;
/// assert!(std::ptr::eq(reference, reference.share()));
///
/// let rc = Rc::new(Cell::new(2));
/// let shared_rc = rc.share();
/// assert!(Rc::ptr_eq(&rc, &shared_rc));
/// shared_rc.set(3);
/// assert_eq!(rc.get(), 3);
///
/// let arc = Arc::new(AtomicUsize::new(4));
/// let shared_arc = arc.share();
/// assert!(Arc::ptr_eq(&arc, &shared_arc));
/// shared_arc.store(5, Ordering::Relaxed);
/// assert_eq!(arc.load(Ordering::Relaxed), 5);
/// ```
///
/// ```
/// #![feature(share_trait)]
///
/// use std::clone::Share;
/// use std::sync::mpsc::{channel, sync_channel};
///
/// let (sender, receiver) = channel();
/// let shared_sender = sender.share();
/// sender.send(1).unwrap();
/// shared_sender.send(2).unwrap();
///
/// let mut received = [receiver.recv().unwrap(), receiver.recv().unwrap()];
/// received.sort();
/// assert_eq!(received, [1, 2]);
///
/// let (sync_sender, sync_receiver) = sync_channel(2);
/// let shared_sync_sender = sync_sender.share();
/// sync_sender.send(3).unwrap();
/// shared_sync_sender.send(4).unwrap();
///
/// let mut received = [sync_receiver.recv().unwrap(), sync_receiver.recv().unwrap()];
/// received.sort();
/// assert_eq!(received, [3, 4]);
/// ```
#[unstable(feature = "share_trait", issue = "156756")]
pub trait Share: Clone {
/// Creates another alias to the same underlying resource or shared state.
///
/// This is equivalent to calling [`Clone::clone`].
#[unstable(feature = "share_trait", issue = "156756")]
fn share(&self) -> Self {
Clone::clone(self)
}
}

/// Trait for objects whose [`Clone`] impl is lightweight (e.g. reference-counted)
///
/// Cloning an object implementing this trait should in general:
Expand Down Expand Up @@ -601,7 +685,7 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr {
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
/// in `rustc_trait_selection`.
mod impls {
use super::TrivialClone;
use super::{Share, TrivialClone};
use crate::marker::PointeeSized;

macro_rules! impl_clone {
Expand Down Expand Up @@ -689,6 +773,9 @@ mod impls {
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
unsafe impl<T: PointeeSized> const TrivialClone for &T {}

#[unstable(feature = "share_trait", issue = "156756")]
impl<T: PointeeSized> Share for &T {}

/// Shared references can be cloned, but mutable references *cannot*!
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PointeeSized> !Clone for &mut T {}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/num/f128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub mod consts {
pub const TAU: f128 = 6.28318530717958647692528676655900576839433879875021164194989_f128;

/// The golden ratio (φ)
#[doc(alias = "phi")]
#[unstable(feature = "f128", issue = "116909")]
pub const GOLDEN_RATIO: f128 =
1.61803398874989484820458683436563811772030917980576286213545_f128;
Expand Down
1 change: 1 addition & 0 deletions library/core/src/num/f16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub mod consts {
pub const TAU: f16 = 6.28318530717958647692528676655900577_f16;

/// The golden ratio (φ)
#[doc(alias = "phi")]
#[unstable(feature = "f16", issue = "116909")]
pub const GOLDEN_RATIO: f16 = 1.618033988749894848204586834365638118_f16;

Expand Down
1 change: 1 addition & 0 deletions library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ pub mod consts {
pub const TAU: f32 = 6.28318530717958647692528676655900577_f32;

/// The golden ratio (φ)
#[doc(alias = "phi")]
#[stable(feature = "euler_gamma_golden_ratio", since = "1.94.0")]
pub const GOLDEN_RATIO: f32 = 1.618033988749894848204586834365638118_f32;

Expand Down
1 change: 1 addition & 0 deletions library/core/src/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ pub mod consts {
pub const TAU: f64 = 6.28318530717958647692528676655900577_f64;

/// The golden ratio (φ)
#[doc(alias = "phi")]
#[stable(feature = "euler_gamma_golden_ratio", since = "1.94.0")]
pub const GOLDEN_RATIO: f64 = 1.618033988749894848204586834365638118_f64;

Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@
#![feature(random)]
#![feature(raw_os_error_ty)]
#![feature(seek_io_take_position)]
#![feature(share_trait)]
#![feature(slice_internals)]
#![feature(slice_ptr_get)]
#![feature(slice_range)]
Expand Down
8 changes: 8 additions & 0 deletions library/std/src/sync/mpsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@
// not exposed publicly, but if you are curious about the implementation,
// that's where everything is.

use core::clone::Share;

use crate::sync::mpmc;
use crate::time::{Duration, Instant};
use crate::{error, fmt};
Expand Down Expand Up @@ -645,6 +647,9 @@ impl<T> Clone for Sender<T> {
}
}

#[unstable(feature = "share_trait", issue = "156756")]
impl<T> Share for Sender<T> {}

#[stable(feature = "mpsc_debug", since = "1.8.0")]
impl<T> fmt::Debug for Sender<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -774,6 +779,9 @@ impl<T> Clone for SyncSender<T> {
}
}

#[unstable(feature = "share_trait", issue = "156756")]
impl<T> Share for SyncSender<T> {}

#[stable(feature = "mpsc_debug", since = "1.8.0")]
impl<T> fmt::Debug for SyncSender<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
4 changes: 0 additions & 4 deletions tests/debuginfo/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@

//@ lldb-command:print pathbuf
//@ lldb-check:[...] "/some/path" { inner = "/some/path" { inner = { inner = size=10 { [0] = '/' [1] = 's' [2] = 'o' [3] = 'm' [4] = 'e' [5] = '/' [6] = 'p' [7] = 'a' [8] = 't' [9] = 'h' } } } }
//@ lldb-command:po pathbuf
//@ lldb-check:"/some/path"
//@ lldb-command:print path
//@ lldb-check:[...] "/some/path" { data_ptr = [...] length = 10 }
//@ lldb-command:po path
//@ lldb-check:"/some/path"

use std::path::Path;

Expand Down
4 changes: 4 additions & 0 deletions tests/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,10 @@ In this directory, multiple crates are compiled, but some of them have `inline`

Tests on name shadowing.

## `tests/ui/share-trait`

Tests for the unstable `Share` trait.

## `tests/ui/shell-argfiles/`: `-Z shell-argfiles` command line flag

The `-Zshell-argfiles` compiler flag allows argfiles to be parsed using POSIX "shell-style" quoting. When enabled, the compiler will use shlex to parse the arguments from argfiles specified with `@shell:<path>`.
Expand Down
3 changes: 3 additions & 0 deletions tests/ui/float/f32-into-f32.next-solver.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ fn main() {
foo(1e5_f32);
//~^ WARN falling back to `f32`
//~| WARN this was previously accepted
foo(0_f32);
//~^ WARN falling back to `f32`
//~| WARN this was previously accepted
foo(4f32); // no warning
let x = -4.0_f32;
//~^ WARN falling back to `f32`
Expand Down
13 changes: 11 additions & 2 deletions tests/ui/float/f32-into-f32.next-solver.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,22 @@ LL | foo(1e5);
= note: for more information, see issue #154024 <https://github.com/rust-lang/rust/issues/154024>

warning: falling back to `f32` as the trait bound `f32: From<f64>` is not satisfied
--> $DIR/f32-into-f32.rs:19:14
--> $DIR/f32-into-f32.rs:18:9
|
LL | foo(0.);
| ^^ help: explicitly specify the type as `f32`: `0_f32`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154024 <https://github.com/rust-lang/rust/issues/154024>

warning: falling back to `f32` as the trait bound `f32: From<f64>` is not satisfied
--> $DIR/f32-into-f32.rs:22:14
|
LL | let x = -4.0;
| ^^^ help: explicitly specify the type as `f32`: `4.0_f32`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154024 <https://github.com/rust-lang/rust/issues/154024>

warning: 4 warnings emitted
warning: 5 warnings emitted

3 changes: 3 additions & 0 deletions tests/ui/float/f32-into-f32.old-solver.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ fn main() {
foo(1e5_f32);
//~^ WARN falling back to `f32`
//~| WARN this was previously accepted
foo(0_f32);
//~^ WARN falling back to `f32`
//~| WARN this was previously accepted
foo(4f32); // no warning
let x = -4.0_f32;
//~^ WARN falling back to `f32`
Expand Down
13 changes: 11 additions & 2 deletions tests/ui/float/f32-into-f32.old-solver.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,22 @@ LL | foo(1e5);
= note: for more information, see issue #154024 <https://github.com/rust-lang/rust/issues/154024>

warning: falling back to `f32` as the trait bound `f32: From<f64>` is not satisfied
--> $DIR/f32-into-f32.rs:19:14
--> $DIR/f32-into-f32.rs:18:9
|
LL | foo(0.);
| ^^ help: explicitly specify the type as `f32`: `0_f32`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154024 <https://github.com/rust-lang/rust/issues/154024>

warning: falling back to `f32` as the trait bound `f32: From<f64>` is not satisfied
--> $DIR/f32-into-f32.rs:22:14
|
LL | let x = -4.0;
| ^^^ help: explicitly specify the type as `f32`: `4.0_f32`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154024 <https://github.com/rust-lang/rust/issues/154024>

warning: 4 warnings emitted
warning: 5 warnings emitted

3 changes: 3 additions & 0 deletions tests/ui/float/f32-into-f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ fn main() {
foo(1e5);
//~^ WARN falling back to `f32`
//~| WARN this was previously accepted
foo(0.);
//~^ WARN falling back to `f32`
//~| WARN this was previously accepted
foo(4f32); // no warning
let x = -4.0;
//~^ WARN falling back to `f32`
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/reborrow/reborrow_multi_field_validation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(reborrow)]

use std::marker::Reborrow;

// Regression test: `reborrow_info` must validate ALL data fields,
// not just stop at the first Reborrow field.

struct Bad<'a> {
first: &'a mut i32,
second: String, //~ ERROR the trait bound `String: Copy` is not satisfied
}

impl<'a> Reborrow for Bad<'a> {}

fn main() {}
9 changes: 9 additions & 0 deletions tests/ui/reborrow/reborrow_multi_field_validation.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/reborrow_multi_field_validation.rs:10:5
|
LL | second: String,
| ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Loading
Loading