11//! Contains basic data about various HIR declarations.
22
3- use std:: { mem , sync:: Arc } ;
3+ use std:: sync:: Arc ;
44
5- use hir_expand:: { name:: Name , AstId , ExpandResult , HirFileId , InFile , MacroCallId , MacroDefKind } ;
5+ use hir_expand:: { name:: Name , AstId , ExpandResult , HirFileId , MacroCallId , MacroDefKind } ;
6+ use smallvec:: SmallVec ;
67use syntax:: ast;
78
89use crate :: {
910 attr:: Attrs ,
1011 body:: { Expander , Mark } ,
1112 db:: DefDatabase ,
1213 intern:: Interned ,
13- item_tree:: { self , AssocItem , FnFlags , ItemTreeId , ModItem , Param , TreeId } ,
14+ item_tree:: { self , AssocItem , FnFlags , ItemTree , ItemTreeId , ModItem , Param , TreeId } ,
1415 nameres:: { attr_resolution:: ResolvedAttr , DefMap } ,
1516 type_ref:: { TraitRef , TypeBound , TypeRef } ,
1617 visibility:: RawVisibility ,
1718 AssocItemId , AstIdWithPath , ConstId , ConstLoc , FunctionId , FunctionLoc , HasModule , ImplId ,
18- Intern , ItemContainerId , Lookup , Macro2Id , MacroRulesId , ModuleId , ProcMacroId , StaticId ,
19- TraitId , TypeAliasId , TypeAliasLoc ,
19+ Intern , ItemContainerId , ItemLoc , Lookup , Macro2Id , MacroRulesId , ModuleId , ProcMacroId ,
20+ StaticId , TraitId , TypeAliasId , TypeAliasLoc ,
2021} ;
2122
2223#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -209,35 +210,31 @@ pub struct TraitData {
209210
210211impl TraitData {
211212 pub ( crate ) fn trait_data_query ( db : & dyn DefDatabase , tr : TraitId ) -> Arc < TraitData > {
212- let tr_loc = tr. lookup ( db) ;
213- let item_tree = tr_loc . id . item_tree ( db) ;
214- let tr_def = & item_tree[ tr_loc . id . value ] ;
213+ let tr_loc @ ItemLoc { container : module_id , id : tree_id } = tr. lookup ( db) ;
214+ let item_tree = tree_id . item_tree ( db) ;
215+ let tr_def = & item_tree[ tree_id . value ] ;
215216 let _cx = stdx:: panic_context:: enter ( format ! (
216217 "trait_data_query({:?} -> {:?} -> {:?})" ,
217218 tr, tr_loc, tr_def
218219 ) ) ;
219220 let name = tr_def. name . clone ( ) ;
220221 let is_auto = tr_def. is_auto ;
221222 let is_unsafe = tr_def. is_unsafe ;
222- let module_id = tr_loc. container ;
223223 let visibility = item_tree[ tr_def. visibility ] . clone ( ) ;
224224 let skip_array_during_method_dispatch = item_tree
225- . attrs ( db, tr_loc . container . krate ( ) , ModItem :: from ( tr_loc . id . value ) . into ( ) )
225+ . attrs ( db, module_id . krate ( ) , ModItem :: from ( tree_id . value ) . into ( ) )
226226 . by_key ( "rustc_skip_array_during_method_dispatch" )
227227 . exists ( ) ;
228228
229- let mut collector = AssocItemCollector :: new (
230- db,
231- module_id,
232- tr_loc. id . file_id ( ) ,
233- ItemContainerId :: TraitId ( tr) ,
234- ) ;
235- collector. collect ( tr_loc. id . tree_id ( ) , & tr_def. items ) ;
229+ let mut collector =
230+ AssocItemCollector :: new ( db, module_id, tree_id. file_id ( ) , ItemContainerId :: TraitId ( tr) ) ;
231+ collector. collect ( & item_tree, tree_id. tree_id ( ) , & tr_def. items ) ;
232+ let ( items, attribute_calls) = collector. finish ( ) ;
236233
237234 Arc :: new ( TraitData {
238235 name,
239- attribute_calls : collector . take_attr_calls ( ) ,
240- items : collector . items ,
236+ attribute_calls,
237+ items,
241238 is_auto,
242239 is_unsafe,
243240 visibility,
@@ -284,25 +281,20 @@ pub struct ImplData {
284281impl ImplData {
285282 pub ( crate ) fn impl_data_query ( db : & dyn DefDatabase , id : ImplId ) -> Arc < ImplData > {
286283 let _p = profile:: span ( "impl_data_query" ) ;
287- let impl_loc = id. lookup ( db) ;
284+ let ItemLoc { container : module_id , id : tree_id } = id. lookup ( db) ;
288285
289- let item_tree = impl_loc . id . item_tree ( db) ;
290- let impl_def = & item_tree[ impl_loc . id . value ] ;
286+ let item_tree = tree_id . item_tree ( db) ;
287+ let impl_def = & item_tree[ tree_id . value ] ;
291288 let target_trait = impl_def. target_trait . clone ( ) ;
292289 let self_ty = impl_def. self_ty . clone ( ) ;
293290 let is_negative = impl_def. is_negative ;
294- let module_id = impl_loc. container ;
295291
296- let mut collector = AssocItemCollector :: new (
297- db,
298- module_id,
299- impl_loc. id . file_id ( ) ,
300- ItemContainerId :: ImplId ( id) ,
301- ) ;
302- collector. collect ( impl_loc. id . tree_id ( ) , & impl_def. items ) ;
292+ let mut collector =
293+ AssocItemCollector :: new ( db, module_id, tree_id. file_id ( ) , ItemContainerId :: ImplId ( id) ) ;
294+ collector. collect ( & item_tree, tree_id. tree_id ( ) , & impl_def. items ) ;
303295
304- let attribute_calls = collector. take_attr_calls ( ) ;
305- let items = collector . items . into_iter ( ) . map ( |( _, item) | item) . collect ( ) ;
296+ let ( items , attribute_calls) = collector. finish ( ) ;
297+ let items = items. into_iter ( ) . map ( |( _, item) | item) . collect ( ) ;
306298
307299 Arc :: new ( ImplData { target_trait, self_ty, items, is_negative, attribute_calls } )
308300 }
@@ -463,18 +455,19 @@ impl<'a> AssocItemCollector<'a> {
463455 }
464456 }
465457
466- fn take_attr_calls ( & mut self ) -> Option < Box < Vec < ( AstId < ast :: Item > , MacroCallId ) > > > {
467- let attribute_calls = mem :: take ( & mut self . attr_calls ) ;
468- if attribute_calls . is_empty ( ) {
469- None
470- } else {
471- Some ( Box :: new ( attribute_calls ) )
472- }
458+ fn finish (
459+ self ,
460+ ) -> ( Vec < ( Name , AssocItemId ) > , Option < Box < Vec < ( AstId < ast :: Item > , MacroCallId ) > > > ) {
461+ (
462+ self . items ,
463+ if self . attr_calls . is_empty ( ) { None } else { Some ( Box :: new ( self . attr_calls ) ) } ,
464+ )
473465 }
474466
475467 // FIXME: proc-macro diagnostics
476- fn collect ( & mut self , tree_id : TreeId , assoc_items : & [ AssocItem ] ) {
477- let item_tree = tree_id. item_tree ( self . db ) ;
468+ fn collect ( & mut self , item_tree : & ItemTree , tree_id : TreeId , assoc_items : & [ AssocItem ] ) {
469+ let container = self . container ;
470+ self . items . reserve ( assoc_items. len ( ) ) ;
478471
479472 ' items: for & item in assoc_items {
480473 let attrs = item_tree. attrs ( self . db , self . module_id . krate , ModItem :: from ( item) . into ( ) ) ;
@@ -509,9 +502,9 @@ impl<'a> AssocItemCollector<'a> {
509502 continue ' attrs;
510503 }
511504 }
512- match self . expander . enter_expand_id ( self . db , call_id) {
513- ExpandResult { value : Some ( ( mark, mac ) ) , .. } => {
514- self . collect_macro_items ( mark, mac ) ;
505+ match self . expander . enter_expand_id :: < ast :: MacroItems > ( self . db , call_id) {
506+ ExpandResult { value : Some ( ( mark, _ ) ) , .. } => {
507+ self . collect_macro_items ( mark) ;
515508 continue ' items;
516509 }
517510 ExpandResult { .. } => { }
@@ -522,59 +515,57 @@ impl<'a> AssocItemCollector<'a> {
522515 match item {
523516 AssocItem :: Function ( id) => {
524517 let item = & item_tree[ id] ;
518+
525519 let def =
526- FunctionLoc { container : self . container , id : ItemTreeId :: new ( tree_id, id) }
527- . intern ( self . db ) ;
520+ FunctionLoc { container, id : ItemTreeId :: new ( tree_id, id) } . intern ( self . db ) ;
528521 self . items . push ( ( item. name . clone ( ) , def. into ( ) ) ) ;
529522 }
530523 AssocItem :: Const ( id) => {
531524 let item = & item_tree[ id] ;
525+
532526 let name = match item. name . clone ( ) {
533527 Some ( name) => name,
534528 None => continue ,
535529 } ;
536530 let def =
537- ConstLoc { container : self . container , id : ItemTreeId :: new ( tree_id, id) }
538- . intern ( self . db ) ;
531+ ConstLoc { container, id : ItemTreeId :: new ( tree_id, id) } . intern ( self . db ) ;
539532 self . items . push ( ( name, def. into ( ) ) ) ;
540533 }
541534 AssocItem :: TypeAlias ( id) => {
542535 let item = & item_tree[ id] ;
543- let def = TypeAliasLoc {
544- container : self . container ,
545- id : ItemTreeId :: new ( tree_id, id) ,
546- }
547- . intern ( self . db ) ;
536+
537+ let def = TypeAliasLoc { container, id : ItemTreeId :: new ( tree_id, id) }
538+ . intern ( self . db ) ;
548539 self . items . push ( ( item. name . clone ( ) , def. into ( ) ) ) ;
549540 }
550541 AssocItem :: MacroCall ( call) => {
551- let call = & item_tree[ call] ;
552- let ast_id_map = self . db . ast_id_map ( self . expander . current_file_id ( ) ) ;
553542 if let Some ( root) = self . db . parse_or_expand ( self . expander . current_file_id ( ) ) {
543+ let call = & item_tree[ call] ;
544+
545+ let ast_id_map = self . db . ast_id_map ( self . expander . current_file_id ( ) ) ;
554546 let call = ast_id_map. get ( call. ast_id ) . to_node ( & root) ;
555547 let _cx = stdx:: panic_context:: enter ( format ! (
556548 "collect_items MacroCall: {}" ,
557549 call
558550 ) ) ;
559- let res = self . expander . enter_expand ( self . db , call) ;
551+ let res = self . expander . enter_expand :: < ast :: MacroItems > ( self . db , call) ;
560552
561- if let Ok ( ExpandResult { value : Some ( ( mark, mac ) ) , .. } ) = res {
562- self . collect_macro_items ( mark, mac ) ;
553+ if let Ok ( ExpandResult { value : Some ( ( mark, _ ) ) , .. } ) = res {
554+ self . collect_macro_items ( mark) ;
563555 }
564556 }
565557 }
566558 }
567559 }
568560 }
569561
570- fn collect_macro_items ( & mut self , mark : Mark , mac : ast:: MacroItems ) {
571- let src: InFile < ast:: MacroItems > = self . expander . to_source ( mac) ;
572- let tree_id = item_tree:: TreeId :: new ( src. file_id , None ) ;
562+ fn collect_macro_items ( & mut self , mark : Mark ) {
563+ let tree_id = item_tree:: TreeId :: new ( self . expander . current_file_id ( ) , None ) ;
573564 let item_tree = tree_id. item_tree ( self . db ) ;
574- let iter: Vec < _ > =
565+ let iter: SmallVec < [ _ ; 2 ] > =
575566 item_tree. top_level_items ( ) . iter ( ) . filter_map ( ModItem :: as_assoc_item) . collect ( ) ;
576567
577- self . collect ( tree_id, & iter) ;
568+ self . collect ( & item_tree , tree_id, & iter) ;
578569
579570 self . expander . exit ( self . db , mark) ;
580571 }
0 commit comments