diff options
Diffstat (limited to 'src/test/ui/fmt')
37 files changed, 1568 insertions, 0 deletions
diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.rs b/src/test/ui/fmt/format-args-capture-issue-93378.rs new file mode 100644 index 000000000..674444442 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-93378.rs @@ -0,0 +1,11 @@ +fn main() { + let a = "a"; + let b = "b"; + + println!("{a} {b} {} {} {c} {}", c = "c"); + //~^ ERROR: invalid reference to positional arguments 1 and 2 (there is 1 argument) + + let n = 1; + println!("{a:.n$} {b:.*}"); + //~^ ERROR: invalid reference to positional argument 0 (no arguments were given) +} diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.stderr b/src/test/ui/fmt/format-args-capture-issue-93378.stderr new file mode 100644 index 000000000..b8e2b2afb --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-93378.stderr @@ -0,0 +1,22 @@ +error: invalid reference to positional arguments 1 and 2 (there is 1 argument) + --> $DIR/format-args-capture-issue-93378.rs:5:26 + | +LL | println!("{a} {b} {} {} {c} {}", c = "c"); + | ^^ ^^ + | + = note: positional arguments are zero-based + +error: invalid reference to positional argument 0 (no arguments were given) + --> $DIR/format-args-capture-issue-93378.rs:9:23 + | +LL | println!("{a:.n$} {b:.*}"); + | - ^^^--^ + | | | + | | this precision flag adds an extra required argument at position 0, which is why there are 3 arguments expected + | this parameter corresponds to the precision flag + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/fmt/format-args-capture-issue-94010.rs b/src/test/ui/fmt/format-args-capture-issue-94010.rs new file mode 100644 index 000000000..bd03e9c93 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-94010.rs @@ -0,0 +1,7 @@ +fn main() { + const FOO: i32 = 123; + println!("{foo:X}"); + //~^ ERROR: cannot find value `foo` in this scope + println!("{:.foo$}", 0); + //~^ ERROR: cannot find value `foo` in this scope +} diff --git a/src/test/ui/fmt/format-args-capture-issue-94010.stderr b/src/test/ui/fmt/format-args-capture-issue-94010.stderr new file mode 100644 index 000000000..ed90dc855 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-94010.stderr @@ -0,0 +1,20 @@ +error[E0425]: cannot find value `foo` in this scope + --> $DIR/format-args-capture-issue-94010.rs:3:16 + | +LL | const FOO: i32 = 123; + | --------------------- similarly named constant `FOO` defined here +LL | println!("{foo:X}"); + | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/format-args-capture-issue-94010.rs:5:18 + | +LL | const FOO: i32 = 123; + | --------------------- similarly named constant `FOO` defined here +... +LL | println!("{:.foo$}", 0); + | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs new file mode 100644 index 000000000..fdbd93836 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs @@ -0,0 +1,4 @@ +fn main() { + format!(concat!("{foo}")); //~ ERROR: there is no argument named `foo` + format!(concat!("{ba", "r} {}"), 1); //~ ERROR: there is no argument named `bar` +} diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr new file mode 100644 index 000000000..9423e8c81 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr @@ -0,0 +1,22 @@ +error: there is no argument named `foo` + --> $DIR/format-args-capture-macro-hygiene.rs:2:13 + | +LL | format!(concat!("{foo}")); + | ^^^^^^^^^^^^^^^^ + | + = note: did you intend to capture a variable `foo` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: there is no argument named `bar` + --> $DIR/format-args-capture-macro-hygiene.rs:3:13 + | +LL | format!(concat!("{ba", "r} {}"), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: did you intend to capture a variable `bar` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/fmt/format-args-capture-missing-variables.rs b/src/test/ui/fmt/format-args-capture-missing-variables.rs new file mode 100644 index 000000000..46fc083cb --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-missing-variables.rs @@ -0,0 +1,20 @@ +fn main() { + format!("{} {foo} {} {bar} {}", 1, 2, 3); + //~^ ERROR: cannot find value `foo` in this scope + //~^^ ERROR: cannot find value `bar` in this scope + + format!("{foo}"); //~ ERROR: cannot find value `foo` in this scope + + format!("{valuea} {valueb}", valuea=5, valuec=7); + //~^ ERROR cannot find value `valueb` in this scope + //~^^ ERROR named argument never used + + format!(r##" + + {foo} + + "##); + //~^^^ ERROR: cannot find value `foo` in this scope + + panic!("{foo} {bar}", bar=1); //~ ERROR: cannot find value `foo` in this scope +} diff --git a/src/test/ui/fmt/format-args-capture-missing-variables.stderr b/src/test/ui/fmt/format-args-capture-missing-variables.stderr new file mode 100644 index 000000000..d980e7be2 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-missing-variables.stderr @@ -0,0 +1,47 @@ +error: named argument never used + --> $DIR/format-args-capture-missing-variables.rs:8:51 + | +LL | format!("{valuea} {valueb}", valuea=5, valuec=7); + | ------------------- ^ named argument never used + | | + | formatting specifier missing + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/format-args-capture-missing-variables.rs:2:18 + | +LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); + | ^^^ not found in this scope + +error[E0425]: cannot find value `bar` in this scope + --> $DIR/format-args-capture-missing-variables.rs:2:27 + | +LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); + | ^^^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/format-args-capture-missing-variables.rs:6:15 + | +LL | format!("{foo}"); + | ^^^ not found in this scope + +error[E0425]: cannot find value `valueb` in this scope + --> $DIR/format-args-capture-missing-variables.rs:8:24 + | +LL | format!("{valuea} {valueb}", valuea=5, valuec=7); + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/format-args-capture-missing-variables.rs:14:10 + | +LL | {foo} + | ^^^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/format-args-capture-missing-variables.rs:19:14 + | +LL | panic!("{foo} {bar}", bar=1); + | ^^^ not found in this scope + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs new file mode 100644 index 000000000..560352b5c --- /dev/null +++ b/src/test/ui/fmt/format-args-capture.rs @@ -0,0 +1,89 @@ +// run-pass + +fn main() { + named_argument_takes_precedence_to_captured(); + formatting_parameters_can_be_captured(); + capture_raw_strings_and_idents(); + repeated_capture(); + + #[cfg(panic = "unwind")] + { + panic_with_single_argument_does_not_get_formatted(); + panic_with_multiple_arguments_is_formatted(); + } +} + +fn named_argument_takes_precedence_to_captured() { + let foo = "captured"; + let s = format!("{foo}", foo = "named"); + assert_eq!(&s, "named"); + + let s = format!("{foo}-{foo}-{foo}", foo = "named"); + assert_eq!(&s, "named-named-named"); + + let s = format!("{}-{bar}-{foo}", "positional", bar = "named"); + assert_eq!(&s, "positional-named-captured"); +} + +fn capture_raw_strings_and_idents() { + let r#type = "apple"; + let s = format!(r#"The fruit is an {type}"#); + assert_eq!(&s, "The fruit is an apple"); + + let r#type = "orange"; + let s = format!(r"The fruit is an {type}"); + assert_eq!(&s, "The fruit is an orange"); +} + +#[cfg(panic = "unwind")] +fn panic_with_single_argument_does_not_get_formatted() { + // panic! with a single argument does not perform string formatting. + // RFC #2795 suggests that this may need to change so that captured arguments are formatted. + // For stability reasons this will need to part of an edition change. + + #[allow(non_fmt_panics)] + let msg = std::panic::catch_unwind(|| { + panic!("{foo}"); + }) + .unwrap_err(); + + assert_eq!(msg.downcast_ref::<&str>(), Some(&"{foo}")) +} + +#[cfg(panic = "unwind")] +fn panic_with_multiple_arguments_is_formatted() { + let foo = "captured"; + + let msg = std::panic::catch_unwind(|| { + panic!("{}-{bar}-{foo}", "positional", bar = "named"); + }) + .unwrap_err(); + + assert_eq!(msg.downcast_ref::<String>(), Some(&"positional-named-captured".to_string())) +} + +fn formatting_parameters_can_be_captured() { + let width = 9; + let precision = 3; + + let x = 7.0; + + let s = format!("{x:width$}"); + assert_eq!(&s, " 7"); + + let s = format!("{x:<width$}"); + assert_eq!(&s, "7 "); + + let s = format!("{x:-^width$}"); + assert_eq!(&s, "----7----"); + + let s = format!("{x:-^width$.precision$}"); + assert_eq!(&s, "--7.000--"); +} + +fn repeated_capture() { + let a = 1; + let b = 2; + let s = format!("{a} {b} {a}"); + assert_eq!(&s, "1 2 1"); +} diff --git a/src/test/ui/fmt/format-concat-span.rs b/src/test/ui/fmt/format-concat-span.rs new file mode 100644 index 000000000..ce92df0ad --- /dev/null +++ b/src/test/ui/fmt/format-concat-span.rs @@ -0,0 +1,15 @@ +// If the format string is another macro invocation, rustc would previously +// compute nonsensical spans, such as: +// +// error: invalid format string: unmatched `}` found +// --> test.rs:2:17 +// | +// 2 | format!(concat!("abc}")); +// | ^ unmatched `}` in format string +// +// This test checks that this behavior has been fixed. + +fn main() { + format!(concat!("abc}")); + //~^ ERROR: invalid format string: unmatched `}` found +} diff --git a/src/test/ui/fmt/format-concat-span.stderr b/src/test/ui/fmt/format-concat-span.stderr new file mode 100644 index 000000000..da46f40ab --- /dev/null +++ b/src/test/ui/fmt/format-concat-span.stderr @@ -0,0 +1,11 @@ +error: invalid format string: unmatched `}` found + --> $DIR/format-concat-span.rs:13:13 + | +LL | format!(concat!("abc}")); + | ^^^^^^^^^^^^^^^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/fmt/format-string-error-2.rs b/src/test/ui/fmt/format-string-error-2.rs new file mode 100644 index 000000000..1f7f0d8f6 --- /dev/null +++ b/src/test/ui/fmt/format-string-error-2.rs @@ -0,0 +1,86 @@ +// ignore-tidy-tab + +fn main() { + format!("{ + a"); + //~^ ERROR invalid format string + format!("{ \ + \ + b"); + //~^ ERROR invalid format string + format!(r#"{ \ + + rawc"#); + //~^^^ ERROR invalid format string + format!(r#"{ \n +\n + rawd"#); + //~^^^ ERROR invalid format string + format!("{ \n +\n + e"); + //~^ ERROR invalid format string + format!(" + { + a"); + //~^ ERROR invalid format string + format!(" + { + a + "); + //~^^ ERROR invalid format string + format!(" \ + { \ + \ + b"); + //~^ ERROR invalid format string + format!(" \ + { \ + \ + b \ + \ + "); + //~^^^ ERROR invalid format string + format!(r#" +raw { \ + \ + c"#); + //~^^^ ERROR invalid format string + format!(r#" +raw { \n +\n + d"#); + //~^^^ ERROR invalid format string + format!(" + { \n +\n + e"); + //~^ ERROR invalid format string + + format!(" + {asdf + } + ", asdf=1); + // ok - this is supported + format!(" + { + asdf} + ", asdf=1); + //~^^ ERROR invalid format string + println!("\t{}"); + //~^ ERROR 1 positional argument in format string + + // note: `\x7B` is `{` + println!("\x7B}\u{8} {", 1); + //~^ ERROR invalid format string: expected `'}'` but string was terminated + + println!("\x7B}\u8 {", 1); + //~^ ERROR incorrect unicode escape sequence + + // note: raw strings don't escape `\xFF` and `\u{FF}` sequences + println!(r#"\x7B}\u{8} {"#, 1); + //~^ ERROR invalid format string: unmatched `}` found + + println!(r#"\x7B}\u8 {"#, 1); + //~^ ERROR invalid format string: unmatched `}` found +} diff --git a/src/test/ui/fmt/format-string-error-2.stderr b/src/test/ui/fmt/format-string-error-2.stderr new file mode 100644 index 000000000..76cdfbb93 --- /dev/null +++ b/src/test/ui/fmt/format-string-error-2.stderr @@ -0,0 +1,175 @@ +error: incorrect unicode escape sequence + --> $DIR/format-string-error-2.rs:77:20 + | +LL | println!("\x7B}\u8 {", 1); + | ^^^ help: format of unicode escape sequences uses braces: `\u{8}` + +error: invalid format string: expected `'}'`, found `'a'` + --> $DIR/format-string-error-2.rs:5:5 + | +LL | format!("{ + | - because of this opening brace +LL | a"); + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'b'` + --> $DIR/format-string-error-2.rs:9:5 + | +LL | format!("{ \ + | - because of this opening brace +LL | \ +LL | b"); + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'\'` + --> $DIR/format-string-error-2.rs:11:18 + | +LL | format!(r#"{ \ + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'\'` + --> $DIR/format-string-error-2.rs:15:18 + | +LL | format!(r#"{ \n + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'e'` + --> $DIR/format-string-error-2.rs:21:5 + | +LL | format!("{ \n + | - because of this opening brace +LL | \n +LL | e"); + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'a'` + --> $DIR/format-string-error-2.rs:25:5 + | +LL | { + | - because of this opening brace +LL | a"); + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'a'` + --> $DIR/format-string-error-2.rs:29:5 + | +LL | { + | - because of this opening brace +LL | a + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'b'` + --> $DIR/format-string-error-2.rs:35:5 + | +LL | { \ + | - because of this opening brace +LL | \ +LL | b"); + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'b'` + --> $DIR/format-string-error-2.rs:40:5 + | +LL | { \ + | - because of this opening brace +LL | \ +LL | b \ + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'\'` + --> $DIR/format-string-error-2.rs:45:8 + | +LL | raw { \ + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'\'` + --> $DIR/format-string-error-2.rs:50:8 + | +LL | raw { \n + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'e'` + --> $DIR/format-string-error-2.rs:57:5 + | +LL | { \n + | - because of this opening brace +LL | \n +LL | e"); + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'`, found `'a'` + --> $DIR/format-string-error-2.rs:67:5 + | +LL | { + | - because of this opening brace +LL | asdf} + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: 1 positional argument in format string, but no arguments were given + --> $DIR/format-string-error-2.rs:70:17 + | +LL | println!("\t{}"); + | ^^ + +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/format-string-error-2.rs:74:27 + | +LL | println!("\x7B}\u{8} {", 1); + | -^ expected `'}'` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: unmatched `}` found + --> $DIR/format-string-error-2.rs:81:21 + | +LL | println!(r#"\x7B}\u{8} {"#, 1); + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: invalid format string: unmatched `}` found + --> $DIR/format-string-error-2.rs:84:21 + | +LL | println!(r#"\x7B}\u8 {"#, 1); + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: aborting due to 18 previous errors + diff --git a/src/test/ui/fmt/format-string-error.rs b/src/test/ui/fmt/format-string-error.rs new file mode 100644 index 000000000..eae4f3cb5 --- /dev/null +++ b/src/test/ui/fmt/format-string-error.rs @@ -0,0 +1,55 @@ +// ignore-tidy-tab + +fn main() { + println!("{"); + //~^ ERROR invalid format string: expected `'}'` but string was terminated + println!("{{}}"); + println!("}"); + //~^ ERROR invalid format string: unmatched `}` found + let _ = format!("{_}", _ = 6usize); + //~^ ERROR invalid format string: invalid argument name `_` + let _ = format!("{a:_}", a = "", _ = 0); + //~^ ERROR invalid format string: invalid argument name `_` + let _ = format!("{a:._$}", a = "", _ = 0); + //~^ ERROR invalid format string: invalid argument name `_` + let _ = format!("{"); + //~^ ERROR invalid format string: expected `'}'` but string was terminated + let _ = format!("}"); + //~^ ERROR invalid format string: unmatched `}` found + let _ = format!("{\\}"); + //~^ ERROR invalid format string: expected `'}'`, found `'\\'` + let _ = format!("\n\n\n{\n\n\n"); + //~^ ERROR invalid format string + let _ = format!(r###" + + + + {"###); + //~^ ERROR invalid format string + let _ = format!(r###" + + + + { + +"###); + //~^ ERROR invalid format string + let _ = format!(r###" + + + + } + +"###); + //~^^^ ERROR invalid format string + let _ = format!(r###" + + + + } + +"###); + //~^^^ ERROR invalid format string: unmatched `}` found + println!("{} {} {}", 1, 2); + //~^ ERROR 3 positional arguments in format string, but there are 2 arguments +} diff --git a/src/test/ui/fmt/format-string-error.stderr b/src/test/ui/fmt/format-string-error.stderr new file mode 100644 index 000000000..8a32c2254 --- /dev/null +++ b/src/test/ui/fmt/format-string-error.stderr @@ -0,0 +1,125 @@ +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/format-string-error.rs:4:16 + | +LL | println!("{"); + | -^ expected `'}'` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: unmatched `}` found + --> $DIR/format-string-error.rs:7:15 + | +LL | println!("}"); + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: invalid format string: invalid argument name `_` + --> $DIR/format-string-error.rs:9:23 + | +LL | let _ = format!("{_}", _ = 6usize); + | ^ invalid argument name in format string + | + = note: argument name cannot be a single underscore + +error: invalid format string: invalid argument name `_` + --> $DIR/format-string-error.rs:11:25 + | +LL | let _ = format!("{a:_}", a = "", _ = 0); + | ^ invalid argument name in format string + | + = note: argument name cannot be a single underscore + +error: invalid format string: invalid argument name `_` + --> $DIR/format-string-error.rs:13:26 + | +LL | let _ = format!("{a:._$}", a = "", _ = 0); + | ^ invalid argument name in format string + | + = note: argument name cannot be a single underscore + +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/format-string-error.rs:15:23 + | +LL | let _ = format!("{"); + | -^ expected `'}'` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: unmatched `}` found + --> $DIR/format-string-error.rs:17:22 + | +LL | let _ = format!("}"); + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: invalid format string: expected `'}'`, found `'\'` + --> $DIR/format-string-error.rs:19:23 + | +LL | let _ = format!("{\}"); + | -^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/format-string-error.rs:21:35 + | +LL | let _ = format!("\n\n\n{\n\n\n"); + | - ^ expected `'}'` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/format-string-error.rs:27:3 + | +LL | {"###); + | -^ expected `'}'` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/format-string-error.rs:35:1 + | +LL | { + | - because of this opening brace +LL | +LL | "###); + | ^ expected `'}'` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: unmatched `}` found + --> $DIR/format-string-error.rs:41:2 + | +LL | } + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: invalid format string: unmatched `}` found + --> $DIR/format-string-error.rs:49:9 + | +LL | } + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: 3 positional arguments in format string, but there are 2 arguments + --> $DIR/format-string-error.rs:53:15 + | +LL | println!("{} {} {}", 1, 2); + | ^^ ^^ ^^ - - + +error: aborting due to 14 previous errors + diff --git a/src/test/ui/fmt/format-with-yield-point.rs b/src/test/ui/fmt/format-with-yield-point.rs new file mode 100644 index 000000000..e484074cc --- /dev/null +++ b/src/test/ui/fmt/format-with-yield-point.rs @@ -0,0 +1,33 @@ +// check-pass +// edition:2021 + +macro_rules! m { + () => { + async {}.await + }; +} + +async fn with_await() { + println!("{} {:?}", "", async {}.await); +} + +async fn with_macro_call_expr() { + println!("{} {:?}", "", m!()); +} + +async fn with_macro_call_stmt_semi() { + println!("{} {:?}", "", { m!(); }); +} + +async fn with_macro_call_stmt_braced() { + println!("{} {:?}", "", { m!{} }); +} + +fn assert_send(_: impl Send) {} + +fn main() { + assert_send(with_await()); + assert_send(with_macro_call_expr()); + assert_send(with_macro_call_stmt_semi()); + assert_send(with_macro_call_stmt_braced()); +} diff --git a/src/test/ui/fmt/ifmt-bad-arg.rs b/src/test/ui/fmt/ifmt-bad-arg.rs new file mode 100644 index 000000000..84f4cc7f4 --- /dev/null +++ b/src/test/ui/fmt/ifmt-bad-arg.rs @@ -0,0 +1,97 @@ +fn main() { + // bad arguments to the format! call + + // bad number of arguments, see #44954 (originally #15780) + + format!("{}"); + //~^ ERROR: 1 positional argument in format string, but no arguments were given + + format!("{1}", 1); + //~^ ERROR: invalid reference to positional argument 1 (there is 1 argument) + //~^^ ERROR: argument never used + + format!("{} {}"); + //~^ ERROR: 2 positional arguments in format string, but no arguments were given + + format!("{0} {1}", 1); + //~^ ERROR: invalid reference to positional argument 1 (there is 1 argument) + + format!("{0} {1} {2}", 1, 2); + //~^ ERROR: invalid reference to positional argument 2 (there are 2 arguments) + + format!("{} {value} {} {}", 1, value=2); + //~^ ERROR: invalid reference to positional argument 2 (there are 2 arguments) + format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2); + //~^ ERROR: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments) + + format!("{} {foo} {} {bar} {}", 1, 2, 3); + //~^ ERROR: cannot find value `foo` in this scope + //~^^ ERROR: cannot find value `bar` in this scope + + format!("{foo}"); //~ ERROR: cannot find value `foo` in this scope + format!("", 1, 2); //~ ERROR: multiple unused formatting arguments + format!("{}", 1, 2); //~ ERROR: argument never used + format!("{1}", 1, 2); //~ ERROR: argument never used + format!("{}", 1, foo=2); //~ ERROR: named argument never used + format!("{foo}", 1, foo=2); //~ ERROR: argument never used + format!("", foo=2); //~ ERROR: named argument never used + format!("{} {}", 1, 2, foo=1, bar=2); //~ ERROR: multiple unused formatting arguments + + format!("{foo}", foo=1, foo=2); //~ ERROR: duplicate argument + format!("{foo} {} {}", foo=1, 2); //~ ERROR: positional arguments cannot follow + + // bad named arguments, #35082 + + format!("{valuea} {valueb}", valuea=5, valuec=7); + //~^ ERROR cannot find value `valueb` in this scope + //~^^ ERROR named argument never used + + // bad syntax of the format string + + format!("{"); //~ ERROR: expected `'}'` but string was terminated + + format!("foo } bar"); //~ ERROR: unmatched `}` found + format!("foo }"); //~ ERROR: unmatched `}` found + + format!("foo %s baz", "bar"); //~ ERROR: argument never used + + format!(r##" + + {foo} + + "##); + //~^^^ ERROR: cannot find value `foo` in this scope + + // bad syntax in format string with multiple newlines, #53836 + format!("first number: {} +second number: {} +third number: {} +fourth number: {} +fifth number: {} +sixth number: {} +seventh number: {} +eighth number: {} +ninth number: { +tenth number: {}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + //~^^ ERROR: invalid format string + println!("{} {:.*} {}", 1, 3.2, 4); + //~^ ERROR 4 positional arguments in format string, but there are 3 arguments + //~| ERROR mismatched types + println!("{} {:07$.*} {}", 1, 3.2, 4); + //~^ ERROR 4 positional arguments in format string, but there are 3 arguments + //~| ERROR mismatched types + println!("{} {:07$} {}", 1, 3.2, 4); + //~^ ERROR invalid reference to positional argument 7 (there are 3 arguments) + println!("{:foo}", 1); //~ ERROR unknown format trait `foo` + println!("{5} {:4$} {6:7$}", 1); + //~^ ERROR invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument) + let foo = 1; + println!("{foo:0$}"); + //~^ ERROR invalid reference to positional argument 0 (no arguments were given) + + // We used to ICE here because we tried to unconditionally access the first argument, which + // doesn't exist. + println!("{:.*}"); + //~^ ERROR 2 positional arguments in format string, but no arguments were given +} diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr new file mode 100644 index 000000000..5439ee173 --- /dev/null +++ b/src/test/ui/fmt/ifmt-bad-arg.stderr @@ -0,0 +1,345 @@ +error: 1 positional argument in format string, but no arguments were given + --> $DIR/ifmt-bad-arg.rs:6:14 + | +LL | format!("{}"); + | ^^ + +error: invalid reference to positional argument 1 (there is 1 argument) + --> $DIR/ifmt-bad-arg.rs:9:14 + | +LL | format!("{1}", 1); + | ^^^ + | + = note: positional arguments are zero-based + +error: argument never used + --> $DIR/ifmt-bad-arg.rs:9:20 + | +LL | format!("{1}", 1); + | ----- ^ argument never used + | | + | formatting specifier missing + +error: 2 positional arguments in format string, but no arguments were given + --> $DIR/ifmt-bad-arg.rs:13:14 + | +LL | format!("{} {}"); + | ^^ ^^ + +error: invalid reference to positional argument 1 (there is 1 argument) + --> $DIR/ifmt-bad-arg.rs:16:18 + | +LL | format!("{0} {1}", 1); + | ^^^ + | + = note: positional arguments are zero-based + +error: invalid reference to positional argument 2 (there are 2 arguments) + --> $DIR/ifmt-bad-arg.rs:19:22 + | +LL | format!("{0} {1} {2}", 1, 2); + | ^^^ + | + = note: positional arguments are zero-based + +error: invalid reference to positional argument 2 (there are 2 arguments) + --> $DIR/ifmt-bad-arg.rs:22:28 + | +LL | format!("{} {value} {} {}", 1, value=2); + | ^^ + | + = note: positional arguments are zero-based + +error: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments) + --> $DIR/ifmt-bad-arg.rs:24:38 + | +LL | format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2); + | ^^ ^^ ^^ + | + = note: positional arguments are zero-based + +error: multiple unused formatting arguments + --> $DIR/ifmt-bad-arg.rs:32:17 + | +LL | format!("", 1, 2); + | -- ^ ^ argument never used + | | | + | | argument never used + | multiple missing formatting specifiers + +error: argument never used + --> $DIR/ifmt-bad-arg.rs:33:22 + | +LL | format!("{}", 1, 2); + | ---- ^ argument never used + | | + | formatting specifier missing + +error: argument never used + --> $DIR/ifmt-bad-arg.rs:34:20 + | +LL | format!("{1}", 1, 2); + | ----- ^ argument never used + | | + | formatting specifier missing + +error: named argument never used + --> $DIR/ifmt-bad-arg.rs:35:26 + | +LL | format!("{}", 1, foo=2); + | ---- ^ named argument never used + | | + | formatting specifier missing + +error: argument never used + --> $DIR/ifmt-bad-arg.rs:36:22 + | +LL | format!("{foo}", 1, foo=2); + | ------- ^ argument never used + | | + | formatting specifier missing + +error: named argument never used + --> $DIR/ifmt-bad-arg.rs:37:21 + | +LL | format!("", foo=2); + | -- ^ named argument never used + | | + | formatting specifier missing + +error: multiple unused formatting arguments + --> $DIR/ifmt-bad-arg.rs:38:32 + | +LL | format!("{} {}", 1, 2, foo=1, bar=2); + | ------- ^ ^ named argument never used + | | | + | | named argument never used + | multiple missing formatting specifiers + +error: duplicate argument named `foo` + --> $DIR/ifmt-bad-arg.rs:40:33 + | +LL | format!("{foo}", foo=1, foo=2); + | - ^ duplicate argument + | | + | previously here + +error: positional arguments cannot follow named arguments + --> $DIR/ifmt-bad-arg.rs:41:35 + | +LL | format!("{foo} {} {}", foo=1, 2); + | - ^ positional arguments must be before named arguments + | | + | named argument + +error: named argument never used + --> $DIR/ifmt-bad-arg.rs:45:51 + | +LL | format!("{valuea} {valueb}", valuea=5, valuec=7); + | ------------------- ^ named argument never used + | | + | formatting specifier missing + +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/ifmt-bad-arg.rs:51:15 + | +LL | format!("{"); + | -^ expected `'}'` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: unmatched `}` found + --> $DIR/ifmt-bad-arg.rs:53:18 + | +LL | format!("foo } bar"); + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: invalid format string: unmatched `}` found + --> $DIR/ifmt-bad-arg.rs:54:18 + | +LL | format!("foo }"); + | ^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: argument never used + --> $DIR/ifmt-bad-arg.rs:56:27 + | +LL | format!("foo %s baz", "bar"); + | -- ^^^^^ argument never used + | | + | help: format specifiers use curly braces: `{}` + | + = note: printf formatting not supported; see the documentation for `std::fmt` + +error: invalid format string: expected `'}'`, found `'t'` + --> $DIR/ifmt-bad-arg.rs:75:1 + | +LL | ninth number: { + | - because of this opening brace +LL | tenth number: {}", + | ^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: 4 positional arguments in format string, but there are 3 arguments + --> $DIR/ifmt-bad-arg.rs:78:15 + | +LL | println!("{} {:.*} {}", 1, 3.2, 4); + | ^^ ^^--^ ^^ - --- - + | | | + | | this parameter corresponds to the precision flag + | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: 4 positional arguments in format string, but there are 3 arguments + --> $DIR/ifmt-bad-arg.rs:81:15 + | +LL | println!("{} {:07$.*} {}", 1, 3.2, 4); + | ^^ ^^^----^ ^^ - --- - + | | | | + | | | this parameter corresponds to the precision flag + | | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected + | this width flag expects an `usize` argument at position 7, but there are 3 arguments + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: invalid reference to positional argument 7 (there are 3 arguments) + --> $DIR/ifmt-bad-arg.rs:84:18 + | +LL | println!("{} {:07$} {}", 1, 3.2, 4); + | ^^^--^ + | | + | this width flag expects an `usize` argument at position 7, but there are 3 arguments + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: unknown format trait `foo` + --> $DIR/ifmt-bad-arg.rs:86:17 + | +LL | println!("{:foo}", 1); + | ^^^ + | + = note: the only appropriate formatting traits are: + - ``, which uses the `Display` trait + - `?`, which uses the `Debug` trait + - `e`, which uses the `LowerExp` trait + - `E`, which uses the `UpperExp` trait + - `o`, which uses the `Octal` trait + - `p`, which uses the `Pointer` trait + - `b`, which uses the `Binary` trait + - `x`, which uses the `LowerHex` trait + - `X`, which uses the `UpperHex` trait + +error: invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument) + --> $DIR/ifmt-bad-arg.rs:87:15 + | +LL | println!("{5} {:4$} {6:7$}", 1); + | ^^^ ^^--^ ^^^--^ + | | | + | | this width flag expects an `usize` argument at position 7, but there is 1 argument + | this width flag expects an `usize` argument at position 4, but there is 1 argument + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: invalid reference to positional argument 0 (no arguments were given) + --> $DIR/ifmt-bad-arg.rs:90:15 + | +LL | println!("{foo:0$}"); + | ^^^^^--^ + | | + | this width flag expects an `usize` argument at position 0, but no arguments were given + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: 2 positional arguments in format string, but no arguments were given + --> $DIR/ifmt-bad-arg.rs:95:15 + | +LL | println!("{:.*}"); + | ^^--^ + | | + | this precision flag adds an extra required argument at position 0, which is why there are 2 arguments expected + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/ifmt-bad-arg.rs:27:18 + | +LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); + | ^^^ not found in this scope + +error[E0425]: cannot find value `bar` in this scope + --> $DIR/ifmt-bad-arg.rs:27:27 + | +LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); + | ^^^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/ifmt-bad-arg.rs:31:15 + | +LL | format!("{foo}"); + | ^^^ not found in this scope + +error[E0425]: cannot find value `valueb` in this scope + --> $DIR/ifmt-bad-arg.rs:45:24 + | +LL | format!("{valuea} {valueb}", valuea=5, valuec=7); + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/ifmt-bad-arg.rs:60:10 + | +LL | {foo} + | ^^^ not found in this scope + +error[E0308]: mismatched types + --> $DIR/ifmt-bad-arg.rs:78:32 + | +LL | println!("{} {:.*} {}", 1, 3.2, 4); + | ---------------------------^^^---- + | | | + | | expected `usize`, found floating-point number + | arguments to this function are incorrect + | + = note: expected reference `&usize` + found reference `&{float}` +note: associated function defined here + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + | +LL | pub fn from_usize(x: &usize) -> ArgumentV1<'_> { + | ^^^^^^^^^^ + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/ifmt-bad-arg.rs:81:35 + | +LL | println!("{} {:07$.*} {}", 1, 3.2, 4); + | ------------------------------^^^---- + | | | + | | expected `usize`, found floating-point number + | arguments to this function are incorrect + | + = note: expected reference `&usize` + found reference `&{float}` +note: associated function defined here + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + | +LL | pub fn from_usize(x: &usize) -> ArgumentV1<'_> { + | ^^^^^^^^^^ + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 37 previous errors + +Some errors have detailed explanations: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/fmt/ifmt-bad-format-args.rs b/src/test/ui/fmt/ifmt-bad-format-args.rs new file mode 100644 index 000000000..ba7301561 --- /dev/null +++ b/src/test/ui/fmt/ifmt-bad-format-args.rs @@ -0,0 +1,4 @@ +fn main() { + format_args!(); //~ ERROR: requires at least a format string argument + format_args!(|| {}); //~ ERROR: must be a string literal +} diff --git a/src/test/ui/fmt/ifmt-bad-format-args.stderr b/src/test/ui/fmt/ifmt-bad-format-args.stderr new file mode 100644 index 000000000..2db280c5e --- /dev/null +++ b/src/test/ui/fmt/ifmt-bad-format-args.stderr @@ -0,0 +1,21 @@ +error: requires at least a format string argument + --> $DIR/ifmt-bad-format-args.rs:2:5 + | +LL | format_args!(); + | ^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: format argument must be a string literal + --> $DIR/ifmt-bad-format-args.rs:3:18 + | +LL | format_args!(|| {}); + | ^^^^^ + | +help: you might be missing a string literal to format with + | +LL | format_args!("{}", || {}); + | +++++ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/fmt/ifmt-unimpl.rs b/src/test/ui/fmt/ifmt-unimpl.rs new file mode 100644 index 000000000..258f4eea5 --- /dev/null +++ b/src/test/ui/fmt/ifmt-unimpl.rs @@ -0,0 +1,4 @@ +fn main() { + format!("{:X}", "3"); + //~^ ERROR: `str: UpperHex` is not satisfied +} diff --git a/src/test/ui/fmt/ifmt-unimpl.stderr b/src/test/ui/fmt/ifmt-unimpl.stderr new file mode 100644 index 000000000..dbcb2eb66 --- /dev/null +++ b/src/test/ui/fmt/ifmt-unimpl.stderr @@ -0,0 +1,27 @@ +error[E0277]: the trait bound `str: UpperHex` is not satisfied + --> $DIR/ifmt-unimpl.rs:2:21 + | +LL | format!("{:X}", "3"); + | ^^^ the trait `UpperHex` is not implemented for `str` + | + = help: the following other types implement trait `UpperHex`: + &T + &mut T + NonZeroI128 + NonZeroI16 + NonZeroI32 + NonZeroI64 + NonZeroI8 + NonZeroIsize + and 21 others + = note: required because of the requirements on the impl of `UpperHex` for `&str` +note: required by a bound in `ArgumentV1::<'a>::new_upper_hex` + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + | +LL | arg_new!(new_upper_hex, UpperHex); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ArgumentV1::<'a>::new_upper_hex` + = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `arg_new` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/fmt/ifmt-unknown-trait.rs b/src/test/ui/fmt/ifmt-unknown-trait.rs new file mode 100644 index 000000000..158152c89 --- /dev/null +++ b/src/test/ui/fmt/ifmt-unknown-trait.rs @@ -0,0 +1,4 @@ +fn main() { + format!("{:notimplemented}", "3"); + //~^ ERROR: unknown format trait `notimplemented` +} diff --git a/src/test/ui/fmt/ifmt-unknown-trait.stderr b/src/test/ui/fmt/ifmt-unknown-trait.stderr new file mode 100644 index 000000000..459432bf4 --- /dev/null +++ b/src/test/ui/fmt/ifmt-unknown-trait.stderr @@ -0,0 +1,19 @@ +error: unknown format trait `notimplemented` + --> $DIR/ifmt-unknown-trait.rs:2:16 + | +LL | format!("{:notimplemented}", "3"); + | ^^^^^^^^^^^^^^ + | + = note: the only appropriate formatting traits are: + - ``, which uses the `Display` trait + - `?`, which uses the `Debug` trait + - `e`, which uses the `LowerExp` trait + - `E`, which uses the `UpperExp` trait + - `o`, which uses the `Octal` trait + - `p`, which uses the `Pointer` trait + - `b`, which uses the `Binary` trait + - `x`, which uses the `LowerHex` trait + - `X`, which uses the `UpperHex` trait + +error: aborting due to previous error + diff --git a/src/test/ui/fmt/incorrect-separator.rs b/src/test/ui/fmt/incorrect-separator.rs new file mode 100644 index 000000000..b8d2e4a34 --- /dev/null +++ b/src/test/ui/fmt/incorrect-separator.rs @@ -0,0 +1,29 @@ +// Allows to track issue #75492: +// https://github.com/rust-lang/rust/issues/75492 + +use std::iter; + +fn main() { + format!("A number: {}". iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `.` + + // Other kind of types are also checked: + + format!("A number: {}" / iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `/` + + format!("A number: {}"; iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `;` + + // Note: this character is an COMBINING COMMA BELOW unicode char + format!("A number: {}" ̦ iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `iter` + //~^^ ERROR unknown start of token: \u{326} + + // Here recovery is tested. + // If the `compile_error!` is emitted, then the parser is able to recover + // from the incorrect first separator. + format!("{}". compile_error!("fail")); + //~^ ERROR expected `,`, found `.` + //~^^ ERROR fail +} diff --git a/src/test/ui/fmt/incorrect-separator.stderr b/src/test/ui/fmt/incorrect-separator.stderr new file mode 100644 index 000000000..5a3e5515b --- /dev/null +++ b/src/test/ui/fmt/incorrect-separator.stderr @@ -0,0 +1,44 @@ +error: unknown start of token: \u{326} + --> $DIR/incorrect-separator.rs:19:28 + | +LL | format!("A number: {}" ̦ iter::once(42).next().unwrap()); + | ^ + +error: expected `,`, found `.` + --> $DIR/incorrect-separator.rs:7:27 + | +LL | format!("A number: {}". iter::once(42).next().unwrap()); + | ^ expected `,` + +error: expected `,`, found `/` + --> $DIR/incorrect-separator.rs:12:28 + | +LL | format!("A number: {}" / iter::once(42).next().unwrap()); + | ^ expected `,` + +error: expected `,`, found `;` + --> $DIR/incorrect-separator.rs:15:27 + | +LL | format!("A number: {}"; iter::once(42).next().unwrap()); + | ^ expected `,` + +error: expected `,`, found `iter` + --> $DIR/incorrect-separator.rs:19:30 + | +LL | format!("A number: {}" ̦ iter::once(42).next().unwrap()); + | ^^^^ expected `,` + +error: expected `,`, found `.` + --> $DIR/incorrect-separator.rs:26:17 + | +LL | format!("{}". compile_error!("fail")); + | ^ expected `,` + +error: fail + --> $DIR/incorrect-separator.rs:26:19 + | +LL | format!("{}". compile_error!("fail")); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/fmt/issue-86085.rs b/src/test/ui/fmt/issue-86085.rs new file mode 100644 index 000000000..63d42b769 --- /dev/null +++ b/src/test/ui/fmt/issue-86085.rs @@ -0,0 +1,6 @@ +// Tests for an ICE with the fuzzed input below. + +fn main ( ) { +format ! ( concat ! ( r#"lJÆ�.�"# , "r} {}" ) ) ; +//~^ ERROR: invalid format string: unmatched `}` found +} diff --git a/src/test/ui/fmt/issue-86085.stderr b/src/test/ui/fmt/issue-86085.stderr new file mode 100644 index 000000000..ee7d8a5cc --- /dev/null +++ b/src/test/ui/fmt/issue-86085.stderr @@ -0,0 +1,11 @@ +error: invalid format string: unmatched `}` found + --> $DIR/issue-86085.rs:4:12 + | +LL | format ! ( concat ! ( r#"lJÆ�.�"# , "r} {}" ) ) ; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/fmt/issue-89173.rs b/src/test/ui/fmt/issue-89173.rs new file mode 100644 index 000000000..96277d4d0 --- /dev/null +++ b/src/test/ui/fmt/issue-89173.rs @@ -0,0 +1,14 @@ +// Regression test for #89173: Make sure a helpful note is issued for +// printf-style format strings using `*` to specify the width. + +fn main() { + let num = 0x0abcde; + let width = 6; + print!("%0*x", width, num); + //~^ ERROR: multiple unused formatting arguments + //~| NOTE: multiple missing formatting specifiers + //~| NOTE: argument never used + //~| NOTE: argument never used + //~| NOTE: format specifiers use curly braces, and you have to use a positional or named parameter for the width + //~| NOTE: printf formatting not supported +} diff --git a/src/test/ui/fmt/issue-89173.stderr b/src/test/ui/fmt/issue-89173.stderr new file mode 100644 index 000000000..7b21e0a4f --- /dev/null +++ b/src/test/ui/fmt/issue-89173.stderr @@ -0,0 +1,18 @@ +error: multiple unused formatting arguments + --> $DIR/issue-89173.rs:7:20 + | +LL | print!("%0*x", width, num); + | ------ ^^^^^ ^^^ argument never used + | | | + | | argument never used + | multiple missing formatting specifiers + | +note: format specifiers use curly braces, and you have to use a positional or named parameter for the width + --> $DIR/issue-89173.rs:7:13 + | +LL | print!("%0*x", width, num); + | ^^^^ + = note: printf formatting not supported; see the documentation for `std::fmt` + +error: aborting due to previous error + diff --git a/src/test/ui/fmt/issue-91556.rs b/src/test/ui/fmt/issue-91556.rs new file mode 100644 index 000000000..e782e6f90 --- /dev/null +++ b/src/test/ui/fmt/issue-91556.rs @@ -0,0 +1,8 @@ +fn main() { + let _ = format!(concat!("{0}𝖳𝖾𝗌𝗍{"), i); + //~^ ERROR: invalid format string: expected `'}'` but string was terminated + //~| NOTE: if you intended to print `{`, you can escape it using `{{` + //~| NOTE: in this expansion of concat! + //~| NOTE: in this expansion of concat! + //~| NOTE: expected `'}'` in format string +} diff --git a/src/test/ui/fmt/issue-91556.stderr b/src/test/ui/fmt/issue-91556.stderr new file mode 100644 index 000000000..dbd5aef45 --- /dev/null +++ b/src/test/ui/fmt/issue-91556.stderr @@ -0,0 +1,11 @@ +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/issue-91556.rs:2:19 + | +LL | let _ = format!(concat!("{0}𝖳𝖾𝗌𝗍{"), i); + | ^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/fmt/send-sync.rs b/src/test/ui/fmt/send-sync.rs new file mode 100644 index 000000000..95ec68d1d --- /dev/null +++ b/src/test/ui/fmt/send-sync.rs @@ -0,0 +1,10 @@ +fn send<T: Send>(_: T) {} +fn sync<T: Sync>(_: T) {} + +fn main() { + // `Cell` is not `Sync`, so `&Cell` is neither `Sync` nor `Send`, + // `std::fmt::Arguments` used to forget this... + let c = std::cell::Cell::new(42); + send(format_args!("{:?}", c)); //~ ERROR E0277 + sync(format_args!("{:?}", c)); //~ ERROR E0277 +} diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr new file mode 100644 index 000000000..7c7a3c884 --- /dev/null +++ b/src/test/ui/fmt/send-sync.stderr @@ -0,0 +1,39 @@ +error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely + --> $DIR/send-sync.rs:8:5 + | +LL | send(format_args!("{:?}", c)); + | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | + = help: within `[ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque` + = note: required because it appears within the type `&core::fmt::Opaque` + = note: required because it appears within the type `ArgumentV1<'_>` + = note: required because it appears within the type `[ArgumentV1<'_>]` + = note: required because of the requirements on the impl of `Send` for `&[ArgumentV1<'_>]` + = note: required because it appears within the type `Arguments<'_>` +note: required by a bound in `send` + --> $DIR/send-sync.rs:1:12 + | +LL | fn send<T: Send>(_: T) {} + | ^^^^ required by this bound in `send` + +error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely + --> $DIR/send-sync.rs:9:5 + | +LL | sync(format_args!("{:?}", c)); + | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | + = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::Opaque` + = note: required because it appears within the type `&core::fmt::Opaque` + = note: required because it appears within the type `ArgumentV1<'_>` + = note: required because it appears within the type `[ArgumentV1<'_>]` + = note: required because it appears within the type `&[ArgumentV1<'_>]` + = note: required because it appears within the type `Arguments<'_>` +note: required by a bound in `sync` + --> $DIR/send-sync.rs:2:12 + | +LL | fn sync<T: Sync>(_: T) {} + | ^^^^ required by this bound in `sync` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/fmt/struct-field-as-captured-argument.fixed b/src/test/ui/fmt/struct-field-as-captured-argument.fixed new file mode 100644 index 000000000..f7244f674 --- /dev/null +++ b/src/test/ui/fmt/struct-field-as-captured-argument.fixed @@ -0,0 +1,18 @@ +// run-rustfix + +#[derive(Debug)] +struct Foo { + field: usize, +} + +fn main() { + let foo = Foo { field: 0 }; + let bar = 3; + format!("{0}", foo.field); //~ ERROR invalid format string: field access isn't supported + format!("{1} {} {bar}", "aa", foo.field); //~ ERROR invalid format string: field access isn't supported + format!("{2} {} {1} {bar}", "aa", "bb", foo.field); //~ ERROR invalid format string: field access isn't supported + format!("{1} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported +} diff --git a/src/test/ui/fmt/struct-field-as-captured-argument.rs b/src/test/ui/fmt/struct-field-as-captured-argument.rs new file mode 100644 index 000000000..ab5f2552b --- /dev/null +++ b/src/test/ui/fmt/struct-field-as-captured-argument.rs @@ -0,0 +1,18 @@ +// run-rustfix + +#[derive(Debug)] +struct Foo { + field: usize, +} + +fn main() { + let foo = Foo { field: 0 }; + let bar = 3; + format!("{foo.field}"); //~ ERROR invalid format string: field access isn't supported + format!("{foo.field} {} {bar}", "aa"); //~ ERROR invalid format string: field access isn't supported + format!("{foo.field} {} {1} {bar}", "aa", "bb"); //~ ERROR invalid format string: field access isn't supported + format!("{foo.field} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + format!("{foo.field:?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + format!("{foo.field:#?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + format!("{foo.field:.3} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported +} diff --git a/src/test/ui/fmt/struct-field-as-captured-argument.stderr b/src/test/ui/fmt/struct-field-as-captured-argument.stderr new file mode 100644 index 000000000..7ea8b4068 --- /dev/null +++ b/src/test/ui/fmt/struct-field-as-captured-argument.stderr @@ -0,0 +1,79 @@ +error: invalid format string: field access isn't supported + --> $DIR/struct-field-as-captured-argument.rs:11:15 + | +LL | format!("{foo.field}"); + | ^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL | format!("{0}", foo.field); + | ~ +++++++++++ + +error: invalid format string: field access isn't supported + --> $DIR/struct-field-as-captured-argument.rs:12:15 + | +LL | format!("{foo.field} {} {bar}", "aa"); + | ^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL | format!("{1} {} {bar}", "aa", foo.field); + | ~ +++++++++++ + +error: invalid format string: field access isn't supported + --> $DIR/struct-field-as-captured-argument.rs:13:15 + | +LL | format!("{foo.field} {} {1} {bar}", "aa", "bb"); + | ^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL | format!("{2} {} {1} {bar}", "aa", "bb", foo.field); + | ~ +++++++++++ + +error: invalid format string: field access isn't supported + --> $DIR/struct-field-as-captured-argument.rs:14:15 + | +LL | format!("{foo.field} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL | format!("{1} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ + +error: invalid format string: field access isn't supported + --> $DIR/struct-field-as-captured-argument.rs:15:15 + | +LL | format!("{foo.field:?} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL | format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ + +error: invalid format string: field access isn't supported + --> $DIR/struct-field-as-captured-argument.rs:16:15 + | +LL | format!("{foo.field:#?} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL | format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ + +error: invalid format string: field access isn't supported + --> $DIR/struct-field-as-captured-argument.rs:17:15 + | +LL | format!("{foo.field:.3} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL | format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ + +error: aborting due to 7 previous errors + |