Skip to content

Commit 5635158

Browse files
committed
Auto merge of rust-lang#99263 - compiler-errors:issue-99261, r=jyn514
Fix ICE in `named_arguments_used_positionally` lint Fixes rust-lang#99261 Fixes rust-lang#99289 Fixes rust-lang#99284 Fixes rust-lang#99273 Fixes rust-lang#99297 Fixes rust-lang#99271 This match pattern: ``` FormatSpec { width: Count::CountIsName(s, _), .. } | FormatSpec { precision: Count::CountIsName(s, _), .. } ``` does not account for when both `width` and `precision` are both `Count::CountIsName`, so split the check for these two fields into two separate `if let`. Also, remove any future potential for ICEs by removing the index operator altogether. --- It is still suspicious that this indexing was broken and caused the ICE, as opposed to just causing a spurious lint message. cc `@PrestonFrom,` who may be familiar with this code because of implementing the lint this touches, perhaps you'd like to look into why named arguments in `FormatSpec.precision` seem to have indices that don't correspond to a span in `Context.arg_spans`? Edit: Opened rust-lang#99265 to track a (related?) incorrect argument indexing issue.
2 parents d695a49 + 2902b92 commit 5635158

File tree

4 files changed

+36
-19
lines changed

4 files changed

+36
-19
lines changed

compiler/rustc_builtin_macros/src/format.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use smallvec::SmallVec;
1616

1717
use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
1818
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId};
19-
use rustc_parse_format::{Count, FormatSpec};
19+
use rustc_parse_format::Count;
2020
use std::borrow::Cow;
2121
use std::collections::hash_map::Entry;
2222

@@ -985,20 +985,19 @@ fn lint_named_arguments_used_positionally(
985985
}
986986
_ => {}
987987
};
988-
match a.format {
989-
FormatSpec { width: Count::CountIsName(s, _), .. }
990-
| FormatSpec { precision: Count::CountIsName(s, _), .. } => {
991-
used_argument_names.insert(s);
992-
}
993-
_ => {}
994-
};
988+
if let Count::CountIsName(s, _) = a.format.width {
989+
used_argument_names.insert(s);
990+
}
991+
if let Count::CountIsName(s, _) = a.format.precision {
992+
used_argument_names.insert(s);
993+
}
995994
}
996995
}
997996

998997
for (symbol, (index, span)) in names {
999998
if !used_argument_names.contains(symbol.as_str()) {
1000999
let msg = format!("named argument `{}` is not used by name", symbol.as_str());
1001-
let arg_span = cx.arg_spans[index];
1000+
let arg_span = cx.arg_spans.get(index).copied();
10021001
cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
10031002
span: MultiSpan::from_span(span),
10041003
msg: msg.clone(),

compiler/rustc_lint/src/context.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -858,15 +858,16 @@ pub trait LintContext: Sized {
858858
},
859859
BuiltinLintDiagnostics::NamedArgumentUsedPositionally(positional_arg, named_arg, name) => {
860860
db.span_label(named_arg, "this named argument is only referred to by position in formatting string");
861-
let msg = format!("this formatting argument uses named argument `{}` by position", name);
862-
db.span_label(positional_arg, msg);
863-
db.span_suggestion_verbose(
864-
positional_arg,
865-
"use the named argument by name to avoid ambiguity",
866-
format!("{{{}}}", name),
867-
Applicability::MaybeIncorrect,
868-
);
869-
861+
if let Some(positional_arg) = positional_arg {
862+
let msg = format!("this formatting argument uses named argument `{}` by position", name);
863+
db.span_label(positional_arg, msg);
864+
db.span_suggestion_verbose(
865+
positional_arg,
866+
"use the named argument by name to avoid ambiguity",
867+
format!("{{{}}}", name),
868+
Applicability::MaybeIncorrect,
869+
);
870+
}
870871
}
871872
}
872873
// Rewrap `db`, and pass control to the user.

compiler/rustc_lint_defs/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ pub enum BuiltinLintDiagnostics {
467467
/// If true, the lifetime will be fully elided.
468468
use_span: Option<(Span, bool)>,
469469
},
470-
NamedArgumentUsedPositionally(Span, Span, String),
470+
NamedArgumentUsedPositionally(Option<Span>, Span, String),
471471
}
472472

473473
/// Lints that are buffered up early on in the `Session` before the

src/test/ui/macros/issue-99261.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-pass
2+
3+
#![deny(named_arguments_used_positionally)]
4+
5+
fn main() {
6+
let value: f64 = 314.15926;
7+
let digits_before_decimal = 1;
8+
let digits_after_decimal = 2;
9+
let width = digits_before_decimal + 1 + digits_after_decimal;
10+
11+
println!(
12+
"{value:0>width$.digits_after_decimal$}",
13+
value = value,
14+
width = width,
15+
digits_after_decimal = digits_after_decimal,
16+
);
17+
}

0 commit comments

Comments
 (0)