Generate correct suggestion with named arguments used positionally

Address issue #99265 by checking each positionally used argument
to see if the argument is named and adding a lint to use the name
instead. This way, when named arguments are used positionally in a
different order than their argument order, the suggested lint is
correct.

For example:
```
println!("{b} {}", a=1, b=2);
```
This will now generate the suggestion:
```
println!("{b} {a}", a=1, b=2);
```

Additionally, this check now also correctly replaces or inserts
only where the positional argument is (or would be if implicit).
Also, width and precision are replaced with their argument names
when they exists.

Since the issues were so closely related, this fix for issue #99265
also fixes issue #99266.

Fixes #99265
Fixes #99266
This commit is contained in:
Preston From 2022-07-16 15:13:14 -06:00
parent 530c0a81d5
commit 3330c7d1c3
12 changed files with 1093 additions and 102 deletions

View File

@ -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)

View File

@ -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()

View File

@ -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,
);
}

View File

@ -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

View File

@ -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`.

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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]);