-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Stabilize count
, ignore
, index
, and len
(macro_metavar_expr
)
#122808
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
count
, index
, ignore
and length
in Rust 1.80count
, ignore
, index
, and length
in Rust 1.80
93b1119
to
1536974
Compare
@c410-f3r Has this been documented in the Reference already? The box is not ticked over at the tracking issue. If not, stabilization is blocked on adding sufficient documentation. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
this is also seen in the recent stabilization PR attempt: rust-lang/rust#122808 and rust playground confirms it.
I tend to agree with @tgross35 -- having to refer to capture groups by index is a really awkward and fragile API, I don't think we should stabilize that if better alternatives exist. After all we generally let the user name things they need to refer to (variables, functions, types, even loops to |
Is there consensus for |
macro_rules! count_value_nested {
( $( $name:ident: $( $value:literal ),* );+ ) => {
[ $(
// using `count` within a repetition group will return the number
// of times `$value` is matched _within that group_.
${count($value)},
)+ ]
};
} So, this is a repetition group that only contains Which repetition group does this count? macro_rules! count_test {
( $( $supername:ident { $( $name:ident: $( $value:ident )* ),+ } )* ) => {
[ $(
${count($value)},
)+ ]
};
} This could reasonably be |
Trying this out, it seems like like it is the former, counting the total number of Usually a metavar "must appear in exactly the same number, kind, and nesting order of repetitions in the transcriber as it did in the matcher". With |
looks kinda like |
As previously commented, the suggestion around named placeholders is orthogonal to the current behavior approved in the RFC and both can co-exist in the future. Fate imposed yet another syntax-related blocking concern in a stabilization PR, as such, I ask the responsible party to decide the final outcome. @rustbot labels +I-lang-nominated |
count
, ignore
, index
, and length
in Rust 1.80count
, ignore
, index
, and length
(macro_metavar_expr
)
@rfcbot concern depth levels are confusing Before reading this thread I had a strong reaction to the RFC exactly in line with @RalfJung's, and I had thoughts along the lines of what @tgross35 is proposing. So I think there's something worth paying attention to here. I see it as a major downside, quite possibly a failure, of the lang team process that we got this far without such syntax concerns being surfaced. With that said, even though the concern is a late breaking one, it feels significant enough to me that I don't think it should be minimized. Rust's declarative macro syntax can already be quite intimidating to the uninitiated, and we should be careful in how we spend our "readability budget" here. This emphasis on readability is the reason I'm not that swayed by the argument of future compatibility: Even if we add named expansions later, the syntax for unnamed depth levels will always exist if we stabilize it now, and people who read Rust macro code will have to know about it. To make my concern more concrete: I think adding recursion depths is a significant step up in both capability and complexity, but I would want that to be equally matched with stronger usability as well as motivation for the feature. The usability piece is quite lacking, in my opinion, in that the recursion depths are unlabeled integers without an obvious meaning. I certainly think they are non-obvious to the reader, and in some cases even to the writer who already knows about this feature (I speculate that many users might forget how In the interest of making forward progress, I'll put forward a proposal that I frame as a question. The implied question in each of these is how much the proposal limits the use cases enabled by these features. If the answer is "not that much" I think we should go forward with stabilizing this subset for now; otherwise, I hope it's a useful starting point for getting things moving.
|
I don't exactly know what you mean here, could you give an example? FWIW, I experimented with The only point that gives me pause around |
What I meant is, why not make |
AFAIK it is currently equivalent to count($x, 0), which does align with my intuition once I re-familiarized myself with how nested capture groups work. I don't know what infinite depth would even mean.
|
I'm not sure what count(x, 0) would mean, based on this from the RFC:
Reading this over again though, I no longer think it makes sense to limit to 1 by default. I still think specifying a max depth level is non-obvious and of dubious value, since you could always rewrite the excerpt above as something like the following; are there cases where you can't do this?
|
I have linked this already above, see here. That's what I reverse engineered based on my experiments, anyway. The default is definitely 0, according to that PR. Maybe the semantics changed since the RFC was accepted? Would be good to get an up=to-date description of the proposed semantics confirmed by the people involved in the implementation -- Cc @c410-f3r , not sure who else?
I think the issue is around matchers like |
I will try to address all questions this weekend in my free time. |
Thank you.
It is more complex but not impossible IMO. One way is to attach a corresponding matcher depth to each named repetition and then evaluate which ones can be associated based on the current transcriber position. Syntax-wise, the distinction between numbers and strings can create appropriated implementation branches.
Before #117050 rust-lang/reference#1485 (comment) will probably provide a better overview.
Unfortunately it is not possible to count without a metavariable. AFAICT, But yeah, the specification of a depth is non-obvious as it depends on the number of nested matcher repetitions as well as the positioning.
|
I see, I was confused by reading the RFC for more detail, but that is now outdated. @c410-f3r Can you please include a list of differences from the RFC in the stabilization report (with rationale; feel free to summarize and link to more context)? |
Sure. The report has been updated. |
@c410-f3r |
Well, I can rebase but I don't think it will make much of a difference. The actual issue lies within the decision around the use of indices in This PR has been waiting for more than 2 months for a response from the responsible team. AFAICT, all questions posted here as well as in rust-lang/reference#1485 have already been answered to the best of my ability. |
count
, ignore
, index
, and length
(macro_metavar_expr
)count
, ignore
, index
, and len
(macro_metavar_expr
)
close #13 ref: rust-lang/rust#122808
close #13 ref: rust-lang/rust#122808 2508e7c
Stabilization proposal
This PR proposes the stabilization of a subset of
#![feature(macro_metavar_expr)]
or more specifically, the stabilization ofcount
,ignore
,index
andlen
.Tracking issue: #83527
Version: 1.80 (June 13 2024 => beta, July 25 2024 => stable).
What is stabilized
Count
The number of times a meta variable repeats in total.
The output of
count
depends on where it is placed as well the provided index. If no index is provided, then it will always start at the innermost level.Ignore
Binds a meta variable for repetition, but expands to nothing.
Index
The current index of the inner-most repetition.
index
is a counter that starts from 0 until the end of the repetition.len
The current index starting from the inner-most repetition.
len
indicates the sum of meta variable elements, aka length, of the current repetition.Motivation
Meta variable expressions not only facilitate the use of macros but also allow things that can't be done today like in the
$index
example.An initial effort to stabilize this feature was made in #111908 but ultimately reverted because of possible obstacles related to syntax and expansion.
Nevertheless, #83527 (comment) tried to address some questions and fortunately the lang team accept #117050 the unblocking suggestions.
Here we are today after ~4 months so everything should be mature enough for wider use.
After RFC changes
In order to unblock progress, some changes were applied in #118958. These changes did not trigger any opposition debates and were quickly integrated.
count
changed fromoutermost-to-innermost
toinnermost-to-outermost
.count(some_metavariable)
but now they must be preceded by$
. For example,count($some_metavariable)
.What isn't stabilized
$$
is not being stabilized due to unresolved concerns.History
count
Tests
This list is a subset of https://github.com/rust-lang/rust/tree/master/tests/ui/macros/rfc-3086-metavar-expr.
Ensures that nested macros have correct behavior
Compares produced tokens to assert expected outputs
Checks the declarations of the features
Verifies all possible errors that can occur due to incorrect user input
Possible future work
With enough consensus, other nightly expressions can be added for experimentation and possibly stabilized in the future. For example, #118958.
Thanks @markbt for creating the RFC and thanks to @petrochenkov and @mark-i-m for reviewing the implementations.