-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
A new lint to remove unneeded arg referencing in a format! #10851
Comments
Performance update: I consistently see a ~5% performance difference in a small benchmark. |
Hello for your problem, I wish to work on this subject. Is it possible? If yes, have you some suggestions to give me? |
For a plain binding yeah you wouldn't be able to do Another thing to watch out for would be
|
@Alexendoo thanks, good points. I am unclear about the last one -- all of these seems to work identically: fn main() {
let s = "hello world";
println!("{}", s);
println!("{}", &s);
println!("{}", &*s);
} The rest of it could be added as unit tests -- these should not trigger the lint: fn main() {
let vec = vec![1, 2, 3];
let int = 42_i32;
println!("{:?}", &vec[0..2]);
println!("{:p}", &int);
} |
@disco07 go for it! See https://doc.rust-lang.org/nightly/clippy/development/adding_lints.html as a good starting point |
e.g. only the last struct S;
impl std::ops::Deref for S {
type Target = str;
fn deref(&self) -> &str {
""
}
}
fn main() {
let s = S;
println!("{}", s);
println!("{}", &s);
println!("{}", *s);
println!("{}", &*s);
} |
Actually only the 3rd one will not compile. But same point :)
|
If you change the code to something else... yes The other two cases still change the behaviour though in that example and so shouldn't be suggested |
Ah oke sorry, now I got your point :) |
Is there ever a case |
It makes sense when |
I somehow feel this is almost never the case... to the point of perhaps creating a lint that flags |
When would you want to print the stack address of a pointer rather than the pointer itself? |
I don't think you ever would... thus my point that |
It's the other way around, |
Avoid ref when using format! in compiler Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See also rust-lang/rust-clippy#10851
Avoid ref when using format! in compiler Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See also rust-lang/rust-clippy#10851
Avoid ref when using format! in src Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See also rust-lang/rust-clippy#10851
Avoid ref when using format! in compiler Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See rust-lang/rust-clippy#10851
Rollup merge of rust-lang#127984 - nyurik:src-refs, r=onur-ozkan Avoid ref when using format! in src Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See also rust-lang/rust-clippy#10851
Rollup merge of rust-lang#127980 - nyurik:compiler-refs, r=oli-obk Avoid ref when using format! in compiler Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See also rust-lang/rust-clippy#10851
Avoid ref when using format! in compiler Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See rust-lang/rust-clippy#10851
Avoid ref when using format! in compiler Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse. See rust-lang/rust-clippy#10851
What it does
Passing a reference to a value instead of the value itself to the
format!
macro causes unneeded double referencing that is not compiled away, as described in my stackoverflow question, and demonstrated in the 1.69 assembly output. The issue seem to be that reference format dispatch is not inlined by llvm. While this might be some issue with the Rust compiler itself, or an issue that is hard/impossible to solve in a general case, I think we could introduce a lint in the mean time to suggest it to improve readability and performance.Lint Name
unneeded_format_arg_ref
Category
No response
Advantage
format!("{}", &var)
-->format!("{var}")
Drawbacks
Uncertain if there could ever be an edge case where formatting
&var
andvar
would produce different result, e.g. if format wants to print the address of a variable?Example
Could be written as:
The text was updated successfully, but these errors were encountered: