-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add unnecessary_debug_formatting
lint
#13893
Add unnecessary_debug_formatting
lint
#13893
Conversation
cc: @kornelski |
8a7ccf4
to
4e1cad1
Compare
@blyxyas Sorry for the CI failures and the force push. But I think the lint should be good now. |
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.
Great first patch!
clippy_lints/src/format_args.rs
Outdated
#[clippy::version = "1.85.0"] | ||
pub UNNECESSARY_DEBUG_FORMATTING, | ||
restriction, | ||
"`Debug` formatting applied to an `OsStr` or `Path`" |
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.
"`Debug` formatting applied to an `OsStr` or `Path`" | |
"`Debug` formatting applied to an `OsStr` or `Path` when `.display()` is available." |
clippy_lints/src/format_args.rs
Outdated
/// ``` | ||
#[clippy::version = "1.85.0"] | ||
pub UNNECESSARY_DEBUG_FORMATTING, | ||
restriction, |
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 think that this would fit better into pedantic
.
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 considered this. But I was concerned there could be legitimate reasons to print a path with debug formatting, and that having to allow
them could get annoying.
I'll change it if you feel strongly.
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 think it'd be better in pedantic
.
This isn't a subjective restriction, but future-proofing for a feature that can disable Debug
entirely, and a warning that Rust never promised any stable syntax of the Debug
format. I've seen a couple of libraries assume the Debug
format is a correct serialization of paths into Rust string syntax, which it is not, and it breaks on non-UTF-8.
So it is pedantically warning about edge cases that may affect all programs.
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.
OK. I'll change it.
@@ -439,6 +478,24 @@ impl FormatArgsExpr<'_, '_> { | |||
} | |||
} | |||
|
|||
fn check_unnecessary_debug_formatting(&self, name: Symbol, value: &Expr<'_>) { | |||
let cx = self.cx; | |||
if !value.span.from_expansion() |
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.
Should this also check for procedural macros? Usually new lints want to make sure we aren't linting in those cases.
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.
Frankly, I'm not sure, though I don't think it would hurt.
You mention "new lints" but are there larger guidelines for when is_from_proc_macro
should be used?
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.
In general, everywhere. There are not many lints that we want to lint in procedural macros. Proc macros are outside of the user's control and could produce any arbitrary output based on any arbitrary input.
For example, a while back we had an issue that a clap
procedural macro produced let _ = _
, Clippy warned about that and the user was confused because there was nothing they could do apart from reporting it to either Clap or Clippy. I'm not sure if there's a case that we want to explicitly lint in procedural macros.
// Even if `ty` is not in `self.ty_feature_map`, check whether `ty` implements `Deref` with with a | ||
// `Target` that is in `self.ty_feature_map`. | ||
if let Some(deref_trait_id) = self.cx.tcx.lang_items().deref_trait() | ||
&& let Some(target_ty) = self.cx.get_associated_type(ty, deref_trait_id, "Target") |
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.
We need to check that ty
implements Deref before calling this function (this would save us a lot of work, as there are not a lot of types that implement Deref after a .peel_refs()
.)
println!("{:?}", path); | ||
println!("{:?}", path_buf); | ||
|
||
let _: String = format!("{:?}", path); | ||
let _: String = format!("{:?}", path_buf); | ||
|
||
let deref_path = DerefPath { path }; | ||
println!("{:?}", &*deref_path); |
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.
println!("{:?}", path); | |
println!("{:?}", path_buf); | |
let _: String = format!("{:?}", path); | |
let _: String = format!("{:?}", path_buf); | |
let deref_path = DerefPath { path }; | |
println!("{:?}", &*deref_path); | |
println!("{:?}", path); //~ unnecessary_debug_formatting | |
println!("{:?}", path_buf); //~ unnecessary_debug_formatting | |
let _: String = format!("{:?}", path); //~ unnecessary_debug_formatting | |
let _: String = format!("{:?}", path_buf); //~ unnecessary_debug_formatting | |
let deref_path = DerefPath { path }; | |
println!("{:?}", &*deref_path); //~ unnecessary_debug_formatting |
println!("{:?}", os_str); | ||
println!("{:?}", os_string); | ||
|
||
let _: String = format!("{:?}", os_str); | ||
let _: String = format!("{:?}", os_string); |
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.
println!("{:?}", os_str); | |
println!("{:?}", os_string); | |
let _: String = format!("{:?}", os_str); | |
let _: String = format!("{:?}", os_string); | |
println!("{:?}", os_str); //~ unnecessary_debug_formatting | |
println!("{:?}", os_string); //~ unnecessary_debug_formatting | |
let _: String = format!("{:?}", os_str); //~ unnecessary_debug_formatting | |
let _: String = format!("{:?}", os_string); //~ unnecessary_debug_formatting |
@blyxyas I think I have addressed all of your comments thus far. |
|
||
// positive tests | ||
println!("{:?}", path); //~ unnecessary_debug_formatting | ||
println!("{:?}", path_buf); //~ unnecessary_debug_formatting |
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 an inline format test as well?
println!("{path_buf:?}"); //~ unnecessary_debug_formatting
(ditto for OsStr
)
Here's the FCP: https://rust-lang.zulipchat.com/#narrow/channel/257328-clippy/topic/FCP.3A.20unnecessary_debug_formatting Alexendoo says: It should definitely note that there is a difference in the output. I agree, we should probably mention that there may be a difference between outputs. (Although in version 1.85 there is not) |
I don't think anything changed in 1.85, While |
I'm proposing to add this text to the description:
Does this sound okay? Where would you add this, under "Why is this bad?"? EDIT: Added. |
I was thinking to add a diagnostic note For the Why is this bad? angle you could phrase it from the perspective of not being able copy/paste a path correctly or click it in an integrated terminal if the characters are escaped |
I'll make both changes. |
@Alexendoo Please tell me if what I pushed is not what you had in mind. |
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.
Sorry for the delay, I was waiting for Alex's input on the change but taking a look at it I think it's very agreeable.
LGTM, thanks! ❤️ Could you change the version to reflect the new current version and squash all commits?
d5bdce7
to
d467273
Compare
No worries at all. Please let me know if there's a Clippy version I missed. And thank you for the review. 🙏 |
clippy_lints/src/format_args.rs
Outdated
/// let path = Path::new("…"); | ||
/// println!("The path is {}", path.display()); | ||
/// ``` | ||
#[clippy::version = "1.86.0"] |
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.
We decide the rust version for new Clippy lints by viewing the output of rustc -Vv
in master
👀
This should be 1.87.0 🐱
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.
Oof. Sorry.
Ah sorry, I thought I had replied to this thread Yeah, LGTM |
Address review comments Fix adjacent code Required now that the lint is pedantic Add inline formatting tests Add note re formatting changes Address `unnecessary_map_or` warnings Address additional review comments Typo Update Clippy version
d467273
to
6af901c
Compare
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.
LGTM, thanks! ❤️
Fixes #12674, i.e., adds a lint to flag
Path
s printed with{:?}
.Nits are welcome.
changelog: Add
unnecessary_debug_formatting
lint