Rollup merge of #101000 - m-ou-se:count-is-star, r=nagisa
Separate CountIsStar from CountIsParam in rustc_parse_format. `rustc_parse_format`'s parser would result in the exact same output for `{:.*}` and `{:.0$}`, making it hard for diagnostics to handle these cases properly. This splits those cases by adding a new `CountIsStar` enum variant. This fixes #100995 Prerequisite for https://github.com/rust-lang/rust/pull/100996
This commit is contained in:
commit
0b6faca670
5 changed files with 24 additions and 9 deletions
|
@ -541,7 +541,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
) {
|
) {
|
||||||
match c {
|
match c {
|
||||||
parse::CountImplied | parse::CountIs(..) => {}
|
parse::CountImplied | parse::CountIs(..) => {}
|
||||||
parse::CountIsParam(i) => {
|
parse::CountIsParam(i) | parse::CountIsStar(i) => {
|
||||||
self.unused_names_lint.maybe_add_positional_named_arg(
|
self.unused_names_lint.maybe_add_positional_named_arg(
|
||||||
self.args.get(i),
|
self.args.get(i),
|
||||||
named_arg_type,
|
named_arg_type,
|
||||||
|
@ -589,7 +589,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
+ self
|
+ self
|
||||||
.arg_with_formatting
|
.arg_with_formatting
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|fmt| matches!(fmt.precision, parse::CountIsParam(_)))
|
.filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_)))
|
||||||
.count();
|
.count();
|
||||||
if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
|
if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
|
||||||
e = self.ecx.struct_span_err(
|
e = self.ecx.struct_span_err(
|
||||||
|
@ -639,7 +639,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
if let Some(span) = fmt.precision_span {
|
if let Some(span) = fmt.precision_span {
|
||||||
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
|
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
|
||||||
match fmt.precision {
|
match fmt.precision {
|
||||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
parse::CountIsParam(pos) if pos >= self.num_args() => {
|
||||||
e.span_label(
|
e.span_label(
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
|
@ -651,12 +651,12 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
);
|
);
|
||||||
zero_based_note = true;
|
zero_based_note = true;
|
||||||
}
|
}
|
||||||
parse::CountIsParam(pos) => {
|
parse::CountIsStar(pos) => {
|
||||||
let count = self.pieces.len()
|
let count = self.pieces.len()
|
||||||
+ self
|
+ self
|
||||||
.arg_with_formatting
|
.arg_with_formatting
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|fmt| matches!(fmt.precision, parse::CountIsParam(_)))
|
.filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_)))
|
||||||
.count();
|
.count();
|
||||||
e.span_label(
|
e.span_label(
|
||||||
span,
|
span,
|
||||||
|
@ -837,7 +837,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
};
|
};
|
||||||
match c {
|
match c {
|
||||||
parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))),
|
parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))),
|
||||||
parse::CountIsParam(i) => {
|
parse::CountIsParam(i) | parse::CountIsStar(i) => {
|
||||||
// This needs mapping too, as `i` is referring to a macro
|
// This needs mapping too, as `i` is referring to a macro
|
||||||
// argument. If `i` is not found in `count_positions` then
|
// argument. If `i` is not found in `count_positions` then
|
||||||
// the error had already been emitted elsewhere.
|
// the error had already been emitted elsewhere.
|
||||||
|
|
|
@ -167,6 +167,8 @@ pub enum Count<'a> {
|
||||||
CountIsName(&'a str, InnerSpan),
|
CountIsName(&'a str, InnerSpan),
|
||||||
/// The count is specified by the argument at the given index.
|
/// The count is specified by the argument at the given index.
|
||||||
CountIsParam(usize),
|
CountIsParam(usize),
|
||||||
|
/// The count is specified by a star (like in `{:.*}`) that refers to the argument at the given index.
|
||||||
|
CountIsStar(usize),
|
||||||
/// The count is implied and cannot be explicitly specified.
|
/// The count is implied and cannot be explicitly specified.
|
||||||
CountImplied,
|
CountImplied,
|
||||||
}
|
}
|
||||||
|
@ -618,7 +620,7 @@ impl<'a> Parser<'a> {
|
||||||
// We can do this immediately as `position` is resolved later.
|
// We can do this immediately as `position` is resolved later.
|
||||||
let i = self.curarg;
|
let i = self.curarg;
|
||||||
self.curarg += 1;
|
self.curarg += 1;
|
||||||
spec.precision = CountIsParam(i);
|
spec.precision = CountIsStar(i);
|
||||||
} else {
|
} else {
|
||||||
spec.precision = self.count(start + 1);
|
spec.precision = self.count(start + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ fn format_counts() {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
precision: CountIsParam(0),
|
precision: CountIsStar(0),
|
||||||
precision_span: Some(InnerSpan { start: 3, end: 5 }),
|
precision_span: Some(InnerSpan { start: 3, end: 5 }),
|
||||||
width: CountImplied,
|
width: CountImplied,
|
||||||
width_span: None,
|
width_span: None,
|
||||||
|
|
|
@ -94,4 +94,6 @@ tenth number: {}",
|
||||||
// doesn't exist.
|
// doesn't exist.
|
||||||
println!("{:.*}");
|
println!("{:.*}");
|
||||||
//~^ ERROR 2 positional arguments in format string, but no arguments were given
|
//~^ ERROR 2 positional arguments in format string, but no arguments were given
|
||||||
|
println!("{:.0$}");
|
||||||
|
//~^ ERROR 1 positional argument in format string, but no arguments were given
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,6 +273,17 @@ LL | println!("{:.*}");
|
||||||
= note: positional arguments are zero-based
|
= note: positional arguments are zero-based
|
||||||
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
|
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
|
||||||
|
|
||||||
|
error: 1 positional argument in format string, but no arguments were given
|
||||||
|
--> $DIR/ifmt-bad-arg.rs:97:15
|
||||||
|
|
|
||||||
|
LL | println!("{:.0$}");
|
||||||
|
| ^^---^
|
||||||
|
| |
|
||||||
|
| this precision 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[E0425]: cannot find value `foo` in this scope
|
error[E0425]: cannot find value `foo` in this scope
|
||||||
--> $DIR/ifmt-bad-arg.rs:27:18
|
--> $DIR/ifmt-bad-arg.rs:27:18
|
||||||
|
|
|
|
||||||
|
@ -339,7 +350,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)
|
= 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 37 previous errors
|
error: aborting due to 38 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0425.
|
Some errors have detailed explanations: E0308, E0425.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue