11//! Retrieves and caches well-known [`DefId`]s.
22
33use std:: cell:: OnceCell ;
4+ use std:: rc:: Rc ;
45
56use rustc_middle:: ty:: TyCtxt ;
67use rustc_span:: def_id:: DefId ;
8+ use rustc_span:: symbol:: Symbol ;
79use rustc_target:: abi:: FieldIdx ;
810
911#[ derive( Debug , Clone , Default ) ]
1012struct DefIds {
1113 unique : OnceCell < Option < DefId > > ,
1214 nonnull : OnceCell < Option < DefId > > ,
15+
16+ model_ty : OnceCell < Option < DefId > > ,
17+ int_model : OnceCell < Option < DefId > > ,
18+ mut_model : OnceCell < Option < DefId > > ,
19+ box_model : OnceCell < Option < DefId > > ,
20+ array_model : OnceCell < Option < DefId > > ,
21+ closure_model : OnceCell < Option < DefId > > ,
1322}
1423
1524/// Retrieves and caches well-known [`DefId`]s.
@@ -19,14 +28,14 @@ struct DefIds {
1928#[ derive( Clone ) ]
2029pub struct DefIdCache < ' tcx > {
2130 tcx : TyCtxt < ' tcx > ,
22- def_ids : DefIds ,
31+ def_ids : Rc < DefIds > ,
2332}
2433
2534impl < ' tcx > DefIdCache < ' tcx > {
2635 pub fn new ( tcx : TyCtxt < ' tcx > ) -> Self {
2736 Self {
2837 tcx,
29- def_ids : DefIds :: default ( ) ,
38+ def_ids : Rc :: new ( DefIds :: default ( ) ) ,
3039 }
3140 }
3241
@@ -63,4 +72,67 @@ impl<'tcx> DefIdCache<'tcx> {
6372 Some ( nonnull_def. did ( ) )
6473 } )
6574 }
75+
76+ fn annotated_def ( & self , path : & [ Symbol ] ) -> Option < DefId > {
77+ let map = self . tcx . hir ( ) ;
78+ for item_id in map. items ( ) {
79+ let def_id = item_id. owner_id . to_def_id ( ) ;
80+ if self . tcx . get_attrs_by_path ( def_id, path) . next ( ) . is_some ( ) {
81+ return Some ( def_id) ;
82+ }
83+
84+ let item = map. item ( item_id) ;
85+ if let rustc_hir:: ItemKind :: Trait ( _, _, _, _, trait_item_refs) = item. kind {
86+ for trait_item_ref in trait_item_refs {
87+ let def_id = trait_item_ref. id . owner_id . to_def_id ( ) ;
88+ if self . tcx . get_attrs_by_path ( def_id, path) . next ( ) . is_some ( ) {
89+ return Some ( def_id) ;
90+ }
91+ }
92+ }
93+ }
94+ None
95+ }
96+
97+ pub fn model_ty ( & self ) -> Option < DefId > {
98+ * self
99+ . def_ids
100+ . model_ty
101+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: model_ty_path ( ) ) )
102+ }
103+
104+ pub fn int_model ( & self ) -> Option < DefId > {
105+ * self
106+ . def_ids
107+ . int_model
108+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: int_model_path ( ) ) )
109+ }
110+
111+ pub fn mut_model ( & self ) -> Option < DefId > {
112+ * self
113+ . def_ids
114+ . mut_model
115+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: mut_model_path ( ) ) )
116+ }
117+
118+ pub fn box_model ( & self ) -> Option < DefId > {
119+ * self
120+ . def_ids
121+ . box_model
122+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: box_model_path ( ) ) )
123+ }
124+
125+ pub fn array_model ( & self ) -> Option < DefId > {
126+ * self
127+ . def_ids
128+ . array_model
129+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: array_model_path ( ) ) )
130+ }
131+
132+ pub fn closure_model ( & self ) -> Option < DefId > {
133+ * self
134+ . def_ids
135+ . closure_model
136+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: closure_model_path ( ) ) )
137+ }
66138}
0 commit comments