-
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
base: master
Are you sure you want to change the base?
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 |
Required now that the lint is pedantic
@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
)
Fixes #12674, i.e., adds a lint to flag
Path
s printed with{:?}
.Nits are welcome.
changelog: Add
unnecessary_debug_formatting
lint