Skip to content
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

Should tokens passed through macro_rules be able to join? #127123

Open
petrochenkov opened this issue Jun 29, 2024 · 2 comments
Open

Should tokens passed through macro_rules be able to join? #127123

petrochenkov opened this issue Jun 29, 2024 · 2 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-proc-macro-back-compat Area: Backwards compatibility hacks for proc macros C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. WG-macros Working group: Macros

Comments

@petrochenkov
Copy link
Contributor

petrochenkov commented Jun 29, 2024

Should this example

macro_rules! mac {
    ($a:tt sep $b:tt) => { 1 $a$b 2 } 
}

fn main() {
    mac!(= sep =);
}

emit 1 == 2 and compile successfully?
Or, in other words, should the first emitted = have the Spacing::Joint set, if the output is processed by a proc macro?

We need some well-defined rule for setting spacing for tokens produced from macro variables.

Possible alternatives:

    • Always use Joint.
      • This is very unreasonable.
    • Always use Alone.
      • This is the first reasonable alternative.
    • Inherit from the passed token - that means Alone in the example above because there is a space after the first = in mac!(= sep =).
      • Probably unreasonable, the token sequence in the input have little relation to the output sequence for which we emit the spacing, in the example above it is demonstrated by sep being present in the input but not in the output.
      • Note: the issue is about single passed token trees (or last token trees in sequences), tokens passed in the middle of something like $($tt)* should of course use this option.
    • Inherit from the macro parameter declaration - i.e. $a:tt in the example (or just the $a part of it).
      • This doesn't seem reasonable to me
    • Inherit from the macro parameter use, that means Joint in the example above because there is no space after $a in 1 $a$b 2.
      • This is the second reasonable alternative.

Right now the spacing is emitted inconsistently, sometimes it follows the rule 2., sometimes 3..
Adopting any consistent rule may cause breakage (@nnethercote may remember which exactly) and needs to go through crater.

  • I would personally try the rule 5. first, because it gives macro author freedom to control and change spacing as they want, unlike rule 2. that prevents joining entirely.
  • However we may be forced to adopt rule 2. instead due to backward compatibility issues. It would be less flexible, but macro variables creating a "barrier" for joining is also a reasonable enough model.
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 29, 2024
@petrochenkov petrochenkov added T-lang Relevant to the language team, which will review and decide on the PR/issue. A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-proc-macro-back-compat Area: Backwards compatibility hacks for proc macros WG-macros Working group: Macros labels Jun 29, 2024
@petrochenkov
Copy link
Contributor Author

Partially switching tokens from tt matcher to Spacing::Alone was tested with crater in #119412 (comment) and there were no regressions.
(Group tokens and tokens in sequences were not switched.)

@nnethercote
Copy link
Contributor

I saw some cases like this in #125174, where identifiers were being joined together. At first I thought about inheriting (from either use or declaration, or a combination), but after a while I concluded that Alone was the most sensible thing.

@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 5, 2024
@jieyouxu jieyouxu added the C-discussion Category: Discussion or questions that doesn't represent real issues. label Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-proc-macro-back-compat Area: Backwards compatibility hacks for proc macros C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. WG-macros Working group: Macros
Projects
None yet
Development

No branches or pull requests

5 participants