diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 7b41023ff31b..5fe5464ab2cd 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -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)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 2905170d22a7..67fa09d22f77 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -245,7 +245,7 @@ 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; @@ -2525,6 +2525,12 @@ fn clone(&self) -> Self { #[unstable(feature = "ergonomic_clones", issue = "132290")] impl UseCloned for Rc {} +// FIXME(share_trait): The initial `Share` impl set is still being confirmed in +// rust-lang/rust#156756. This assumes cloning `Rc` creates a clone-as-alias +// value because the new handle points to the same allocation. +#[unstable(feature = "share_trait", issue = "156756")] +impl Share for Rc {} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Default for Rc { diff --git a/tests/ui/share-trait/share-trait-rc.rs b/tests/ui/share-trait/share-trait-rc.rs new file mode 100644 index 000000000000..7de6936bcc9c --- /dev/null +++ b/tests/ui/share-trait/share-trait-rc.rs @@ -0,0 +1,32 @@ +//@ run-pass + +#![feature(share_trait)] + +use std::cell::Cell; +use std::clone::Share; +use std::rc::Rc; + +trait Value { + fn get(&self) -> i32; +} + +impl Value for Cell { + fn get(&self) -> i32 { + Cell::get(self) + } +} + +fn main() { + let value = Rc::new(Cell::new(1)); + let shared = value.share(); + + assert!(Rc::ptr_eq(&value, &shared)); + shared.set(2); + assert_eq!(value.get(), 2); + + let dyn_value: Rc = Rc::new(Cell::new(3)); + let shared_dyn_value = dyn_value.share(); + + assert!(Rc::ptr_eq(&dyn_value, &shared_dyn_value)); + assert_eq!(shared_dyn_value.get(), 3); +}