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 length
in Rust 1.80
#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. |
What does this mean, and why does "length" not show up in the explanation of the All these "functions" expand to integers -- of which type? Or do they end up being like integer literals without a suffix, i.e., the concrete integer type gets inferred following the usual rules? |
Note that the tracking issue still has an unresolved question/bug open #83527 Has this been resolved? |
@rfcbot concern hygiene-handled? |
Ah actually, it seems the checkbox was never ticked? #95188 |
@rfcbot resolved hygiene-handled? |
what is the difference between |
Are the functions that take depth such as Nonblocker, diagnostics are pretty bare bones with no error codes or help
|
Date seems incorrect :) |
To follow up on the question on the depth of The RFC text does not really make this clear… |
No but documentation will be provided as soon as possible.
The nested repetitions of https://user-images.githubusercontent.com/17877264/158820060-035b2548-9ea9-4cbb-850b-e5836cf892fe.png illustrate better this concept. More information is available at https://rust-lang.github.io/rfcs/3086-macro-metavar-expr.html#index-and-length
More information is available at https://rust-lang.github.io/rfcs/3086-macro-metavar-expr.html#count rust/compiler/rustc_expand/src/mbe/transcribe.rs Lines 677 to 683 in df8ac8f
macro_rules! index {
( $( $tt:tt ),* ) => {
[$( ${ignore($tt)} ${index()}, )*]
};
}
macro_rules! length {
( $( $tt:tt ),* ) => {
[$( ${ignore($tt)} ${length()}, )*]
};
}
fn main() {
// 3 tokens generate an increment list of 3 elements starting from 0
assert_eq!(index!(A, B, C), [0, 1, 2]);
// 4 tokens generate a list of 4 elements containing 4
assert_eq!(length!(A, B, C, D), [4, 4, 4, 4]);
} More information is available at https://rust-lang.github.io/rfcs/3086-macro-metavar-expr.html#index-and-length @ slanterns
Thanks
So in your example a declaration of // Other examples
macro_rules! no_repetition {
( $( $a:ident: $( $b:literal ),* );+ ) => {
[${count($b)}]
};
}
macro_rules! no_repetition_with_index {
( $( $a:ident: $( $b:literal ),* );+ ) => {
[${count($b, 1)}]
};
}
macro_rules! outermost_repetition {
( $( $a:ident: $( $b:literal ),* );+ ) => {
[$( ${ignore($a)} ${count($b)}, )+]
};
}
fn main() {
// 1 2 3 4 5 = 5 elements
assert_eq!(no_repetition!(a: 1, 2, 3; b: 4, 5), [5]);
// a b = 2 elements
assert_eq!(no_repetition_with_index!(a: 1, 2, 3; b: 4, 5), [2]);
// 1 2 3 = 3 elements, 4 5 = 2 elements
assert_eq!(outermost_repetition!(a: 1, 2, 3; b: 4, 5), [3, 2]);
} https://user-images.githubusercontent.com/17877264/158820060-035b2548-9ea9-4cbb-850b-e5836cf892fe.png might help you but it was created in a time when * PR updated |
So does |
@jdahlstrom [$( $x / ${length()} ),*] to be morally equivalent to: let n = ${count(x)};
[$( $x / n ),*]
|
Would it be possible to prepare the PR for the reference before this lands? It seems like there is quite a bit of uncertainty about how all the features work, which makes me thing that perhaps this feature isn't very widely tested. As semantics have changed a few times since the RFC, that isn't the best reference either. Quick search for usage that isn't in rustc forks https://github.com/search?q=lang%3Arust+%2F%28%3F-i%29%5C%24%5C%7B%28ignore%7Ccount%7Clength%7Cindex%29%5C%28.*%5C%7D%2F+-path%3Acompiler%2F+-path%3Alibrary%2F+-path%3Asrc%2Ftools%2Frust-analyzer&type=code |
As commented above, reference will be provided as soon as possible. Semantic changed only once when |
Is there any realistic pattern to suffix the integer literal expansions or nah? |
well, I expect |
☔ The latest upstream changes (presumably #123390) made this pull request unmergeable. Please resolve the merge conflicts. |
@rfcbot reviewed -- this would definitely be handy! |
I brought this up in the doc PR but it belongs here – |
I'm slightly worried about random inference regressions punishing this particularly hard if there's no standard/easy way to proof the emitted literals against such. I guess we can use a block expression for each one? |
☔ The latest upstream changes (presumably #104087) made this pull request unmergeable. Please resolve the merge conflicts. |
Stabilization proposal
This PR proposes the stabilization of a subset of
#![feature(macro_metavar_expr)]
or more specifically, the stabilization ofcount
,ignore
,index
andlength
.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.Length
The current index starting from the inner-most repetition.
length
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.
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.