rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.98k stars 12.54k forks source link

does not detect {} not being in quotes when looking for a string literal, instead offers an incorrect solution #130170

Open EnderNon opened 1 week ago

EnderNon commented 1 week ago

Code

use serde_json;

let idsmap: HashMap<String, u8> = serde_json::from_reader(fs::File::open("id_keys.json").expect("error 3"))
    .expect("error 4");
println!({},idsmap.get("1stSpellCost"));

Current output

error: format argument must be a string literal
  --> src/main.rs:55:14
   |
55 |     println!({},idsmap.get("1stSpellCost"));
   |              ^^
   |
help: you might be missing a string literal to format with
   |
55 |     println!("{} {}", {},idsmap.get("1stSpellCost"));
   |              ++++++++

Desired output

error: format argument must be a string literal
  --> src/main.rs:55:14
   |
55 |     println!({},idsmap.get("1stSpellCost"));
   |              ^^
   |
help: you might be missing brackets
   |
55 |     println!("{}",idsmap.get("1stSpellCost"));
   |              +  +

Rationale and extra context

Cargo does not seem to be detecting the {} outside brackets and provides an incredibly strange fix instead.

Other cases

No response

Rust Version

rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: x86_64-unknown-linux-gnu
release: 1.81.0
LLVM version: 18.1.7

Anything else?

the file is from here: https://github.com/Wynntils/Static-Storage/blob/main/Reference/id_keys.json
You will need serde_json crate.

lolbinarycat commented 1 week ago

it's worth noting that {} is a valid rust expression, it evaluates to the empty tuple.

this is perfectly valid code:

fn main() {
    println!("{:?}", {});
}

minimal repro:

fn main() {
    println!({});
}
EnderNon commented 1 week ago

huh, didn't know that. good to know ig

asquared31415 commented 1 week ago

I think it is worth special casing this in diagnostics though, if someone wanted to print a unit type (for some reason?) they probably should use the () value or just embed it directly in the format string. An empty {} expression as the first argument of a format macro is almost certainly a mistake.