@@ -83,104 +83,99 @@ impl LangItemTarget {
83
83
}
84
84
}
85
85
86
- # [ derive ( Default , Debug , Clone , PartialEq , Eq ) ]
87
- pub struct LangItems {
88
- items : FxHashMap < LangItem , LangItemTarget > ,
89
- }
86
+ /// Salsa query. This will look for lang items in a specific crate.
87
+ # [ salsa :: tracked ( return_ref ) ]
88
+ pub fn crate_lang_items ( db : & dyn DefDatabase , krate : Crate ) -> Option < Box < LangItems > > {
89
+ let _p = tracing :: info_span! ( "crate_lang_items_query" ) . entered ( ) ;
90
90
91
- impl LangItems {
92
- pub fn target ( & self , item : LangItem ) -> Option < LangItemTarget > {
93
- self . items . get ( & item) . copied ( )
94
- }
91
+ let mut lang_items = LangItems :: default ( ) ;
95
92
96
- /// Salsa query. This will look for lang items in a specific crate.
97
- pub ( crate ) fn crate_lang_items_query (
98
- db : & dyn DefDatabase ,
99
- krate : Crate ,
100
- ) -> Option < Arc < LangItems > > {
101
- let _p = tracing:: info_span!( "crate_lang_items_query" ) . entered ( ) ;
102
-
103
- let mut lang_items = LangItems :: default ( ) ;
93
+ let crate_def_map = db. crate_def_map ( krate) ;
104
94
105
- let crate_def_map = db. crate_def_map ( krate) ;
95
+ for ( _, module_data) in crate_def_map. modules ( ) {
96
+ for impl_def in module_data. scope . impls ( ) {
97
+ lang_items. collect_lang_item ( db, impl_def, LangItemTarget :: ImplDef ) ;
98
+ for & ( _, assoc) in db. impl_items ( impl_def) . items . iter ( ) {
99
+ match assoc {
100
+ AssocItemId :: FunctionId ( f) => {
101
+ lang_items. collect_lang_item ( db, f, LangItemTarget :: Function )
102
+ }
103
+ AssocItemId :: TypeAliasId ( t) => {
104
+ lang_items. collect_lang_item ( db, t, LangItemTarget :: TypeAlias )
105
+ }
106
+ AssocItemId :: ConstId ( _) => ( ) ,
107
+ }
108
+ }
109
+ }
106
110
107
- for ( _ , module_data ) in crate_def_map . modules ( ) {
108
- for impl_def in module_data . scope . impls ( ) {
109
- lang_items . collect_lang_item ( db , impl_def , LangItemTarget :: ImplDef ) ;
110
- for & ( _ , assoc ) in db . impl_items ( impl_def ) . items . iter ( ) {
111
- match assoc {
111
+ for def in module_data . scope . declarations ( ) {
112
+ match def {
113
+ ModuleDefId :: TraitId ( trait_ ) => {
114
+ lang_items . collect_lang_item ( db , trait_ , LangItemTarget :: Trait ) ;
115
+ db . trait_items ( trait_ ) . items . iter ( ) . for_each ( | & ( _ , assoc_id ) | match assoc_id {
112
116
AssocItemId :: FunctionId ( f) => {
113
- lang_items. collect_lang_item ( db, f, LangItemTarget :: Function )
117
+ lang_items. collect_lang_item ( db, f, LangItemTarget :: Function ) ;
114
118
}
115
- AssocItemId :: TypeAliasId ( t ) => {
116
- lang_items. collect_lang_item ( db, t , LangItemTarget :: TypeAlias )
119
+ AssocItemId :: TypeAliasId ( alias ) => {
120
+ lang_items. collect_lang_item ( db, alias , LangItemTarget :: TypeAlias )
117
121
}
118
- AssocItemId :: ConstId ( _) => ( ) ,
119
- }
122
+ AssocItemId :: ConstId ( _) => { }
123
+ } ) ;
120
124
}
121
- }
122
-
123
- for def in module_data. scope . declarations ( ) {
124
- match def {
125
- ModuleDefId :: TraitId ( trait_) => {
126
- lang_items. collect_lang_item ( db, trait_, LangItemTarget :: Trait ) ;
127
- db. trait_items ( trait_) . items . iter ( ) . for_each (
128
- |& ( _, assoc_id) | match assoc_id {
129
- AssocItemId :: FunctionId ( f) => {
130
- lang_items. collect_lang_item ( db, f, LangItemTarget :: Function ) ;
131
- }
132
- AssocItemId :: TypeAliasId ( alias) => lang_items. collect_lang_item (
133
- db,
134
- alias,
135
- LangItemTarget :: TypeAlias ,
136
- ) ,
137
- AssocItemId :: ConstId ( _) => { }
138
- } ,
139
- ) ;
140
- }
141
- ModuleDefId :: AdtId ( AdtId :: EnumId ( e) ) => {
142
- lang_items. collect_lang_item ( db, e, LangItemTarget :: EnumId ) ;
143
- db. enum_variants ( e) . variants . iter ( ) . for_each ( |& ( id, _) | {
144
- lang_items. collect_lang_item ( db, id, LangItemTarget :: EnumVariant ) ;
145
- } ) ;
146
- }
147
- ModuleDefId :: AdtId ( AdtId :: StructId ( s) ) => {
148
- lang_items. collect_lang_item ( db, s, LangItemTarget :: Struct ) ;
149
- }
150
- ModuleDefId :: AdtId ( AdtId :: UnionId ( u) ) => {
151
- lang_items. collect_lang_item ( db, u, LangItemTarget :: Union ) ;
152
- }
153
- ModuleDefId :: FunctionId ( f) => {
154
- lang_items. collect_lang_item ( db, f, LangItemTarget :: Function ) ;
155
- }
156
- ModuleDefId :: StaticId ( s) => {
157
- lang_items. collect_lang_item ( db, s, LangItemTarget :: Static ) ;
158
- }
159
- ModuleDefId :: TypeAliasId ( t) => {
160
- lang_items. collect_lang_item ( db, t, LangItemTarget :: TypeAlias ) ;
161
- }
162
- _ => { }
125
+ ModuleDefId :: AdtId ( AdtId :: EnumId ( e) ) => {
126
+ lang_items. collect_lang_item ( db, e, LangItemTarget :: EnumId ) ;
127
+ db. enum_variants ( e) . variants . iter ( ) . for_each ( |& ( id, _) | {
128
+ lang_items. collect_lang_item ( db, id, LangItemTarget :: EnumVariant ) ;
129
+ } ) ;
130
+ }
131
+ ModuleDefId :: AdtId ( AdtId :: StructId ( s) ) => {
132
+ lang_items. collect_lang_item ( db, s, LangItemTarget :: Struct ) ;
133
+ }
134
+ ModuleDefId :: AdtId ( AdtId :: UnionId ( u) ) => {
135
+ lang_items. collect_lang_item ( db, u, LangItemTarget :: Union ) ;
163
136
}
137
+ ModuleDefId :: FunctionId ( f) => {
138
+ lang_items. collect_lang_item ( db, f, LangItemTarget :: Function ) ;
139
+ }
140
+ ModuleDefId :: StaticId ( s) => {
141
+ lang_items. collect_lang_item ( db, s, LangItemTarget :: Static ) ;
142
+ }
143
+ ModuleDefId :: TypeAliasId ( t) => {
144
+ lang_items. collect_lang_item ( db, t, LangItemTarget :: TypeAlias ) ;
145
+ }
146
+ _ => { }
164
147
}
165
148
}
149
+ }
166
150
167
- if lang_items. items . is_empty ( ) { None } else { Some ( Arc :: new ( lang_items) ) }
151
+ if lang_items. items . is_empty ( ) { None } else { Some ( Box :: new ( lang_items) ) }
152
+ }
153
+
154
+ /// Salsa query. Look for a lang item, starting from the specified crate and recursively
155
+ /// traversing its dependencies.
156
+ #[ salsa:: tracked]
157
+ pub fn lang_item (
158
+ db : & dyn DefDatabase ,
159
+ start_crate : Crate ,
160
+ item : LangItem ,
161
+ ) -> Option < LangItemTarget > {
162
+ let _p = tracing:: info_span!( "lang_item_query" ) . entered ( ) ;
163
+ if let Some ( target) =
164
+ crate_lang_items ( db, start_crate) . as_ref ( ) . and_then ( |it| it. items . get ( & item) . copied ( ) )
165
+ {
166
+ return Some ( target) ;
168
167
}
168
+ start_crate. data ( db) . dependencies . iter ( ) . find_map ( |dep| lang_item ( db, dep. crate_id , item) )
169
+ }
169
170
170
- /// Salsa query. Look for a lang item, starting from the specified crate and recursively
171
- /// traversing its dependencies.
172
- pub ( crate ) fn lang_item_query (
173
- db : & dyn DefDatabase ,
174
- start_crate : Crate ,
175
- item : LangItem ,
176
- ) -> Option < LangItemTarget > {
177
- let _p = tracing:: info_span!( "lang_item_query" ) . entered ( ) ;
178
- if let Some ( target) =
179
- db. crate_lang_items ( start_crate) . and_then ( |it| it. items . get ( & item) . copied ( ) )
180
- {
181
- return Some ( target) ;
182
- }
183
- start_crate. data ( db) . dependencies . iter ( ) . find_map ( |dep| db. lang_item ( dep. crate_id , item) )
171
+ #[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
172
+ pub struct LangItems {
173
+ items : FxHashMap < LangItem , LangItemTarget > ,
174
+ }
175
+
176
+ impl LangItems {
177
+ pub fn target ( & self , item : LangItem ) -> Option < LangItemTarget > {
178
+ self . items . get ( & item) . copied ( )
184
179
}
185
180
186
181
fn collect_lang_item < T > (
@@ -269,18 +264,38 @@ macro_rules! language_item_table {
269
264
}
270
265
271
266
impl LangItem {
267
+ pub fn resolve_function ( self , db : & dyn DefDatabase , start_crate : Crate ) -> Option < FunctionId > {
268
+ lang_item ( db, start_crate, self ) . and_then ( |t| t. as_function ( ) )
269
+ }
270
+
271
+ pub fn resolve_trait ( self , db : & dyn DefDatabase , start_crate : Crate ) -> Option < TraitId > {
272
+ lang_item ( db, start_crate, self ) . and_then ( |t| t. as_trait ( ) )
273
+ }
274
+
275
+ pub fn resolve_enum ( self , db : & dyn DefDatabase , start_crate : Crate ) -> Option < EnumId > {
276
+ lang_item ( db, start_crate, self ) . and_then ( |t| t. as_enum ( ) )
277
+ }
278
+
279
+ pub fn resolve_type_alias (
280
+ self ,
281
+ db : & dyn DefDatabase ,
282
+ start_crate : Crate ,
283
+ ) -> Option < TypeAliasId > {
284
+ lang_item ( db, start_crate, self ) . and_then ( |t| t. as_type_alias ( ) )
285
+ }
286
+
272
287
/// Opposite of [`LangItem::name`]
273
288
pub fn from_name ( name : & hir_expand:: name:: Name ) -> Option < Self > {
274
289
Self :: from_symbol ( name. symbol ( ) )
275
290
}
276
291
277
292
pub fn path ( & self , db : & dyn DefDatabase , start_crate : Crate ) -> Option < Path > {
278
- let t = db . lang_item ( start_crate, * self ) ?;
293
+ let t = lang_item ( db , start_crate, * self ) ?;
279
294
Some ( Path :: LangItem ( t, None ) )
280
295
}
281
296
282
297
pub fn ty_rel_path ( & self , db : & dyn DefDatabase , start_crate : Crate , seg : Name ) -> Option < Path > {
283
- let t = db . lang_item ( start_crate, * self ) ?;
298
+ let t = lang_item ( db , start_crate, * self ) ?;
284
299
Some ( Path :: LangItem ( t, Some ( seg) ) )
285
300
}
286
301
}
0 commit comments