diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index dbfd2e74abee6..ee810339df24a 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -341,7 +341,7 @@ where } #[unstable(feature = "deref_pure_trait", issue = "87121")] -unsafe impl DerefPure for Cow<'_, B> where B::Owned: Borrow {} +unsafe impl DerefPure for Cow<'_, B> where B::Owned: Borrow + BorrowPure {} #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Cow<'_, B> where B: Eq + ToOwned {} diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 1ea7b731461e7..3dfe263981db2 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -183,7 +183,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::borrow::{Borrow, BorrowMut}; +use core::borrow::{Borrow, BorrowMut, BorrowPure}; #[cfg(not(no_global_oom_handling))] use core::clone::CloneToUninit; use core::cmp::Ordering; @@ -2046,6 +2046,9 @@ impl BorrowMut for Box { } } +#[unstable(feature = "borrow_pure_trait", issue = "87121")] +unsafe impl BorrowPure for Box {} + #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] impl AsRef for Box { fn as_ref(&self) -> &T { diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 6fee8d3fe3346..1ffe43f8a00b3 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -7,7 +7,7 @@ // It's cleaner to just turn off the unused_imports warning than to fix them. #![allow(unused_imports)] -use core::borrow::{Borrow, BorrowMut}; +use core::borrow::{Borrow, BorrowMut, BorrowPure}; use core::iter::FusedIterator; use core::mem::MaybeUninit; #[stable(feature = "encode_utf16", since = "1.8.0")] @@ -201,6 +201,9 @@ impl BorrowMut for String { } } +#[unstable(feature = "borrow_pure_trait", issue = "87121")] +unsafe impl BorrowPure for String {} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for str { diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index ccb1cc4e974d6..2d8baa3434f27 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -240,3 +240,21 @@ impl BorrowMut for &mut T { &mut **self } } + +/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Borrow`] +/// (and, if applicable, [`BorrowMut`]) implementation. This is relied on for soundness +/// of deref patterns of [`Cow`](alloc::borrow::Cow). +/// +/// FIXME(deref_patterns): The precise semantics are undecided; the rough idea is that +/// successive calls to `borrow`/`borrow_mut` without intermediate mutation should be +/// idempotent, in the sense that they return the same value as far as pattern-matching +/// is concerned. Calls to `borrow`/`borrow_mut` must leave the pointer itself likewise +/// unchanged. +#[unstable(feature = "borrow_pure_trait", issue = "87121")] +pub unsafe trait BorrowPure {} + +#[unstable(feature = "borrow_pure_trait", issue = "87121")] +unsafe impl BorrowPure for &T {} + +#[unstable(feature = "borrow_pure_trait", issue = "87121")] +unsafe impl BorrowPure for &mut T {}