@@ -22,8 +22,15 @@ use crate::{Allocator, Vec};
22
22
///
23
23
/// UTF-8 encoded, growable string. Identical to [`std::string::String`] except that it stores
24
24
/// string contents in arena allocator.
25
+ //
26
+ // We wrap the inner `BumpaloString` in `ManuallyDrop` to make `String` non-Drop.
27
+ // `bumpalo::collections::String` is a wrapper around `bumpalo::collections::Vec<u8>`.
28
+ // Even though a `Vec<u8>` cannot require dropping (because `u8` is not `Drop`), `Vec<u8>` still has
29
+ // a `Drop` impl, which means `bumpalo::collections::String` is `Drop` too.
30
+ // We want to make it clear to compiler that `String` doesn't require dropping, so it doesn't
31
+ // produce pointless "drop guard" code to handle dropping a `String` in case of a panic.
25
32
#[ derive( PartialOrd , Eq , Ord ) ]
26
- pub struct String < ' alloc > ( BumpaloString < ' alloc > ) ;
33
+ pub struct String < ' alloc > ( ManuallyDrop < BumpaloString < ' alloc > > ) ;
27
34
28
35
impl < ' alloc > String < ' alloc > {
29
36
/// Creates a new empty [`String`].
@@ -38,7 +45,7 @@ impl<'alloc> String<'alloc> {
38
45
/// [`with_capacity_in`]: String::with_capacity_in
39
46
#[ inline( always) ]
40
47
pub fn new_in ( allocator : & ' alloc Allocator ) -> String < ' alloc > {
41
- Self ( BumpaloString :: new_in ( allocator. bump ( ) ) )
48
+ Self ( ManuallyDrop :: new ( BumpaloString :: new_in ( allocator. bump ( ) ) ) )
42
49
}
43
50
44
51
/// Creates a new empty [`String`] with specified capacity.
@@ -57,7 +64,7 @@ impl<'alloc> String<'alloc> {
57
64
/// [`new_in`]: String::new_in
58
65
#[ inline( always) ]
59
66
pub fn with_capacity_in ( capacity : usize , allocator : & ' alloc Allocator ) -> String < ' alloc > {
60
- Self ( BumpaloString :: with_capacity_in ( capacity, allocator. bump ( ) ) )
67
+ Self ( ManuallyDrop :: new ( BumpaloString :: with_capacity_in ( capacity, allocator. bump ( ) ) ) )
61
68
}
62
69
63
70
/// Construct a new [`String`] from a string slice.
@@ -73,7 +80,7 @@ impl<'alloc> String<'alloc> {
73
80
/// ```
74
81
#[ inline( always) ]
75
82
pub fn from_str_in ( s : & str , allocator : & ' alloc Allocator ) -> String < ' alloc > {
76
- Self ( BumpaloString :: from_str_in ( s, allocator. bump ( ) ) )
83
+ Self ( ManuallyDrop :: new ( BumpaloString :: from_str_in ( s, allocator. bump ( ) ) ) )
77
84
}
78
85
79
86
/// Convert `Vec<u8>` into [`String`].
@@ -105,7 +112,7 @@ impl<'alloc> String<'alloc> {
105
112
// Lifetime of returned `String` is same as lifetime of original `Vec<u8>`.
106
113
let inner = ManuallyDrop :: into_inner ( bytes. 0 ) ;
107
114
let ( ptr, len, capacity, bump) = inner. into_raw_parts_with_alloc ( ) ;
108
- Self ( BumpaloString :: from_raw_parts_in ( ptr, len, capacity, bump) )
115
+ Self ( ManuallyDrop :: new ( BumpaloString :: from_raw_parts_in ( ptr, len, capacity, bump) ) )
109
116
}
110
117
111
118
/// Creates a new [`String`] from a length, capacity, and pointer.
@@ -137,8 +144,6 @@ impl<'alloc> String<'alloc> {
137
144
/// let len = s.len();
138
145
/// let capacity = s.capacity();
139
146
///
140
- /// mem::forget(s);
141
- ///
142
147
/// let s = String::from_raw_parts_in(ptr, len, capacity, &allocator);
143
148
///
144
149
/// assert_eq!(s, "hello");
@@ -153,7 +158,8 @@ impl<'alloc> String<'alloc> {
153
158
allocator : & ' alloc Allocator ,
154
159
) -> String < ' alloc > {
155
160
// SAFETY: Safety conditions of this method are the same as `BumpaloString`'s method
156
- Self ( BumpaloString :: from_raw_parts_in ( buf, length, capacity, allocator. bump ( ) ) )
161
+ let inner = BumpaloString :: from_raw_parts_in ( buf, length, capacity, allocator. bump ( ) ) ;
162
+ Self ( ManuallyDrop :: new ( inner) )
157
163
}
158
164
159
165
/// Convert this `String<'alloc>` into an `&'alloc str`. This is analogous to
@@ -170,7 +176,8 @@ impl<'alloc> String<'alloc> {
170
176
/// ```
171
177
#[ inline( always) ]
172
178
pub fn into_bump_str ( self ) -> & ' alloc str {
173
- self . 0 . into_bump_str ( )
179
+ let inner = ManuallyDrop :: into_inner ( self . 0 ) ;
180
+ inner. into_bump_str ( )
174
181
}
175
182
}
176
183
0 commit comments