summaryrefslogtreecommitdiffstats
path: root/tests/ui/fmt
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/fmt')
-rw-r--r--tests/ui/fmt/auxiliary/format-string-proc-macro.rs52
-rw-r--r--tests/ui/fmt/format-args-capture-issue-102057.rs19
-rw-r--r--tests/ui/fmt/format-args-capture-issue-102057.stderr45
-rw-r--r--tests/ui/fmt/format-args-capture-issue-93378.rs11
-rw-r--r--tests/ui/fmt/format-args-capture-issue-93378.stderr17
-rw-r--r--tests/ui/fmt/format-args-capture-issue-94010.rs7
-rw-r--r--tests/ui/fmt/format-args-capture-issue-94010.stderr20
-rw-r--r--tests/ui/fmt/format-args-capture-macro-hygiene.rs22
-rw-r--r--tests/ui/fmt/format-args-capture-macro-hygiene.stderr53
-rw-r--r--tests/ui/fmt/format-args-capture-missing-variables.rs20
-rw-r--r--tests/ui/fmt/format-args-capture-missing-variables.stderr47
-rw-r--r--tests/ui/fmt/format-args-capture.rs89
-rw-r--r--tests/ui/fmt/format-expanded-string.rs24
-rw-r--r--tests/ui/fmt/format-expanded-string.stderr19
-rw-r--r--tests/ui/fmt/format-raw-string-error.rs3
-rw-r--r--tests/ui/fmt/format-raw-string-error.stderr10
-rw-r--r--tests/ui/fmt/format-string-error-2.rs86
-rw-r--r--tests/ui/fmt/format-string-error-2.stderr175
-rw-r--r--tests/ui/fmt/format-string-error.rs55
-rw-r--r--tests/ui/fmt/format-string-error.stderr125
-rw-r--r--tests/ui/fmt/format-with-yield-point.rs33
-rw-r--r--tests/ui/fmt/ifmt-bad-arg.rs99
-rw-r--r--tests/ui/fmt/ifmt-bad-arg.stderr332
-rw-r--r--tests/ui/fmt/ifmt-bad-format-args.rs4
-rw-r--r--tests/ui/fmt/ifmt-bad-format-args.stderr21
-rw-r--r--tests/ui/fmt/ifmt-unimpl.rs4
-rw-r--r--tests/ui/fmt/ifmt-unimpl.stderr24
-rw-r--r--tests/ui/fmt/ifmt-unknown-trait.rs4
-rw-r--r--tests/ui/fmt/ifmt-unknown-trait.stderr19
-rw-r--r--tests/ui/fmt/incorrect-separator.rs29
-rw-r--r--tests/ui/fmt/incorrect-separator.stderr44
-rw-r--r--tests/ui/fmt/indoc-issue-106408.rs9
-rw-r--r--tests/ui/fmt/issue-103826.rs8
-rw-r--r--tests/ui/fmt/issue-103826.stderr20
-rw-r--r--tests/ui/fmt/issue-104142.rs6
-rw-r--r--tests/ui/fmt/issue-104142.stderr10
-rw-r--r--tests/ui/fmt/issue-86085.rs6
-rw-r--r--tests/ui/fmt/issue-86085.stderr11
-rw-r--r--tests/ui/fmt/issue-89173.rs14
-rw-r--r--tests/ui/fmt/issue-89173.stderr18
-rw-r--r--tests/ui/fmt/issue-91556.rs8
-rw-r--r--tests/ui/fmt/issue-91556.stderr11
-rw-r--r--tests/ui/fmt/respanned-literal-issue-106191.rs15
-rw-r--r--tests/ui/fmt/respanned-literal-issue-106191.stderr2
-rw-r--r--tests/ui/fmt/send-sync.rs10
-rw-r--r--tests/ui/fmt/send-sync.stderr43
-rw-r--r--tests/ui/fmt/struct-field-as-captured-argument.fixed18
-rw-r--r--tests/ui/fmt/struct-field-as-captured-argument.rs18
-rw-r--r--tests/ui/fmt/struct-field-as-captured-argument.stderr79
-rw-r--r--tests/ui/fmt/unicode-escape-spans.rs19
-rw-r--r--tests/ui/fmt/unicode-escape-spans.stderr63
51 files changed, 1900 insertions, 0 deletions
diff --git a/tests/ui/fmt/auxiliary/format-string-proc-macro.rs b/tests/ui/fmt/auxiliary/format-string-proc-macro.rs
new file mode 100644
index 000000000..1b7ef93f4
--- /dev/null
+++ b/tests/ui/fmt/auxiliary/format-string-proc-macro.rs
@@ -0,0 +1,52 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
+use std::iter::FromIterator;
+
+#[proc_macro]
+pub fn foo_with_input_span(input: TokenStream) -> TokenStream {
+ let span = input.into_iter().next().unwrap().span();
+
+ let mut lit = Literal::string("{foo}");
+ lit.set_span(span);
+
+ TokenStream::from(TokenTree::Literal(lit))
+}
+
+#[proc_macro]
+pub fn err_with_input_span(input: TokenStream) -> TokenStream {
+ let span = input.into_iter().next().unwrap().span();
+
+ let mut lit = Literal::string(" }");
+ lit.set_span(span);
+
+ TokenStream::from(TokenTree::Literal(lit))
+}
+
+
+#[proc_macro]
+pub fn respan_to_invalid_format_literal(input: TokenStream) -> TokenStream {
+ let mut s = Literal::string("{");
+ s.set_span(input.into_iter().next().unwrap().span());
+ TokenStream::from_iter([
+ TokenTree::from(Ident::new("format", Span::call_site())),
+ TokenTree::from(Punct::new('!', Spacing::Alone)),
+ TokenTree::from(Group::new(Delimiter::Parenthesis, TokenTree::from(s).into())),
+ ])
+}
+
+#[proc_macro]
+pub fn capture_a_with_prepended_space_preserve_span(input: TokenStream) -> TokenStream {
+ let mut s = Literal::string(" {a}");
+ s.set_span(input.into_iter().next().unwrap().span());
+ TokenStream::from_iter([
+ TokenTree::from(Ident::new("format", Span::call_site())),
+ TokenTree::from(Punct::new('!', Spacing::Alone)),
+ TokenTree::from(Group::new(Delimiter::Parenthesis, TokenTree::from(s).into())),
+ ])
+}
diff --git a/tests/ui/fmt/format-args-capture-issue-102057.rs b/tests/ui/fmt/format-args-capture-issue-102057.rs
new file mode 100644
index 000000000..b8089d49b
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-issue-102057.rs
@@ -0,0 +1,19 @@
+fn main() {
+ format!("\x7Ba}");
+ //~^ ERROR cannot find value `a` in this scope
+ format!("\x7Ba\x7D");
+ //~^ ERROR cannot find value `a` in this scope
+
+ let a = 0;
+
+ format!("\x7Ba} {b}");
+ //~^ ERROR cannot find value `b` in this scope
+ format!("\x7Ba\x7D {b}");
+ //~^ ERROR cannot find value `b` in this scope
+ format!("\x7Ba} \x7Bb}");
+ //~^ ERROR cannot find value `b` in this scope
+ format!("\x7Ba\x7D \x7Bb}");
+ //~^ ERROR cannot find value `b` in this scope
+ format!("\x7Ba\x7D \x7Bb\x7D");
+ //~^ ERROR cannot find value `b` in this scope
+}
diff --git a/tests/ui/fmt/format-args-capture-issue-102057.stderr b/tests/ui/fmt/format-args-capture-issue-102057.stderr
new file mode 100644
index 000000000..f2d625e7f
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-issue-102057.stderr
@@ -0,0 +1,45 @@
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/format-args-capture-issue-102057.rs:2:18
+ |
+LL | format!("\x7Ba}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/format-args-capture-issue-102057.rs:4:18
+ |
+LL | format!("\x7Ba\x7D");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `b` in this scope
+ --> $DIR/format-args-capture-issue-102057.rs:9:22
+ |
+LL | format!("\x7Ba} {b}");
+ | ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+ --> $DIR/format-args-capture-issue-102057.rs:11:25
+ |
+LL | format!("\x7Ba\x7D {b}");
+ | ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+ --> $DIR/format-args-capture-issue-102057.rs:13:25
+ |
+LL | format!("\x7Ba} \x7Bb}");
+ | ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+ --> $DIR/format-args-capture-issue-102057.rs:15:28
+ |
+LL | format!("\x7Ba\x7D \x7Bb}");
+ | ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+ --> $DIR/format-args-capture-issue-102057.rs:17:28
+ |
+LL | format!("\x7Ba\x7D \x7Bb\x7D");
+ | ^ help: a local variable with a similar name exists: `a`
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/fmt/format-args-capture-issue-93378.rs b/tests/ui/fmt/format-args-capture-issue-93378.rs
new file mode 100644
index 000000000..9d722a028
--- /dev/null
+++ b/tests/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: 3 positional arguments in format string, but there is 1 argument
+
+ let n = 1;
+ println!("{a:.n$} {b:.*}");
+ //~^ ERROR: 1 positional argument in format string, but no arguments were given
+}
diff --git a/tests/ui/fmt/format-args-capture-issue-93378.stderr b/tests/ui/fmt/format-args-capture-issue-93378.stderr
new file mode 100644
index 000000000..6429b0d46
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-issue-93378.stderr
@@ -0,0 +1,17 @@
+error: 3 positional arguments in format string, but there is 1 argument
+ --> $DIR/format-args-capture-issue-93378.rs:5:23
+ |
+LL | println!("{a} {b} {} {} {c} {}", c = "c");
+ | ^^ ^^ ^^ ---
+
+error: 1 positional argument in format string, but no arguments were given
+ --> $DIR/format-args-capture-issue-93378.rs:9:26
+ |
+LL | println!("{a:.n$} {b:.*}");
+ | ^^ this precision flag adds an extra required argument at position 0, which is why there is 1 argument expected
+ |
+ = 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/tests/ui/fmt/format-args-capture-issue-94010.rs b/tests/ui/fmt/format-args-capture-issue-94010.rs
new file mode 100644
index 000000000..bd03e9c93
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-args-capture-issue-94010.stderr b/tests/ui/fmt/format-args-capture-issue-94010.stderr
new file mode 100644
index 000000000..ed90dc855
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-args-capture-macro-hygiene.rs b/tests/ui/fmt/format-args-capture-macro-hygiene.rs
new file mode 100644
index 000000000..b04f80ba4
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-macro-hygiene.rs
@@ -0,0 +1,22 @@
+// aux-build:format-string-proc-macro.rs
+
+#[macro_use]
+extern crate format_string_proc_macro;
+
+macro_rules! def_site {
+ () => { "{foo}" } //~ ERROR: there is no argument named `foo`
+}
+
+macro_rules! call_site {
+ ($fmt:literal) => { $fmt }
+}
+
+fn main() {
+ format!(concat!("{foo}")); //~ ERROR: there is no argument named `foo`
+ format!(concat!("{ba", "r} {}"), 1); //~ ERROR: there is no argument named `bar`
+
+ format!(def_site!());
+ format!(call_site!("{foo}")); //~ ERROR: there is no argument named `foo`
+
+ format!(foo_with_input_span!("")); //~ ERROR: there is no argument named `foo`
+}
diff --git a/tests/ui/fmt/format-args-capture-macro-hygiene.stderr b/tests/ui/fmt/format-args-capture-macro-hygiene.stderr
new file mode 100644
index 000000000..1b5fbd2af
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-macro-hygiene.stderr
@@ -0,0 +1,53 @@
+error: there is no argument named `foo`
+ --> $DIR/format-args-capture-macro-hygiene.rs:15: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:16: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: there is no argument named `foo`
+ --> $DIR/format-args-capture-macro-hygiene.rs:7:13
+ |
+LL | () => { "{foo}" }
+ | ^^^^^^^
+...
+LL | format!(def_site!());
+ | ----------- in this macro invocation
+ |
+ = 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 `def_site` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: there is no argument named `foo`
+ --> $DIR/format-args-capture-macro-hygiene.rs:19:24
+ |
+LL | format!(call_site!("{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
+
+error: there is no argument named `foo`
+ --> $DIR/format-args-capture-macro-hygiene.rs:21:34
+ |
+LL | format!(foo_with_input_span!(""));
+ | ^^
+ |
+ = 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
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/fmt/format-args-capture-missing-variables.rs b/tests/ui/fmt/format-args-capture-missing-variables.rs
new file mode 100644
index 000000000..46fc083cb
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-args-capture-missing-variables.stderr b/tests/ui/fmt/format-args-capture-missing-variables.stderr
new file mode 100644
index 000000000..d980e7be2
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-args-capture.rs b/tests/ui/fmt/format-args-capture.rs
new file mode 100644
index 000000000..560352b5c
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-expanded-string.rs b/tests/ui/fmt/format-expanded-string.rs
new file mode 100644
index 000000000..4c716f08c
--- /dev/null
+++ b/tests/ui/fmt/format-expanded-string.rs
@@ -0,0 +1,24 @@
+// aux-build:format-string-proc-macro.rs
+
+#[macro_use]
+extern crate format_string_proc_macro;
+
+
+// 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
+
+ format!(err_with_input_span!(""));
+ //~^ ERROR: invalid format string: unmatched `}` found
+}
diff --git a/tests/ui/fmt/format-expanded-string.stderr b/tests/ui/fmt/format-expanded-string.stderr
new file mode 100644
index 000000000..26ce7f269
--- /dev/null
+++ b/tests/ui/fmt/format-expanded-string.stderr
@@ -0,0 +1,19 @@
+error: invalid format string: unmatched `}` found
+ --> $DIR/format-expanded-string.rs:19: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: invalid format string: unmatched `}` found
+ --> $DIR/format-expanded-string.rs:22:34
+ |
+LL | format!(err_with_input_span!(""));
+ | ^^ unmatched `}` in format string
+ |
+ = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/fmt/format-raw-string-error.rs b/tests/ui/fmt/format-raw-string-error.rs
new file mode 100644
index 000000000..9f0bc01a7
--- /dev/null
+++ b/tests/ui/fmt/format-raw-string-error.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!(r#"\'\'\'\'\'\'\'\'\'\'\'\'\'\'}"#); //~ ERROR invalid format string: unmatched `}` found
+}
diff --git a/tests/ui/fmt/format-raw-string-error.stderr b/tests/ui/fmt/format-raw-string-error.stderr
new file mode 100644
index 000000000..8d61950d8
--- /dev/null
+++ b/tests/ui/fmt/format-raw-string-error.stderr
@@ -0,0 +1,10 @@
+error: invalid format string: unmatched `}` found
+ --> $DIR/format-raw-string-error.rs:2:45
+ |
+LL | println!(r#"\'\'\'\'\'\'\'\'\'\'\'\'\'\'}"#);
+ | ^ unmatched `}` in format string
+ |
+ = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/fmt/format-string-error-2.rs b/tests/ui/fmt/format-string-error-2.rs
new file mode 100644
index 000000000..1f7f0d8f6
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr
new file mode 100644
index 000000000..76cdfbb93
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-string-error.rs b/tests/ui/fmt/format-string-error.rs
new file mode 100644
index 000000000..eae4f3cb5
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-string-error.stderr b/tests/ui/fmt/format-string-error.stderr
new file mode 100644
index 000000000..8a32c2254
--- /dev/null
+++ b/tests/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/tests/ui/fmt/format-with-yield-point.rs b/tests/ui/fmt/format-with-yield-point.rs
new file mode 100644
index 000000000..e484074cc
--- /dev/null
+++ b/tests/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/tests/ui/fmt/ifmt-bad-arg.rs b/tests/ui/fmt/ifmt-bad-arg.rs
new file mode 100644
index 000000000..68861d7bf
--- /dev/null
+++ b/tests/ui/fmt/ifmt-bad-arg.rs
@@ -0,0 +1,99 @@
+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: 3 positional arguments in format string, but there are 2 arguments
+ format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
+ //~^ ERROR: 6 positional arguments in format string, but 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 invalid reference to positional arguments 3 and 7 (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
+ println!("{:.0$}");
+ //~^ ERROR invalid reference to positional argument 0 (no arguments were given)
+}
diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr
new file mode 100644
index 000000000..c2619d6df
--- /dev/null
+++ b/tests/ui/fmt/ifmt-bad-arg.stderr
@@ -0,0 +1,332 @@
+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:15
+ |
+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:19
+ |
+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:23
+ |
+LL | format!("{0} {1} {2}", 1, 2);
+ | ^
+ |
+ = note: positional arguments are zero-based
+
+error: 3 positional arguments in format string, but there are 2 arguments
+ --> $DIR/ifmt-bad-arg.rs:22:14
+ |
+LL | format!("{} {value} {} {}", 1, value=2);
+ | ^^ ^^ ^^ - -
+
+error: 6 positional arguments in format string, but there are 3 arguments
+ --> $DIR/ifmt-bad-arg.rs:24:29
+ |
+LL | format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
+ | ^^ ^^ ^^ ^^ ^^ ^^ - - -
+
+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:29
+ |
+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 is 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 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: invalid reference to positional arguments 3 and 7 (there are 3 arguments)
+ --> $DIR/ifmt-bad-arg.rs:81:21
+ |
+LL | println!("{} {:07$.*} {}", 1, 3.2, 4);
+ | ^^ ^
+ |
+ = 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:21
+ |
+LL | println!("{} {:07$} {}", 1, 3.2, 4);
+ | ^^
+ |
+ = 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:16
+ |
+LL | println!("{5} {:4$} {6:7$}", 1);
+ | ^ ^^ ^ ^^
+ |
+ = 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:20
+ |
+LL | println!("{foo:0$}");
+ | ^^
+ |
+ = 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: invalid reference to positional argument 0 (no arguments were given)
+ --> $DIR/ifmt-bad-arg.rs:97:16
+ |
+LL | println!("{:.0$}");
+ | ^^^^
+ |
+ = 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
+ = 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
+ = 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 38 previous errors
+
+Some errors have detailed explanations: E0308, E0425.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/fmt/ifmt-bad-format-args.rs b/tests/ui/fmt/ifmt-bad-format-args.rs
new file mode 100644
index 000000000..ba7301561
--- /dev/null
+++ b/tests/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/tests/ui/fmt/ifmt-bad-format-args.stderr b/tests/ui/fmt/ifmt-bad-format-args.stderr
new file mode 100644
index 000000000..2db280c5e
--- /dev/null
+++ b/tests/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/tests/ui/fmt/ifmt-unimpl.rs b/tests/ui/fmt/ifmt-unimpl.rs
new file mode 100644
index 000000000..258f4eea5
--- /dev/null
+++ b/tests/ui/fmt/ifmt-unimpl.rs
@@ -0,0 +1,4 @@
+fn main() {
+ format!("{:X}", "3");
+ //~^ ERROR: `str: UpperHex` is not satisfied
+}
diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr
new file mode 100644
index 000000000..be321c3c5
--- /dev/null
+++ b/tests/ui/fmt/ifmt-unimpl.stderr
@@ -0,0 +1,24 @@
+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 for `&str` to implement `UpperHex`
+note: required by a bound in `ArgumentV1::<'a>::new_upper_hex`
+ --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
+ = 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/tests/ui/fmt/ifmt-unknown-trait.rs b/tests/ui/fmt/ifmt-unknown-trait.rs
new file mode 100644
index 000000000..158152c89
--- /dev/null
+++ b/tests/ui/fmt/ifmt-unknown-trait.rs
@@ -0,0 +1,4 @@
+fn main() {
+ format!("{:notimplemented}", "3");
+ //~^ ERROR: unknown format trait `notimplemented`
+}
diff --git a/tests/ui/fmt/ifmt-unknown-trait.stderr b/tests/ui/fmt/ifmt-unknown-trait.stderr
new file mode 100644
index 000000000..459432bf4
--- /dev/null
+++ b/tests/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/tests/ui/fmt/incorrect-separator.rs b/tests/ui/fmt/incorrect-separator.rs
new file mode 100644
index 000000000..b8d2e4a34
--- /dev/null
+++ b/tests/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/tests/ui/fmt/incorrect-separator.stderr b/tests/ui/fmt/incorrect-separator.stderr
new file mode 100644
index 000000000..5a3e5515b
--- /dev/null
+++ b/tests/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/tests/ui/fmt/indoc-issue-106408.rs b/tests/ui/fmt/indoc-issue-106408.rs
new file mode 100644
index 000000000..e4e3093b5
--- /dev/null
+++ b/tests/ui/fmt/indoc-issue-106408.rs
@@ -0,0 +1,9 @@
+// aux-build:format-string-proc-macro.rs
+// check-pass
+
+extern crate format_string_proc_macro;
+
+fn main() {
+ let a = 0;
+ format_string_proc_macro::capture_a_with_prepended_space_preserve_span!("{a}");
+}
diff --git a/tests/ui/fmt/issue-103826.rs b/tests/ui/fmt/issue-103826.rs
new file mode 100644
index 000000000..a11ec37a0
--- /dev/null
+++ b/tests/ui/fmt/issue-103826.rs
@@ -0,0 +1,8 @@
+fn main() {
+ format!("{\x7D");
+ //~^ ERROR 1 positional argument in format string, but no arguments were given
+ format!("\x7B\x7D");
+ //~^ ERROR 1 positional argument in format string, but no arguments were given
+ format!("{\x7D {\x7D");
+ //~^ ERROR 2 positional arguments in format string, but no arguments were given
+}
diff --git a/tests/ui/fmt/issue-103826.stderr b/tests/ui/fmt/issue-103826.stderr
new file mode 100644
index 000000000..0f27e1930
--- /dev/null
+++ b/tests/ui/fmt/issue-103826.stderr
@@ -0,0 +1,20 @@
+error: 1 positional argument in format string, but no arguments were given
+ --> $DIR/issue-103826.rs:2:14
+ |
+LL | format!("{\x7D");
+ | ^^^^^
+
+error: 1 positional argument in format string, but no arguments were given
+ --> $DIR/issue-103826.rs:4:14
+ |
+LL | format!("\x7B\x7D");
+ | ^^^^^^^^
+
+error: 2 positional arguments in format string, but no arguments were given
+ --> $DIR/issue-103826.rs:6:14
+ |
+LL | format!("{\x7D {\x7D");
+ | ^^^^^ ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/fmt/issue-104142.rs b/tests/ui/fmt/issue-104142.rs
new file mode 100644
index 000000000..8d7283a71
--- /dev/null
+++ b/tests/ui/fmt/issue-104142.rs
@@ -0,0 +1,6 @@
+fn main() {
+ println!(
+ r#"
+ \"\'}、"# //~ ERROR invalid format string: unmatched `}` found
+ );
+}
diff --git a/tests/ui/fmt/issue-104142.stderr b/tests/ui/fmt/issue-104142.stderr
new file mode 100644
index 000000000..d41644faa
--- /dev/null
+++ b/tests/ui/fmt/issue-104142.stderr
@@ -0,0 +1,10 @@
+error: invalid format string: unmatched `}` found
+ --> $DIR/issue-104142.rs:4:9
+ |
+LL | \"\'}、"#
+ | ^ unmatched `}` in format string
+ |
+ = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/fmt/issue-86085.rs b/tests/ui/fmt/issue-86085.rs
new file mode 100644
index 000000000..63d42b769
--- /dev/null
+++ b/tests/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/tests/ui/fmt/issue-86085.stderr b/tests/ui/fmt/issue-86085.stderr
new file mode 100644
index 000000000..ee7d8a5cc
--- /dev/null
+++ b/tests/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/tests/ui/fmt/issue-89173.rs b/tests/ui/fmt/issue-89173.rs
new file mode 100644
index 000000000..fc99af408
--- /dev/null
+++ b/tests/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 is not supported
+}
diff --git a/tests/ui/fmt/issue-89173.stderr b/tests/ui/fmt/issue-89173.stderr
new file mode 100644
index 000000000..ddeb769ea
--- /dev/null
+++ b/tests/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 is not supported; see the documentation for `std::fmt`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/fmt/issue-91556.rs b/tests/ui/fmt/issue-91556.rs
new file mode 100644
index 000000000..e782e6f90
--- /dev/null
+++ b/tests/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/tests/ui/fmt/issue-91556.stderr b/tests/ui/fmt/issue-91556.stderr
new file mode 100644
index 000000000..dbd5aef45
--- /dev/null
+++ b/tests/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/tests/ui/fmt/respanned-literal-issue-106191.rs b/tests/ui/fmt/respanned-literal-issue-106191.rs
new file mode 100644
index 000000000..bb741c0ef
--- /dev/null
+++ b/tests/ui/fmt/respanned-literal-issue-106191.rs
@@ -0,0 +1,15 @@
+// aux-build:format-string-proc-macro.rs
+// check-fail
+// known-bug: #106191
+// unset-rustc-env:RUST_BACKTRACE
+// had to be reverted
+// error-pattern:internal compiler error
+// failure-status:101
+// dont-check-compiler-stderr
+
+extern crate format_string_proc_macro;
+
+fn main() {
+ format_string_proc_macro::respan_to_invalid_format_literal!("¡");
+ format_args!(r#concat!("¡ {"));
+}
diff --git a/tests/ui/fmt/respanned-literal-issue-106191.stderr b/tests/ui/fmt/respanned-literal-issue-106191.stderr
new file mode 100644
index 000000000..16717f422
--- /dev/null
+++ b/tests/ui/fmt/respanned-literal-issue-106191.stderr
@@ -0,0 +1,2 @@
+ query stack during panic:
+end of query stack
diff --git a/tests/ui/fmt/send-sync.rs b/tests/ui/fmt/send-sync.rs
new file mode 100644
index 000000000..95ec68d1d
--- /dev/null
+++ b/tests/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/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr
new file mode 100644
index 000000000..3ed040c3a
--- /dev/null
+++ b/tests/ui/fmt/send-sync.stderr
@@ -0,0 +1,43 @@
+error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
+ --> $DIR/send-sync.rs:8:10
+ |
+LL | send(format_args!("{:?}", c));
+ | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
+ |
+ = 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 for `&[ArgumentV1<'_>]` to implement `Send`
+ = 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:10
+ |
+LL | sync(format_args!("{:?}", c));
+ | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
+ |
+ = 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/tests/ui/fmt/struct-field-as-captured-argument.fixed b/tests/ui/fmt/struct-field-as-captured-argument.fixed
new file mode 100644
index 000000000..f7244f674
--- /dev/null
+++ b/tests/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/tests/ui/fmt/struct-field-as-captured-argument.rs b/tests/ui/fmt/struct-field-as-captured-argument.rs
new file mode 100644
index 000000000..ab5f2552b
--- /dev/null
+++ b/tests/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/tests/ui/fmt/struct-field-as-captured-argument.stderr b/tests/ui/fmt/struct-field-as-captured-argument.stderr
new file mode 100644
index 000000000..7ea8b4068
--- /dev/null
+++ b/tests/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
+
diff --git a/tests/ui/fmt/unicode-escape-spans.rs b/tests/ui/fmt/unicode-escape-spans.rs
new file mode 100644
index 000000000..753d91ce5
--- /dev/null
+++ b/tests/ui/fmt/unicode-escape-spans.rs
@@ -0,0 +1,19 @@
+fn main() {
+ // 1 byte in UTF-8
+ format!("\u{000041}{a}"); //~ ERROR cannot find value
+ format!("\u{0041}{a}"); //~ ERROR cannot find value
+ format!("\u{41}{a}"); //~ ERROR cannot find value
+ format!("\u{0}{a}"); //~ ERROR cannot find value
+
+ // 2 bytes
+ format!("\u{0df}{a}"); //~ ERROR cannot find value
+ format!("\u{df}{a}"); //~ ERROR cannot find value
+
+ // 3 bytes
+ format!("\u{00211d}{a}"); //~ ERROR cannot find value
+ format!("\u{211d}{a}"); //~ ERROR cannot find value
+
+ // 4 bytes
+ format!("\u{1f4a3}{a}"); //~ ERROR cannot find value
+ format!("\u{10ffff}{a}"); //~ ERROR cannot find value
+}
diff --git a/tests/ui/fmt/unicode-escape-spans.stderr b/tests/ui/fmt/unicode-escape-spans.stderr
new file mode 100644
index 000000000..1d8473f01
--- /dev/null
+++ b/tests/ui/fmt/unicode-escape-spans.stderr
@@ -0,0 +1,63 @@
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:3:25
+ |
+LL | format!("\u{000041}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:4:23
+ |
+LL | format!("\u{0041}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:5:21
+ |
+LL | format!("\u{41}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:6:20
+ |
+LL | format!("\u{0}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:9:22
+ |
+LL | format!("\u{0df}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:10:21
+ |
+LL | format!("\u{df}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:13:25
+ |
+LL | format!("\u{00211d}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:14:23
+ |
+LL | format!("\u{211d}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:17:24
+ |
+LL | format!("\u{1f4a3}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:18:25
+ |
+LL | format!("\u{10ffff}{a}");
+ | ^ not found in this scope
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0425`.