@@ -106,9 +106,8 @@ impl RawAttrs {
106
106
. cloned ( )
107
107
. chain ( b. slice . iter ( ) . map ( |it| {
108
108
let mut it = it. clone ( ) ;
109
- it. id . id = ( it. id . ast_index ( ) as u32 + last_ast_index)
110
- | ( ( it. id . cfg_attr_index ( ) . unwrap_or ( 0 ) as u32 )
111
- << AttrId :: AST_INDEX_BITS ) ;
109
+ let id = it. id . ast_index ( ) as u32 + last_ast_index;
110
+ it. id = AttrId :: new ( id as usize , it. id . is_inner_attr ( ) ) ;
112
111
it
113
112
} ) )
114
113
. collect :: < Vec < _ > > ( ) ;
@@ -128,40 +127,38 @@ impl RawAttrs {
128
127
}
129
128
130
129
let cfg_options = krate. cfg_options ( db) ;
131
- let new_attrs =
132
- self . iter ( )
133
- . flat_map ( |attr| -> SmallVec < [ _ ; 1 ] > {
134
- let is_cfg_attr =
135
- attr. path . as_ident ( ) . is_some_and ( |name| * name == sym:: cfg_attr. clone ( ) ) ;
136
- if !is_cfg_attr {
137
- return smallvec ! [ attr. clone( ) ] ;
138
- }
130
+ let new_attrs = self
131
+ . iter ( )
132
+ . flat_map ( |attr| -> SmallVec < [ _ ; 1 ] > {
133
+ let is_cfg_attr =
134
+ attr. path . as_ident ( ) . is_some_and ( |name| * name == sym:: cfg_attr. clone ( ) ) ;
135
+ if !is_cfg_attr {
136
+ return smallvec ! [ attr. clone( ) ] ;
137
+ }
139
138
140
- let subtree = match attr. token_tree_value ( ) {
141
- Some ( it) => it,
142
- _ => return smallvec ! [ attr. clone( ) ] ,
143
- } ;
144
-
145
- let ( cfg, parts) = match parse_cfg_attr_input ( subtree) {
146
- Some ( it) => it,
147
- None => return smallvec ! [ attr. clone( ) ] ,
148
- } ;
149
- let index = attr. id ;
150
- let attrs = parts. enumerate ( ) . take ( 1 << AttrId :: CFG_ATTR_BITS ) . filter_map (
151
- |( idx, attr) | Attr :: from_tt ( db, attr, index. with_cfg_attr ( idx) ) ,
152
- ) ;
153
-
154
- let cfg = TopSubtree :: from_token_trees ( subtree. top_subtree ( ) . delimiter , cfg) ;
155
- let cfg = CfgExpr :: parse ( & cfg) ;
156
- if cfg_options. check ( & cfg) == Some ( false ) {
157
- smallvec ! [ ]
158
- } else {
159
- cov_mark:: hit!( cfg_attr_active) ;
160
-
161
- attrs. collect ( )
162
- }
163
- } )
164
- . collect :: < Vec < _ > > ( ) ;
139
+ let subtree = match attr. token_tree_value ( ) {
140
+ Some ( it) => it,
141
+ _ => return smallvec ! [ attr. clone( ) ] ,
142
+ } ;
143
+
144
+ let ( cfg, parts) = match parse_cfg_attr_input ( subtree) {
145
+ Some ( it) => it,
146
+ None => return smallvec ! [ attr. clone( ) ] ,
147
+ } ;
148
+ let index = attr. id ;
149
+ let attrs = parts. filter_map ( |attr| Attr :: from_tt ( db, attr, index) ) ;
150
+
151
+ let cfg = TopSubtree :: from_token_trees ( subtree. top_subtree ( ) . delimiter , cfg) ;
152
+ let cfg = CfgExpr :: parse ( & cfg) ;
153
+ if cfg_options. check ( & cfg) == Some ( false ) {
154
+ smallvec ! [ ]
155
+ } else {
156
+ cov_mark:: hit!( cfg_attr_active) ;
157
+
158
+ attrs. collect ( )
159
+ }
160
+ } )
161
+ . collect :: < Vec < _ > > ( ) ;
165
162
let entries = if new_attrs. is_empty ( ) {
166
163
None
167
164
} else {
@@ -183,25 +180,21 @@ pub struct AttrId {
183
180
// FIXME: This only handles a single level of cfg_attr nesting
184
181
// that is `#[cfg_attr(all(), cfg_attr(all(), cfg(any())))]` breaks again
185
182
impl AttrId {
186
- const CFG_ATTR_BITS : usize = 7 ;
187
183
const AST_INDEX_MASK : usize = 0x00FF_FFFF ;
188
- const AST_INDEX_BITS : usize = Self :: AST_INDEX_MASK . count_ones ( ) as usize ;
189
- const CFG_ATTR_SET_BITS : u32 = 1 << 31 ;
184
+ const INNER_ATTR_BIT : usize = 1 << 31 ;
190
185
191
- pub fn ast_index ( & self ) -> usize {
192
- self . id as usize & Self :: AST_INDEX_MASK
186
+ pub fn new ( id : usize , is_inner : bool ) -> Self {
187
+ let id = id & Self :: AST_INDEX_MASK ;
188
+ let id = if is_inner { id | Self :: INNER_ATTR_BIT } else { id } ;
189
+ Self { id : id as u32 }
193
190
}
194
191
195
- pub fn cfg_attr_index ( & self ) -> Option < usize > {
196
- if self . id & Self :: CFG_ATTR_SET_BITS == 0 {
197
- None
198
- } else {
199
- Some ( self . id as usize >> Self :: AST_INDEX_BITS )
200
- }
192
+ pub fn ast_index ( & self ) -> usize {
193
+ self . id as usize & Self :: AST_INDEX_MASK
201
194
}
202
195
203
- pub fn with_cfg_attr ( self , idx : usize ) -> AttrId {
204
- AttrId { id : self . id | ( ( idx as u32 ) << Self :: AST_INDEX_BITS ) | Self :: CFG_ATTR_SET_BITS }
196
+ pub fn is_inner_attr ( & self ) -> bool {
197
+ ( self . id as usize ) & Self :: INNER_ATTR_BIT != 0
205
198
}
206
199
}
207
200
@@ -439,13 +432,18 @@ fn unescape(s: &str) -> Option<Cow<'_, str>> {
439
432
pub fn collect_attrs (
440
433
owner : & dyn ast:: HasAttrs ,
441
434
) -> impl Iterator < Item = ( AttrId , Either < ast:: Attr , ast:: Comment > ) > {
442
- let inner_attrs = inner_attributes ( owner. syntax ( ) ) . into_iter ( ) . flatten ( ) ;
443
- let outer_attrs =
444
- ast:: AttrDocCommentIter :: from_syntax_node ( owner. syntax ( ) ) . filter ( |el| match el {
435
+ let inner_attrs =
436
+ inner_attributes ( owner. syntax ( ) ) . into_iter ( ) . flatten ( ) . map ( |attr| ( attr, true ) ) ;
437
+ let outer_attrs = ast:: AttrDocCommentIter :: from_syntax_node ( owner. syntax ( ) )
438
+ . filter ( |el| match el {
445
439
Either :: Left ( attr) => attr. kind ( ) . is_outer ( ) ,
446
440
Either :: Right ( comment) => comment. is_outer ( ) ,
447
- } ) ;
448
- outer_attrs. chain ( inner_attrs) . enumerate ( ) . map ( |( id, attr) | ( AttrId { id : id as u32 } , attr) )
441
+ } )
442
+ . map ( |attr| ( attr, false ) ) ;
443
+ outer_attrs
444
+ . chain ( inner_attrs)
445
+ . enumerate ( )
446
+ . map ( |( id, ( attr, is_inner) ) | ( AttrId :: new ( id, is_inner) , attr) )
449
447
}
450
448
451
449
fn inner_attributes (
0 commit comments