@@ -83,104 +83,99 @@ impl LangItemTarget {
8383 }
8484}
8585
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 ( ) ;
9090
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 ( ) ;
9592
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) ;
10494
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+ }
106110
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 {
112116 AssocItemId :: FunctionId ( f) => {
113- lang_items. collect_lang_item ( db, f, LangItemTarget :: Function )
117+ lang_items. collect_lang_item ( db, f, LangItemTarget :: Function ) ;
114118 }
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 )
117121 }
118- AssocItemId :: ConstId ( _) => ( ) ,
119- }
122+ AssocItemId :: ConstId ( _) => { }
123+ } ) ;
120124 }
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 ) ;
163136 }
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+ _ => { }
164147 }
165148 }
149+ }
166150
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) ;
168167 }
168+ start_crate. data ( db) . dependencies . iter ( ) . find_map ( |dep| lang_item ( db, dep. crate_id , item) )
169+ }
169170
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 ( )
184179 }
185180
186181 fn collect_lang_item < T > (
@@ -269,18 +264,38 @@ macro_rules! language_item_table {
269264}
270265
271266impl 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+
272287 /// Opposite of [`LangItem::name`]
273288 pub fn from_name ( name : & hir_expand:: name:: Name ) -> Option < Self > {
274289 Self :: from_symbol ( name. symbol ( ) )
275290 }
276291
277292 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 ) ?;
279294 Some ( Path :: LangItem ( t, None ) )
280295 }
281296
282297 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 ) ?;
284299 Some ( Path :: LangItem ( t, Some ( seg) ) )
285300 }
286301}
0 commit comments