@@ -24,6 +24,8 @@ use std::{slice, vec};
24
24
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
25
25
26
26
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
27
+ use rustc_data_structures:: sync:: { DynSend , DynSync , Lrc } ;
28
+
27
29
/// An owned smart pointer.
28
30
///
29
31
/// See the [module level documentation][crate::ptr] for details.
@@ -208,3 +210,75 @@ where
208
210
( * * self ) . hash_stable ( hcx, hasher) ;
209
211
}
210
212
}
213
+
214
+ #[ derive( Debug ) ]
215
+ pub enum AstOwnerRef < ' a > {
216
+ NonOwner ,
217
+ Synthetic ( rustc_span:: def_id:: LocalDefId ) ,
218
+ Crate ( & ' a crate :: Crate ) ,
219
+ Item ( & ' a crate :: Item ) ,
220
+ TraitItem ( & ' a crate :: AssocItem ) ,
221
+ ImplItem ( & ' a crate :: AssocItem ) ,
222
+ ForeignItem ( & ' a crate :: ForeignItem ) ,
223
+ }
224
+
225
+ #[ derive( Debug ) ]
226
+ enum AstOwnerPtr {
227
+ NonOwner ,
228
+ Synthetic ( rustc_span:: def_id:: LocalDefId ) ,
229
+ Crate ,
230
+ Item ( * const crate :: Item ) ,
231
+ TraitItem ( * const crate :: AssocItem ) ,
232
+ ImplItem ( * const crate :: AssocItem ) ,
233
+ ForeignItem ( * const crate :: ForeignItem ) ,
234
+ }
235
+
236
+ /// Derived pointer to a part of the AST. This data structure is strongly inspired from
237
+ /// `owning_ref`, but with restricted API to suit its single use.
238
+ #[ derive( Debug ) ]
239
+ pub struct AstOwner {
240
+ /// Pointer to the full crate.
241
+ krate : Lrc < crate :: Crate > ,
242
+ /// Pointer to an item in that crate.
243
+ ptr : AstOwnerPtr ,
244
+ }
245
+
246
+ unsafe impl DynSend for AstOwner { }
247
+ unsafe impl DynSync for AstOwner { }
248
+
249
+ impl AstOwner {
250
+ /// Create a new `AstOwner` from the crate and an item derived from it.
251
+ pub unsafe fn new ( krate : Lrc < crate :: Crate > , item : AstOwnerRef < ' _ > ) -> AstOwner {
252
+ let ptr = match item {
253
+ AstOwnerRef :: NonOwner => AstOwnerPtr :: NonOwner ,
254
+ AstOwnerRef :: Synthetic ( def_id) => AstOwnerPtr :: Synthetic ( def_id) ,
255
+ AstOwnerRef :: Crate ( _) => AstOwnerPtr :: Crate ,
256
+ AstOwnerRef :: Item ( item) => AstOwnerPtr :: Item ( item as * const _ ) ,
257
+ AstOwnerRef :: TraitItem ( item) => AstOwnerPtr :: TraitItem ( item as * const _ ) ,
258
+ AstOwnerRef :: ImplItem ( item) => AstOwnerPtr :: ImplItem ( item as * const _ ) ,
259
+ AstOwnerRef :: ForeignItem ( item) => AstOwnerPtr :: ForeignItem ( item as * const _ ) ,
260
+ } ;
261
+
262
+ AstOwner { krate, ptr }
263
+ }
264
+
265
+ pub fn new_non_owner ( krate : Lrc < crate :: Crate > ) -> AstOwner {
266
+ AstOwner { krate, ptr : AstOwnerPtr :: NonOwner }
267
+ }
268
+
269
+ pub fn as_ref ( & self ) -> AstOwnerRef < ' _ > {
270
+ match self . ptr {
271
+ AstOwnerPtr :: NonOwner => AstOwnerRef :: NonOwner ,
272
+ AstOwnerPtr :: Synthetic ( def_id) => AstOwnerRef :: Synthetic ( def_id) ,
273
+ AstOwnerPtr :: Crate => AstOwnerRef :: Crate ( & * self . krate ) ,
274
+ // SAFETY: the item is live as long as `krate` is.
275
+ AstOwnerPtr :: Item ( item) => AstOwnerRef :: Item ( unsafe { & * item } ) ,
276
+ // SAFETY: the item is live as long as `krate` is.
277
+ AstOwnerPtr :: TraitItem ( item) => AstOwnerRef :: TraitItem ( unsafe { & * item } ) ,
278
+ // SAFETY: the item is live as long as `krate` is.
279
+ AstOwnerPtr :: ImplItem ( item) => AstOwnerRef :: ImplItem ( unsafe { & * item } ) ,
280
+ // SAFETY: the item is live as long as `krate` is.
281
+ AstOwnerPtr :: ForeignItem ( item) => AstOwnerRef :: ForeignItem ( unsafe { & * item } ) ,
282
+ }
283
+ }
284
+ }
0 commit comments