5
5
//! and make comparisons for any type as fast as integers.
6
6
7
7
use std:: {
8
- borrow:: { Borrow , Cow } ,
8
+ borrow:: Borrow ,
9
9
fmt:: Debug ,
10
10
hash:: Hash ,
11
11
ops:: Deref ,
@@ -76,31 +76,15 @@ impl<T> From<&Interned<T>> for Interned<T> {
76
76
/// A trait for leaking data.
77
77
///
78
78
/// This is used by [`Interner<T>`] to create static references for values that are interned.
79
- ///
80
- /// It is implemented for static references of `T`, [`Box<T>`], and [`Cow<'static, T>`].
81
- pub trait Leak < T : ?Sized > : Borrow < T > {
82
- /// Creates a static reference to a value equal to `self.borrow()`, possibly leaking memory.
83
- fn leak ( self ) -> & ' static T ;
84
- }
85
-
86
- impl < T : ?Sized > Leak < T > for & ' static T {
87
- fn leak ( self ) -> & ' static T {
88
- self
89
- }
79
+ pub trait Leak {
80
+ /// Creates a static reference to `self`, possibly leaking memory.
81
+ fn leak ( & self ) -> & ' static Self ;
90
82
}
91
83
92
- impl < T : ?Sized > Leak < T > for Box < T > {
93
- fn leak ( self ) -> & ' static T {
94
- Box :: leak ( self )
95
- }
96
- }
97
-
98
- impl < T : Clone + ?Sized > Leak < T > for Cow < ' static , T > {
99
- fn leak ( self ) -> & ' static T {
100
- match self {
101
- Cow :: Borrowed ( value) => value,
102
- Cow :: Owned ( value) => Box :: leak ( Box :: new ( value) ) ,
103
- }
84
+ impl Leak for str {
85
+ fn leak ( & self ) -> & ' static Self {
86
+ let str = self . to_owned ( ) . into_boxed_str ( ) ;
87
+ Box :: leak ( str)
104
88
}
105
89
}
106
90
@@ -161,16 +145,16 @@ impl<T: ?Sized> Interner<T> {
161
145
}
162
146
}
163
147
164
- impl < T : StaticRef + Hash + Eq + ?Sized > Interner < T > {
148
+ impl < T : Leak + StaticRef + Hash + Eq + ?Sized > Interner < T > {
165
149
/// Return the [`Interned<T>`] corresponding to `value`.
166
150
///
167
151
/// If it is called the first time for `value`, it will possibly leak the value and return an
168
152
/// [`Interned<T>`] using the obtained static reference. Subsequent calls for the same `value`
169
153
/// will return [`Interned<T>`] using the same static reference.
170
154
///
171
155
/// This uses [`StaticRef::static_ref`] to short-circuit the interning process.
172
- pub fn intern < Q : Leak < T > > ( & self , value : Q ) -> Interned < T > {
173
- if let Some ( value) = value. borrow ( ) . static_ref ( ) {
156
+ pub fn intern ( & self , value : & T ) -> Interned < T > {
157
+ if let Some ( value) = value. static_ref ( ) {
174
158
return Interned ( value) ;
175
159
}
176
160
let lock = self . 0 . get_or_init ( Default :: default) ;
@@ -219,15 +203,15 @@ mod tests {
219
203
}
220
204
}
221
205
222
- impl Leak < A > for A {
223
- fn leak ( self ) -> & ' static Self {
206
+ impl Leak for A {
207
+ fn leak ( & self ) -> & ' static Self {
224
208
& A
225
209
}
226
210
}
227
211
228
212
let interner = Interner :: default ( ) ;
229
- let x = interner. intern ( A ) ;
230
- let y = interner. intern ( A ) ;
213
+ let x = interner. intern ( & A ) ;
214
+ let y = interner. intern ( & A ) ;
231
215
assert_eq ! ( x, y) ;
232
216
}
233
217
@@ -248,8 +232,8 @@ mod tests {
248
232
}
249
233
}
250
234
251
- impl Leak < A > for A {
252
- fn leak ( self ) -> & ' static Self {
235
+ impl Leak for A {
236
+ fn leak ( & self ) -> & ' static Self {
253
237
match self {
254
238
A :: X => & A :: X ,
255
239
A :: Y => & A :: Y ,
@@ -258,8 +242,8 @@ mod tests {
258
242
}
259
243
260
244
let interner = Interner :: default ( ) ;
261
- let x = interner. intern ( A :: X ) ;
262
- let y = interner. intern ( A :: Y ) ;
245
+ let x = interner. intern ( & A :: X ) ;
246
+ let y = interner. intern ( & A :: Y ) ;
263
247
assert_ne ! ( x, y) ;
264
248
}
265
249
0 commit comments