8000 Allow lifetime repeats in macros: $($x)'a* by tadeokondrak · Pull Request #20000 · rust-lang/rust-analyzer · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

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

Merged
merged 3 commits into from
Jun 15, 2025

Conversation

tadeokondrak
Copy link
Contributor

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.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 13, 2025
@tadeokondrak tadeokondrak force-pushed the lifetime-repeat-macro branch 2 times, most recently from 64ca12c to 23a511f Compare June 14, 2025 00:03
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.
@tadeokondrak tadeokondrak force-pushed the lifetime-repeat-macro branch from 23a511f to a7c0953 Compare June 14, 2025 00:17
Copy link
Contributor
@ChayimFriedman2 ChayimFriedman2 left a 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.

@tadeokondrak tadeokondrak force-pushed the lifetime-repeat-macro branch from aa90dc7 to 12226b7 Compare June 15, 2025 15:43
(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() =>
Copy link
Contributor

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).

Copy link
Contributor Author

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

Copy link
Contributor Author

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)

Copy link
Contributor

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.

Copy link
Contributor Author
@tadeokondrak tadeokondrak Jun 15, 2025

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?

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor
@ChayimFriedman2 ChayimFriedman2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@ChayimFriedman2 ChayimFriedman2 added this pull request to the merge queue Jun 15, 2025
Merged via the queue into rust-lang:master with commit a207299 Jun 15, 2025
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0