From 218caa410aa38c29984be31a5229b9fa717560ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:13 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/fmt/auxiliary/format-string-proc-macro.rs | 52 ++++ tests/ui/fmt/format-args-capture-issue-102057.rs | 19 ++ .../ui/fmt/format-args-capture-issue-102057.stderr | 45 +++ tests/ui/fmt/format-args-capture-issue-93378.rs | 11 + .../ui/fmt/format-args-capture-issue-93378.stderr | 17 ++ tests/ui/fmt/format-args-capture-issue-94010.rs | 7 + .../ui/fmt/format-args-capture-issue-94010.stderr | 20 ++ tests/ui/fmt/format-args-capture-macro-hygiene.rs | 22 ++ .../fmt/format-args-capture-macro-hygiene.stderr | 53 ++++ .../fmt/format-args-capture-missing-variables.rs | 20 ++ .../format-args-capture-missing-variables.stderr | 47 +++ tests/ui/fmt/format-args-capture.rs | 89 ++++++ tests/ui/fmt/format-expanded-string.rs | 24 ++ tests/ui/fmt/format-expanded-string.stderr | 19 ++ tests/ui/fmt/format-raw-string-error.rs | 3 + tests/ui/fmt/format-raw-string-error.stderr | 10 + tests/ui/fmt/format-string-error-2.rs | 86 ++++++ tests/ui/fmt/format-string-error-2.stderr | 175 +++++++++++ tests/ui/fmt/format-string-error.rs | 55 ++++ tests/ui/fmt/format-string-error.stderr | 125 ++++++++ tests/ui/fmt/format-with-yield-point.rs | 33 ++ tests/ui/fmt/ifmt-bad-arg.rs | 99 ++++++ tests/ui/fmt/ifmt-bad-arg.stderr | 332 +++++++++++++++++++++ tests/ui/fmt/ifmt-bad-format-args.rs | 4 + tests/ui/fmt/ifmt-bad-format-args.stderr | 21 ++ tests/ui/fmt/ifmt-unimpl.rs | 4 + tests/ui/fmt/ifmt-unimpl.stderr | 24 ++ tests/ui/fmt/ifmt-unknown-trait.rs | 4 + tests/ui/fmt/ifmt-unknown-trait.stderr | 19 ++ tests/ui/fmt/incorrect-separator.rs | 29 ++ tests/ui/fmt/incorrect-separator.stderr | 44 +++ tests/ui/fmt/indoc-issue-106408.rs | 9 + tests/ui/fmt/issue-103826.rs | 8 + tests/ui/fmt/issue-103826.stderr | 20 ++ tests/ui/fmt/issue-104142.rs | 6 + tests/ui/fmt/issue-104142.stderr | 10 + tests/ui/fmt/issue-86085.rs | 6 + tests/ui/fmt/issue-86085.stderr | 11 + tests/ui/fmt/issue-89173.rs | 14 + tests/ui/fmt/issue-89173.stderr | 18 ++ tests/ui/fmt/issue-91556.rs | 8 + tests/ui/fmt/issue-91556.stderr | 11 + tests/ui/fmt/respanned-literal-issue-106191.rs | 15 + tests/ui/fmt/respanned-literal-issue-106191.stderr | 2 + tests/ui/fmt/send-sync.rs | 10 + tests/ui/fmt/send-sync.stderr | 43 +++ .../ui/fmt/struct-field-as-captured-argument.fixed | 18 ++ tests/ui/fmt/struct-field-as-captured-argument.rs | 18 ++ .../fmt/struct-field-as-captured-argument.stderr | 79 +++++ tests/ui/fmt/unicode-escape-spans.rs | 19 ++ tests/ui/fmt/unicode-escape-spans.stderr | 63 ++++ 51 files changed, 1900 insertions(+) create mode 100644 tests/ui/fmt/auxiliary/format-string-proc-macro.rs create mode 100644 tests/ui/fmt/format-args-capture-issue-102057.rs create mode 100644 tests/ui/fmt/format-args-capture-issue-102057.stderr create mode 100644 tests/ui/fmt/format-args-capture-issue-93378.rs create mode 100644 tests/ui/fmt/format-args-capture-issue-93378.stderr create mode 100644 tests/ui/fmt/format-args-capture-issue-94010.rs create mode 100644 tests/ui/fmt/format-args-capture-issue-94010.stderr create mode 100644 tests/ui/fmt/format-args-capture-macro-hygiene.rs create mode 100644 tests/ui/fmt/format-args-capture-macro-hygiene.stderr create mode 100644 tests/ui/fmt/format-args-capture-missing-variables.rs create mode 100644 tests/ui/fmt/format-args-capture-missing-variables.stderr create mode 100644 tests/ui/fmt/format-args-capture.rs create mode 100644 tests/ui/fmt/format-expanded-string.rs create mode 100644 tests/ui/fmt/format-expanded-string.stderr create mode 100644 tests/ui/fmt/format-raw-string-error.rs create mode 100644 tests/ui/fmt/format-raw-string-error.stderr create mode 100644 tests/ui/fmt/format-string-error-2.rs create mode 100644 tests/ui/fmt/format-string-error-2.stderr create mode 100644 tests/ui/fmt/format-string-error.rs create mode 100644 tests/ui/fmt/format-string-error.stderr create mode 100644 tests/ui/fmt/format-with-yield-point.rs create mode 100644 tests/ui/fmt/ifmt-bad-arg.rs create mode 100644 tests/ui/fmt/ifmt-bad-arg.stderr create mode 100644 tests/ui/fmt/ifmt-bad-format-args.rs create mode 100644 tests/ui/fmt/ifmt-bad-format-args.stderr create mode 100644 tests/ui/fmt/ifmt-unimpl.rs create mode 100644 tests/ui/fmt/ifmt-unimpl.stderr create mode 100644 tests/ui/fmt/ifmt-unknown-trait.rs create mode 100644 tests/ui/fmt/ifmt-unknown-trait.stderr create mode 100644 tests/ui/fmt/incorrect-separator.rs create mode 100644 tests/ui/fmt/incorrect-separator.stderr create mode 100644 tests/ui/fmt/indoc-issue-106408.rs create mode 100644 tests/ui/fmt/issue-103826.rs create mode 100644 tests/ui/fmt/issue-103826.stderr create mode 100644 tests/ui/fmt/issue-104142.rs create mode 100644 tests/ui/fmt/issue-104142.stderr create mode 100644 tests/ui/fmt/issue-86085.rs create mode 100644 tests/ui/fmt/issue-86085.stderr create mode 100644 tests/ui/fmt/issue-89173.rs create mode 100644 tests/ui/fmt/issue-89173.stderr create mode 100644 tests/ui/fmt/issue-91556.rs create mode 100644 tests/ui/fmt/issue-91556.stderr create mode 100644 tests/ui/fmt/respanned-literal-issue-106191.rs create mode 100644 tests/ui/fmt/respanned-literal-issue-106191.stderr create mode 100644 tests/ui/fmt/send-sync.rs create mode 100644 tests/ui/fmt/send-sync.stderr create mode 100644 tests/ui/fmt/struct-field-as-captured-argument.fixed create mode 100644 tests/ui/fmt/struct-field-as-captured-argument.rs create mode 100644 tests/ui/fmt/struct-field-as-captured-argument.stderr create mode 100644 tests/ui/fmt/unicode-escape-spans.rs create mode 100644 tests/ui/fmt/unicode-escape-spans.stderr (limited to 'tests/ui/fmt') 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::(), 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: 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) {} +fn 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) {} + | ^^^^ 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) {} + | ^^^^ 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`. -- cgit v1.2.3