Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Point spans to inner elements of format strings #52649

Merged
merged 11 commits into from
Jul 26, 2018
Merged

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Jul 23, 2018

  • Point at missing positional specifiers in string literal
error: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments)
  --> $DIR/ifmt-bad-arg.rs:34:38
   |
LL |     format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
   |                                      ^^ ^^ ^^
   |
   = note: positional arguments are zero-based
  • Point at named formatting specifier in string literal
error: there is no argument named `foo`
  --> $DIR/ifmt-bad-arg.rs:37:17
   |
LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
   |                 ^^^^^
  • Update label for formatting string in "multiple unused formatting arguments" to be more correct
error: multiple unused formatting arguments
  --> $DIR/ifmt-bad-arg.rs:42:17
   |
LL |     format!("", 1, 2);               //~ ERROR: multiple unused formatting arguments
   |             --  ^  ^
   |             |
   |             multiple missing formatting specifiers
  • When using printf string formatting, provide a structured suggestion instead of a note
error: multiple unused formatting arguments
  --> $DIR/format-foreign.rs:12:30
   |
LL |     println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
   |              --------------  ^^^^^^^^  ^^^^^^^  ^
   |              |
   |              multiple missing formatting specifiers
   |
   = note: printf formatting not supported; see the documentation for `std::fmt`
help: format specifiers in Rust are written using `{}`
   |
LL |     println!("{:.2$} {}!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
   |               ^^^^^^ ^^

@rust-highfive
Copy link
Collaborator

r? @alexcrichton

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 23, 2018
|
LL | ($fmt:expr) => (myprint!(concat!($fmt, "/n"))); //~ ERROR no arguments were given
| ^^^^^^^^^^^^^^^^^^^
| ^^
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not apply if not a string literal.

--> $DIR/ifmt-bad-arg.rs:34:14
|
LL | format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
| ^^^^^^ ^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Point only to positional arguments 3, 4 and 5.

--> $DIR/ifmt-bad-arg.rs:29:14
|
LL | format!("{0} {1} {2}", 1, 2);
| ^^^ ^^^ ^^^
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Point only to positional argument 2.

@rust-highfive

This comment has been minimized.

@alexcrichton
Copy link
Member

This looks like a fantastic idea to me! I'll take a closer look with tests passing?

@estebank estebank changed the title [WIP] Point spans to inner elements of format strings Point spans to inner elements of format strings Jul 23, 2018
@rust-highfive

This comment has been minimized.

@estebank
Copy link
Contributor Author

I'm really happy with how it ended up looking.

@alexcrichton do you think I should add a secondary span pointing at the complete string for all of these errors? Also, I feel we should also add labels to the primary spans, but I can do these things in a separate PR.

@estebank
Copy link
Contributor Author

cc @nikomatsakis and @oli-obk who might have ideas around what these should look like.

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely great. This deserves its own blog/reddit/users post. It's gonna blow ppls minds

@@ -154,6 +154,7 @@ pub struct Parser<'a> {
style: Option<usize>,
/// How many newlines have been seen in the string so far, to adjust the error spans
seen_newlines: usize,
pub arg_places: Vec<(usize, usize)>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so these are offsets into the format string? A comment would be nice (I'm using this struct in clippy ^^)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added docs.

--> $DIR/ifmt-bad-arg.rs:34:38
|
LL | format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
| ^^ ^^ ^^
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is absolutely great

LL | format!("", 1, 2); //~ ERROR: multiple unused formatting arguments
| -- ^ ^
| |
| multiple missing formatting arguments
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not missing formatting arguments, it's missing formatting specifiers, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

LL | format!("{"); //~ ERROR: expected `'}'` but string was terminated
| ^ expected `'}'` in format string
|
= note: if you intended to print `{`, you can escape it using `{{`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this a structured suggestion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into this as a follow up, because the output would look a bit bad (it'd have to suggest {" as it is now, which is hard to understand).

LL | format!("foo %s baz", "bar"); //~ ERROR: argument never used
| ^^^^^
|
= help: `%s` should be written as `{}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has no span associated with it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@rust-highfive

This comment has been minimized.

@oli-obk
Copy link
Contributor

oli-obk commented Jul 25, 2018

@bors r+ wonderful

@bors
Copy link
Contributor

bors commented Jul 25, 2018

📌 Commit 9a893cc has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 25, 2018
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Jul 26, 2018
Point spans to inner elements of format strings

- Point at missing positional specifiers in string literal
```
error: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments)
  --> $DIR/ifmt-bad-arg.rs:34:38
   |
LL |     format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
   |                                      ^^ ^^ ^^
   |
   = note: positional arguments are zero-based
```

- Point at named formatting specifier in string literal
```
error: there is no argument named `foo`
  --> $DIR/ifmt-bad-arg.rs:37:17
   |
LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
   |                 ^^^^^
```

- Update label for formatting string in "multiple unused formatting arguments" to be more correct
```
error: multiple unused formatting arguments
  --> $DIR/ifmt-bad-arg.rs:42:17
   |
LL |     format!("", 1, 2);               //~ ERROR: multiple unused formatting arguments
   |             --  ^  ^
   |             |
   |             multiple missing formatting specifiers
```

- When using `printf` string formatting, provide a structured suggestion instead of a note
```
error: multiple unused formatting arguments
  --> $DIR/format-foreign.rs:12:30
   |
LL |     println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
   |              --------------  ^^^^^^^^  ^^^^^^^  ^
   |              |
   |              multiple missing formatting specifiers
   |
   = note: printf formatting not supported; see the documentation for `std::fmt`
help: format specifiers in Rust are written using `{}`
   |
LL |     println!("{:.2$} {}!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
   |               ^^^^^^ ^^
```
bors added a commit that referenced this pull request Jul 26, 2018
Rollup of 16 pull requests

Successful merges:

 - #52558 (Add tests for ICEs which no longer repro)
 - #52610 (Clarify what a task is)
 - #52617 (Don't match on region kinds when reporting NLL errors)
 - #52635 (Fix #[linkage] propagation though generic functions)
 - #52647 (Suggest to take and ignore args while closure args count mismatching)
 - #52649 (Point spans to inner elements of format strings)
 - #52654 (Format linker args in a way that works for gcc and ld)
 - #52667 (update the stdsimd submodule)
 - #52674 (Impl Executor for Box<E: Executor>)
 - #52690 (ARM: expose `rclass` and `dsp` target features)
 - #52692 (Improve readability in a few sorts)
 - #52695 (Hide some lints which are not quite right the way they are reported to the user)
 - #52718 (State default capacity for BufReader/BufWriter)
 - #52721 (std::ops::Try impl for std::task::Poll)
 - #52723 (rustc: Register crates under their real names)
 - #52734 (sparc ABI issue - structure returning from function is returned in 64bit registers (with tests))

Failed merges:

 - #52678 ([NLL] Use better spans in some errors)

r? @ghost
@bors bors merged commit 9a893cc into rust-lang:master Jul 26, 2018
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Aug 1, 2018
Use suggestions for shell format arguments

Follow up to rust-lang#52649.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants