Skip to content

Commit

Permalink
Rollup merge of #99480 - miam-miam100:arg-format, r=oli-obk
Browse files Browse the repository at this point in the history
Diagnostic width span is not added when '0$' is used as width in format strings

When the following code is run rustc does not add diagnostic spans for the width argument. Such spans are necessary for a clippy lint that I am currently writing.

```rust
println!("Hello {1:0$}!", 5, "x");
//                 ^^
// Should have a span here
```
  • Loading branch information
matthiaskrgr authored Jul 20, 2022
2 parents 82d9ae9 + f8dfc4b commit 9e197b7
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 4 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ impl<'a, 'b> Context<'a, 'b> {
if let Some(span) = fmt.width_span {
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
match fmt.width {
parse::CountIsParam(pos) if pos > self.num_args() => {
parse::CountIsParam(pos) if pos >= self.num_args() => {
e.span_label(
span,
&format!(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_parse_format/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,9 +572,10 @@ impl<'a> Parser<'a> {
// '0' flag and then an ill-formatted format string with just a '$'
// and no count, but this is better if we instead interpret this as
// no '0' flag and '0$' as the width instead.
if self.consume('$') {
if let Some(end) = self.consume_pos('$') {
spec.width = CountIsParam(0);
havewidth = true;
spec.width_span = Some(self.to_span_index(end - 1).to(self.to_span_index(end + 1)));
} else {
spec.flags |= 1 << (FlagSignAwareZeroPad as u32);
}
Expand Down
17 changes: 17 additions & 0 deletions compiler/rustc_parse_format/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,23 @@ fn format_counts() {
},
})],
);
same(
"{1:0$.10x}",
&[NextArgument(Argument {
position: ArgumentIs(1),
format: FormatSpec {
fill: None,
align: AlignUnknown,
flags: 0,
precision: CountIs(10),
width: CountIsParam(0),
precision_span: None,
width_span: Some(InnerSpan::new(4, 6)),
ty: "x",
ty_span: None,
},
})],
);
same(
"{:.*x}",
&[NextArgument(Argument {
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/fmt/ifmt-bad-arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ tenth number: {}",
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.
Expand Down
15 changes: 13 additions & 2 deletions src/test/ui/fmt/ifmt-bad-arg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,19 @@ 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:15
|
LL | println!("{foo:0$}");
| ^^^^^--^
| |
| this width flag expects an `usize` argument at position 0, but no arguments were given
|
= 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:92:15
--> $DIR/ifmt-bad-arg.rs:95:15
|
LL | println!("{:.*}");
| ^^--^
Expand Down Expand Up @@ -328,7 +339,7 @@ LL | pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
| ^^^^^^^^^^
= 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 36 previous errors
error: aborting due to 37 previous errors

Some errors have detailed explanations: E0308, E0425.
For more information about an error, try `rustc --explain E0308`.

0 comments on commit 9e197b7

Please sign in to comment.