Skip to content

Commit 9e197b7

Browse files
authored
Rollup merge of #99480 - miam-miam100:arg-format, r=oli-obk
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 ```
2 parents 82d9ae9 + f8dfc4b commit 9e197b7

File tree

5 files changed

+36
-4
lines changed

5 files changed

+36
-4
lines changed

compiler/rustc_builtin_macros/src/format.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ impl<'a, 'b> Context<'a, 'b> {
485485
if let Some(span) = fmt.width_span {
486486
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
487487
match fmt.width {
488-
parse::CountIsParam(pos) if pos > self.num_args() => {
488+
parse::CountIsParam(pos) if pos >= self.num_args() => {
489489
e.span_label(
490490
span,
491491
&format!(

compiler/rustc_parse_format/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,10 @@ impl<'a> Parser<'a> {
572572
// '0' flag and then an ill-formatted format string with just a '$'
573573
// and no count, but this is better if we instead interpret this as
574574
// no '0' flag and '0$' as the width instead.
575-
if self.consume('$') {
575+
if let Some(end) = self.consume_pos('$') {
576576
spec.width = CountIsParam(0);
577577
havewidth = true;
578+
spec.width_span = Some(self.to_span_index(end - 1).to(self.to_span_index(end + 1)));
578579
} else {
579580
spec.flags |= 1 << (FlagSignAwareZeroPad as u32);
580581
}

compiler/rustc_parse_format/src/tests.rs

+17
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,23 @@ fn format_counts() {
178178
},
179179
})],
180180
);
181+
same(
182+
"{1:0$.10x}",
183+
&[NextArgument(Argument {
184+
position: ArgumentIs(1),
185+
format: FormatSpec {
186+
fill: None,
187+
align: AlignUnknown,
188+
flags: 0,
189+
precision: CountIs(10),
190+
width: CountIsParam(0),
191+
precision_span: None,
192+
width_span: Some(InnerSpan::new(4, 6)),
193+
ty: "x",
194+
ty_span: None,
195+
},
196+
})],
197+
);
181198
same(
182199
"{:.*x}",
183200
&[NextArgument(Argument {

src/test/ui/fmt/ifmt-bad-arg.rs

+3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ tenth number: {}",
8686
println!("{:foo}", 1); //~ ERROR unknown format trait `foo`
8787
println!("{5} {:4$} {6:7$}", 1);
8888
//~^ ERROR invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument)
89+
let foo = 1;
90+
println!("{foo:0$}");
91+
//~^ ERROR invalid reference to positional argument 0 (no arguments were given)
8992

9093
// We used to ICE here because we tried to unconditionally access the first argument, which
9194
// doesn't exist.

src/test/ui/fmt/ifmt-bad-arg.stderr

+13-2
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,19 @@ LL | println!("{5} {:4$} {6:7$}", 1);
251251
= note: positional arguments are zero-based
252252
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
253253

254+
error: invalid reference to positional argument 0 (no arguments were given)
255+
--> $DIR/ifmt-bad-arg.rs:90:15
256+
|
257+
LL | println!("{foo:0$}");
258+
| ^^^^^--^
259+
| |
260+
| this width flag expects an `usize` argument at position 0, but no arguments were given
261+
|
262+
= note: positional arguments are zero-based
263+
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
264+
254265
error: 2 positional arguments in format string, but no arguments were given
255-
--> $DIR/ifmt-bad-arg.rs:92:15
266+
--> $DIR/ifmt-bad-arg.rs:95:15
256267
|
257268
LL | println!("{:.*}");
258269
| ^^--^
@@ -328,7 +339,7 @@ LL | pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
328339
| ^^^^^^^^^^
329340
= 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)
330341

331-
error: aborting due to 36 previous errors
342+
error: aborting due to 37 previous errors
332343

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

0 commit comments

Comments
 (0)