-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Ensure a sole string-literal passed to panic!
is not a fmt string.
#24370
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
e4d1e6b
to
ac56d7f
Compare
} | ||
|
||
pub fn f0_a() { | ||
ensure_not_fmt_string_literal!("`f0_a`", "this does not work {}"); |
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.
Can this macro be put behind a feature gate as well?
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.
yes good idea.
This has the potential to be a large-ish breaking change, so it may be useful to gather metrics and see how much breaks. This is a pretty minor problem that may not be worth fixing if it breaks too much. |
@bors try |
Ensure a sole string-literal passed to `panic!` is not a fmt string. To accomplish this, adds `ensure_not_fmt_string_literal!` macro that will fail the compile if its expression argument is a fmt string literal. Since this is making a certain kind of use of `panic!` illegal, it is a: [breaking-change] In particular, a panic like this: ```rust panic!("Is it stringified code: { or is it a ill-formed fmt arg? }"); ``` must be rewritten; one easy rewrite is to add parentheses: ```rust panic!(("Is it stringified code: { or is it a ill-formed fmt arg? }")); ``` ---- Fix #22932.
💔 Test failed - try-mac |
@brson argh i'm sorry this clearly does not build. I blame the slow build times on my horribly messed up laptop. :( |
@bors try |
⌛ Trying commit 21e580f with merge 2b32efb... |
21e580f
to
08079d5
Compare
@bors try force |
Ensure a sole string-literal passed to `panic!` is not a fmt string. To accomplish this, adds `ensure_not_fmt_string_literal!` macro that will fail the compile if its expression argument is a fmt string literal. Since this is making a certain kind of use of `panic!` illegal, it is a: [breaking-change] In particular, a panic like this: ```rust panic!("Is it stringified code: { or is it a ill-formed fmt arg? }"); ``` must be rewritten; one easy rewrite is to add parentheses: ```rust panic!(("Is it stringified code: { or is it a ill-formed fmt arg? }")); ``` ---- Fix #22932.
💔 Test failed - try-bsd |
(I do not yet understand why the @brson was kind enough to run his regression tool on this. So on the one hand, the reported breakage seems ... pretty minimal? Just two crates on crates.io seem to regress due to this change. In particular:
But on the other hand, looking at this again, I would probably be pretty annoyed to get an outright compile failure for the two cases above, as opposed to a lint warning. I'm going to see if I can easily rejigger this into a lint instead of a inescapable failure. |
@pnkfelix hm what's the rationale for having this be a lint? As in, when the lint warning fires and I change my code, what benefit is reaped from the modification? |
@alexcrichton the benefit is that you have a chance to see that you intended to actually pass arguments. I cannot stop people who blindly wrap the literal in parens, but at least that stands out visually compared to Update: to be clear: The macro being added here would cause a warning to be emitted on the above assert!(cond, "input {} was messed up", heres_the_input); or as: assert!(cond, ("input {} was messed up")); // as in, yes, I really meant `{}` to be printed |
@pnkfelix ah right good point! |
08079d5
to
4ca0ba6
Compare
@bors try |
🔒 Merge conflict |
4ca0ba6
to
12706c9
Compare
@bors try |
Ensure a sole string-literal passed to `panic!` is not a fmt string. To accomplish this, adds `ensure_not_fmt_string_literal!` macro that will fail the compile if its expression argument is a fmt string literal. Since this is making a certain kind of use of `panic!` illegal, it is a: [breaking-change] In particular, a panic like this: ```rust panic!("Is it stringified code: { or is it a ill-formed fmt arg? }"); ``` must be rewritten; one easy rewrite is to add parentheses: ```rust panic!(("Is it stringified code: { or is it a ill-formed fmt arg? }")); ``` ---- Fix #22932.
💔 Test failed - try-linux |
To accomplish this, adds `ensure_not_fmt_string_literal!` macro that will fail the compile if its argument is a fmt string literal. `ensure_not_fmt_string_literal!` takes a name along with expr; this allows for better error messages at its usage sites (like `panic!`). ---- Since this is making a certain kind of use of `panic!` illegal, it is a: [breaking-change] In particular, a panic like this: ```rust panic!("Is it stringified code: { or is it a ill-formed fmt arg? }"); ``` must be rewritten; one easy rewrite is to add parentheses: ```rust panic!(("Is it stringified code: { or is it a ill-formed fmt arg? }")); ``` ---- Fix rust-lang#22932.
As a drive-by, attempt to treat the macro as unstable by having it emit a reference to an unstable constant in its expansion. We *do* allow such an expansion when it occurs within `panic!`, for discussion, see large comment explaining the hack in the code.
At this point I've tried several different strategies for enforcing and checking the unstable-ness of the helper macro, but none have worked (they either fail to reject the macro, or they reject too much, like invocations of For now, I am planning to just give the helper macro a very ugly, obscure name, and file a bug for investigating the other problems later, but not holding up this PR based on that. |
On Fri, Apr 17, 2015 at 07:06:32AM -0700, Felix S Klock II wrote:
my opinion is we could live with this helper macro indefinitely it push came to shove |
We have a few other macros in the standard library that start with two underscores, and that's generally enough of a deterrent to say "we're not providing guarantees about this" |
…s internally. Unfortunately, i am having issues getting this to actually work. I repeatedly see: ``` failures: [run-fail] run-fail/explicit-panic-msg.rs ``` Namely: ``` failures: ---- [run-fail] run-fail/explicit-panic-msg.rs stdout ---- error: compilation failed! status: exit code: 101 command: x86_64-apple-darwin/stage2/bin/rustc /Users/fklock/Dev/Mozilla/rust-panic/src/test/run-fail/explicit-panic-msg.rs -L x86_64-apple-darwin/test/run-fail/ --target=x86_64-apple-darwin -L x86_64-apple-darwin/test/run-fail/explicit-panic-msg.stage2-x86_64-apple-darwinlibaux -C prefer-dynamic -o x86_64-apple-darwin/test/run-fail/explicit-panic-msg.stage2-x86_64-apple-darwin --cfg rtopt --cfg debug -L x86_64-apple-darwin/rt stdout: ------------------------------------------ ------------------------------------------ stderr: ------------------------------------------ <std macros>:2:26: 2:57 error: use of unstable library feature 'core': internal to format_args! <std macros>:2 $ crate:: fmt:: format ( format_args ! ( $ ( $ arg ) * ) ) ) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: in expansion of __unstable_rustc_ensure_not_fmt_string_literal! <std macros>:4:1: 4:78 note: expansion site <std macros>:1:1: 12:23 note: in expansion of panic! /Users/fklock/Dev/Mozilla/rust-panic/src/test/run-fail/explicit-panic-msg.rs:18:5: 18:37 note: expansion site <std macros>:2:26: 2:57 help: add #![feature(core)] to the crate attributes to enable <std macros>:2:26: 2:57 error: use of unstable library feature 'core': internal to format_args! <std macros>:2 $ crate:: fmt:: format ( format_args ! ( $ ( $ arg ) * ) ) ) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: in expansion of __unstable_rustc_ensure_not_fmt_string_literal! <std macros>:4:1: 4:78 note: expansion site <std macros>:1:1: 12:23 note: in expansion of panic! /Users/fklock/Dev/Mozilla/rust-panic/src/test/run-fail/explicit-panic-msg.rs:18:5: 18:37 note: expansion site <std macros>:2:26: 2:57 help: add #![feature(core)] to the crate attributes to enable error: aborting due to 2 previous errors ------------------------------------------ ``` and I have not yet figured out why this happens even now, nor how to resolve it.
c53b532
to
4efe144
Compare
I'm not clear on whether this is still waiting for review or what. At this point, it's just a warning, right? So it's not backwards incompatible? The stability code is not really my area of expertise, so I'll change this to: |
Its not done yet, unfortunately; I believe there is still some other fallout I need to address in a manner analogous to b58359a -- but yes, my current plan is for just a warning, which means we probably can land it at any time. (I would like it to end up in the beta nonetheless, but I don't know what our threshold is going to be about what warrants cherry-picking.) |
@@ -15,5 +15,6 @@ | |||
fn main() { | |||
let mut a = 1; | |||
if 1 == 1 { a = 2; } | |||
panic!(format!("woooo{}", "o")); | |||
let msg = format!("woooo{}", "o"); | |||
panic!(msg); |
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.
Was this necessary to change?
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.
Ah wait I see the commit now, how come this was necessary to change?
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.
Because otherwise I get stability warnings saying that the internals of float are unstable.
I assume this is due to a bug in either my macro, the expander, or in the way we lint stability via the chain of spans associated with the expansion. I was/am not sure if this is a deal-breaker for this change; maybe I will have to track down that bug first (and presumably let this wait until 1.x to land.)
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.
on reflection, the benefit of the warning (catching the programming mistake where one passes a format literal string to panic!
but forgets the associated format arguments) does not warrant breaking even code like the example above.
I still think the fact that my macro did not work represents a bug somewhere, perhaps in the macro system or in the stability checker.
But for now I am closing this PR; we can put in this warning later (i.e. after 1.0).
Ensure a sole string-literal passed to
panic!
is not a fmt string.To accomplish this, adds
ensure_not_fmt_string_literal!
macro that will warn during compilation if its expression argument is a fmt string literal.Since this is making a certain kind of use of
panic!
illegal, it is a:[breaking-change]
In particular, a panic like this:
must be rewritten; one easy rewrite is to add parentheses:
Fix #22932.