@@ -27,6 +27,15 @@ pub(crate) struct BoxedString {
2727 ptr : NonNull < u8 > ,
2828}
2929
30+ /// Checks if a pointer is aligned to an even address (good)
31+ /// or an odd address (either actually an InlineString or very, very bad).
32+ ///
33+ /// Returns `true` if aligned to an odd address, `false` if even. The sense of
34+ /// the boolean is "does this look like an InlineString? true/false"
35+ fn check_alignment ( ptr : * const u8 ) -> bool {
36+ ptr. align_offset ( 2 ) > 0
37+ }
38+
3039impl GenericString for BoxedString {
3140 fn set_size ( & mut self , size : usize ) {
3241 self . len = size;
@@ -44,9 +53,8 @@ impl GenericString for BoxedString {
4453impl BoxedString {
4554 const MINIMAL_CAPACITY : usize = MAX_INLINE * 2 ;
4655
47- pub ( crate ) fn check_alignment ( this : & Self ) -> usize {
48- let ptr: * const u8 = this. ptr . as_ptr ( ) ;
49- ptr. align_offset ( 2 )
56+ pub ( crate ) fn check_alignment ( this : & Self ) -> bool {
57+ check_alignment ( this. ptr . as_ptr ( ) )
5058 }
5159
5260 fn layout_for ( cap : usize ) -> Layout {
@@ -163,6 +171,10 @@ impl From<String> for BoxedString {
163171 if s. is_empty ( ) {
164172 Self :: new ( s. capacity ( ) )
165173 } else {
174+ // If the `String`'s buffer isn't word aligned, we can't reuse it.
175+ if check_alignment ( s. as_ptr ( ) ) {
176+ return Self :: from_str ( s. capacity ( ) , & s) ;
177+ }
166178 // TODO: Use String::into_raw_parts when stabilised, meanwhile let's get unsafe
167179 let len = s. len ( ) ;
168180 let cap = s. capacity ( ) ;
0 commit comments