@@ -24,6 +24,8 @@ use std::{slice, vec};
2424use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
2525
2626use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
27+ use rustc_data_structures:: sync:: { DynSend , DynSync , Lrc } ;
28+
2729/// An owned smart pointer.
2830///
2931/// See the [module level documentation][crate::ptr] for details.
@@ -208,3 +210,75 @@ where
208210 ( * * self ) . hash_stable ( hcx, hasher) ;
209211 }
210212}
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