Skip to content

Commit 4206d09

Browse files
Adding COOP_PREFERRED to Cow, ToOwned...
1 parent 87499b8 commit 4206d09

File tree

8 files changed

+117
-53
lines changed

8 files changed

+117
-53
lines changed

library/alloc/src/borrow.rs

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ use crate::string::String;
1717

1818
use Cow::*;
1919

20+
// @FIXME check if used & needed
21+
pub(crate) const BORROW_COOP_PREFERRED: bool = DEFAULT_COOP_PREFERRED!();
22+
2023
#[stable(feature = "rust1", since = "1.0.0")]
2124
impl<'a, B: ?Sized, const COOP_PREFERRED: bool> Borrow<B> for Cow<'a, B, COOP_PREFERRED>
2225
where
@@ -344,9 +347,10 @@ where
344347

345348
#[stable(feature = "rust1", since = "1.0.0")]
346349
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
347-
impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
350+
impl<B: ?Sized + ToOwned<COOP_PREFERRED>, const COOP_PREFERRED: bool> const Deref for Cow<'_, B, COOP_PREFERRED>
348351
where
349352
B::Owned: ~const Borrow<B>,
353+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
350354
{
351355
type Target = B;
352356

@@ -359,12 +363,18 @@ where
359363
}
360364

361365
#[stable(feature = "rust1", since = "1.0.0")]
362-
impl<B: ?Sized> Eq for Cow<'_, B> where B: Eq + ToOwned {}
366+
impl<B: ?Sized, const COOP_PREFERRED: bool> Eq for Cow<'_, B, COOP_PREFERRED>
367+
where
368+
B: Eq + ToOwned<COOP_PREFERRED>,
369+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
370+
371+
{}
363372

364373
#[stable(feature = "rust1", since = "1.0.0")]
365-
impl<B: ?Sized> Ord for Cow<'_, B>
374+
impl<B: ?Sized, const COOP_PREFERRED: bool> Ord for Cow<'_, B, COOP_PREFERRED>
366375
where
367-
B: Ord + ToOwned,
376+
B: Ord + ToOwned<COOP_PREFERRED>,
377+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
368378
{
369379
#[inline]
370380
fn cmp(&self, other: &Self) -> Ordering {
@@ -373,24 +383,26 @@ where
373383
}
374384

375385
#[stable(feature = "rust1", since = "1.0.0")]
376-
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B>
386+
impl<'a, 'b, B: ?Sized, C: ?Sized, const COOP_PREFERRED: bool> PartialEq<Cow<'b, C, COOP_PREFERRED>> for Cow<'a, B, COOP_PREFERRED>
377387
where
378-
B: PartialEq<C> + ToOwned,
379-
C: ToOwned,
388+
B: PartialEq<C> + ToOwned<COOP_PREFERRED>,
389+
C: ToOwned<COOP_PREFERRED>,
390+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
380391
{
381392
#[inline]
382-
fn eq(&self, other: &Cow<'b, C>) -> bool {
393+
fn eq(&self, other: &Cow<'b, C, COOP_PREFERRED>) -> bool {
383394
PartialEq::eq(&**self, &**other)
384395
}
385396
}
386397

387398
#[stable(feature = "rust1", since = "1.0.0")]
388-
impl<'a, B: ?Sized> PartialOrd for Cow<'a, B>
399+
impl<'a, B: ?Sized, const COOP_PREFERRED: bool> PartialOrd for Cow<'a, B, COOP_PREFERRED>
389400
where
390-
B: PartialOrd + ToOwned,
401+
B: PartialOrd + ToOwned<COOP_PREFERRED>,
402+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
391403
{
392404
#[inline]
393-
fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
405+
fn partial_cmp(&self, other: &Cow<'a, B, COOP_PREFERRED>) -> Option<Ordering> {
394406
PartialOrd::partial_cmp(&**self, &**other)
395407
}
396408
}
@@ -436,9 +448,10 @@ where
436448
}
437449

438450
#[stable(feature = "rust1", since = "1.0.0")]
439-
impl<B: ?Sized> Hash for Cow<'_, B>
451+
impl<B: ?Sized, const COOP_PREFERRED: bool> Hash for Cow<'_, B, COOP_PREFERRED>
440452
where
441-
B: Hash + ToOwned,
453+
B: Hash + ToOwned<COOP_PREFERRED>,
454+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
442455
{
443456
#[inline]
444457
fn hash<H: Hasher>(&self, state: &mut H) {
@@ -447,16 +460,20 @@ where
447460
}
448461

449462
#[stable(feature = "rust1", since = "1.0.0")]
450-
impl<T: ?Sized + ToOwned> AsRef<T> for Cow<'_, T> {
463+
impl<T: ?Sized + ToOwned<COOP_PREFERRED>, const COOP_PREFERRED: bool> AsRef<T> for Cow<'_, T, COOP_PREFERRED>
464+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
465+
{
451466
fn as_ref(&self) -> &T {
452467
self
453468
}
454469
}
455470

456471
#[cfg(not(no_global_oom_handling))]
457472
#[stable(feature = "cow_add", since = "1.14.0")]
458-
impl<'a> Add<&'a str> for Cow<'a, str> {
459-
type Output = Cow<'a, str>;
473+
impl<'a, const COOP_PREFERRED: bool> Add<&'a str> for Cow<'a, str, COOP_PREFERRED>
474+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
475+
{
476+
type Output = Cow<'a, str, COOP_PREFERRED>;
460477

461478
#[inline]
462479
fn add(mut self, rhs: &'a str) -> Self::Output {
@@ -467,19 +484,23 @@ impl<'a> Add<&'a str> for Cow<'a, str> {
467484

468485
#[cfg(not(no_global_oom_handling))]
469486
#[stable(feature = "cow_add", since = "1.14.0")]
470-
impl<'a> Add<Cow<'a, str>> for Cow<'a, str> {
471-
type Output = Cow<'a, str>;
487+
impl<'a, const COOP_PREFERRED: bool> Add<Cow<'a, str, COOP_PREFERRED>> for Cow<'a, str, COOP_PREFERRED>
488+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
489+
{
490+
type Output = Cow<'a, str, COOP_PREFERRED>;
472491

473492
#[inline]
474-
fn add(mut self, rhs: Cow<'a, str>) -> Self::Output {
493+
fn add(mut self, rhs: Cow<'a, str, COOP_PREFERRED>) -> Self::Output {
475494
self += rhs;
476495
self
477496
}
478497
}
479498

480499
#[cfg(not(no_global_oom_handling))]
481500
#[stable(feature = "cow_add", since = "1.14.0")]
482-
impl<'a> AddAssign<&'a str> for Cow<'a, str> {
501+
impl<'a, const COOP_PREFERRED: bool> AddAssign<&'a str> for Cow<'a, str, COOP_PREFERRED>
502+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
503+
{
483504
fn add_assign(&mut self, rhs: &'a str) {
484505
if self.is_empty() {
485506
*self = Cow::Borrowed(rhs)
@@ -496,8 +517,10 @@ impl<'a> AddAssign<&'a str> for Cow<'a, str> {
496517

497518
#[cfg(not(no_global_oom_handling))]
498519
#[stable(feature = "cow_add", since = "1.14.0")]
499-
impl<'a> AddAssign<Cow<'a, str>> for Cow<'a, str> {
500-
fn add_assign(&mut self, rhs: Cow<'a, str>) {
520+
impl<'a, const COOP_PREFERRED: bool> AddAssign<Cow<'a, str, COOP_PREFERRED>> for Cow<'a, str, COOP_PREFERRED>
521+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
522+
{
523+
fn add_assign(&mut self, rhs: Cow<'a, str, COOP_PREFERRED>) {
501524
if self.is_empty() {
502525
*self = rhs
503526
} else if !rhs.is_empty() {

library/alloc/src/ffi/c_str.rs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,10 @@ impl CString {
496496
/// ```
497497
#[must_use = "`self` will be dropped if the result is not used"]
498498
#[stable(feature = "cstring_into", since = "1.7.0")]
499-
pub fn into_bytes(self) -> Vec<u8> {
499+
pub fn into_bytes<const COOP_PREFERRED: bool>(self) -> Vec<u8, Global, COOP_PREFERRED>
500+
where
501+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
502+
{
500503
let mut vec = into_vec(self.into_inner());
501504
let _nul = vec.pop();
502505
debug_assert_eq!(_nul, Some(0u8));
@@ -726,12 +729,14 @@ impl fmt::Debug for CString {
726729

727730
#[stable(feature = "cstring_into", since = "1.7.0")]
728731
#[allow(unused_braces)]
729-
impl From<CString> for Vec<u8, Global, {DEFAULT_COOP_PREFERRED!()}> {
732+
impl<const COOP_PREFERRED: bool> From<CString> for Vec<u8, Global, COOP_PREFERRED>
733+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
734+
{
730735
/// Converts a [`CString`] into a <code>[Vec]<[u8]></code>.
731736
///
732737
/// The conversion consumes the [`CString`], and removes the terminating NUL byte.
733738
#[inline]
734-
fn from(s: CString) -> Vec<u8> {
739+
fn from(s: CString) -> Vec<u8, Global, COOP_PREFERRED> {
735740
s.into_bytes()
736741
}
737742
}
@@ -741,7 +746,8 @@ impl Default for CString {
741746
/// Creates an empty `CString`.
742747
fn default() -> CString {
743748
let a: &CStr = Default::default();
744-
a.to_owned()
749+
// false = no need for co-alloc metadata, since it would get lost once converted to Box.
750+
<CStr as ToOwned<false>>::to_owned(a)
745751
}
746752
}
747753

@@ -754,11 +760,13 @@ impl Borrow<CStr> for CString {
754760
}
755761

756762
#[stable(feature = "cstring_from_cow_cstr", since = "1.28.0")]
757-
impl<'a> From<Cow<'a, CStr>> for CString {
763+
impl<'a, const COOP_PREFERRED: bool> From<Cow<'a, CStr, COOP_PREFERRED>> for CString
764+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
765+
{
758766
/// Converts a `Cow<'a, CStr>` into a `CString`, by copying the contents if they are
759767
/// borrowed.
760768
#[inline]
761-
fn from(s: Cow<'a, CStr>) -> Self {
769+
fn from(s: Cow<'a, CStr, COOP_PREFERRED>) -> Self {
762770
s.into_owned()
763771
}
764772
}
@@ -775,11 +783,13 @@ impl From<&CStr> for Box<CStr> {
775783
}
776784

777785
#[stable(feature = "box_from_cow", since = "1.45.0")]
778-
impl From<Cow<'_, CStr>> for Box<CStr> {
786+
impl<const COOP_PREFERRED: bool> From<Cow<'_, CStr, COOP_PREFERRED>> for Box<CStr>
787+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
788+
{
779789
/// Converts a `Cow<'a, CStr>` into a `Box<CStr>`,
780790
/// by copying the contents if they are borrowed.
781791
#[inline]
782-
fn from(cow: Cow<'_, CStr>) -> Box<CStr> {
792+
fn from(cow: Cow<'_, CStr, COOP_PREFERRED>) -> Box<CStr> {
783793
match cow {
784794
Cow::Borrowed(s) => Box::from(s),
785795
Cow::Owned(s) => Box::from(s),
@@ -838,28 +848,33 @@ impl From<CString> for Box<CStr> {
838848
}
839849

840850
#[stable(feature = "cow_from_cstr", since = "1.28.0")]
841-
impl<'a> From<CString> for Cow<'a, CStr> {
851+
#[allow(unused_braces)]
852+
impl<'a> From<CString> for Cow<'a, CStr, { DEFAULT_COOP_PREFERRED!() }> {
842853
/// Converts a [`CString`] into an owned [`Cow`] without copying or allocating.
843854
#[inline]
844-
fn from(s: CString) -> Cow<'a, CStr> {
855+
fn from(s: CString) -> Cow<'a, CStr, { DEFAULT_COOP_PREFERRED!() }> {
845856
Cow::Owned(s)
846857
}
847858
}
848859

849860
#[stable(feature = "cow_from_cstr", since = "1.28.0")]
850-
impl<'a> From<&'a CStr> for Cow<'a, CStr> {
861+
#[allow(unused_braces)]
862+
impl<'a> From<&'a CStr> for Cow<'a, CStr, { DEFAULT_COOP_PREFERRED!() }> {
851863
/// Converts a [`CStr`] into a borrowed [`Cow`] without copying or allocating.
852864
#[inline]
853-
fn from(s: &'a CStr) -> Cow<'a, CStr> {
865+
fn from(s: &'a CStr) -> Cow<'a, CStr, { DEFAULT_COOP_PREFERRED!() }> {
854866
Cow::Borrowed(s)
855867
}
856868
}
857869

858870
#[stable(feature = "cow_from_cstr", since = "1.28.0")]
859-
impl<'a> From<&'a CString> for Cow<'a, CStr> {
871+
impl<'a, const COOP_PREFERRED: bool> From<&'a CString> for Cow<'a, CStr, COOP_PREFERRED>
872+
where
873+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
874+
{
860875
/// Converts a `&`[`CString`] into a borrowed [`Cow`] without copying or allocating.
861876
#[inline]
862-
fn from(s: &'a CString) -> Cow<'a, CStr> {
877+
fn from(s: &'a CString) -> Cow<'a, CStr, COOP_PREFERRED> {
863878
Cow::Borrowed(s.as_c_str())
864879
}
865880
}
@@ -1017,7 +1032,11 @@ impl fmt::Display for IntoStringError {
10171032
}
10181033

10191034
#[stable(feature = "cstr_borrow", since = "1.3.0")]
1020-
impl ToOwned for CStr {
1035+
// @FIXME try remove COOP_PREFERRED and have ToOwned<_>
1036+
impl<const COOP_PREFERRED: bool> ToOwned<COOP_PREFERRED> for CStr
1037+
where
1038+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
1039+
{
10211040
type Owned = CString;
10221041

10231042
fn to_owned(&self) -> CString {
@@ -1034,7 +1053,8 @@ impl ToOwned for CStr {
10341053
#[stable(feature = "cstring_asref", since = "1.7.0")]
10351054
impl From<&CStr> for CString {
10361055
fn from(s: &CStr) -> CString {
1037-
s.to_owned()
1056+
// false = no need for co-alloc metadata, since it would get lost once converted to Box.
1057+
<CStr as ToOwned<false>>::to_owned(s)
10381058
}
10391059
}
10401060

@@ -1102,9 +1122,11 @@ impl CStr {
11021122
#[must_use = "this returns the result of the operation, \
11031123
without modifying the original"]
11041124
#[stable(feature = "cstr_to_str", since = "1.4.0")]
1105-
pub fn to_string_lossy(&self) -> Cow<'_, str, false> {
1125+
pub fn to_string_lossy<const COOP_PREFERRED: bool>(&self) -> Cow<'_, str, COOP_PREFERRED>
1126+
where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
1127+
{
11061128
// false = no need for co-alloc metadata, since it would get lost once converted to the slice.
1107-
String::<false>::from_utf8_lossy(self.to_bytes())
1129+
String::<COOP_PREFERRED>::from_utf8_lossy(self.to_bytes())
11081130
}
11091131

11101132
/// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating.

library/alloc/src/slice.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -852,22 +852,26 @@ where
852852
}
853853
}
854854

855-
// COOP_NOT_POSSIBLE
856855
#[cfg(not(no_global_oom_handling))]
857856
#[stable(feature = "rust1", since = "1.0.0")]
858-
impl<T: Clone> ToOwned for [T] {
859-
type Owned = Vec<T>;
857+
impl<T: Clone, const COOP_PREFERRED: bool> ToOwned<COOP_PREFERRED> for [T]
858+
where
859+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(
860+
COOP_PREFERRED,
861+
)]:,
862+
{
863+
type Owned = Vec<T, Global, COOP_PREFERRED>;
860864
#[cfg(not(test))]
861-
fn to_owned(&self) -> Vec<T> {
865+
fn to_owned(&self) -> Vec<T, Global, COOP_PREFERRED> {
862866
self.to_vec()
863867
}
864868

865869
#[cfg(test)]
866-
fn to_owned(&self) -> Vec<T> {
870+
fn to_owned(&self) -> Vec<T, Global, COOP_PREFERRED> {
867871
hack::to_vec(self, Global)
868872
}
869873

870-
fn clone_into(&self, target: &mut Vec<T>) {
874+
fn clone_into(&self, target: &mut Vec<T, Global, COOP_PREFERRED>) {
871875
// drop anything in target that will not be overwritten
872876
target.truncate(self.len());
873877

library/alloc/src/str.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,21 @@ where
191191
}
192192

193193
#[stable(feature = "rust1", since = "1.0.0")]
194-
impl Borrow<str> for String {
194+
impl<const COOP_PREFERRED: bool> Borrow<str> for String<COOP_PREFERRED>
195+
where
196+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
197+
{
195198
#[inline]
196199
fn borrow(&self) -> &str {
197200
&self[..]
198201
}
199202
}
200203

201204
#[stable(feature = "string_borrow_mut", since = "1.36.0")]
202-
impl BorrowMut<str> for String {
205+
impl<const COOP_PREFERRED: bool> BorrowMut<str> for String<COOP_PREFERRED>
206+
where
207+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
208+
{
203209
#[inline]
204210
fn borrow_mut(&mut self) -> &mut str {
205211
&mut self[..]

library/alloc/src/string.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,7 +3014,7 @@ where
30143014

30153015
#[cfg(not(no_global_oom_handling))]
30163016
#[stable(feature = "cow_from_string_ref", since = "1.28.0")]
3017-
impl<'a, const COOP_PREFERRED: bool> From<&'a String<COOP_PREFERRED>> for Cow<'a, str>
3017+
impl<'a, const COOP_PREFERRED: bool> From<&'a String<COOP_PREFERRED>> for Cow<'a, str, COOP_PREFERRED>
30183018
where
30193019
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
30203020
{
@@ -3055,7 +3055,7 @@ impl<'a, 'b> FromIterator<&'b str> for Cow<'a, str> {
30553055

30563056
#[cfg(not(no_global_oom_handling))]
30573057
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
3058-
impl<'a, const COOP_PREFERRED: bool> FromIterator<String<COOP_PREFERRED>> for Cow<'a, str>
3058+
impl<'a, const COOP_PREFERRED: bool> FromIterator<String<COOP_PREFERRED>> for Cow<'a, str, COOP_PREFERRED>
30593059
where
30603060
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
30613061
{

library/alloc/tests/string.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ where
1515
fn into_cow(self) -> Cow<'a, B>;
1616
}
1717

18-
impl<'a> IntoCow<'a, str> for String {
18+
impl<'a, const COOP_PREFERRED: bool> IntoCow<'a, str> for String<COOP_PREFERRED>
19+
where
20+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
21+
{
1922
fn into_cow(self) -> Cow<'a, str> {
2023
Cow::Owned(self)
2124
}

0 commit comments

Comments
 (0)