-
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
Comprehensively support trailing commas in std/core macros #48056
Conversation
BREAKING CHANGE: (or perhaps, *bugfix*) In #![no_std] applications, the following calls to `panic!` used to behave differently; they now behave the same. Old behavior: panic!("{{"); // panics with "{{" panic!("{{",); // panics with "{" New behavior: panic!("{{"); // panics with "{{" panic!("{{",); // panics with "{{" This only affects calls to `panic!` (and by proxy `assert` and `debug_assert`) with a single string literal followed by a trailing comma, and only in `#![no_std]` applications.
Most notably this changes 'syntax::ext::base::get_single_str_from_tts' to accept a trailing comma, and revises the documentation so that this aspect is not surprising. I made this change under the understanding that this crate is private rustc implementation detail (I hope this is correct!). After reviewing all call sites, I believe the revised semantics are closer to the intended spirit of the function.
Highfive's missing, randomly assigning a reviewer. r? @dtolnay |
// make sure we don't accidentally forward to `write!("text")` | ||
#[cfg(std)] | ||
#[test] | ||
fn writeln_2arg() { |
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.
whoops, I had intended to test the single-argument invocation instead, because it is currently handled by its own separate pattern and it is unlikely that there are any other tests in test/ that use it. Like:
#[cfg(std)]
#[test]
fn writeln_1arg() {
use fmt::Write;
let mut s = String::new();
writeln!(&mut s,).unwrap();
assert_eq!(&s, "\n");
}
Do we want to wait for #47752 to use |
I don't think so. I think that by far the most onerous part is writing the tests. The actual fixes to After my changes, libcore has 7 places in its // current form
macro_rules! format_args {
($fmt:expr) => ({ /* compiler built-in */ });
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
}
// "best practices"
macro_rules! format_args {
($fmt:expr $(,)?) => ({ /* compiler built-in */ });
($fmt:expr, $($args:tt)+) => ({ /* compiler built-in */ });
} |
@dtolnay this needs a review! |
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.
Thanks so much for working through this and for the clear explanations.
|
Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), 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! See this document for info about what commands tagged team members can give me. |
@mark-i-m: So fast! But in any case, since these definitions show up in documentation, the std and core macros probably shouldn't be changed to use it until the feature is stabilized. |
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.
Note there are some FIXMEs I left in the tests since I didn't figure that it would get approved in this revision. 🙂
// The expectation is for this to be updated as new macros are added, | ||
// or as functionality is added to existing macros. | ||
// | ||
// (FIXME: (please discuss in PR) is the above expectation reasonable?) |
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.
Leftover FIXME
(I think I might just consider it my own responsibility to update this every now and then. Additions to stdlib macros seem pretty infrequent and hard to miss)
println!("hello {}", "world",); | ||
} | ||
|
||
// FIXME: select! (please discuss in PR) |
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.
Leftover FIXME
I might just change this to TODO: select!
and move my concerns about select!
to its tracking issue (#27800)
} | ||
|
||
#[cfg(std)] { | ||
// FIXME: compile-fail says "expected error not found" even though |
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.
Leftover FIXME
Unless someone knows what's up, I'm tempted to just leave this one here, to document that it would be tested here if it could.
(IMO the regressions that would be caught by this test are far, far less likely to occur than the ones that would be caught by the corresponding tests in run-pass
.)
🔔 This is now entering its final comment period, as per the review above. 🔔 |
1 similar comment
🔔 This is now entering its final comment period, as per the review above. 🔔 |
@bors r+ |
📌 Commit 9205f3d has been approved by |
Comprehensively support trailing commas in std/core macros I carefully organized the changes into four commits: * Test cases * Fixes for `macro_rules!` macros * Fixes for builtin macros * Docs for builtins **I can easily scale this back to just the first two commits for now if such is desired.** ### Breaking (?) changes * This fixes rust-lang#48042, which is a breaking change that I hope people can agree is just a bugfix for an extremely dark corner case. * To fix five of the builtins, this changes `syntax::ext::base::get_single_str_from_tts` to accept a trailing comma, and revises the documentation so that this aspect is not surprising. **I made this change under the (hopefully correct) understanding that `libsyntax` is private rustc implementation detail.** After reviewing all call sites (which were, you guessed it, *precisely those five macros*), I believe the revised semantics are closer to the intended spirit of the function. ### Changes which may require concensus Up until now, it could be argued that some or all the following macros did not conceptually take a comma-separated list, because they only took one argument: * **`cfg(unix,)`** (most notable since cfg! is unique in taking a meta tag) * **`include{,_bytes,_str}("file.rs",)`** (in item form this might be written as "`include!{"file.rs",}`" which is even slightly more odd) * **`compile_error("message",);`** * **`option_env!("PATH",)`** * **`try!(Ok(()),)`** So I think these particular changes may require some sort of consensus. **All of the fixes for builtins are included this list, so if we want to defer these decisions to later then I can scale this PR back to just the first two commits.** ### Other notes/general requests for comment * Do we have a big checklist somewhere of "things to do when adding macros?" My hope is for `run-pass/macro-comma-support.rs` to remain comprehensive. * Originally I wanted the tests to also comprehensively forbid double trailing commas. However, this didn't work out too well: [see this gist and the giant FIXME in it](https://gist.github.com/ExpHP/6fc40e82f3d73267c4e590a9a94966f1#file-compile-fail_macro-comma-support-rs-L33-L50) * I did not touch `select!`. It appears to me to be a complete mess, and its trailing comma mishaps are only the tip of the iceberg. * There are [some compile-fail test cases](https://github.com/ExpHP/rust/blob/5fa97c35da2f0ee/src/test/compile-fail/macro-comma-behavior.rs#L49-L52) that didn't seem to work (rustc emits errors, but compile-fail doesn't acknowledge them), so they are disabled. Any clues? (Possibly related: These happen to be precisely the set of errors which are tagged by rustc as "this error originates in a macro outside of the current crate".) --- Fixes rust-lang#48042 Closes rust-lang#46241
|
odd, will try to reproduce Update:
|
include! and the pretty test do not mix
Should be fixed now. |
@bors: r=dtolnay |
📌 Commit af503be has been approved by |
The final comment period is now complete. |
Comprehensively support trailing commas in std/core macros I carefully organized the changes into four commits: * Test cases * Fixes for `macro_rules!` macros * Fixes for builtin macros * Docs for builtins **I can easily scale this back to just the first two commits for now if such is desired.** ### Breaking (?) changes * This fixes #48042, which is a breaking change that I hope people can agree is just a bugfix for an extremely dark corner case. * To fix five of the builtins, this changes `syntax::ext::base::get_single_str_from_tts` to accept a trailing comma, and revises the documentation so that this aspect is not surprising. **I made this change under the (hopefully correct) understanding that `libsyntax` is private rustc implementation detail.** After reviewing all call sites (which were, you guessed it, *precisely those five macros*), I believe the revised semantics are closer to the intended spirit of the function. ### Changes which may require concensus Up until now, it could be argued that some or all the following macros did not conceptually take a comma-separated list, because they only took one argument: * **`cfg(unix,)`** (most notable since cfg! is unique in taking a meta tag) * **`include{,_bytes,_str}("file.rs",)`** (in item form this might be written as "`include!{"file.rs",}`" which is even slightly more odd) * **`compile_error("message",);`** * **`option_env!("PATH",)`** * **`try!(Ok(()),)`** So I think these particular changes may require some sort of consensus. **All of the fixes for builtins are included this list, so if we want to defer these decisions to later then I can scale this PR back to just the first two commits.** ### Other notes/general requests for comment * Do we have a big checklist somewhere of "things to do when adding macros?" My hope is for `run-pass/macro-comma-support.rs` to remain comprehensive. * Originally I wanted the tests to also comprehensively forbid double trailing commas. However, this didn't work out too well: [see this gist and the giant FIXME in it](https://gist.github.com/ExpHP/6fc40e82f3d73267c4e590a9a94966f1#file-compile-fail_macro-comma-support-rs-L33-L50) * I did not touch `select!`. It appears to me to be a complete mess, and its trailing comma mishaps are only the tip of the iceberg. * There are [some compile-fail test cases](https://github.com/ExpHP/rust/blob/5fa97c35da2f0ee/src/test/compile-fail/macro-comma-behavior.rs#L49-L52) that didn't seem to work (rustc emits errors, but compile-fail doesn't acknowledge them), so they are disabled. Any clues? (Possibly related: These happen to be precisely the set of errors which are tagged by rustc as "this error originates in a macro outside of the current crate".) --- Fixes #48042 Closes #46241
☀️ Test successful - status-appveyor, status-travis |
I carefully organized the changes into four commits:
macro_rules!
macrosI can easily scale this back to just the first two commits for now if such is desired.
Breaking (?) changes
This fixes with #![no_std] enabled, 'panic!("{{}}")' and 'panic!("{{}}",)' are different #48042, which is a breaking change that I hope people can agree is just a bugfix for an extremely dark corner case.
To fix five of the builtins, this changes
syntax::ext::base::get_single_str_from_tts
to accept a trailing comma, and revises the documentation so that this aspect is not surprising. I made this change under the (hopefully correct) understanding thatlibsyntax
is private rustc implementation detail. After reviewing all call sites (which were, you guessed it, precisely those five macros), I believe the revised semantics are closer to the intended spirit of the function.Changes which may require concensus
Up until now, it could be argued that some or all the following macros did not conceptually take a comma-separated list, because they only took one argument:
cfg(unix,)
(most notable since cfg! is unique in taking a meta tag)include{,_bytes,_str}("file.rs",)
(in item form this might be written as "include!{"file.rs",}
" which is even slightly more odd)compile_error("message",);
option_env!("PATH",)
try!(Ok(()),)
So I think these particular changes may require some sort of consensus. All of the fixes for builtins are included this list, so if we want to defer these decisions to later then I can scale this PR back to just the first two commits.
Other notes/general requests for comment
run-pass/macro-comma-support.rs
to remain comprehensive.select!
. It appears to me to be a complete mess, and its trailing comma mishaps are only the tip of the iceberg.Fixes #48042
Closes #46241