-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking issue for concat_idents
#29599
Comments
|
Relevant blog for future plans: http://www.ncameron.org/blog/untitledconcat_idents-and-macros-in-ident-position/ |
A solution that has been thrown around on IRC (but never ended up anywhere else AFAIK): macro_rules! wrap {
($name:ident) => { struct concat_idents!!(Wrapped, $name)($name); }
} The "early expansion" If we move towards having all macros produce token streams that are parsed on-demand, such "early expansion" could be used in many more locations without adding macro support for each one. The only disadvantage is that |
https://github.com/mikkyang/rust-blas uses it for quick notation of FFI functions that follow a certain scheme: https://github.com/mikkyang/rust-blas/blob/master/src/prefix.rs https://github.com/mikkyang/rust-blas/blob/master/src/matrix/ll.rs |
Well, given that mikkyang/rust-blas#12 is a nicer solution within the current language, I'd also like to raise my hand for "useless". |
I think we should never stabilise the current version - as others have noted it is useless. |
Since this is the tracking issue, other who stumble across it might be interested in https://github.com/SkylerLipthay/interpolate_idents which works on nightly rust. |
Unfortunately that solution will always depend on nightly Rust (until the day that syntax extensions become stable and pigs fly). |
Given that the consensus seems to be "useless" and theres nicer solutions (e.g. [1], maybe we can remove this feature? |
See rust-lang/rfcs#1628. |
@retep998 yes, just noting it as a stopgap. @skade it's the implementation rather than the idea that's useless. If |
@aidanhs that still means that we should drop the feature to make sure no one uses it. I agree that my solution doesn't cover all edge-cases, but all uses that I've currently seen in the wild. Also, but this is outside of my competence to decide, I think this is a perfect case for the use of a code generator. |
@skade afaict nobody can use it, so that's not a big concern...but equally there's no reason to keep it around. My main motivation for leaving it was as a reminder that people do want the functionality, but I'm content to follow the RFC and have changed my position to "I don't mind either way". Regarding use cases, here's the motivating example that brought me to this issue in the first place. Codegen's awesome for things like phf, but it feels a bit like overkill when I just want to generate some repetitive methods to extract tuples from enum variants. I guess it's down to personal preference. |
An amusing fact about the current implementation of
(good luck actually doing anything with it) |
Empty string is used as a reserved identifier with special meaning in several places in the compiler, so this can potentially cause issues. |
The linked RFC has been closed as postponed. Should |
The RFC should be reopened. It never should have been closed, as no better solution was proposed. |
@durka I don't agree. There's ample reason to expect a new one when moving towards macros 2.0. RFCs are not necessarily closed to be replaced immediately, they are closed to stop following that line of discussion. Future RFCs might refer to it. |
I'm with @durka on this. |
Is there a way to use this but with a type |
Once a (or if it's a macro for internal use, you can always settle for some subset of type syntax that's easier to parse, e.g. |
If we were to keep/stabilize this, it would need to work in the fashion people expect it to work (in place of an identifier). |
I'd like for this to also support concatenating with integer literals, e.g. const MY_CONST1: u32 = 1;
const MY_CONST2: u32 = 2;
concat_idents!(MY_CONST, 2) |
This is especially useful for embedded when we have many names we do not have control over. (register names) where most of the difference is a number. |
It would be nice if we could use |
@dvdsk, I think this is already covered by #29599 (comment). If the macro works in |
Ah I thought 'ident positions' referres to things like Reading the rust reference the dot symbol ( On a separate note Finally self is not an ident but a keyword. So strictly speaking concat_idents should not cover it. So maybe we should drop |
Three comments:
|
From the docs:
Is there any particular rationale for disallowing identifier concatenation in the definition of items? I really hate using |
It’s not that they’re excluded explicitly. It’s the other way around: parts of the language that expect an item, statement, or expression each accept various kinds of syntax, one of which being a macro invocation. In parts of the language that expect an identifier, the syntax is more restrictive (only accepting a plain or raw identifier token). Accepting a macro invocation everywhere an identifier is accepted would be tricky at best because macro invocations themselves start with an identifier. |
What about having Of course, this might cause parsing problems. In particular, I doubt it would be compatible with an LALR(1) or LR(1) grammar. |
At this point it would probably be better to implement ident concatenation as a "metavariable expression", like Then in a code produced by |
I think it would be nice to have something like |
I'm sure there is a good answer but I don't see it here - why do we need Also, it is extremely helpful to be able to convert between upper, lower, snake, and camel cases identifiers in paste. I sure wouldn't mind having this in std somehow if there were a good syntax... |
Add a new concat metavar expr Revival of rust-lang#111930 Giving it another try now that rust-lang#117050 was merged. With the new rules, meta-variable expressions must be referenced with a dollar sign (`$`) and this can cause misunderstands with `$concat`. ```rust 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 rust-lang#29599 cc rust-lang#124225
🚀 I found a way to evaluate And in other words, Also, Also, https://crates.io/crates/with_builtin_macros allows one to use // (This code was not tested, may contain typos)
fn concat_idents!(a, b) () {} // Doesn't work
with_builtin_macros::with_eager_expansions! {
fn #{ concat_idents!(a, b) } () {} // Works! Even on stable!
}
macro_rules! this_macro_accepts_ident {
($a:ident) => {}
}
this_macro_accepts_ident!(concat_idents!(a, b)); // Doesn't work, because "this_macro_accepts_ident" evaluates before "concat_idents"
with_builtin_macros::with_eager_expansions! {
this_macro_accepts_ident!(#{ concat_idents!(a, b) }); // Works! Even on stable!
} |
Tracks stabilization for the
concat_idents
macro.Update(fmease): Please see #124225 (comment) (an alternative to this feature).
The text was updated successfully, but these errors were encountered: