22 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44
5+ use std:: mem:: MaybeUninit ;
6+
57// See docs of the `procedural-masquerade` crate.
68define_invoke_proc_macro ! ( cssparser_internal__invoke_proc_macro) ;
79
@@ -110,42 +112,15 @@ macro_rules! ascii_case_insensitive_phf_map {
110112#[ doc( hidden) ]
111113macro_rules! cssparser_internal__to_lowercase {
112114 ( $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.
117115 #[ 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( ) . assume_init( )
118+ } ;
119119 let input: & str = $input;
120- let $output = $crate:: _internal__to_lowercase( buffer, input) ;
120+ let $output = $crate:: _internal__to_lowercase( & mut buffer, input) ;
121121 } ;
122122}
123123
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-
149124/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
150125///
151126/// **This function is not part of the public API. It can change or be removed between any verisons.**
@@ -154,10 +129,14 @@ macro_rules! cssparser_internal__uninit {
154129/// Otherwise, return `input` ASCII-lowercased, using `buffer` as temporary space if necessary.
155130#[ doc( hidden) ]
156131#[ allow( non_snake_case) ]
157- pub fn _internal__to_lowercase < ' a > ( buffer : & ' a mut [ u8 ] , input : & ' a str ) -> Option < & ' a str > {
132+ pub fn _internal__to_lowercase < ' a > ( buffer : & ' a mut [ MaybeUninit < u8 > ] , input : & ' a str ) -> Option < & ' a str > {
158133 if let Some ( buffer) = buffer. get_mut ( ..input. len ( ) ) {
159134 if let Some ( first_uppercase) = input. bytes ( ) . position ( |byte| matches ! ( byte, b'A' ..=b'Z' ) ) {
160- buffer. copy_from_slice ( input. as_bytes ( ) ) ;
135+ let buffer = unsafe {
136+ let ptr = buffer. as_mut_ptr ( ) as * mut u8 ;
137+ std:: ptr:: copy_nonoverlapping ( input. as_bytes ( ) . as_ptr ( ) , ptr, input. len ( ) ) ;
138+ & mut * ( buffer as * mut [ MaybeUninit < u8 > ] as * mut [ u8 ] )
139+ } ;
161140 buffer[ first_uppercase..] . make_ascii_lowercase ( ) ;
162141 // `buffer` was initialized to a copy of `input` (which is &str so well-formed UTF-8)
163142 // then lowercased (which preserves UTF-8 well-formedness)
0 commit comments