Do not remove the original token when descending into derives

This caused rename to remove both, because it couldn't rename the derive-expanded one.

I spent some time trying to create a test for this, before giving up. But I checked manually that this works.
This commit is contained in:
Chayim Refael Friedman 2025-08-05 01:04:21 +03:00
parent 47845d6097
commit ea140ef0a8

View File

@ -1241,29 +1241,27 @@ impl<'db> SemanticsImpl<'db> {
adt, adt,
)) ))
})?; })?;
let mut res = None;
for (_, derive_attr, derives) in derives { for (_, derive_attr, derives) in derives {
// as there may be multiple derives registering the same helper // as there may be multiple derives registering the same helper
// name, we gotta make sure to call this for all of them! // name, we gotta make sure to call this for all of them!
// FIXME: We need to call `f` for all of them as well though! // FIXME: We need to call `f` for all of them as well though!
res = res.or(process_expansion_for_token( process_expansion_for_token(ctx, &mut stack, derive_attr);
ctx,
&mut stack,
derive_attr,
));
for derive in derives.into_iter().flatten() { for derive in derives.into_iter().flatten() {
res = res process_expansion_for_token(ctx, &mut stack, derive);
.or(process_expansion_for_token(ctx, &mut stack, derive));
} }
} }
// remove all tokens that are within the derives expansion // remove all tokens that are within the derives expansion
filter_duplicates(tokens, adt.syntax().text_range()); filter_duplicates(tokens, adt.syntax().text_range());
Some(res) Some(())
}); });
// if we found derives, we can early exit. There is no way we can be in any // if we found derives, we can early exit. There is no way we can be in any
// macro call at this point given we are not in a token tree // macro call at this point given we are not in a token tree
if let Some(res) = res { if let Some(()) = res {
return res; // Note: derives do not remap the original token. Furthermore, we want
// the original token to be before the derives in the list, because if they
// upmap to the same token and we deduplicate them (e.g. in rename), we
// want the original token to remain, not the derive.
return None;
} }
} }
// Then check for token trees, that means we are either in a function-like macro or // Then check for token trees, that means we are either in a function-like macro or