diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs index 307e582d65e..bc2c6def68a 100644 --- a/compiler/rustc_builtin_macros/src/format_foreign.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign.rs @@ -263,13 +263,13 @@ pub(crate) mod printf { } impl Num { - fn from_str(s: &str, arg: Option<&str>) -> Self { + fn from_str(s: &str, arg: Option<&str>) -> Option { if let Some(arg) = arg { - Num::Arg(arg.parse().unwrap_or_else(|_| panic!("invalid format arg `{arg:?}`"))) + arg.parse().ok().map(|arg| Num::Arg(arg)) } else if s == "*" { - Num::Next + Some(Num::Next) } else { - Num::Num(s.parse().unwrap_or_else(|_| panic!("invalid format num `{s:?}`"))) + s.parse().ok().map(|num| Num::Num(num)) } } @@ -421,7 +421,10 @@ pub(crate) mod printf { state = Prec; parameter = None; flags = ""; - width = Some(Num::from_str(at.slice_between(end).unwrap(), None)); + width = at.slice_between(end).and_then(|num| Num::from_str(num, None)); + if width.is_none() { + return fallback(); + } move_to!(end); } // It's invalid, is what it is. @@ -452,7 +455,10 @@ pub(crate) mod printf { '1'..='9' => { let end = at_next_cp_while(next, char::is_ascii_digit); state = Prec; - width = Some(Num::from_str(at.slice_between(end).unwrap(), None)); + width = at.slice_between(end).and_then(|num| Num::from_str(num, None)); + if width.is_none() { + return fallback(); + } move_to!(end); } _ => { @@ -468,7 +474,7 @@ pub(crate) mod printf { match end.next_cp() { Some(('$', end2)) => { state = Prec; - width = Some(Num::from_str("", Some(at.slice_between(end).unwrap()))); + width = Num::from_str("", at.slice_between(end)); move_to!(end2); } _ => { @@ -500,7 +506,7 @@ pub(crate) mod printf { match end.next_cp() { Some(('$', end2)) => { state = Length; - precision = Some(Num::from_str("*", next.slice_between(end))); + precision = Num::from_str("*", next.slice_between(end)); move_to!(end2); } _ => { @@ -513,7 +519,7 @@ pub(crate) mod printf { '0'..='9' => { let end = at_next_cp_while(next, char::is_ascii_digit); state = Length; - precision = Some(Num::from_str(at.slice_between(end).unwrap(), None)); + precision = at.slice_between(end).and_then(|num| Num::from_str(num, None)); move_to!(end); } _ => return fallback(), diff --git a/tests/ui/macros/println-percent-prefix-num-issue-125002.rs b/tests/ui/macros/println-percent-prefix-num-issue-125002.rs new file mode 100644 index 00000000000..9f30d48a5cd --- /dev/null +++ b/tests/ui/macros/println-percent-prefix-num-issue-125002.rs @@ -0,0 +1,6 @@ +fn main() { + println!("%100000", 1); + //~^ ERROR argument never used + println!("% 65536", 1); + //~^ ERROR argument never used +} diff --git a/tests/ui/macros/println-percent-prefix-num-issue-125002.stderr b/tests/ui/macros/println-percent-prefix-num-issue-125002.stderr new file mode 100644 index 00000000000..7575137be6d --- /dev/null +++ b/tests/ui/macros/println-percent-prefix-num-issue-125002.stderr @@ -0,0 +1,28 @@ +error: argument never used + --> $DIR/println-percent-prefix-num-issue-125002.rs:2:25 + | +LL | println!("%100000", 1); + | ^ argument never used + | +note: format specifiers use curly braces, and the conversion specifier `1` is unknown or unsupported + --> $DIR/println-percent-prefix-num-issue-125002.rs:2:15 + | +LL | println!("%100000", 1); + | ^^ + = note: printf formatting is not supported; see the documentation for `std::fmt` + +error: argument never used + --> $DIR/println-percent-prefix-num-issue-125002.rs:4:29 + | +LL | println!("% 65536", 1); + | ^ argument never used + | +note: format specifiers use curly braces, and the conversion specifier ` ` is unknown or unsupported + --> $DIR/println-percent-prefix-num-issue-125002.rs:4:15 + | +LL | println!("% 65536", 1); + | ^^ + = note: printf formatting is not supported; see the documentation for `std::fmt` + +error: aborting due to 2 previous errors +