33 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44
55use std:: borrow:: { Borrow , Cow } ;
6- use std:: cmp;
7- use std:: fmt;
8- use std:: hash;
9- use std:: marker:: PhantomData ;
10- use std:: mem;
11- use std:: ops:: Deref ;
126use std:: rc:: Rc ;
13- use std:: slice;
14- use std:: str;
7+ use std:: { cmp, fmt, hash, marker, mem, ops, slice, str, ptr} ;
158
169/// A string that is either shared (heap-allocated and reference-counted) or borrowed.
1710///
1811/// Equivalent to `enum { Borrowed(&'a str), Shared(Rc<String>) }`, but stored more compactly.
1912///
20- /// FIXME(https://github.com/rust-lang/rfcs/issues/1230): use an actual enum if/when
21- /// the compiler can do this layout optimization.
13+ /// * If `borrowed_len_or_max == usize::MAX`, then `ptr` represents `NonZero<*const String>`
14+ /// from `Rc::into_raw`.
15+ /// The lifetime parameter `'a` is irrelevant in this case.
16+ ///
17+ /// * Otherwise, `ptr` represents the `NonZero<*const u8>` data component of `&'a str`,
18+ /// and `borrowed_len_or_max` its length.
2219pub struct CowRcStr < ' a > {
23- /// FIXME: https://github.com/rust-lang/rust/issues/27730 use NonZero or Shared.
24- /// In the meantime we abuse `&'static _` to get the effect of `NonZero<*const _>`.
25- /// `ptr` doesn’t really have the 'static lifetime!
26- ptr : & ' static ( ) ,
27-
28- /// * If `borrowed_len_or_max == usize::MAX`, then `ptr` represents `NonZero<*const String>`
29- /// from `Rc::into_raw`.
30- /// The lifetime parameter `'a` is irrelevant in this case.
31- ///
32- /// * Otherwise, `ptr` represents the `NonZero<*const u8>` data component of `&'a str`,
33- /// and `borrowed_len_or_max` its length.
20+ ptr : ptr:: NonNull < ( ) > ,
3421 borrowed_len_or_max : usize ,
3522
36- phantom : PhantomData < Result < & ' a str , Rc < String > > > ,
23+ phantom : marker :: PhantomData < Result < & ' a str , Rc < String > > > ,
3724}
3825
3926fn _static_assert_same_size < ' a > ( ) {
@@ -57,9 +44,9 @@ impl<'a> From<&'a str> for CowRcStr<'a> {
5744 let len = s. len ( ) ;
5845 assert ! ( len < usize :: MAX ) ;
5946 CowRcStr {
60- ptr : unsafe { & * ( s. as_ptr ( ) as * const ( ) ) } ,
47+ ptr : unsafe { ptr :: NonNull :: new_unchecked ( s. as_ptr ( ) as * mut ( ) ) } ,
6148 borrowed_len_or_max : len,
62- phantom : PhantomData ,
49+ phantom : marker :: PhantomData ,
6350 }
6451 }
6552}
@@ -74,22 +61,22 @@ impl<'a> From<String> for CowRcStr<'a> {
7461impl < ' a > CowRcStr < ' a > {
7562 #[ inline]
7663 fn from_rc ( s : Rc < String > ) -> Self {
77- let ptr = unsafe { & * ( Rc :: into_raw ( s) as * const ( ) ) } ;
64+ let ptr = unsafe { ptr :: NonNull :: new_unchecked ( Rc :: into_raw ( s) as * mut ( ) ) } ;
7865 CowRcStr {
79- ptr : ptr ,
66+ ptr,
8067 borrowed_len_or_max : usize:: MAX ,
81- phantom : PhantomData ,
68+ phantom : marker :: PhantomData ,
8269 }
8370 }
8471
8572 #[ inline]
8673 fn unpack ( & self ) -> Result < & ' a str , * const String > {
8774 if self . borrowed_len_or_max == usize:: MAX {
88- Err ( self . ptr as * const ( ) as * const String )
75+ Err ( self . ptr . as_ptr ( ) as * const String )
8976 } else {
9077 unsafe {
9178 Ok ( str:: from_utf8_unchecked ( slice:: from_raw_parts (
92- self . ptr as * const ( ) as * const u8 ,
79+ self . ptr . as_ptr ( ) as * const u8 ,
9380 self . borrowed_len_or_max ,
9481 ) ) )
9582 }
@@ -121,7 +108,7 @@ impl<'a> Drop for CowRcStr<'a> {
121108 }
122109}
123110
124- impl < ' a > Deref for CowRcStr < ' a > {
111+ impl < ' a > ops :: Deref for CowRcStr < ' a > {
125112 type Target = str ;
126113
127114 #[ inline]
0 commit comments