3
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
4
5
5
use 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 ;
12
6
use std:: rc:: Rc ;
13
- use std:: slice;
14
- use std:: str;
7
+ use std:: { cmp, fmt, hash, marker, mem, ops, slice, str, ptr} ;
15
8
16
9
/// A string that is either shared (heap-allocated and reference-counted) or borrowed.
17
10
///
18
11
/// Equivalent to `enum { Borrowed(&'a str), Shared(Rc<String>) }`, but stored more compactly.
19
12
///
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.
22
19
pub 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 < ( ) > ,
34
21
borrowed_len_or_max : usize ,
35
22
36
- phantom : PhantomData < Result < & ' a str , Rc < String > > > ,
23
+ phantom : marker :: PhantomData < Result < & ' a str , Rc < String > > > ,
37
24
}
38
25
39
26
fn _static_assert_same_size < ' a > ( ) {
@@ -57,9 +44,9 @@ impl<'a> From<&'a str> for CowRcStr<'a> {
57
44
let len = s. len ( ) ;
58
45
assert ! ( len < usize :: MAX ) ;
59
46
CowRcStr {
60
- ptr : unsafe { & * ( s. as_ptr ( ) as * const ( ) ) } ,
47
+ ptr : unsafe { ptr :: NonNull :: new_unchecked ( s. as_ptr ( ) as * mut ( ) ) } ,
61
48
borrowed_len_or_max : len,
62
- phantom : PhantomData ,
49
+ phantom : marker :: PhantomData ,
63
50
}
64
51
}
65
52
}
@@ -74,22 +61,22 @@ impl<'a> From<String> for CowRcStr<'a> {
74
61
impl < ' a > CowRcStr < ' a > {
75
62
#[ inline]
76
63
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 ( ) ) } ;
78
65
CowRcStr {
79
- ptr : ptr ,
66
+ ptr,
80
67
borrowed_len_or_max : usize:: MAX ,
81
- phantom : PhantomData ,
68
+ phantom : marker :: PhantomData ,
82
69
}
83
70
}
84
71
85
72
#[ inline]
86
73
fn unpack ( & self ) -> Result < & ' a str , * const String > {
87
74
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 )
89
76
} else {
90
77
unsafe {
91
78
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 ,
93
80
self . borrowed_len_or_max ,
94
81
) ) )
95
82
}
@@ -121,7 +108,7 @@ impl<'a> Drop for CowRcStr<'a> {
121
108
}
122
109
}
123
110
124
- impl < ' a > Deref for CowRcStr < ' a > {
111
+ impl < ' a > ops :: Deref for CowRcStr < ' a > {
125
112
type Target = str ;
126
113
127
114
#[ inline]
0 commit comments