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 > > ,
1321}
1422
1523/// Retrieves and caches well-known [`DefId`]s.
@@ -19,14 +27,14 @@ struct DefIds {
1927#[ derive( Clone ) ]
2028pub struct DefIdCache < ' tcx > {
2129 tcx : TyCtxt < ' tcx > ,
22- def_ids : DefIds ,
30+ def_ids : Rc < DefIds > ,
2331}
2432
2533impl < ' tcx > DefIdCache < ' tcx > {
2634 pub fn new ( tcx : TyCtxt < ' tcx > ) -> Self {
2735 Self {
2836 tcx,
29- def_ids : DefIds :: default ( ) ,
37+ def_ids : Rc :: new ( DefIds :: default ( ) ) ,
3038 }
3139 }
3240
@@ -63,4 +71,60 @@ impl<'tcx> DefIdCache<'tcx> {
6371 Some ( nonnull_def. did ( ) )
6472 } )
6573 }
74+
75+ fn annotated_def ( & self , path : & [ Symbol ] ) -> Option < DefId > {
76+ let map = self . tcx . hir ( ) ;
77+ for item_id in map. items ( ) {
78+ let def_id = item_id. owner_id . to_def_id ( ) ;
79+ if self . tcx . get_attrs_by_path ( def_id, path) . next ( ) . is_some ( ) {
80+ return Some ( def_id) ;
81+ }
82+
83+ let item = map. item ( item_id) ;
84+ if let rustc_hir:: ItemKind :: Trait ( _, _, _, _, trait_item_refs) = item. kind {
85+ for trait_item_ref in trait_item_refs {
86+ let def_id = trait_item_ref. id . owner_id . to_def_id ( ) ;
87+ if self . tcx . get_attrs_by_path ( def_id, path) . next ( ) . is_some ( ) {
88+ return Some ( def_id) ;
89+ }
90+ }
91+ }
92+ }
93+ None
94+ }
95+
96+ pub fn model_ty ( & self ) -> Option < DefId > {
97+ * self
98+ . def_ids
99+ . model_ty
100+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: model_ty_path ( ) ) )
101+ }
102+
103+ pub fn int_model ( & self ) -> Option < DefId > {
104+ * self
105+ . def_ids
106+ . int_model
107+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: int_model_path ( ) ) )
108+ }
109+
110+ pub fn mut_model ( & self ) -> Option < DefId > {
111+ * self
112+ . def_ids
113+ . mut_model
114+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: mut_model_path ( ) ) )
115+ }
116+
117+ pub fn box_model ( & self ) -> Option < DefId > {
118+ * self
119+ . def_ids
120+ . box_model
121+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: box_model_path ( ) ) )
122+ }
123+
124+ pub fn array_model ( & self ) -> Option < DefId > {
125+ * self
126+ . def_ids
127+ . array_model
128+ . get_or_init ( || self . annotated_def ( & crate :: analyze:: annot:: array_model_path ( ) ) )
129+ }
66130}
0 commit comments