-
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
Macros: Add a 'literal' fragment specifier #49835
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @petrochenkov (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
Your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem. Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Could you add tests where literals of various kinds (integral, string, boolean) are used in expressions, patterns (including range patterns |
This also needs to be feature gated, see b284419 for an example. |
Ping from triage @da-x! Will you have some time to work on this in the future? |
@pietroalbini - Yes - I am planning to add tests, feature gating, and documentation. Hopefully soon! |
☔ The latest upstream changes (presumably #50155) made this pull request unmergeable. Please resolve the merge conflicts. |
Added tests, feature gate, and docs. Testing revealed that |
} | ||
|
||
macro_rules! match_attr { | ||
(#[$attr:meta] $e:literal) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant literal inside the attribute produced by the macro, e.g. something like
macro_rules! match_attr {
($e: literal) => {
// Struct with doc comment passed via $literal
#[doc = $literal]
struct S;
}
}
} | ||
|
||
macro_rules! test_user { | ||
($s:literal, $e:literal) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a case checking that $lit1 ... $lit2
is parsed as a range pattern in patterns?
} | ||
|
||
macro_rules! catch_range { | ||
($s:literal ... $e:literal) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly to attributes, the range should rather be produced by a macro (1833a1f#r184891034), this test with ...
on the left side of the macro is testing something entirely different and probably not useful.
☔ The latest upstream changes (presumably #49789) made this pull request unmergeable. Please resolve the merge conflicts. |
Ping from triage, @da-x ! You have review comments and merge conflicts to address! |
Yes, will be on it! |
@petrochenkov Tried to address your comments. Thanks. |
Also fixed for |
src/libsyntax/parse/token.rs
Outdated
match *self { | ||
Literal(..) => true, | ||
Ident(ident, false) if ident.name == "true" => true, | ||
Ident(ident, false) if ident.name == "false" => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: keywords::True.name()
/keywords::False.name()
instead of "true"
/"false"
.
@da-x |
I've added a fix for negative literals. Thanks for the help. |
src/libsyntax/parse/token.rs
Outdated
@@ -310,6 +315,14 @@ impl Token { | |||
} | |||
} | |||
|
|||
/// Returns true if this token can begin a two-token literal (i.e. negative numbers) | |||
pub fn can_begin_literal(&self) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you merge this with is_lit_or_bool
?
src/libsyntax/ext/tt/macro_rules.rs
Outdated
"ident" | "lifetime" => { | ||
// being a single token, idents and lifetimes are harmless | ||
"ident" | "lifetime" | "literal" => { | ||
// being a single token, idents, literals and lifetimes are harmless |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, literals are no longer necessarily single-token, but it shouldn't change anything with regards to follow set.
src/libsyntax/fold.rs
Outdated
@@ -156,6 +156,10 @@ pub trait Folder : Sized { | |||
noop_fold_ident(i, self) | |||
} | |||
|
|||
fn fold_lit(&mut self, i: P<Expr>) -> P<Expr> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fold_lit
and noop_fold_lit
are no longer necessary.
Excellent, thanks! |
Implements RFC 1576. See: https://github.com/rust-lang/rfcs/blob/master/text/1576-macros-literal-matcher.md Changes are mostly in libsyntax, docs, and tests. Feature gate is enabled for 1.27.0. Many thanks to Vadim Petrochenkov for following through code reviews and suggestions. Example: ````rust macro_rules! test_literal { ($l:literal) => { println!("literal: {}", $l); }; ($e:expr) => { println!("expr: {}", $e); }; } fn main() { let a = 1; test_literal!(a); test_literal!(2); test_literal!(-3); } ``` Output: ``` expr: 1 literal: 2 literal: -3 ```
@bors r+ |
📌 Commit 37ed2ab has been approved by |
Macros: Add a 'literal' fragment specifier See: #35625 ```rust macro_rules! test_literal { ($l:literal) => { println!("literal: {}", $l); }; ($e:expr) => { println!("expr: {}", $e); }; } fn main() { let a = 1; test_literal!(a); test_literal!(2); test_literal!(-3); } ``` Output: ``` expr: 1 literal: 2 literal: -3 ``` ToDo: * [x] Feature gate * [x] Basic tests * [x] Tests for range patterns * [x] Tests for attributes * [x] Documentation * [x] Fix for `true`/`false` * [x] Fix for negative number literals
☀️ Test successful - status-appveyor, status-travis |
See: #35625
Output:
ToDo:
true
/false