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

Add a new concat metavar expr #118958

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

c410-f3r
Copy link
Contributor

Revival of #111930

Giving it another try now that #117050 was merged.

With the new rules, meta-variable expressions must be referenced with a dollar sign ($) and this can cause misunderstands with $concat.

macro_rules! foo {
    ( $bar:ident ) => {
        const ${concat(VAR, bar)}: i32 = 1;
    };
}

// Will produce `VARbar` instead of `VAR_123`
foo!(_123);

In other words, forgetting the dollar symbol can produce undesired outputs.

cc #29599

@rustbot
Copy link
Collaborator

rustbot commented Dec 15, 2023

r? @WaffleLapkin

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 15, 2023
compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/metavar_expr.rs Show resolved Hide resolved
compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/transcribe.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/transcribe.rs Outdated Show resolved Hide resolved
tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs Outdated Show resolved Hide resolved
@WaffleLapkin WaffleLapkin added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 17, 2023
@rust-log-analyzer

This comment has been minimized.

@c410-f3r c410-f3r force-pushed the concat-again branch 2 times, most recently from 97b22d8 to c04e3a6 Compare December 18, 2023 22:18
@tgross35
Copy link
Contributor

@rustbot label +A-macros

@rustbot rustbot added the A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) label Dec 22, 2023
Copy link
Contributor

@tgross35 tgross35 left a comment

Choose a reason for hiding this comment

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

Looks pretty good to me. I started some discussion in wg-macros https://rust-lang.zulipchat.com/#narrow/stream/404510-wg-macros/topic/concat_idents.20as.20metavar.20.24.7B.2E.2E.2E.7D.

I don't think you need to mention the RFC in the title/commit message since this specific function wasn't called out in the RFC.

compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
"concat" => {
let lhs_is_var = try_eat_dollar(&mut iter);
let lhs_ident = parse_ident(&mut iter, sess, ident.span)?;
if !try_eat_comma(&mut iter) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we even need commas? Referencing paste again, the syntax is

[<Q R S T>] // turns into QRST

Which is somewhat easier to read without the commas. (Similar to C Q ## R ## S ## T, though that definitely isn't easier to read)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The comma was added to follow the syntax of the other meta-variable expressions. For example: count($foo, 0).

In my personal opinion, the matter about case conversion and omission of commas should be discussed at a later opportunity.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@c410-f3r c410-f3r changed the title [RFC-3086] Add a new concat metavar expr Add a new concat metavar expr Dec 26, 2023
@WaffleLapkin
Copy link
Member

(please use @rustbot review once my review is needed, this is currently S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. )

@tgross35
Copy link
Contributor

tgross35 commented Jan 5, 2024

@c410-f3r is this ready for review? I didn't intend for my comments to be blocking

@c410-f3r
Copy link
Contributor Author

c410-f3r commented Jan 5, 2024

Yeap, it is ready for review

@rustbot labels -S-waiting-on-author +S-waiting-on-review

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 5, 2024
@bors

This comment was marked as resolved.

Comment on lines 382 to 391
error: expected identifier, found `$`
--> $DIR/syntax-errors.rs:178:15
|
LL | const ${concat($sign name, _123)}: () = ();
| ^ expected identifier
...
LL | tt_that_is_dollar_sign_with_concat!($, FOO);
| ------------------------------------------- in this macro invocation
|
= note: this error originates in the macro `tt_that_is_dollar_sign_with_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to point to a better span? this looks like the problem is that const ${concat(...)} is not supported at all, but the actual problem seems to be $sign?..

Copy link
Contributor Author

@c410-f3r c410-f3r Mar 3, 2024

Choose a reason for hiding this comment

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

This diagnostic isn't originated from parse_ident. Mabe something after expansion?

If a better span is desirable, then a separated investigation should be created.

Copy link
Contributor

Choose a reason for hiding this comment

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

parse_ident shouldn't take a span from the outside in general.
It should use span of the unexpected token in its errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IFAICT, this specific diagnostic wasn't emitted by parse_ident.

But regardless parse_ident was modified to use as much span from tokens as possible. The outside span is still being used in case the RefTokenTreeCursor iterator doesn't yield.

compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/transcribe.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/transcribe.rs Outdated Show resolved Hide resolved
Comment on lines +593 to +667
result.push(TokenTree::Token(
Token::from_ast_ident(Ident::new(Symbol::intern(&concatenated), visited_span())),
Spacing::Alone,
));
Copy link
Member

Choose a reason for hiding this comment

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

Looking at the tests I still don't quite get how hygiene works...tests/ui/macros/rfc-3086-metavar-expr/concat-hygiene.rs implies that xy and ${concat($x, $y)} are different, but then tests/ui/macros/rfc-3086-metavar-expr/concat.rs uses things defined inside the macro outside of it...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Marker is the responsible entity that process hygiene for tokens emitted by meta-variable expressions.

Its internal aspects are not entirely clear to me but if you want to know how everything works I guess @petrochenkov can give you a better answer.

Copy link
Contributor

Choose a reason for hiding this comment

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

The current implementation marks the result as coming from the macro (using span of the metavar expression itself), regardless of contexts of the concatenated identifiers.
concat_idents!() macro works in a similar way, ignoring input contexts, but the output context is assigned in a different way.

What the desired behavior should be is a design question.

  • Are we supposed to use local variables produced by concat inside macro_rules (macros 1.0) outside of the macro? Not sure.
  • Are we supposed to use any names produced by concat inside macro (macros 2.0) outside of the macro?
    Likely yes, so some kind of hygiene opt out, or support for inheriting context from some token, should be added, but that applies to many things produced by macro, not just concat.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 12, 2024
@rustbot rustbot added the A-testsuite Area: The testsuite used to check the correctness of rustc label Feb 4, 2024
@tgross35
Copy link
Contributor

It might not be a bad idea to put this under a separate feature gate from the rest of macro_metavar_expr since it is probably pretty unlikely to stabilize together. Not much of a difference at this point, just slightly less future work.

@c410-f3r
Copy link
Contributor Author

r? compiler

@rustbot rustbot assigned Nadrieril and unassigned wesleywiser Apr 17, 2024
@Nadrieril
Copy link
Contributor

r? @tgross35 may I let you review this?

@rustbot rustbot assigned tgross35 and unassigned Nadrieril Apr 18, 2024
@tgross35
Copy link
Contributor

tgross35 commented Apr 18, 2024

@Nadrieril I don't know enough about this area to make a call (also don't have r+), but this looks fine to me with a feature gate added. If this isn't your area either then I guess we can see who gets the hot potato next.

r? compiler

@rustbot rustbot assigned wesleywiser and unassigned tgross35 Apr 18, 2024
@tgross35
Copy link
Contributor

Reroll since Wesley passed off the review initially

r? compiler

@rustbot rustbot assigned nnethercote and unassigned wesleywiser Apr 18, 2024
@nnethercote
Copy link
Contributor

I suspect r? @petrochenkov might be more suitable?

@rustbot rustbot assigned petrochenkov and unassigned nnethercote Apr 19, 2024
tests/ui/macros/rfc-3086-metavar-expr/concat-hygiene.rs Outdated Show resolved Hide resolved

macro_rules! tt_that_is_dollar_sign_with_concat {
($sign:tt, $name:ident) => {
const ${concat($sign name, _123)}: () = ();
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not specific to concat, right?
Macros don't generally treat $dollar name as $name in any contexts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like this test is therefore unnecessary. Removed.

compiler/rustc_expand/src/mbe/metavar_expr.rs Show resolved Hide resolved
Comment on lines 382 to 391
error: expected identifier, found `$`
--> $DIR/syntax-errors.rs:178:15
|
LL | const ${concat($sign name, _123)}: () = ();
| ^ expected identifier
...
LL | tt_that_is_dollar_sign_with_concat!($, FOO);
| ------------------------------------------- in this macro invocation
|
= note: this error originates in the macro `tt_that_is_dollar_sign_with_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
Copy link
Contributor

Choose a reason for hiding this comment

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

parse_ident shouldn't take a span from the outside in general.
It should use span of the unexpected token in its errors.

let mut result = Vec::new();
result.push(element(&mut iter, sess, ident.span)?);
if !try_eat_comma(&mut iter) {
return Err(sess.dcx.struct_span_err(ident.span, "expected comma"));
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, this should use span of the unexpected token.

compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/metavar_expr.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/transcribe.rs Outdated Show resolved Hide resolved
compiler/rustc_expand/src/mbe/transcribe.rs Outdated Show resolved Hide resolved
Comment on lines +593 to +667
result.push(TokenTree::Token(
Token::from_ast_ident(Ident::new(Symbol::intern(&concatenated), visited_span())),
Spacing::Alone,
));
Copy link
Contributor

Choose a reason for hiding this comment

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

The current implementation marks the result as coming from the macro (using span of the metavar expression itself), regardless of contexts of the concatenated identifiers.
concat_idents!() macro works in a similar way, ignoring input contexts, but the output context is assigned in a different way.

What the desired behavior should be is a design question.

  • Are we supposed to use local variables produced by concat inside macro_rules (macros 1.0) outside of the macro? Not sure.
  • Are we supposed to use any names produced by concat inside macro (macros 2.0) outside of the macro?
    Likely yes, so some kind of hygiene opt out, or support for inheriting context from some token, should be added, but that applies to many things produced by macro, not just concat.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 19, 2024
@c410-f3r c410-f3r force-pushed the concat-again branch 3 times, most recently from e810b88 to 2ce0a7b Compare April 21, 2024 14:48
@rust-log-analyzer

This comment has been minimized.

@c410-f3r
Copy link
Contributor Author

Thanks for the review. Let me know if anything is missing.

Questions around potential design concerns were placed in the requested tracking issue.

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-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet