@@ -206,6 +206,19 @@ fn traverse(
206
206
let is_unlinked = sema. to_module_def ( file_id) . is_none ( ) ;
207
207
let mut bindings_shadow_count: FxHashMap < Name , u32 > = FxHashMap :: default ( ) ;
208
208
209
+ enum AttrOrDerive {
210
+ Attr ( ast:: Item ) ,
211
+ Derive ( ast:: Item ) ,
212
+ }
213
+
214
+ impl AttrOrDerive {
215
+ fn item ( & self ) -> & ast:: Item {
216
+ match self {
217
+ AttrOrDerive :: Attr ( item) | AttrOrDerive :: Derive ( item) => item,
218
+ }
219
+ }
220
+ }
221
+
209
222
let mut tt_level = 0 ;
210
223
let mut attr_or_derive_item = None ;
211
224
let mut current_macro: Option < ast:: Macro > = None ;
@@ -260,7 +273,7 @@ fn traverse(
260
273
261
274
if attr_or_derive_item. is_none ( ) {
262
275
if sema. is_attr_macro_call ( & item) {
263
- attr_or_derive_item = Some ( item) ;
276
+ attr_or_derive_item = Some ( AttrOrDerive :: Attr ( item) ) ;
264
277
} else {
265
278
let adt = match item {
266
279
ast:: Item :: Enum ( it) => Some ( ast:: Adt :: Enum ( it) ) ,
@@ -270,7 +283,8 @@ fn traverse(
270
283
} ;
271
284
match adt {
272
285
Some ( adt) if sema. is_derive_annotated ( & adt) => {
273
- attr_or_derive_item = Some ( ast:: Item :: from ( adt) ) ;
286
+ attr_or_derive_item =
287
+ Some ( AttrOrDerive :: Derive ( ast:: Item :: from ( adt) ) ) ;
274
288
}
275
289
_ => ( ) ,
276
290
}
@@ -292,7 +306,9 @@ fn traverse(
292
306
current_macro = None ;
293
307
macro_highlighter = MacroHighlighter :: default ( ) ;
294
308
}
295
- Some ( item) if attr_or_derive_item. as_ref ( ) . map_or ( false , |it| * it == item) => {
309
+ Some ( item)
310
+ if attr_or_derive_item. as_ref ( ) . map_or ( false , |it| * it. item ( ) == item) =>
311
+ {
296
312
attr_or_derive_item = None ;
297
313
}
298
314
_ => ( ) ,
@@ -330,15 +346,26 @@ fn traverse(
330
346
331
347
// Descending tokens into macros is expensive even if no descending occurs, so make sure
332
348
// that we actually are in a position where descending is possible.
333
- let in_macro = tt_level > 0 || attr_or_derive_item. is_some ( ) ;
349
+ let in_macro = tt_level > 0
350
+ || match attr_or_derive_item {
351
+ Some ( AttrOrDerive :: Attr ( _) ) => true ,
352
+ Some ( AttrOrDerive :: Derive ( _) ) => inside_attribute,
353
+ None => false ,
354
+ } ;
334
355
let descended_element = if in_macro {
335
356
// Attempt to descend tokens into macro-calls.
336
357
match element {
337
358
NodeOrToken :: Token ( token) if token. kind ( ) != COMMENT => {
338
- let token = sema. descend_into_macros_single ( token) ;
359
+ let token = match attr_or_derive_item {
360
+ Some ( AttrOrDerive :: Attr ( _) ) => {
361
+ sema. descend_into_macros_with_kind_preference ( token)
362
+ }
363
+ Some ( AttrOrDerive :: Derive ( _) ) | None => {
364
+ sema. descend_into_macros_single ( token)
365
+ }
366
+ } ;
339
367
match token. parent ( ) . and_then ( ast:: NameLike :: cast) {
340
368
// Remap the token into the wrapping single token nodes
341
- // FIXME: if the node doesn't resolve, we also won't do token based highlighting!
342
369
Some ( parent) => match ( token. kind ( ) , parent. syntax ( ) . kind ( ) ) {
343
370
( T ! [ self ] | T ! [ ident] , NAME | NAME_REF ) => NodeOrToken :: Node ( parent) ,
344
371
( T ! [ self ] | T ! [ super ] | T ! [ crate ] | T ! [ Self ] , NAME_REF ) => {
0 commit comments