From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/fmt/auxiliary/format-string-proc-macro.rs | 36 +++++++++++---- tests/ui/fmt/format-args-argument-span.rs | 22 +++++++++ tests/ui/fmt/format-args-argument-span.stderr | 53 ++++++++++++++++++++++ .../format-args-capture-first-literal-is-macro.rs | 21 +++++++++ ...rmat-args-capture-first-literal-is-macro.stderr | 30 ++++++++++++ .../format-args-capture-from-pm-first-arg-macro.rs | 8 ++++ ...mat-args-capture-from-pm-first-arg-macro.stderr | 12 +++++ tests/ui/fmt/format-args-capture-issue-106408.rs | 10 ++++ .../fmt/format-args-capture-macro-hygiene-pass.rs | 16 +++++++ tests/ui/fmt/ifmt-bad-arg.stderr | 14 +++--- tests/ui/fmt/ifmt-unimpl.stderr | 4 +- tests/ui/fmt/respanned-literal-issue-106191.rs | 9 +--- tests/ui/fmt/respanned-literal-issue-106191.stderr | 21 ++++++++- 13 files changed, 228 insertions(+), 28 deletions(-) create mode 100644 tests/ui/fmt/format-args-argument-span.rs create mode 100644 tests/ui/fmt/format-args-argument-span.stderr create mode 100644 tests/ui/fmt/format-args-capture-first-literal-is-macro.rs create mode 100644 tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr create mode 100644 tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs create mode 100644 tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr create mode 100644 tests/ui/fmt/format-args-capture-issue-106408.rs create mode 100644 tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs (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 index 1b7ef93f4..0c39ade72 100644 --- a/tests/ui/fmt/auxiliary/format-string-proc-macro.rs +++ b/tests/ui/fmt/auxiliary/format-string-proc-macro.rs @@ -28,25 +28,41 @@ pub fn err_with_input_span(input: TokenStream) -> TokenStream { TokenStream::from(TokenTree::Literal(lit)) } +fn build_format(args: impl Into) -> TokenStream { + TokenStream::from_iter([ + TokenTree::from(Ident::new("format", Span::call_site())), + TokenTree::from(Punct::new('!', Spacing::Alone)), + TokenTree::from(Group::new(Delimiter::Parenthesis, args.into())), + ]) +} #[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())), - ]) + + build_format(TokenTree::from(s)) } #[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())), - ]) + + build_format(TokenTree::from(s)) +} + +#[proc_macro] +pub fn format_args_captures(_: TokenStream) -> TokenStream { + r#"{ let x = 5; format!("{x}") }"#.parse().unwrap() +} + +#[proc_macro] +pub fn bad_format_args_captures(_: TokenStream) -> TokenStream { + r#"{ let x = 5; format!(concat!("{x}")) }"#.parse().unwrap() +} + +#[proc_macro] +pub fn identity_pm(input: TokenStream) -> TokenStream { + input } diff --git a/tests/ui/fmt/format-args-argument-span.rs b/tests/ui/fmt/format-args-argument-span.rs new file mode 100644 index 000000000..c7acb08f8 --- /dev/null +++ b/tests/ui/fmt/format-args-argument-span.rs @@ -0,0 +1,22 @@ +// check-compile + +struct DisplayOnly; + +impl std::fmt::Display for DisplayOnly { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + unimplemented!() + } +} + +fn main() { + let x = Some(1); + println!("{x:?} {x} {x:?}"); + //~^ ERROR: `Option<{integer}>` doesn't implement `std::fmt::Display` + println!("{x:?} {x} {x:?}", x = Some(1)); + //~^ ERROR: `Option<{integer}>` doesn't implement `std::fmt::Display` + let x = DisplayOnly; + println!("{x} {x:?} {x}"); + //~^ ERROR: `DisplayOnly` doesn't implement `Debug` + println!("{x} {x:?} {x}", x = DisplayOnly); + //~^ ERROR: `DisplayOnly` doesn't implement `Debug` +} diff --git a/tests/ui/fmt/format-args-argument-span.stderr b/tests/ui/fmt/format-args-argument-span.stderr new file mode 100644 index 000000000..4e2702383 --- /dev/null +++ b/tests/ui/fmt/format-args-argument-span.stderr @@ -0,0 +1,53 @@ +error[E0277]: `Option<{integer}>` doesn't implement `std::fmt::Display` + --> $DIR/format-args-argument-span.rs:13:21 + | +LL | println!("{x:?} {x} {x:?}"); + | ^^^ `Option<{integer}>` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = 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[E0277]: `Option<{integer}>` doesn't implement `std::fmt::Display` + --> $DIR/format-args-argument-span.rs:15:37 + | +LL | println!("{x:?} {x} {x:?}", x = Some(1)); + | ^^^^^^^ `Option<{integer}>` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = 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[E0277]: `DisplayOnly` doesn't implement `Debug` + --> $DIR/format-args-argument-span.rs:18:19 + | +LL | println!("{x} {x:?} {x}"); + | ^^^^^ `DisplayOnly` cannot be formatted using `{:?}` + | + = help: the trait `Debug` is not implemented for `DisplayOnly` + = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` + = 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) +help: consider annotating `DisplayOnly` with `#[derive(Debug)]` + | +LL + #[derive(Debug)] +LL | struct DisplayOnly; + | + +error[E0277]: `DisplayOnly` doesn't implement `Debug` + --> $DIR/format-args-argument-span.rs:20:35 + | +LL | println!("{x} {x:?} {x}", x = DisplayOnly); + | ^^^^^^^^^^^ `DisplayOnly` cannot be formatted using `{:?}` + | + = help: the trait `Debug` is not implemented for `DisplayOnly` + = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` + = 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) +help: consider annotating `DisplayOnly` with `#[derive(Debug)]` + | +LL + #[derive(Debug)] +LL | struct DisplayOnly; + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs b/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs new file mode 100644 index 000000000..bf5c0dcb5 --- /dev/null +++ b/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs @@ -0,0 +1,21 @@ +// aux-build:format-string-proc-macro.rs + +#[macro_use] +extern crate format_string_proc_macro; + +macro_rules! identity_mbe { + ($tt:tt) => { + $tt + //~^ ERROR there is no argument named `a` + }; +} + +fn main() { + let a = 0; + + format!(identity_pm!("{a}")); + //~^ ERROR there is no argument named `a` + format!(identity_mbe!("{a}")); + format!(concat!("{a}")); + //~^ ERROR there is no argument named `a` +} diff --git a/tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr b/tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr new file mode 100644 index 000000000..4cf3afad7 --- /dev/null +++ b/tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr @@ -0,0 +1,30 @@ +error: there is no argument named `a` + --> $DIR/format-args-capture-first-literal-is-macro.rs:16:26 + | +LL | format!(identity_pm!("{a}")); + | ^^^^^ + | + = note: did you intend to capture a variable `a` 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 `a` + --> $DIR/format-args-capture-first-literal-is-macro.rs:8:9 + | +LL | $tt + | ^^^ + | + = note: did you intend to capture a variable `a` 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 `a` + --> $DIR/format-args-capture-first-literal-is-macro.rs:19:13 + | +LL | format!(concat!("{a}")); + | ^^^^^^^^^^^^^^ + | + = note: did you intend to capture a variable `a` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs new file mode 100644 index 000000000..f67edf5e1 --- /dev/null +++ b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs @@ -0,0 +1,8 @@ +// aux-build:format-string-proc-macro.rs + +extern crate format_string_proc_macro; + +fn main() { + format_string_proc_macro::bad_format_args_captures!(); + //~^ ERROR there is no argument named `x` +} diff --git a/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr new file mode 100644 index 000000000..bb6a14d88 --- /dev/null +++ b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr @@ -0,0 +1,12 @@ +error: there is no argument named `x` + --> $DIR/format-args-capture-from-pm-first-arg-macro.rs:6:5 + | +LL | format_string_proc_macro::bad_format_args_captures!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: did you intend to capture a variable `x` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/tests/ui/fmt/format-args-capture-issue-106408.rs b/tests/ui/fmt/format-args-capture-issue-106408.rs new file mode 100644 index 000000000..0fd195416 --- /dev/null +++ b/tests/ui/fmt/format-args-capture-issue-106408.rs @@ -0,0 +1,10 @@ +// check-pass +// aux-build:format-string-proc-macro.rs + +extern crate format_string_proc_macro; + +fn main() { + // While literal macros like `format_args!(concat!())` are not supposed to work with implicit + // captures, it should work if the whole invocation comes from a macro expansion (#106408). + format_string_proc_macro::format_args_captures!(); +} diff --git a/tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs b/tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs new file mode 100644 index 000000000..7553fcc4e --- /dev/null +++ b/tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs @@ -0,0 +1,16 @@ +// run-pass + +macro_rules! format_mbe { + ($tt:tt) => { + { + #[allow(unused_variables)] + let a = 123; + format!($tt) + } + }; +} + +fn main() { + let a = 0; + assert_eq!(format_mbe!("{a}"), "0"); +} diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index d716bbe51..bf18fb315 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -300,10 +300,9 @@ error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:78:32 | LL | println!("{} {:.*} {}", 1, 3.2, 4); - | ^^^ - | | - | expected `&usize`, found `&{float}` - | arguments to this function are incorrect + | -- ^^^ expected `&usize`, found `&{float}` + | | + | arguments to this function are incorrect | = note: expected reference `&usize` found reference `&{float}` @@ -315,10 +314,9 @@ error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:81:35 | LL | println!("{} {:07$.*} {}", 1, 3.2, 4); - | ^^^ - | | - | expected `&usize`, found `&{float}` - | arguments to this function are incorrect + | -- ^^^ expected `&usize`, found `&{float}` + | | + | arguments to this function are incorrect | = note: expected reference `&usize` found reference `&{float}` diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr index 3480a2ec8..dc2dee3f3 100644 --- a/tests/ui/fmt/ifmt-unimpl.stderr +++ b/tests/ui/fmt/ifmt-unimpl.stderr @@ -2,7 +2,9 @@ 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` + | ---- ^^^ the trait `UpperHex` is not implemented for `str` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `UpperHex`: &T diff --git a/tests/ui/fmt/respanned-literal-issue-106191.rs b/tests/ui/fmt/respanned-literal-issue-106191.rs index 5a18983a3..44642a10f 100644 --- a/tests/ui/fmt/respanned-literal-issue-106191.rs +++ b/tests/ui/fmt/respanned-literal-issue-106191.rs @@ -1,15 +1,10 @@ // aux-build:format-string-proc-macro.rs -// check-fail -// known-bug: #106191 -// unset-rustc-env:RUST_BACKTRACE -// had to be reverted -// error-pattern:unexpectedly panicked -// failure-status:101 -// dont-check-compiler-stderr extern crate format_string_proc_macro; fn main() { format_string_proc_macro::respan_to_invalid_format_literal!("¡"); + //~^ ERROR invalid format string: expected `'}'` but string was terminated format_args!(r#concat!("¡ {")); + //~^ ERROR invalid format string: expected `'}'` but string was terminated } diff --git a/tests/ui/fmt/respanned-literal-issue-106191.stderr b/tests/ui/fmt/respanned-literal-issue-106191.stderr index 16717f422..73a3af65a 100644 --- a/tests/ui/fmt/respanned-literal-issue-106191.stderr +++ b/tests/ui/fmt/respanned-literal-issue-106191.stderr @@ -1,2 +1,19 @@ - query stack during panic: -end of query stack +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/respanned-literal-issue-106191.rs:6:65 + | +LL | format_string_proc_macro::respan_to_invalid_format_literal!("¡"); + | ^^^ expected `'}'` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/respanned-literal-issue-106191.rs:8:18 + | +LL | format_args!(r#concat!("¡ {")); + | ^^^^^^^^^^^^^^^^^^^^^^^ 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 2 previous errors + -- cgit v1.2.3