-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Allow lifetime repeats in macros: $($x)'a* #20000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow lifetime repeats in macros: $($x)'a* #20000
Conversation
64ca12c
to
23a511f
Compare
This works in rustc. This change isn't motivated by any real code. I just learned about it and decided to see why it doesn't work with rust-analyzer.
23a511f
to
a7c0953
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm worried about the incorrect test. Please investigate that. Other than that, LGTM.
aa90dc7
to
12226b7
Compare
(IDENT, _) if curr_kind.is_keyword(Edition::CURRENT) => " ", | ||
(_, IDENT) if prev_kind.is_keyword(Edition::CURRENT) => " ", | ||
(IDENT | LIFETIME_IDENT, _) | ||
if curr_kind.is_keyword(Edition::CURRENT) || curr_kind.is_literal() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is is_any_identifier()
for that (search for it, I don't remember where it is defined).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not include LIFETIME_IDENT but I will try adding that and running all tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests fail; I don't think is_any_identifier() is supposed to match LIFETIME_IDENT. It just matches identifiers and keywords (which are much closer to identifiers than part of a lifetime is)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you need to match lifetimes separately. But still use it, e.g. it avoids encoding the assumption that editions only add keywords.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay I've updated the lines I changed to use is_any_identifier. I didn't update the whole match: some of those seem to actually match keywords and identifiers differently, and changing that messes with the diff:
for token in iter::successors(expn.first_token(), |t| t.next_token())
.take_while(|token| token.text_range().start() < expn.text_range().end())
{
let curr_kind = token.kind();
let space = match (prev_kind, curr_kind) {
_ if prev_kind.is_trivia() || curr_kind.is_trivia() => "",
_ if prev_kind.is_literal() && !curr_kind.is_punct() => " ",
(T!['{'], T!['}']) => "",
(T![=], _) | (_, T![=]) => " ",
(_, T!['{']) => " ",
(T![;] | T!['{'] | T!['}'], _) => "\n",
(_, T!['}']) => "\n",
_ if (prev_kind.is_any_identifier()
|| prev_kind == LIFETIME_IDENT
|| prev_kind.is_literal())
&& (curr_kind.is_any_identifier()
|| curr_kind == LIFETIME_IDENT
|| curr_kind.is_literal()) =>
{
" "
}
(T![>], IDENT) => " ",
(T![>], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
(T![->], _) | (_, T![->]) => " ",
(T![&&], _) | (_, T![&&]) => " ",
(T![,], _) => " ",
(T![:], IDENT | T!['(']) => " ",
(T![:], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
(T![fn], T!['(']) => "",
(T![']'], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
(T![']'], T![#]) => "\n",
(T![Self], T![::]) => "",
_ if prev_kind.is_keyword(Edition::CURRENT) => " ",
_ => "",
};
It's probably okay to change a bunch of generated test cases if I'm making the output better, but some of them get better and some of them get worse. Not sure if I should be putting more work into this function. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be more specific
_ if prev_kind.is_keyword(Edition::CURRENT) => " ",
Changing this to is_any_identifier
means there is now a space after every identifier which is not great (like x ::y ::z
). Then I tried removing space between idents and puncts and get impl X for&'a mut T
.
Just wanted to avoid a big diff that messes with git blame without a good reason. I don't see why this code needs to treat keywords and identifiers the same anyway - it's only used for test cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's okay now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
This works in rustc. This change isn't motivated by any real code. I just learned about it and decided to see why it doesn't work with rust-analyzer.