2
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
4
5
+ use std:: mem:: MaybeUninit ;
6
+
5
7
// See docs of the `procedural-masquerade` crate.
6
8
define_invoke_proc_macro ! ( cssparser_internal__invoke_proc_macro) ;
7
9
@@ -110,42 +112,16 @@ macro_rules! ascii_case_insensitive_phf_map {
110
112
#[ doc( hidden) ]
111
113
macro_rules! cssparser_internal__to_lowercase {
112
114
( $input: expr, $BUFFER_SIZE: expr => $output: ident) => {
113
- let mut buffer;
114
- // Safety: `buffer` is only used in `_internal__to_lowercase`,
115
- // which initializes with `copy_from_slice` the part of the buffer it uses,
116
- // before it uses it.
117
115
#[ allow( unsafe_code) ]
118
- let buffer = unsafe { cssparser_internal__uninit!( buffer, $BUFFER_SIZE) } ;
116
+ let mut buffer = unsafe {
117
+ :: std:: mem:: MaybeUninit :: <[ :: std:: mem:: MaybeUninit <u8 >; $BUFFER_SIZE] >:: uninit( )
118
+ . assume_init( )
119
+ } ;
119
120
let input: & str = $input;
120
- let $output = $crate:: _internal__to_lowercase( buffer, input) ;
121
+ let $output = $crate:: _internal__to_lowercase( & mut buffer, input) ;
121
122
} ;
122
123
}
123
124
124
- #[ cfg( has_std__mem__MaybeUninit) ]
125
- #[ macro_export]
126
- #[ doc( hidden) ]
127
- macro_rules! cssparser_internal__uninit {
128
- ( $buffer: ident, $BUFFER_SIZE: expr) => {
129
- {
130
- $buffer = :: std:: mem:: MaybeUninit :: <[ u8 ; $BUFFER_SIZE] >:: uninit( ) ;
131
- & mut * ( $buffer. as_mut_ptr( ) )
132
- }
133
- }
134
- }
135
-
136
- // FIXME: remove this when we require Rust 1.36
137
- #[ cfg( not( has_std__mem__MaybeUninit) ) ]
138
- #[ macro_export]
139
- #[ doc( hidden) ]
140
- macro_rules! cssparser_internal__uninit {
141
- ( $buffer: ident, $BUFFER_SIZE: expr) => {
142
- {
143
- $buffer = :: std:: mem:: uninitialized:: <[ u8 ; $BUFFER_SIZE] >( ) ;
144
- & mut $buffer
145
- }
146
- }
147
- }
148
-
149
125
/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
150
126
///
151
127
/// **This function is not part of the public API. It can change or be removed between any verisons.**
@@ -154,14 +130,28 @@ macro_rules! cssparser_internal__uninit {
154
130
/// Otherwise, return `input` ASCII-lowercased, using `buffer` as temporary space if necessary.
155
131
#[ doc( hidden) ]
156
132
#[ allow( non_snake_case) ]
157
- pub fn _internal__to_lowercase < ' a > ( buffer : & ' a mut [ u8 ] , input : & ' a str ) -> Option < & ' a str > {
133
+ pub fn _internal__to_lowercase < ' a > (
134
+ buffer : & ' a mut [ MaybeUninit < u8 > ] ,
135
+ input : & ' a str ,
136
+ ) -> Option < & ' a str > {
158
137
if let Some ( buffer) = buffer. get_mut ( ..input. len ( ) ) {
159
138
if let Some ( first_uppercase) = input. bytes ( ) . position ( |byte| matches ! ( byte, b'A' ..=b'Z' ) ) {
160
- buffer. copy_from_slice ( input. as_bytes ( ) ) ;
161
- buffer[ first_uppercase..] . make_ascii_lowercase ( ) ;
162
- // `buffer` was initialized to a copy of `input` (which is &str so well-formed UTF-8)
163
- // then lowercased (which preserves UTF-8 well-formedness)
164
- unsafe { Some ( :: std:: str:: from_utf8_unchecked ( buffer) ) }
139
+ unsafe {
140
+ // This cast doesn’t change the pointer’s validity
141
+ // since `u8` has the same layout as `MaybeUninit<u8>`:
142
+ let input_bytes = & * ( input. as_bytes ( ) as * const [ u8 ] as * const [ MaybeUninit < u8 > ] ) ;
143
+
144
+ buffer. copy_from_slice ( & * input_bytes) ;
145
+
146
+ // Same as above re layout, plus these bytes have been initialized:
147
+ let buffer = & mut * ( buffer as * mut [ MaybeUninit < u8 > ] as * mut [ u8 ] ) ;
148
+
149
+ buffer[ first_uppercase..] . make_ascii_lowercase ( ) ;
150
+ // `buffer` was initialized to a copy of `input`
151
+ // (which is `&str` so well-formed UTF-8)
152
+ // then ASCII-lowercased (which preserves UTF-8 well-formedness):
153
+ Some ( :: std:: str:: from_utf8_unchecked ( buffer) )
154
+ }
165
155
} else {
166
156
// Input is already lower-case
167
157
Some ( input)
0 commit comments