diff options
| author | bors <bors@rust-lang.org> | 2022-07-16 14:05:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-07-16 14:05:52 +0000 |
| commit | 56351589f8c5afe07a9151dd4a75976aebd1a709 (patch) | |
| tree | f808a337116ebb9aa8f47464ea3bf77cad7dd3e3 | |
| parent | d695a497bbf4b20d2580b75075faa80230d41667 (diff) | |
| parent | 2902b92769a29d24f9107d2e322ed9c92990da98 (diff) | |
| download | rust-56351589f8c5afe07a9151dd4a75976aebd1a709.tar.gz rust-56351589f8c5afe07a9151dd4a75976aebd1a709.zip | |
Auto merge of #99263 - compiler-errors:issue-99261, r=jyn514
Fix ICE in `named_arguments_used_positionally` lint
Fixes #99261
Fixes #99289
Fixes #99284
Fixes #99273
Fixes #99297
Fixes #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 #99265 to track a (related?) incorrect argument indexing issue.
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/lib.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/macros/issue-99261.rs | 17 |
4 files changed, 36 insertions, 19 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 4791151c7d3..3b7e2102ffa 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -16,7 +16,7 @@ use smallvec::SmallVec; use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId}; -use rustc_parse_format::{Count, FormatSpec}; +use rustc_parse_format::Count; use std::borrow::Cow; use std::collections::hash_map::Entry; @@ -985,20 +985,19 @@ fn lint_named_arguments_used_positionally( } _ => {} }; - match a.format { - FormatSpec { width: Count::CountIsName(s, _), .. } - | FormatSpec { precision: Count::CountIsName(s, _), .. } => { - used_argument_names.insert(s); - } - _ => {} - }; + if let Count::CountIsName(s, _) = a.format.width { + used_argument_names.insert(s); + } + if let Count::CountIsName(s, _) = a.format.precision { + used_argument_names.insert(s); + } } } for (symbol, (index, span)) in names { if !used_argument_names.contains(symbol.as_str()) { let msg = format!("named argument `{}` is not used by name", symbol.as_str()); - let arg_span = cx.arg_spans[index]; + let arg_span = cx.arg_spans.get(index).copied(); cx.ecx.buffered_early_lint.push(BufferedEarlyLint { span: MultiSpan::from_span(span), msg: msg.clone(), diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 50e9383cacc..b4b472fe2df 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -858,15 +858,16 @@ pub trait LintContext: Sized { }, BuiltinLintDiagnostics::NamedArgumentUsedPositionally(positional_arg, named_arg, name) => { db.span_label(named_arg, "this named argument is only referred to by position in formatting string"); - let msg = format!("this formatting argument uses named argument `{}` by position", name); - db.span_label(positional_arg, msg); - db.span_suggestion_verbose( - positional_arg, - "use the named argument by name to avoid ambiguity", - format!("{{{}}}", name), - Applicability::MaybeIncorrect, - ); - + if let Some(positional_arg) = positional_arg { + let msg = format!("this formatting argument uses named argument `{}` by position", name); + db.span_label(positional_arg, msg); + db.span_suggestion_verbose( + positional_arg, + "use the named argument by name to avoid ambiguity", + format!("{{{}}}", name), + Applicability::MaybeIncorrect, + ); + } } } // Rewrap `db`, and pass control to the user. diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 1bc7e7de660..4fd57ed8533 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -467,7 +467,7 @@ pub enum BuiltinLintDiagnostics { /// If true, the lifetime will be fully elided. use_span: Option<(Span, bool)>, }, - NamedArgumentUsedPositionally(Span, Span, String), + NamedArgumentUsedPositionally(Option<Span>, Span, String), } /// Lints that are buffered up early on in the `Session` before the diff --git a/src/test/ui/macros/issue-99261.rs b/src/test/ui/macros/issue-99261.rs new file mode 100644 index 00000000000..40d26d08cba --- /dev/null +++ b/src/test/ui/macros/issue-99261.rs @@ -0,0 +1,17 @@ +// check-pass + +#![deny(named_arguments_used_positionally)] + +fn main() { + let value: f64 = 314.15926; + let digits_before_decimal = 1; + let digits_after_decimal = 2; + let width = digits_before_decimal + 1 + digits_after_decimal; + + println!( + "{value:0>width$.digits_after_decimal$}", + value = value, + width = width, + digits_after_decimal = digits_after_decimal, + ); +} |
