@@ -206,6 +206,19 @@ fn traverse(
206206 let is_unlinked = sema. to_module_def ( file_id) . is_none ( ) ;
207207 let mut bindings_shadow_count: FxHashMap < Name , u32 > = FxHashMap :: default ( ) ;
208208
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+
209222 let mut tt_level = 0 ;
210223 let mut attr_or_derive_item = None ;
211224 let mut current_macro: Option < ast:: Macro > = None ;
@@ -260,7 +273,7 @@ fn traverse(
260273
261274 if attr_or_derive_item. is_none ( ) {
262275 if sema. is_attr_macro_call ( & item) {
263- attr_or_derive_item = Some ( item) ;
276+ attr_or_derive_item = Some ( AttrOrDerive :: Attr ( item) ) ;
264277 } else {
265278 let adt = match item {
266279 ast:: Item :: Enum ( it) => Some ( ast:: Adt :: Enum ( it) ) ,
@@ -270,7 +283,8 @@ fn traverse(
270283 } ;
271284 match adt {
272285 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) ) ) ;
274288 }
275289 _ => ( ) ,
276290 }
@@ -292,7 +306,9 @@ fn traverse(
292306 current_macro = None ;
293307 macro_highlighter = MacroHighlighter :: default ( ) ;
294308 }
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+ {
296312 attr_or_derive_item = None ;
297313 }
298314 _ => ( ) ,
@@ -330,15 +346,26 @@ fn traverse(
330346
331347 // Descending tokens into macros is expensive even if no descending occurs, so make sure
332348 // 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+ } ;
334355 let descended_element = if in_macro {
335356 // Attempt to descend tokens into macro-calls.
336357 match element {
337358 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+ } ;
339367 match token. parent ( ) . and_then ( ast:: NameLike :: cast) {
340368 // 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!
342369 Some ( parent) => match ( token. kind ( ) , parent. syntax ( ) . kind ( ) ) {
343370 ( T ! [ self ] | T ! [ ident] , NAME | NAME_REF ) => NodeOrToken :: Node ( parent) ,
344371 ( T ! [ self ] | T ! [ super ] | T ! [ crate ] | T ! [ Self ] , NAME_REF ) => {
0 commit comments