@@ -14,6 +14,7 @@ use intern::{Symbol, sym};
14
14
use la_arena:: { ArenaMap , Idx , RawIdx } ;
15
15
use mbe:: DelimiterKind ;
16
16
use rustc_abi:: ReprOptions ;
17
+ use span:: AstIdNode ;
17
18
use syntax:: {
18
19
AstPtr ,
19
20
ast:: { self , HasAttrs } ,
@@ -22,10 +23,10 @@ use triomphe::Arc;
22
23
use tt:: iter:: { TtElement , TtIter } ;
23
24
24
25
use crate :: {
25
- AdtId , AttrDefId , GenericParamId , HasModule , ItemTreeLoc , LocalFieldId , Lookup , MacroId ,
26
+ AdtId , AstIdLoc , AttrDefId , GenericParamId , HasModule , LocalFieldId , Lookup , MacroId ,
26
27
VariantId ,
27
28
db:: DefDatabase ,
28
- item_tree:: { AttrOwner , FieldParent , ItemTreeNode } ,
29
+ item_tree:: AttrOwner ,
29
30
lang_item:: LangItem ,
30
31
nameres:: { ModuleOrigin , ModuleSource } ,
31
32
src:: { HasChildSource , HasSource } ,
@@ -42,6 +43,15 @@ pub struct AttrsWithOwner {
42
43
}
43
44
44
45
impl 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
+
45
55
pub fn get ( & self , id : AttrId ) -> Option < & Attr > {
46
56
( * * self ) . iter ( ) . find ( |attr| attr. id == id)
47
57
}
@@ -94,44 +104,64 @@ impl Attrs {
94
104
v : VariantId ,
95
105
) -> Arc < ArenaMap < LocalFieldId , Attrs > > {
96
106
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
98
107
let mut res = ArenaMap :: default ( ) ;
99
- let item_tree;
100
- let ( parent, fields, krate) = match v {
108
+ let ( fields, file_id, krate) = match v {
101
109
VariantId :: EnumVariantId ( it) => {
102
110
let loc = it. lookup ( db) ;
103
111
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)
107
114
}
108
115
VariantId :: StructId ( it) => {
109
116
let loc = it. lookup ( db) ;
110
117
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)
114
120
}
115
121
VariantId :: UnionId ( it) => {
116
122
let loc = it. lookup ( db) ;
117
123
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
+ )
121
130
}
122
131
} ;
132
+ let Some ( fields) = fields else {
133
+ return Arc :: new ( res) ;
134
+ } ;
123
135
124
136
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
+ }
132
161
}
133
162
}
134
163
164
+ res. shrink_to_fit ( ) ;
135
165
Arc :: new ( res)
136
166
}
137
167
}
@@ -167,11 +197,10 @@ impl Attrs {
167
197
}
168
198
169
199
#[ 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
+ } )
175
204
}
176
205
177
206
#[ inline]
@@ -488,12 +517,12 @@ impl AttrsWithOwner {
488
517
pub ( crate ) fn attrs_query ( db : & dyn DefDatabase , def : AttrDefId ) -> Attrs {
489
518
let _p = tracing:: info_span!( "attrs_query" ) . entered ( ) ;
490
519
// FIXME: this should use `Trace` to avoid duplication in `source_map` below
491
- let raw_attrs = match def {
520
+ match def {
492
521
AttrDefId :: ModuleId ( module) => {
493
522
let def_map = module. def_map ( db) ;
494
523
let mod_data = & def_map[ module. local_id ] ;
495
524
496
- match mod_data. origin {
525
+ let raw_attrs = match mod_data. origin {
497
526
ModuleOrigin :: File { definition, declaration_tree_id, .. } => {
498
527
let decl_attrs = declaration_tree_id
499
528
. item_tree ( db)
@@ -515,77 +544,73 @@ impl AttrsWithOwner {
515
544
let tree = db. block_item_tree ( id) ;
516
545
tree. raw_attrs ( AttrOwner :: TopLevel ) . clone ( )
517
546
}
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)
522
549
}
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) ,
524
552
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) ,
528
556
} ,
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) ,
531
559
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) ,
535
563
} ,
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) ,
541
569
AttrDefId :: GenericParamId ( it) => match it {
542
570
GenericParamId :: ConstParamId ( it) => {
543
571
let src = it. parent ( ) . child_source ( db) ;
544
572
// 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 ( ) ) {
546
574
Some ( val) => RawAttrs :: new_expanded (
547
575
db,
548
576
val,
549
577
db. span_map ( src. file_id ) . as_ref ( ) ,
550
578
def. krate ( db) . cfg_options ( db) ,
551
579
) ,
552
580
None => RawAttrs :: EMPTY ,
553
- } ) ;
581
+ } )
554
582
}
555
583
GenericParamId :: TypeParamId ( it) => {
556
584
let src = it. parent ( ) . child_source ( db) ;
557
585
// 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 ( ) ) {
559
587
Some ( val) => RawAttrs :: new_expanded (
560
588
db,
561
589
val,
562
590
db. span_map ( src. file_id ) . as_ref ( ) ,
563
591
def. krate ( db) . cfg_options ( db) ,
564
592
) ,
565
593
None => RawAttrs :: EMPTY ,
566
- } ) ;
594
+ } )
567
595
}
568
596
GenericParamId :: LifetimeParamId ( it) => {
569
597
let src = it. parent . child_source ( db) ;
570
598
// 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 ) {
572
600
Some ( val) => RawAttrs :: new_expanded (
573
601
db,
574
602
val,
575
603
db. span_map ( src. file_id ) . as_ref ( ) ,
576
604
def. krate ( db) . cfg_options ( db) ,
577
605
) ,
578
606
None => RawAttrs :: EMPTY ,
579
- } ) ;
607
+ } )
580
608
}
581
609
} ,
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
+ }
589
614
}
590
615
591
616
pub fn source_map ( & self , db : & dyn DefDatabase ) -> AttrSourceMap {
@@ -787,14 +812,15 @@ fn any_has_attrs<'db>(
787
812
id. lookup ( db) . source ( db) . map ( ast:: AnyHasAttrs :: new)
788
813
}
789
814
790
- fn attrs_from_item_tree_loc < ' db , N : ItemTreeNode > (
815
+ fn attrs_from_ast_id_loc < ' db , N : AstIdNode + HasAttrs > (
791
816
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) )
798
824
}
799
825
800
826
pub ( crate ) fn fields_attrs_source_map (
0 commit comments