diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2020-07-03 17:16:52 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-03 17:16:52 -0700 |
| commit | 4a8d9ea80ff8d7ec4dcc6da7d36fe60ecaa55539 (patch) | |
| tree | 95dcbc65f6c216af2314d646227859c0573d4522 /src/test | |
| parent | df8f551e796e3dd86a1ea8fb23b96cefbc7cdf85 (diff) | |
| parent | 93d662fd9d0e39145ac45fc08f35a619e0cb3f8c (diff) | |
| download | rust-4a8d9ea80ff8d7ec4dcc6da7d36fe60ecaa55539.tar.gz rust-4a8d9ea80ff8d7ec4dcc6da7d36fe60ecaa55539.zip | |
Rollup merge of #73670 - davidhewitt:format-args-capture, r=varkor
Add `format_args_capture` feature This is the initial implementation PR for [RFC 2795](https://github.com/rust-lang/rfcs/pull/2795). Note that, as dicussed in the tracking issue (#67984), the feature gate has been called `format_args_capture`. Next up I guess I need to add documentation for this feature. I've not written any docs before for rustc / std so I would appreciate suggestions on where I should add docs.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/ui/fmt/feature-gate-format-args-capture.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/fmt/feature-gate-format-args-capture.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/fmt/format-args-capture-macro-hygiene.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/fmt/format-args-capture-macro-hygiene.stderr | 22 | ||||
| -rw-r--r-- | src/test/ui/fmt/format-args-capture-missing-variables.rs | 22 | ||||
| -rw-r--r-- | src/test/ui/fmt/format-args-capture-missing-variables.stderr | 52 | ||||
| -rw-r--r-- | src/test/ui/fmt/format-args-capture.rs | 64 | ||||
| -rw-r--r-- | src/test/ui/if/ifmt-bad-arg.stderr | 10 |
8 files changed, 200 insertions, 0 deletions
diff --git a/src/test/ui/fmt/feature-gate-format-args-capture.rs b/src/test/ui/fmt/feature-gate-format-args-capture.rs new file mode 100644 index 00000000000..21af9161091 --- /dev/null +++ b/src/test/ui/fmt/feature-gate-format-args-capture.rs @@ -0,0 +1,6 @@ +fn main() { + format!("{foo}"); //~ ERROR: there is no argument named `foo` + + // panic! doesn't hit format_args! unless there are two or more arguments. + panic!("{foo} {bar}", bar=1); //~ ERROR: there is no argument named `foo` +} diff --git a/src/test/ui/fmt/feature-gate-format-args-capture.stderr b/src/test/ui/fmt/feature-gate-format-args-capture.stderr new file mode 100644 index 00000000000..f08f1651cb6 --- /dev/null +++ b/src/test/ui/fmt/feature-gate-format-args-capture.stderr @@ -0,0 +1,18 @@ +error: there is no argument named `foo` + --> $DIR/feature-gate-format-args-capture.rs:2:14 + | +LL | format!("{foo}"); + | ^^^^^ + | + = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes + +error: there is no argument named `foo` + --> $DIR/feature-gate-format-args-capture.rs:5:13 + | +LL | panic!("{foo} {bar}", bar=1); + | ^^^^^ + | + = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs new file mode 100644 index 00000000000..6ca7dcc216f --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs @@ -0,0 +1,6 @@ +#![feature(format_args_capture)] + +fn main() { + format!(concat!("{foo}")); //~ ERROR: there is no argument named `foo` + format!(concat!("{ba", "r} {}"), 1); //~ ERROR: there is no argument named `bar` +} diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr new file mode 100644 index 00000000000..0c5915149cd --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr @@ -0,0 +1,22 @@ +error: there is no argument named `foo` + --> $DIR/format-args-capture-macro-hygiene.rs:4: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 a macro (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:5: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 a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/fmt/format-args-capture-missing-variables.rs b/src/test/ui/fmt/format-args-capture-missing-variables.rs new file mode 100644 index 00000000000..3c596ae3bb8 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-missing-variables.rs @@ -0,0 +1,22 @@ +#![feature(format_args_capture)] + +fn main() { + format!("{} {foo} {} {bar} {}", 1, 2, 3); + //~^ ERROR: cannot find value `foo` in this scope + //~^^ ERROR: cannot find value `bar` in this scope + + format!("{foo}"); //~ ERROR: cannot find value `foo` in this scope + + format!("{valuea} {valueb}", valuea=5, valuec=7); + //~^ ERROR cannot find value `valueb` in this scope + //~^^ ERROR named argument never used + + format!(r##" + + {foo} + + "##); + //~^^^^^ ERROR: cannot find value `foo` in this scope + + panic!("{foo} {bar}", bar=1); //~ ERROR: cannot find value `foo` in this scope +} diff --git a/src/test/ui/fmt/format-args-capture-missing-variables.stderr b/src/test/ui/fmt/format-args-capture-missing-variables.stderr new file mode 100644 index 00000000000..c3d740eef9d --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-missing-variables.stderr @@ -0,0 +1,52 @@ +error: named argument never used + --> $DIR/format-args-capture-missing-variables.rs:10: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:4:13 + | +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:4:13 + | +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:8:13 + | +LL | format!("{foo}"); + | ^^^^^^^ not found in this scope + +error[E0425]: cannot find value `valueb` in this scope + --> $DIR/format-args-capture-missing-variables.rs:10:13 + | +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:13 + | +LL | format!(r##" + | _____________^ +LL | | +LL | | {foo} +LL | | +LL | | "##); + | |_______^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/format-args-capture-missing-variables.rs:21:12 + | +LL | panic!("{foo} {bar}", bar=1); + | ^^^^^^^^^^^^^ not found in this scope + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs new file mode 100644 index 00000000000..7490632110c --- /dev/null +++ b/src/test/ui/fmt/format-args-capture.rs @@ -0,0 +1,64 @@ +// run-pass +// ignore-wasm32 +// ignore-wasm64 +#![feature(format_args_capture)] + +fn main() { + named_argument_takes_precedence_to_captured(); + panic_with_single_argument_does_not_get_formatted(); + panic_with_multiple_arguments_is_formatted(); + formatting_parameters_can_be_captured(); +} + +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 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. + + let msg = std::panic::catch_unwind(|| { + panic!("{foo}"); + }).unwrap_err(); + + assert_eq!(msg.downcast_ref::<&str>(), Some(&"{foo}")) +} + +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--"); +} diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/if/ifmt-bad-arg.stderr index 3e5f5a63742..0ff478826f7 100644 --- a/src/test/ui/if/ifmt-bad-arg.stderr +++ b/src/test/ui/if/ifmt-bad-arg.stderr @@ -63,18 +63,24 @@ error: there is no argument named `foo` | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^^^ + | + = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes error: there is no argument named `bar` --> $DIR/ifmt-bad-arg.rs:27:26 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^^^ + | + = help: if you intended to capture `bar` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes error: there is no argument named `foo` --> $DIR/ifmt-bad-arg.rs:31:14 | LL | format!("{foo}"); | ^^^^^ + | + = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes error: multiple unused formatting arguments --> $DIR/ifmt-bad-arg.rs:32:17 @@ -155,6 +161,8 @@ error: there is no argument named `valueb` | LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | ^^^^^^^^ + | + = help: if you intended to capture `valueb` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes error: named argument never used --> $DIR/ifmt-bad-arg.rs:45:51 @@ -205,6 +213,8 @@ error: there is no argument named `foo` | LL | {foo} | ^^^^^ + | + = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes error: invalid format string: expected `'}'`, found `'t'` --> $DIR/ifmt-bad-arg.rs:75:1 |
