summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs247
-rw-r--r--compiler/rustc_lint/src/context.rs4
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs2
-rw-r--r--compiler/rustc_parse_format/src/lib.rs20
-rw-r--r--compiler/rustc_parse_format/src/tests.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/on_unimplemented.rs2
-rw-r--r--src/test/ui/macros/issue-98466.stderr48
-rw-r--r--src/test/ui/macros/issue-99265.fixed139
-rw-r--r--src/test/ui/macros/issue-99265.rs139
-rw-r--r--src/test/ui/macros/issue-99265.stderr562
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs2
12 files changed, 1093 insertions, 102 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 829eaa305e8..a2205c3613d 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -656,7 +656,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
let span = arg_spans.next().unwrap_or(template_sp);
let operand_idx = match arg.position {
- parse::ArgumentIs(idx) | parse::ArgumentImplicitlyIs(idx) => {
+ parse::ArgumentIs(idx, _) | parse::ArgumentImplicitlyIs(idx) => {
if idx >= args.operands.len()
|| named_pos.contains_key(&idx)
|| args.reg_args.contains(&idx)
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index ce897abb766..f5eb984c138 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -11,14 +11,14 @@ use rustc_errors::{pluralize, Applicability, MultiSpan, PResult};
use rustc_expand::base::{self, *};
use rustc_parse_format as parse;
use rustc_span::symbol::{sym, Ident, Symbol};
-use rustc_span::{InnerSpan, Span};
+use rustc_span::{BytePos, InnerSpan, Span};
use smallvec::SmallVec;
use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId};
-use rustc_parse_format::Count;
use std::borrow::Cow;
use std::collections::hash_map::Entry;
+use std::ops::Deref;
#[derive(PartialEq)]
enum ArgumentType {
@@ -32,6 +32,105 @@ enum Position {
Named(Symbol, InnerSpan),
}
+/// Indicates how positional named argument (i.e. an named argument which is used by position
+/// instead of by name) is used in format string
+/// * `Arg` is the actual argument to print
+/// * `Width` is width format argument
+/// * `Precision` is precion format argument
+/// Example: `{Arg:Width$.Precision$}
+#[derive(Debug, Eq, PartialEq)]
+enum PositionalNamedArgType {
+ Arg,
+ Width,
+ Precision,
+}
+
+/// Contains information necessary to create a lint for a positional named argument
+#[derive(Debug)]
+struct PositionalNamedArg {
+ ty: PositionalNamedArgType,
+ /// The piece of the using this argument (multiple pieces can use the same argument)
+ cur_piece: usize,
+ /// The InnerSpan for in the string to be replaced with the named argument
+ /// This will be None when the position is implicit
+ inner_span_to_replace: Option<rustc_parse_format::InnerSpan>,
+ /// The name to use instead of the position
+ replacement: Symbol,
+ /// The span for the positional named argument (so the lint can point a message to it)
+ positional_named_arg_span: Span,
+}
+
+impl PositionalNamedArg {
+ /// Determines what span to replace with the name of the named argument
+ fn get_span_to_replace(&self, cx: &Context<'_, '_>) -> Option<Span> {
+ if let Some(inner_span) = &self.inner_span_to_replace {
+ return match self.ty {
+ PositionalNamedArgType::Arg | PositionalNamedArgType::Width => Some(Span::new(
+ cx.fmtsp.lo() + BytePos(inner_span.start.try_into().unwrap()),
+ cx.fmtsp.lo() + BytePos(inner_span.end.try_into().unwrap()),
+ self.positional_named_arg_span.ctxt(),
+ self.positional_named_arg_span.parent(),
+ )),
+ PositionalNamedArgType::Precision => Some(Span::new(
+ cx.fmtsp.lo() + BytePos(inner_span.start.try_into().unwrap()) + BytePos(1),
+ cx.fmtsp.lo() + BytePos(inner_span.end.try_into().unwrap()),
+ self.positional_named_arg_span.ctxt(),
+ self.positional_named_arg_span.parent(),
+ )),
+ };
+ } else if self.ty == PositionalNamedArgType::Arg {
+ // In the case of a named argument whose position is implicit, there will not be a span
+ // to replace. Instead, we insert the name after the `{`, which is the first character
+ // of arg_span.
+ if let Some(arg_span) = cx.arg_spans.get(self.cur_piece).copied() {
+ return Some(Span::new(
+ arg_span.lo() + BytePos(1),
+ arg_span.lo() + BytePos(1),
+ self.positional_named_arg_span.ctxt(),
+ self.positional_named_arg_span.parent(),
+ ));
+ }
+ }
+
+ None
+ }
+}
+
+/// Encapsulates all the named arguments that have been used positionally
+#[derive(Debug)]
+struct PositionalNamedArgsLint {
+ positional_named_args: Vec<PositionalNamedArg>,
+}
+
+impl PositionalNamedArgsLint {
+ /// Try constructing a PositionalNamedArg struct and pushing it into the vec of positional
+ /// named arguments. If a named arg associated with `format_argument_index` cannot be found,
+ /// a new item will not be added as the lint cannot be emitted in this case.
+ fn maybe_push(
+ &mut self,
+ format_argument_index: usize,
+ ty: PositionalNamedArgType,
+ cur_piece: usize,
+ inner_span: Option<rustc_parse_format::InnerSpan>,
+ names: &FxHashMap<Symbol, (usize, Span)>,
+ ) {
+ let named_arg = names
+ .iter()
+ .find(|name| name.deref().1.0 == format_argument_index)
+ .map(|found| found.clone());
+
+ if let Some(named_arg) = named_arg {
+ self.positional_named_args.push(PositionalNamedArg {
+ ty,
+ cur_piece,
+ inner_span_to_replace: inner_span,
+ replacement: named_arg.0.clone(),
+ positional_named_arg_span: named_arg.1.1.clone(),
+ });
+ }
+ }
+}
+
struct Context<'a, 'b> {
ecx: &'a mut ExtCtxt<'b>,
/// The macro's call site. References to unstable formatting internals must
@@ -118,6 +217,7 @@ struct Context<'a, 'b> {
/// Whether this format string came from a string literal, as opposed to a macro.
is_literal: bool,
+ unused_names_lint: PositionalNamedArgsLint,
}
/// Parses the arguments from the given list of tokens, returning the diagnostic
@@ -242,7 +342,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.args.len() - self.num_captured_args
}
- fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) {
+ fn resolve_name_inplace(&mut self, p: &mut parse::Piece<'_>) {
// NOTE: the `unwrap_or` branch is needed in case of invalid format
// arguments, e.g., `format_args!("{foo}")`.
let lookup =
@@ -252,7 +352,7 @@ impl<'a, 'b> Context<'a, 'b> {
parse::String(_) => {}
parse::NextArgument(ref mut arg) => {
if let parse::ArgumentNamed(s, _) = arg.position {
- arg.position = parse::ArgumentIs(lookup(s));
+ arg.position = parse::ArgumentIs(lookup(s), None);
}
if let parse::CountIsName(s, _) = arg.format.width {
arg.format.width = parse::CountIsParam(lookup(s));
@@ -273,15 +373,50 @@ impl<'a, 'b> Context<'a, 'b> {
parse::NextArgument(ref arg) => {
// width/precision first, if they have implicit positional
// parameters it makes more sense to consume them first.
- self.verify_count(arg.format.width);
- self.verify_count(arg.format.precision);
+ self.verify_count(
+ arg.format.width,
+ &arg.format.width_span,
+ PositionalNamedArgType::Width,
+ );
+ self.verify_count(
+ arg.format.precision,
+ &arg.format.precision_span,
+ PositionalNamedArgType::Precision,
+ );
// argument second, if it's an implicit positional parameter
// it's written second, so it should come after width/precision.
let pos = match arg.position {
- parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => Exact(i),
+ parse::ArgumentIs(i, arg_end) => {
+ let start_of_named_args = self.args.len() - self.names.len();
+ if self.curpiece >= start_of_named_args {
+ self.unused_names_lint.maybe_push(
+ i,
+ PositionalNamedArgType::Arg,
+ self.curpiece,
+ arg_end,
+ &self.names,
+ );
+ }
+
+ Exact(i)
+ }
+ parse::ArgumentImplicitlyIs(i) => {
+ let start_of_named_args = self.args.len() - self.names.len();
+ if self.curpiece >= start_of_named_args {
+ self.unused_names_lint.maybe_push(
+ i,
+ PositionalNamedArgType::Arg,
+ self.curpiece,
+ None,
+ &self.names,
+ );
+ }
+ Exact(i)
+ }
parse::ArgumentNamed(s, span) => {
- Named(Symbol::intern(s), InnerSpan::new(span.start, span.end))
+ let symbol = Symbol::intern(s);
+ Named(symbol, InnerSpan::new(span.start, span.end))
}
};
@@ -349,10 +484,25 @@ impl<'a, 'b> Context<'a, 'b> {
}
}
- fn verify_count(&mut self, c: parse::Count<'_>) {
+ fn verify_count(
+ &mut self,
+ c: parse::Count<'_>,
+ inner_span: &Option<rustc_parse_format::InnerSpan>,
+ named_arg_type: PositionalNamedArgType,
+ ) {
match c {
parse::CountImplied | parse::CountIs(..) => {}
parse::CountIsParam(i) => {
+ let start_of_named_args = self.args.len() - self.names.len();
+ if i >= start_of_named_args {
+ self.unused_names_lint.maybe_push(
+ i,
+ named_arg_type,
+ self.curpiece,
+ inner_span.clone(),
+ &self.names,
+ );
+ }
self.verify_arg_type(Exact(i), Count);
}
parse::CountIsName(s, span) => {
@@ -673,7 +823,7 @@ impl<'a, 'b> Context<'a, 'b> {
// Build the position
let pos = {
match arg.position {
- parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => {
+ parse::ArgumentIs(i, ..) | parse::ArgumentImplicitlyIs(i) => {
// Map to index in final generated argument array
// in case of multiple types specified
let arg_idx = match arg_index_consumed.get_mut(i) {
@@ -701,7 +851,7 @@ impl<'a, 'b> Context<'a, 'b> {
// track the current argument ourselves.
let i = self.curarg;
self.curarg += 1;
- parse::ArgumentIs(i)
+ parse::ArgumentIs(i, None)
},
format: parse::FormatSpec {
fill: arg.format.fill,
@@ -971,43 +1121,27 @@ pub fn expand_format_args_nl<'cx>(
expand_format_args_impl(ecx, sp, tts, true)
}
-fn lint_named_arguments_used_positionally(
- names: FxHashMap<Symbol, (usize, Span)>,
- cx: &mut Context<'_, '_>,
- unverified_pieces: Vec<parse::Piece<'_>>,
-) {
- let mut used_argument_names = FxHashSet::<&str>::default();
- for piece in unverified_pieces {
- if let rustc_parse_format::Piece::NextArgument(a) = piece {
- match a.position {
- rustc_parse_format::Position::ArgumentNamed(arg_name, _) => {
- used_argument_names.insert(arg_name);
- }
- _ => {}
- };
- 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);
- }
- }
- }
+fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>) {
+ for named_arg in &cx.unused_names_lint.positional_named_args {
+ let arg_span = named_arg.get_span_to_replace(cx);
- 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.get(index).copied();
- cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
- span: MultiSpan::from_span(span),
- msg: msg.clone(),
- node_id: ast::CRATE_NODE_ID,
- lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
- diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally(
- arg_span, span, symbol,
- ),
- });
- }
+ let msg = format!("named argument `{}` is not used by name", named_arg.replacement);
+ let replacement = match named_arg.ty {
+ PositionalNamedArgType::Arg => named_arg.replacement.to_string(),
+ _ => named_arg.replacement.to_string() + "$",
+ };
+
+ cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
+ span: MultiSpan::from_span(named_arg.positional_named_arg_span),
+ msg: msg.clone(),
+ node_id: ast::CRATE_NODE_ID,
+ lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
+ diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally(
+ arg_span,
+ named_arg.positional_named_arg_span,
+ replacement,
+ ),
+ });
}
}
@@ -1119,11 +1253,6 @@ pub fn expand_preparsed_format_args(
let named_pos: FxHashSet<usize> = names.values().cloned().map(|(i, _)| i).collect();
- // Clone `names` because `names` in Context get updated by verify_piece, which includes usages
- // of the names of named arguments, resulting in incorrect errors if a name argument is used
- // but not declared, such as: `println!("x = {x}");`
- let named_arguments = names.clone();
-
let mut cx = Context {
ecx,
args,
@@ -1148,13 +1277,12 @@ pub fn expand_preparsed_format_args(
arg_spans,
arg_with_formatting: Vec::new(),
is_literal: parser.is_literal,
+ unused_names_lint: PositionalNamedArgsLint { positional_named_args: vec![] },
};
- // This needs to happen *after* the Parser has consumed all pieces to create all the spans.
- // unverified_pieces is used later to check named argument names are used, so clone each piece.
+ // This needs to happen *after* the Parser has consumed all pieces to create all the spans
let pieces = unverified_pieces
- .iter()
- .cloned()
+ .into_iter()
.map(|mut piece| {
cx.verify_piece(&piece);
cx.resolve_name_inplace(&mut piece);
@@ -1164,7 +1292,7 @@ pub fn expand_preparsed_format_args(
let numbered_position_args = pieces.iter().any(|arg: &parse::Piece<'_>| match *arg {
parse::String(_) => false,
- parse::NextArgument(arg) => matches!(arg.position, parse::Position::ArgumentIs(_)),
+ parse::NextArgument(arg) => matches!(arg.position, parse::Position::ArgumentIs(..)),
});
cx.build_index_map();
@@ -1316,11 +1444,10 @@ pub fn expand_preparsed_format_args(
}
diag.emit();
- } else if cx.invalid_refs.is_empty() && !named_arguments.is_empty() {
+ } else if cx.invalid_refs.is_empty() && cx.ecx.sess.err_count() == 0 {
// Only check for unused named argument names if there are no other errors to avoid causing
// too much noise in output errors, such as when a named argument is entirely unused.
- // We also only need to perform this check if there are actually named arguments.
- lint_named_arguments_used_positionally(named_arguments, &mut cx, unverified_pieces);
+ create_lints_for_named_arguments_used_positionally(&mut cx);
}
cx.into_expr()
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index b4b472fe2df..04ac50f1d48 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -861,10 +861,10 @@ pub trait LintContext: Sized {
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(
+ db.span_suggestion_verbose(
positional_arg,
"use the named argument by name to avoid ambiguity",
- format!("{{{}}}", name),
+ name,
Applicability::MaybeIncorrect,
);
}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 3872d866dee..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(Option<Span>, Span, Symbol),
+ NamedArgumentUsedPositionally(Option<Span>, Span, String),
}
/// Lints that are buffered up early on in the `Session` before the
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 6e7553f5e49..5deb17b8651 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -104,8 +104,8 @@ pub struct FormatSpec<'a> {
pub enum Position<'a> {
/// The argument is implied to be located at an index
ArgumentImplicitlyIs(usize),
- /// The argument is located at a specific index given in the format
- ArgumentIs(usize),
+ /// The argument is located at a specific index given in the format,
+ ArgumentIs(usize, Option<InnerSpan>),
/// The argument has a name.
ArgumentNamed(&'a str, InnerSpan),
}
@@ -113,7 +113,7 @@ pub enum Position<'a> {
impl Position<'_> {
pub fn index(&self) -> Option<usize> {
match self {
- ArgumentIs(i) | ArgumentImplicitlyIs(i) => Some(*i),
+ ArgumentIs(i, ..) | ArgumentImplicitlyIs(i) => Some(*i),
_ => None,
}
}
@@ -502,8 +502,15 @@ impl<'a> Parser<'a> {
/// Returns `Some(parsed_position)` if the position is not implicitly
/// consuming a macro argument, `None` if it's the case.
fn position(&mut self) -> Option<Position<'a>> {
+ let start_position = self.cur.peek().map(|item| item.0);
if let Some(i) = self.integer() {
- Some(ArgumentIs(i))
+ let inner_span = start_position.and_then(|start| {
+ self.cur
+ .peek()
+ .cloned()
+ .and_then(|item| Some(self.to_span_index(start).to(self.to_span_index(item.0))))
+ });
+ Some(ArgumentIs(i, inner_span))
} else {
match self.cur.peek() {
Some(&(start, c)) if rustc_lexer::is_id_start(c) => {
@@ -574,6 +581,10 @@ impl<'a> Parser<'a> {
// no '0' flag and '0$' as the width instead.
if let Some(end) = self.consume_pos('$') {
spec.width = CountIsParam(0);
+
+ if let Some((pos, _)) = self.cur.peek().cloned() {
+ spec.width_span = Some(self.to_span_index(pos - 2).to(self.to_span_index(pos)));
+ }
havewidth = true;
spec.width_span = Some(self.to_span_index(end - 1).to(self.to_span_index(end + 1)));
} else {
@@ -586,6 +597,7 @@ impl<'a> Parser<'a> {
spec.width = w;
spec.width_span = sp;
}
+
if let Some(start) = self.consume_pos('.') {
if let Some(end) = self.consume_pos('*') {
// Resolve `CountIsNextParam`.
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index 9c305b4996a..a98f816644b 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -62,18 +62,30 @@ fn format_nothing() {
}
#[test]
fn format_position() {
- same("{3}", &[NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt() })]);
+ same(
+ "{3}",
+ &[NextArgument(Argument {
+ position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+ format: fmtdflt(),
+ })],
+ );
}
#[test]
fn format_position_nothing_else() {
- same("{3:}", &[NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt() })]);
+ same(
+ "{3:}",
+ &[NextArgument(Argument {
+ position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+ format: fmtdflt(),
+ })],
+ );
}
#[test]
fn format_type() {
same(
"{3:x}",
&[NextArgument(Argument {
- position: ArgumentIs(3),
+ position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
format: FormatSpec {
fill: None,
align: AlignUnknown,
@@ -93,7 +105,7 @@ fn format_align_fill() {
same(
"{3:>}",
&[NextArgument(Argument {
- position: ArgumentIs(3),
+ position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
format: FormatSpec {
fill: None,
align: AlignRight,
@@ -110,7 +122,7 @@ fn format_align_fill() {
same(
"{3:0<}",
&[NextArgument(Argument {
- position: ArgumentIs(3),
+ position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
format: FormatSpec {
fill: Some('0'),
align: AlignLeft,
@@ -127,7 +139,7 @@ fn format_align_fill() {
same(
"{3:*<abcd}",
&[NextArgument(Argument {
- position: ArgumentIs(3),
+ position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
format: FormatSpec {
fill: Some('*'),
align: AlignLeft,
@@ -181,7 +193,7 @@ fn format_counts() {
same(
"{1:0$.10x}",
&[NextArgument(Argument {
- position: ArgumentIs(1),
+ position: ArgumentIs(1, Some(InnerSpan { start: 2, end: 3 })),
format: FormatSpec {
fill: None,
align: AlignUnknown,
@@ -291,7 +303,7 @@ fn format_mixture() {
&[
String("abcd "),
NextArgument(Argument {
- position: ArgumentIs(3),
+ position: ArgumentIs(3, Some(InnerSpan { start: 7, end: 8 })),
format: FormatSpec {
fill: None,
align: AlignUnknown,
diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index ed7d16f7a54..4d3b0b4cf07 100644
--- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
@@ -337,7 +337,7 @@ impl<'tcx> OnUnimplementedFormatString {
}
}
// `{:1}` and `{}` are not to be used
- Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => {
+ Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => {
let reported = struct_span_err!(
tcx.sess,
span,
diff --git a/src/test/ui/macros/issue-98466.stderr b/src/test/ui/macros/issue-98466.stderr
index ad11d181b62..4a39dd1440b 100644
--- a/src/test/ui/macros/issue-98466.stderr
+++ b/src/test/ui/macros/issue-98466.stderr
@@ -2,80 +2,80 @@ warning: named argument `_x` is not used by name
--> $DIR/issue-98466.rs:7:26
|
LL | println!("_x is {}", _x = 5);
- | -- ^^ this named argument is only referred to by position in formatting string
- | |
- | this formatting argument uses named argument `_x` by position
+ | - ^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `_x` by position
|
= note: `#[warn(named_arguments_used_positionally)]` on by default
help: use the named argument by name to avoid ambiguity
|
LL | println!("_x is {_x}", _x = 5);
- | ~~~~
+ | ++
warning: named argument `y` is not used by name
--> $DIR/issue-98466.rs:10:26
|
LL | println!("_x is {}", y = _x);
- | -- ^ this named argument is only referred to by position in formatting string
- | |
- | this formatting argument uses named argument `y` by position
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `y` by position
|
help: use the named argument by name to avoid ambiguity
|
LL | println!("_x is {y}", y = _x);
- | ~~~
+ | +
warning: named argument `y` is not used by name
--> $DIR/issue-98466.rs:13:83
|
LL | println!("first positional arg {}, second positional arg {}, _x is {}", 1, 2, y = _x);
- | -- ^ this named argument is only referred to by position in formatting string
- | |
- | this formatting argument uses named argument `y` by position
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `y` by position
|
help: use the named argument by name to avoid ambiguity
|
LL | println!("first positional arg {}, second positional arg {}, _x is {y}", 1, 2, y = _x);
- | ~~~
+ | +
warning: named argument `_x` is not used by name
--> $DIR/issue-98466.rs:19:34
|
LL | let _f = format!("_x is {}", _x = 5);
- | -- ^^ this named argument is only referred to by position in formatting string
- | |
- | this formatting argument uses named argument `_x` by position
+ | - ^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `_x` by position
|
help: use the named argument by name to avoid ambiguity
|
LL | let _f = format!("_x is {_x}", _x = 5);
- | ~~~~
+ | ++
warning: named argument `y` is not used by name
--> $DIR/issue-98466.rs:22:34
|
LL | let _f = format!("_x is {}", y = _x);
- | -- ^ this named argument is only referred to by position in formatting string
- | |
- | this formatting argument uses named argument `y` by position
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `y` by position
|
help: use the named argument by name to avoid ambiguity
|
LL | let _f = format!("_x is {y}", y = _x);
- | ~~~
+ | +
warning: named argument `y` is not used by name
--> $DIR/issue-98466.rs:25:91
|
LL | let _f = format!("first positional arg {}, second positional arg {}, _x is {}", 1, 2, y = _x);
- | -- ^ this named argument is only referred to by position in formatting string
- | |
- | this formatting argument uses named argument `y` by position
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `y` by position
|
help: use the named argument by name to avoid ambiguity
|
LL | let _f = format!("first positional arg {}, second positional arg {}, _x is {y}", 1, 2, y = _x);
- | ~~~
+ | +
warning: 6 warnings emitted
diff --git a/src/test/ui/macros/issue-99265.fixed b/src/test/ui/macros/issue-99265.fixed
new file mode 100644
index 00000000000..f3be9c6285d
--- /dev/null
+++ b/src/test/ui/macros/issue-99265.fixed
@@ -0,0 +1,139 @@
+// check-pass
+// run-rustfix
+
+fn main() {
+ println!("{b} {a}", a=1, b=2);
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("{} {a} {b} {c} {d}", 0, a=1, b=2, c=3, d=4);
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `b` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `c` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `d` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {:width$}!", "x", width = 5);
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {f:width$.precision$}!", f = 0.02f32, width = 5, precision = 2);
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ //~| WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {f:width$.precision$}!", f = 0.02f32, width = 5, precision = 2);
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ //~| WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!(
+ "{}, Hello {f:width$.precision$} {g:width2$.precision2$}! {f}",
+ //~^ HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ 1,
+ f = 0.02f32,
+ //~^ WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ width = 5,
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ precision = 2,
+ //~^ WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ g = 0.02f32,
+ //~^ WARNING named argument `g` is not used by name [named_arguments_used_positionally]
+ width2 = 5,
+ //~^ WARNING named argument `width2` is not used by name [named_arguments_used_positionally
+ precision2 = 2
+ //~^ WARNING named argument `precision2` is not used by name [named_arguments_used_positionally]
+ );
+
+ println!("Hello {f:0.1}!", f = 0.02f32);
+ //~^ WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {f:0.1}!", f = 0.02f32);
+ //~^ WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {f:width$.precision$}!", f = 0.02f32, width = 5, precision = 2);
+
+ let width = 5;
+ let precision = 2;
+ println!("Hello {f:width$.precision$}!", f = 0.02f32);
+
+ let val = 5;
+ println!("{v:v$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ println!("{v:v$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ println!("{v:v$.v$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ println!("{v:v$.v$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("{a} {a} {a}", a = 1);
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("aaaaaaaaaaaaaaa\
+ {a:b$.c$}",
+ //~^ HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ a = 1.0, b = 1, c = 2,
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `b` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `c` is not used by name [named_arguments_used_positionally]
+ );
+
+ println!("aaaaaaaaaaaaaaa\
+ {a:b$.c$}",
+ //~^ HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ a = 1.0, b = 1, c = 2,
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `b` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `c` is not used by name [named_arguments_used_positionally]
+ );
+
+ println!("{{{x:width$.precision$}}}", x = 1.0, width = 3, precision = 2);
+ //~^ WARNING named argument `x` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `width` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+}
diff --git a/src/test/ui/macros/issue-99265.rs b/src/test/ui/macros/issue-99265.rs
new file mode 100644
index 00000000000..e7cf608765b
--- /dev/null
+++ b/src/test/ui/macros/issue-99265.rs
@@ -0,0 +1,139 @@
+// check-pass
+// run-rustfix
+
+fn main() {
+ println!("{b} {}", a=1, b=2);
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("{} {} {} {} {}", 0, a=1, b=2, c=3, d=4);
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `b` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `c` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `d` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {:1$}!", "x", width = 5);
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ //~| WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {0:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ //~| WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!(
+ "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ //~^ HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ 1,
+ f = 0.02f32,
+ //~^ WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ width = 5,
+ //~^ WARNING named argument `width` is not used by name [named_arguments_used_positionally
+ precision = 2,
+ //~^ WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ g = 0.02f32,
+ //~^ WARNING named argument `g` is not used by name [named_arguments_used_positionally]
+ width2 = 5,
+ //~^ WARNING named argument `width2` is not used by name [named_arguments_used_positionally
+ precision2 = 2
+ //~^ WARNING named argument `precision2` is not used by name [named_arguments_used_positionally]
+ );
+
+ println!("Hello {:0.1}!", f = 0.02f32);
+ //~^ WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {0:0.1}!", f = 0.02f32);
+ //~^ WARNING named argument `f` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("Hello {f:width$.precision$}!", f = 0.02f32, width = 5, precision = 2);
+
+ let width = 5;
+ let precision = 2;
+ println!("Hello {f:width$.precision$}!", f = 0.02f32);
+
+ let val = 5;
+ println!("{:0$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ println!("{0:0$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ println!("{:0$.0$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ println!("{0:0$.0$}", v = val);
+ //~^ WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `v` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("{} {a} {0}", a = 1);
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+
+ println!("aaaaaaaaaaaaaaa\
+ {:1$.2$}",
+ //~^ HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ a = 1.0, b = 1, c = 2,
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `b` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `c` is not used by name [named_arguments_used_positionally]
+ );
+
+ println!("aaaaaaaaaaaaaaa\
+ {0:1$.2$}",
+ //~^ HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ a = 1.0, b = 1, c = 2,
+ //~^ WARNING named argument `a` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `b` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `c` is not used by name [named_arguments_used_positionally]
+ );
+
+ println!("{{{:1$.2$}}}", x = 1.0, width = 3, precision = 2);
+ //~^ WARNING named argument `x` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `width` is not used by name [named_arguments_used_positionally]
+ //~| WARNING named argument `precision` is not used by name [named_arguments_used_positionally]
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| HELP use the named argument by name to avoid ambiguity
+}
diff --git a/src/test/ui/macros/issue-99265.stderr b/src/test/ui/macros/issue-99265.stderr
new file mode 100644
index 00000000000..0798ad8dc51
--- /dev/null
+++ b/src/test/ui/macros/issue-99265.stderr
@@ -0,0 +1,562 @@
+warning: named argument `a` is not used by name
+ --> $DIR/issue-99265.rs:5:24
+ |
+LL | println!("{b} {}", a=1, b=2);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `a` by position
+ |
+ = note: `#[warn(named_arguments_used_positionally)]` on by default
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{b} {a}", a=1, b=2);
+ | +
+
+warning: named argument `a` is not used by name
+ --> $DIR/issue-99265.rs:9:35
+ |
+LL | println!("{} {} {} {} {}", 0, a=1, b=2, c=3, d=4);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `a` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{} {a} {} {} {}", 0, a=1, b=2, c=3, d=4);
+ | +
+
+warning: named argument `b` is not used by name
+ --> $DIR/issue-99265.rs:9:40
+ |
+LL | println!("{} {} {} {} {}", 0, a=1, b=2, c=3, d=4);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `b` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{} {} {b} {} {}", 0, a=1, b=2, c=3, d=4);
+ | +
+
+warning: named argument `c` is not used by name
+ --> $DIR/issue-99265.rs:9:45
+ |
+LL | println!("{} {} {} {} {}", 0, a=1, b=2, c=3, d=4);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `c` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{} {} {} {c} {}", 0, a=1, b=2, c=3, d=4);
+ | +
+
+warning: named argument `d` is not used by name
+ --> $DIR/issue-99265.rs:9:50
+ |
+LL | println!("{} {} {} {} {}", 0, a=1, b=2, c=3, d=4);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `d` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{} {} {} {} {d}", 0, a=1, b=2, c=3, d=4);
+ | +
+
+warning: named argument `width` is not used by name
+ --> $DIR/issue-99265.rs:19:35
+ |
+LL | println!("Hello {:1$}!", "x", width = 5);
+ | -- ^^^^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `width$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {:width$}!", "x", width = 5);
+ | ~~~~~~
+
+warning: named argument `width` is not used by name
+ --> $DIR/issue-99265.rs:23:46
+ |
+LL | println!("Hello {:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | -- ^^^^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `width$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {:width$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | ~~~~~~
+
+warning: named argument `precision` is not used by name
+ --> $DIR/issue-99265.rs:23:57
+ |
+LL | println!("Hello {:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | -- ^^^^^^^^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `precision$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {:1$.precision$}!", f = 0.02f32, width = 5, precision = 2);
+ | ~~~~~~~~~~
+
+warning: named argument `f` is not used by name
+ --> $DIR/issue-99265.rs:23:33
+ |
+LL | println!("Hello {:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `f` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {f:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | +
+
+warning: named argument `width` is not used by name
+ --> $DIR/issue-99265.rs:31:47
+ |
+LL | println!("Hello {0:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | -- ^^^^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `width$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {0:width$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | ~~~~~~
+
+warning: named argument `precision` is not used by name
+ --> $DIR/issue-99265.rs:31:58
+ |
+LL | println!("Hello {0:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | -- ^^^^^^^^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `precision$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {0:1$.precision$}!", f = 0.02f32, width = 5, precision = 2);
+ | ~~~~~~~~~~
+
+warning: named argument `f` is not used by name
+ --> $DIR/issue-99265.rs:31:34
+ |
+LL | println!("Hello {0:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `f` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {f:1$.2$}!", f = 0.02f32, width = 5, precision = 2);
+ | ~
+
+warning: named argument `width` is not used by name
+ --> $DIR/issue-99265.rs:52:9
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ | -- this formatting argument uses named argument `width$` by position
+...
+LL | width = 5,
+ | ^^^^^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | "{}, Hello {1:width$.3$} {4:5$.6$}! {1}",
+ | ~~~~~~
+
+warning: named argument `precision` is not used by name
+ --> $DIR/issue-99265.rs:54:9
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ | -- this formatting argument uses named argument `precision$` by position
+...
+LL | precision = 2,
+ | ^^^^^^^^^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | "{}, Hello {1:2$.precision$} {4:5$.6$}! {1}",
+ | ~~~~~~~~~~
+
+warning: named argument `f` is not used by name
+ --> $DIR/issue-99265.rs:49:9
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ | - this formatting argument uses named argument `f` by position
+...
+LL | f = 0.02f32,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | "{}, Hello {f:2$.3$} {4:5$.6$}! {1}",
+ | ~
+
+warning: named argument `width2` is not used by name
+ --> $DIR/issue-99265.rs:58:9
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ | -- this formatting argument uses named argument `width2$` by position
+...
+LL | width2 = 5,
+ | ^^^^^^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | "{}, Hello {1:2$.3$} {4:width2$.6$}! {1}",
+ | ~~~~~~~
+
+warning: named argument `precision2` is not used by name
+ --> $DIR/issue-99265.rs:60:9
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ | -- this formatting argument uses named argument `precision2$` by position
+...
+LL | precision2 = 2
+ | ^^^^^^^^^^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.precision2$}! {1}",
+ | ~~~~~~~~~~~
+
+warning: named argument `g` is not used by name
+ --> $DIR/issue-99265.rs:56:9
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ | - this formatting argument uses named argument `g` by position
+...
+LL | g = 0.02f32,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | "{}, Hello {1:2$.3$} {g:5$.6$}! {1}",
+ | ~
+
+warning: named argument `f` is not used by name
+ --> $DIR/issue-99265.rs:49:9
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {1}",
+ | - this formatting argument uses named argument `f` by position
+...
+LL | f = 0.02f32,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | "{}, Hello {1:2$.3$} {4:5$.6$}! {f}",
+ | ~
+
+warning: named argument `f` is not used by name
+ --> $DIR/issue-99265.rs:64:31
+ |
+LL | println!("Hello {:0.1}!", f = 0.02f32);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `f` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {f:0.1}!", f = 0.02f32);
+ | +
+
+warning: named argument `f` is not used by name
+ --> $DIR/issue-99265.rs:68:32
+ |
+LL | println!("Hello {0:0.1}!", f = 0.02f32);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `f` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("Hello {f:0.1}!", f = 0.02f32);
+ | ~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:79:23
+ |
+LL | println!("{:0$}", v = val);
+ | -- ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{:v$}", v = val);
+ | ~~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:79:23
+ |
+LL | println!("{:0$}", v = val);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{v:0$}", v = val);
+ | +
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:84:24
+ |
+LL | println!("{0:0$}", v = val);
+ | -- ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{0:v$}", v = val);
+ | ~~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:84:24
+ |
+LL | println!("{0:0$}", v = val);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{v:0$}", v = val);
+ | ~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:89:26
+ |
+LL | println!("{:0$.0$}", v = val);
+ | -- ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{:v$.0$}", v = val);
+ | ~~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:89:26
+ |
+LL | println!("{:0$.0$}", v = val);
+ | -- ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{:0$.v$}", v = val);
+ | ~~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:89:26
+ |
+LL | println!("{:0$.0$}", v = val);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{v:0$.0$}", v = val);
+ | +
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:96:27
+ |
+LL | println!("{0:0$.0$}", v = val);
+ | -- ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{0:v$.0$}", v = val);
+ | ~~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:96:27
+ |
+LL | println!("{0:0$.0$}", v = val);
+ | -- ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{0:0$.v$}", v = val);
+ | ~~
+
+warning: named argument `v` is not used by name
+ --> $DIR/issue-99265.rs:96:27
+ |
+LL | println!("{0:0$.0$}", v = val);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `v` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{v:0$.0$}", v = val);
+ | ~
+
+warning: named argument `a` is not used by name
+ --> $DIR/issue-99265.rs:104:28
+ |
+LL | println!("{} {a} {0}", a = 1);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `a` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{a} {a} {0}", a = 1);
+ | +
+
+warning: named argument `a` is not used by name
+ --> $DIR/issue-99265.rs:104:28
+ |
+LL | println!("{} {a} {0}", a = 1);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `a` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{} {a} {a}", a = 1);
+ | ~
+
+warning: named argument `b` is not used by name
+ --> $DIR/issue-99265.rs:115:23
+ |
+LL | {:1$.2$}",
+ | -- this formatting argument uses named argument `b$` by position
+...
+LL | a = 1.0, b = 1, c = 2,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | {:b$.2$}",
+ | ~~
+
+warning: named argument `c` is not used by name
+ --> $DIR/issue-99265.rs:115:30
+ |
+LL | {:1$.2$}",
+ | -- this formatting argument uses named argument `c$` by position
+...
+LL | a = 1.0, b = 1, c = 2,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | {:1$.c$}",
+ | ~~
+
+warning: named argument `a` is not used by name
+ --> $DIR/issue-99265.rs:115:14
+ |
+LL | {:1$.2$}",
+ | - this formatting argument uses named argument `a` by position
+...
+LL | a = 1.0, b = 1, c = 2,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | {a:1$.2$}",
+ | +
+
+warning: named argument `b` is not used by name
+ --> $DIR/issue-99265.rs:126:23
+ |
+LL | {0:1$.2$}",
+ | -- this formatting argument uses named argument `b$` by position
+...
+LL | a = 1.0, b = 1, c = 2,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | {0:b$.2$}",
+ | ~~
+
+warning: named argument `c` is not used by name
+ --> $DIR/issue-99265.rs:126:30
+ |
+LL | {0:1$.2$}",
+ | -- this formatting argument uses named argument `c$` by position
+...
+LL | a = 1.0, b = 1, c = 2,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | {0:1$.c$}",
+ | ~~
+
+warning: named argument `a` is not used by name
+ --> $DIR/issue-99265.rs:126:14
+ |
+LL | {0:1$.2$}",
+ | - this formatting argument uses named argument `a` by position
+...
+LL | a = 1.0, b = 1, c = 2,
+ | ^ this named argument is only referred to by position in formatting string
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | {a:1$.2$}",
+ | ~
+
+warning: named argument `width` is not used by name
+ --> $DIR/issue-99265.rs:132:39
+ |
+LL | println!("{{{:1$.2$}}}", x = 1.0, width = 3, precision = 2);
+ | -- ^^^^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `width$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{{{:width$.2$}}}", x = 1.0, width = 3, precision = 2);
+ | ~~~~~~
+
+warning: named argument `precision` is not used by name
+ --> $DIR/issue-99265.rs:132:50
+ |
+LL | println!("{{{:1$.2$}}}", x = 1.0, width = 3, precision = 2);
+ | -- ^^^^^^^^^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `precision$` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{{{:1$.precision$}}}", x = 1.0, width = 3, precision = 2);
+ | ~~~~~~~~~~
+
+warning: named argument `x` is not used by name
+ --> $DIR/issue-99265.rs:132:30
+ |
+LL | println!("{{{:1$.2$}}}", x = 1.0, width = 3, precision = 2);
+ | - ^ this named argument is only referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `x` by position
+ |
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("{{{x:1$.2$}}}", x = 1.0, width = 3, precision = 2);
+ | +
+
+warning: 42 warnings emitted
+
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 08b88947520..3a99d1b417f 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -441,7 +441,7 @@ impl SimpleFormatArgs {
};
match arg.position {
- ArgumentIs(n) | ArgumentImplicitlyIs(n) => {
+ ArgumentIs(n, _) | ArgumentImplicitlyIs(n) => {
if self.unnamed.len() <= n {
// Use a dummy span to mark all unseen arguments.
self.unnamed.resize_with(n, || vec![DUMMY_SP]);