Skip to content
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

warn on strings that look like inline format strings but aren't #10195

Closed
matthiaskrgr opened this issue Jan 13, 2023 · 7 comments · Fixed by #13410
Closed

warn on strings that look like inline format strings but aren't #10195

matthiaskrgr opened this issue Jan 13, 2023 · 7 comments · Fixed by #13410
Labels
A-lint Area: New lints

Comments

@matthiaskrgr
Copy link
Member

What it does

fn main() {
    let number = 123;
    let s = "{number:?}"; // this is likely a bug.
    println!("{s}");
}

Lint Name

No response

Category

No response

Advantage

No response

Drawbacks

No response

Example

fn main() {
    let number = 123;
    let s = "{number:?}"; // this is likely a bug.
    println!("{s}");
}

Could be written as:

fn main() {
    let number = 123;
    let s = format!("{number:?}"); 
    println!("{s}");
}
@matthiaskrgr matthiaskrgr added the A-lint Area: New lints label Jan 13, 2023
@awused
Copy link

awused commented Aug 1, 2023

I've noticed myself running into this a fair bit with the new format syntax, especially when refactoring code. Before, "{}", arg would be two arguments and fail type checking if I put it into a function call that was expecting a &str, but now "{arg}" is one &str and type checks without issue.

@matthiaskrgr
Copy link
Member Author

matthiaskrgr commented Nov 7, 2023

I just found an even more interesting case IRL in kani, where it looks like expect()would take a format string, but it does just print the raw strwithout applying any formatting 😄

model-checking/kani#2865

pub fn main() {
    let mut x = Some(3);
    let y = "aaa";
    x = None.expect("hello {y}");
}

will print literally hello {y} instead of hello aaa

@TTWNO
Copy link

TTWNO commented Feb 29, 2024

Found some code in my crate that did the same thing:

role.rs:632: let encoded = to_bytes(ctxt, &from_role).expect("Unable to encode {from_role}");
role.rs:635: from_slice(&encoded, ctxt).expect("Unable to convert {encoded} into Role");
interface.rs:390: let serde_val = serde_plain::to_string(&iface).expect("Unable to serialize {iface}");
tests.rs:35: .expect("Could not set sender to {unique_bus_name:?}")
tests.rs:91: .expect("Could not set sender to {unique_bus_name:?}")
tests.rs:169: .expect("Could not set sender to {unique_bus_name:?}")

Could we get a comment on if this would be a reasonable lint or not?

@emilk
Copy link

emilk commented Sep 9, 2024

This is an easy mistake when using UI toolkits:

let x = 42;
ui.label("The value is {x}"); // oops!

@emilk
Copy link

emilk commented Sep 10, 2024

@GuillaumeGomez wdyt?

It requires some thought on exactly what patterns to look for, and I'm sure there will be false positives (so this should probably be an opt-in lint). But at looking for the regex \{\w*:?\??\} should catch quite a lot of the problems, without too many false positives. Looking for the regex \{.*} would catch all problems, but would perhaps have too many false positives

@GuillaumeGomez
Copy link
Member

GuillaumeGomez commented Sep 11, 2024

I think it's common enough to definitely deserve a lint. I'm at rustconf currently but I'm putting it in my todo list for next week when I'm back.

EDIT: as for the "level" of check, I'll give a try at different approaches but I think a global regex that then is checked individually (to see if it's actually valid rust syntax and not {{ escaped too) should allow to rule out most false-positive.

@GuillaumeGomez
Copy link
Member

I opened #13410. Don't hesitate to give it a try as I'm interested to find out cases I might have missed. :)

github-merge-queue bot pushed a commit that referenced this issue Dec 1, 2024
Fixes #10195.

changelog: Added new [`literal_string_with_formatting_args`] `pedantic`
lint
[#13410](#13410)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants