@@ -14,6 +14,7 @@ use intern::{Symbol, sym};
1414use la_arena:: { ArenaMap , Idx , RawIdx } ;
1515use mbe:: DelimiterKind ;
1616use rustc_abi:: ReprOptions ;
17+ use span:: AstIdNode ;
1718use syntax:: {
1819 AstPtr ,
1920 ast:: { self , HasAttrs } ,
@@ -22,10 +23,10 @@ use triomphe::Arc;
2223use tt:: iter:: { TtElement , TtIter } ;
2324
2425use crate :: {
25- AdtId , AttrDefId , GenericParamId , HasModule , ItemTreeLoc , LocalFieldId , Lookup , MacroId ,
26+ AdtId , AstIdLoc , AttrDefId , GenericParamId , HasModule , LocalFieldId , Lookup , MacroId ,
2627 VariantId ,
2728 db:: DefDatabase ,
28- item_tree:: { AttrOwner , FieldParent , ItemTreeNode } ,
29+ item_tree:: AttrOwner ,
2930 lang_item:: LangItem ,
3031 nameres:: { ModuleOrigin , ModuleSource } ,
3132 src:: { HasChildSource , HasSource } ,
@@ -42,6 +43,15 @@ pub struct AttrsWithOwner {
4243}
4344
4445impl Attrs {
46+ pub fn new (
47+ db : & dyn DefDatabase ,
48+ owner : & dyn ast:: HasAttrs ,
49+ span_map : SpanMapRef < ' _ > ,
50+ cfg_options : & CfgOptions ,
51+ ) -> Self {
52+ Attrs ( RawAttrs :: new_expanded ( db, owner, span_map, cfg_options) )
53+ }
54+
4555 pub fn get ( & self , id : AttrId ) -> Option < & Attr > {
4656 ( * * self ) . iter ( ) . find ( |attr| attr. id == id)
4757 }
@@ -94,44 +104,64 @@ impl Attrs {
94104 v : VariantId ,
95105 ) -> Arc < ArenaMap < LocalFieldId , Attrs > > {
96106 let _p = tracing:: info_span!( "fields_attrs_query" ) . entered ( ) ;
97- // FIXME: There should be some proper form of mapping between item tree field ids and hir field ids
98107 let mut res = ArenaMap :: default ( ) ;
99- let item_tree;
100- let ( parent, fields, krate) = match v {
108+ let ( fields, file_id, krate) = match v {
101109 VariantId :: EnumVariantId ( it) => {
102110 let loc = it. lookup ( db) ;
103111 let krate = loc. parent . lookup ( db) . container . krate ;
104- item_tree = loc. id . item_tree ( db) ;
105- let variant = & item_tree[ loc. id . value ] ;
106- ( FieldParent :: EnumVariant ( loc. id . value ) , & variant. fields , krate)
112+ let source = loc. source ( db) ;
113+ ( source. value . field_list ( ) , source. file_id , krate)
107114 }
108115 VariantId :: StructId ( it) => {
109116 let loc = it. lookup ( db) ;
110117 let krate = loc. container . krate ;
111- item_tree = loc. id . item_tree ( db) ;
112- let struct_ = & item_tree[ loc. id . value ] ;
113- ( FieldParent :: Struct ( loc. id . value ) , & struct_. fields , krate)
118+ let source = loc. source ( db) ;
119+ ( source. value . field_list ( ) , source. file_id , krate)
114120 }
115121 VariantId :: UnionId ( it) => {
116122 let loc = it. lookup ( db) ;
117123 let krate = loc. container . krate ;
118- item_tree = loc. id . item_tree ( db) ;
119- let union_ = & item_tree[ loc. id . value ] ;
120- ( FieldParent :: Union ( loc. id . value ) , & union_. fields , krate)
124+ let source = loc. source ( db) ;
125+ (
126+ source. value . record_field_list ( ) . map ( ast:: FieldList :: RecordFieldList ) ,
127+ source. file_id ,
128+ krate,
129+ )
121130 }
122131 } ;
132+ let Some ( fields) = fields else {
133+ return Arc :: new ( res) ;
134+ } ;
123135
124136 let cfg_options = krate. cfg_options ( db) ;
125-
126- let mut idx = 0 ;
127- for ( id, _field) in fields. iter ( ) . enumerate ( ) {
128- let attrs = item_tree. attrs ( db, krate, AttrOwner :: make_field_indexed ( parent, id) ) ;
129- if attrs. is_cfg_enabled ( cfg_options) {
130- res. insert ( Idx :: from_raw ( RawIdx :: from ( idx) ) , attrs) ;
131- idx += 1 ;
137+ let span_map = db. span_map ( file_id) ;
138+
139+ match fields {
140+ ast:: FieldList :: RecordFieldList ( fields) => {
141+ let mut idx = 0 ;
142+ for field in fields. fields ( ) {
143+ let attrs =
144+ Attrs ( RawAttrs :: new_expanded ( db, & field, span_map. as_ref ( ) , cfg_options) ) ;
145+ if attrs. is_cfg_enabled ( cfg_options) . is_ok ( ) {
146+ res. insert ( Idx :: from_raw ( RawIdx :: from ( idx) ) , attrs) ;
147+ idx += 1 ;
148+ }
149+ }
150+ }
151+ ast:: FieldList :: TupleFieldList ( fields) => {
152+ let mut idx = 0 ;
153+ for field in fields. fields ( ) {
154+ let attrs =
155+ Attrs ( RawAttrs :: new_expanded ( db, & field, span_map. as_ref ( ) , cfg_options) ) ;
156+ if attrs. is_cfg_enabled ( cfg_options) . is_ok ( ) {
157+ res. insert ( Idx :: from_raw ( RawIdx :: from ( idx) ) , attrs) ;
158+ idx += 1 ;
159+ }
160+ }
132161 }
133162 }
134163
164+ res. shrink_to_fit ( ) ;
135165 Arc :: new ( res)
136166 }
137167}
@@ -167,11 +197,10 @@ impl Attrs {
167197 }
168198
169199 #[ inline]
170- pub ( crate ) fn is_cfg_enabled ( & self , cfg_options : & CfgOptions ) -> bool {
171- match self . cfg ( ) {
172- None => true ,
173- Some ( cfg) => cfg_options. check ( & cfg) != Some ( false ) ,
174- }
200+ pub ( crate ) fn is_cfg_enabled ( & self , cfg_options : & CfgOptions ) -> Result < ( ) , CfgExpr > {
201+ self . cfgs ( ) . try_for_each ( |cfg| {
202+ if cfg_options. check ( & cfg) != Some ( false ) { Ok ( ( ) ) } else { Err ( cfg) }
203+ } )
175204 }
176205
177206 #[ inline]
@@ -488,12 +517,12 @@ impl AttrsWithOwner {
488517 pub ( crate ) fn attrs_query ( db : & dyn DefDatabase , def : AttrDefId ) -> Attrs {
489518 let _p = tracing:: info_span!( "attrs_query" ) . entered ( ) ;
490519 // FIXME: this should use `Trace` to avoid duplication in `source_map` below
491- let raw_attrs = match def {
520+ match def {
492521 AttrDefId :: ModuleId ( module) => {
493522 let def_map = module. def_map ( db) ;
494523 let mod_data = & def_map[ module. local_id ] ;
495524
496- match mod_data. origin {
525+ let raw_attrs = match mod_data. origin {
497526 ModuleOrigin :: File { definition, declaration_tree_id, .. } => {
498527 let decl_attrs = declaration_tree_id
499528 . item_tree ( db)
@@ -515,77 +544,73 @@ impl AttrsWithOwner {
515544 let tree = db. block_item_tree ( id) ;
516545 tree. raw_attrs ( AttrOwner :: TopLevel ) . clone ( )
517546 }
518- }
519- }
520- AttrDefId :: FieldId ( it) => {
521- return db. fields_attrs ( it. parent ) [ it. local_id ] . clone ( ) ;
547+ } ;
548+ Attrs :: expand_cfg_attr ( db, module. krate , raw_attrs)
522549 }
523- AttrDefId :: EnumVariantId ( it) => attrs_from_item_tree_loc ( db, it) ,
550+ AttrDefId :: FieldId ( it) => db. fields_attrs ( it. parent ) [ it. local_id ] . clone ( ) ,
551+ AttrDefId :: EnumVariantId ( it) => attrs_from_ast_id_loc ( db, it) ,
524552 AttrDefId :: AdtId ( it) => match it {
525- AdtId :: StructId ( it) => attrs_from_item_tree_loc ( db, it) ,
526- AdtId :: EnumId ( it) => attrs_from_item_tree_loc ( db, it) ,
527- AdtId :: UnionId ( it) => attrs_from_item_tree_loc ( db, it) ,
553+ AdtId :: StructId ( it) => attrs_from_ast_id_loc ( db, it) ,
554+ AdtId :: EnumId ( it) => attrs_from_ast_id_loc ( db, it) ,
555+ AdtId :: UnionId ( it) => attrs_from_ast_id_loc ( db, it) ,
528556 } ,
529- AttrDefId :: TraitId ( it) => attrs_from_item_tree_loc ( db, it) ,
530- AttrDefId :: TraitAliasId ( it) => attrs_from_item_tree_loc ( db, it) ,
557+ AttrDefId :: TraitId ( it) => attrs_from_ast_id_loc ( db, it) ,
558+ AttrDefId :: TraitAliasId ( it) => attrs_from_ast_id_loc ( db, it) ,
531559 AttrDefId :: MacroId ( it) => match it {
532- MacroId :: Macro2Id ( it) => attrs_from_item_tree_loc ( db, it) ,
533- MacroId :: MacroRulesId ( it) => attrs_from_item_tree_loc ( db, it) ,
534- MacroId :: ProcMacroId ( it) => attrs_from_item_tree_loc ( db, it) ,
560+ MacroId :: Macro2Id ( it) => attrs_from_ast_id_loc ( db, it) ,
561+ MacroId :: MacroRulesId ( it) => attrs_from_ast_id_loc ( db, it) ,
562+ MacroId :: ProcMacroId ( it) => attrs_from_ast_id_loc ( db, it) ,
535563 } ,
536- AttrDefId :: ImplId ( it) => attrs_from_item_tree_loc ( db, it) ,
537- AttrDefId :: ConstId ( it) => attrs_from_item_tree_loc ( db, it) ,
538- AttrDefId :: StaticId ( it) => attrs_from_item_tree_loc ( db, it) ,
539- AttrDefId :: FunctionId ( it) => attrs_from_item_tree_loc ( db, it) ,
540- AttrDefId :: TypeAliasId ( it) => attrs_from_item_tree_loc ( db, it) ,
564+ AttrDefId :: ImplId ( it) => attrs_from_ast_id_loc ( db, it) ,
565+ AttrDefId :: ConstId ( it) => attrs_from_ast_id_loc ( db, it) ,
566+ AttrDefId :: StaticId ( it) => attrs_from_ast_id_loc ( db, it) ,
567+ AttrDefId :: FunctionId ( it) => attrs_from_ast_id_loc ( db, it) ,
568+ AttrDefId :: TypeAliasId ( it) => attrs_from_ast_id_loc ( db, it) ,
541569 AttrDefId :: GenericParamId ( it) => match it {
542570 GenericParamId :: ConstParamId ( it) => {
543571 let src = it. parent ( ) . child_source ( db) ;
544572 // FIXME: We should be never getting `None` here.
545- return Attrs ( match src. value . get ( it. local_id ( ) ) {
573+ Attrs ( match src. value . get ( it. local_id ( ) ) {
546574 Some ( val) => RawAttrs :: new_expanded (
547575 db,
548576 val,
549577 db. span_map ( src. file_id ) . as_ref ( ) ,
550578 def. krate ( db) . cfg_options ( db) ,
551579 ) ,
552580 None => RawAttrs :: EMPTY ,
553- } ) ;
581+ } )
554582 }
555583 GenericParamId :: TypeParamId ( it) => {
556584 let src = it. parent ( ) . child_source ( db) ;
557585 // FIXME: We should be never getting `None` here.
558- return Attrs ( match src. value . get ( it. local_id ( ) ) {
586+ Attrs ( match src. value . get ( it. local_id ( ) ) {
559587 Some ( val) => RawAttrs :: new_expanded (
560588 db,
561589 val,
562590 db. span_map ( src. file_id ) . as_ref ( ) ,
563591 def. krate ( db) . cfg_options ( db) ,
564592 ) ,
565593 None => RawAttrs :: EMPTY ,
566- } ) ;
594+ } )
567595 }
568596 GenericParamId :: LifetimeParamId ( it) => {
569597 let src = it. parent . child_source ( db) ;
570598 // FIXME: We should be never getting `None` here.
571- return Attrs ( match src. value . get ( it. local_id ) {
599+ Attrs ( match src. value . get ( it. local_id ) {
572600 Some ( val) => RawAttrs :: new_expanded (
573601 db,
574602 val,
575603 db. span_map ( src. file_id ) . as_ref ( ) ,
576604 def. krate ( db) . cfg_options ( db) ,
577605 ) ,
578606 None => RawAttrs :: EMPTY ,
579- } ) ;
607+ } )
580608 }
581609 } ,
582- AttrDefId :: ExternBlockId ( it) => attrs_from_item_tree_loc ( db, it) ,
583- AttrDefId :: ExternCrateId ( it) => attrs_from_item_tree_loc ( db, it) ,
584- AttrDefId :: UseId ( it) => attrs_from_item_tree_loc ( db, it) ,
585- } ;
586-
587- let attrs = raw_attrs. expand_cfg_attr ( db, def. krate ( db) ) ;
588- Attrs ( attrs)
610+ AttrDefId :: ExternBlockId ( it) => attrs_from_ast_id_loc ( db, it) ,
611+ AttrDefId :: ExternCrateId ( it) => attrs_from_ast_id_loc ( db, it) ,
612+ AttrDefId :: UseId ( it) => attrs_from_ast_id_loc ( db, it) ,
613+ }
589614 }
590615
591616 pub fn source_map ( & self , db : & dyn DefDatabase ) -> AttrSourceMap {
@@ -787,14 +812,15 @@ fn any_has_attrs<'db>(
787812 id. lookup ( db) . source ( db) . map ( ast:: AnyHasAttrs :: new)
788813}
789814
790- fn attrs_from_item_tree_loc < ' db , N : ItemTreeNode > (
815+ fn attrs_from_ast_id_loc < ' db , N : AstIdNode + HasAttrs > (
791816 db : & ( dyn DefDatabase + ' db ) ,
792- lookup : impl Lookup < Database = dyn DefDatabase , Data = impl ItemTreeLoc < Id = N > > ,
793- ) -> RawAttrs {
794- let id = lookup. lookup ( db) . item_tree_id ( ) ;
795- let tree = id. item_tree ( db) ;
796- let attr_owner = N :: attr_owner ( id. value ) ;
797- tree. raw_attrs ( attr_owner) . clone ( )
817+ lookup : impl Lookup < Database = dyn DefDatabase , Data = impl AstIdLoc < Ast = N > + HasModule > ,
818+ ) -> Attrs {
819+ let loc = lookup. lookup ( db) ;
820+ let source = loc. source ( db) ;
821+ let span_map = db. span_map ( source. file_id ) ;
822+ let cfg_options = loc. krate ( db) . cfg_options ( db) ;
823+ Attrs ( RawAttrs :: new_expanded ( db, & source. value , span_map. as_ref ( ) , cfg_options) )
798824}
799825
800826pub ( crate ) fn fields_attrs_source_map (
0 commit comments