Skip to content

Commit 2ebd535

Browse files
committed
Auto merge of rust-lang#7906 - smoelius:master, r=camsteffen
Fix rust-lang#7903 Fixes rust-lang#7903 (cc: `@Arnavion)` changelog: none (bug is in same release) r? `@camsteffen`
2 parents 18cc4e7 + 5edb02a commit 2ebd535

File tree

5 files changed

+82
-23
lines changed

5 files changed

+82
-23
lines changed

clippy_utils/src/higher.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
//! This module contains functions that retrieves specifiec elements.
1+
//! This module contains functions that retrieve specific elements.
22
33
#![deny(clippy::missing_docs_in_private_items)]
44

55
use crate::ty::is_type_diagnostic_item;
6-
use crate::{is_expn_of, last_path_segment, match_def_path, paths};
6+
use crate::{is_expn_of, last_path_segment, match_def_path, path_to_local_id, paths};
77
use if_chain::if_chain;
88
use rustc_ast::ast::{self, LitKind};
99
use rustc_hir as hir;
1010
use rustc_hir::{
11-
Arm, Block, BorrowKind, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath, StmtKind, UnOp,
11+
Arm, Block, BorrowKind, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, PatKind, QPath, StmtKind, UnOp,
1212
};
1313
use rustc_lint::LateContext;
1414
use rustc_span::{sym, symbol, ExpnKind, Span, Symbol};
@@ -513,6 +513,8 @@ pub struct FormatArgsExpn<'tcx> {
513513
pub format_string_parts: &'tcx [Expr<'tcx>],
514514
/// Symbols corresponding to [`Self::format_string_parts`]
515515
pub format_string_symbols: Vec<Symbol>,
516+
/// Match arm patterns, the `arg0`, etc. from the next field `args`
517+
pub arg_names: &'tcx [Pat<'tcx>],
516518
/// Expressions like `ArgumentV1::new(arg0, Debug::fmt)`
517519
pub args: &'tcx [Expr<'tcx>],
518520
/// The final argument passed to `Arguments::new_v1_formatted`, if applicable
@@ -557,13 +559,15 @@ impl FormatArgsExpn<'tcx> {
557559
_ => None,
558560
})
559561
.collect();
562+
if let PatKind::Tuple(arg_names, None) = arm.pat.kind;
560563
if let ExprKind::Array(args) = arm.body.kind;
561564
then {
562565
Some(FormatArgsExpn {
563566
format_string_span: strs_ref.span,
564567
value_args,
565568
format_string_parts,
566569
format_string_symbols,
570+
arg_names,
567571
args,
568572
fmt_expr,
569573
})
@@ -587,9 +591,15 @@ impl FormatArgsExpn<'tcx> {
587591
if let Some(position_field) = fields.iter().find(|f| f.ident.name == sym::position);
588592
if let ExprKind::Lit(lit) = &position_field.expr.kind;
589593
if let LitKind::Int(position, _) = lit.node;
594+
if let Ok(i) = usize::try_from(position);
595+
let arg = &self.args[i];
596+
if let ExprKind::Call(_, [arg_name, _]) = arg.kind;
597+
if let Some(j) = self
598+
.arg_names
599+
.iter()
600+
.position(|pat| path_to_local_id(arg_name, pat.hir_id));
590601
then {
591-
let i = usize::try_from(position).unwrap();
592-
Some(FormatArgsArg { value: self.value_args[i], arg: &self.args[i], fmt: Some(fmt) })
602+
Some(FormatArgsArg { value: self.value_args[j], arg, fmt: Some(fmt) })
593603
} else {
594604
None
595605
}

tests/ui/format_args.fixed

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![allow(unused_variables)]
66
#![allow(clippy::assertions_on_constants)]
77
#![allow(clippy::eq_op)]
8+
#![allow(clippy::print_literal)]
89
#![warn(clippy::to_string_in_format_args)]
910

1011
use std::io::{stdout, Write};
@@ -97,9 +98,20 @@ fn main() {
9798
println!("{}", Z(1));
9899
println!("{}", **x);
99100
println!("{}", ***x_ref);
101+
// https://github.com/rust-lang/rust-clippy/issues/7903
102+
println!("{foo}{bar}", foo = "foo", bar = "bar");
103+
println!("{foo}{bar}", foo = "foo", bar = "bar");
104+
println!("{foo}{bar}", bar = "bar", foo = "foo");
105+
println!("{foo}{bar}", bar = "bar", foo = "foo");
100106

107+
// negative tests
101108
println!("error: something failed at {}", Somewhere.to_string());
109+
// The next two tests are negative because caching the string might be faster than calling `<X as
110+
// Display>::fmt` twice.
102111
println!("{} and again {0}", x.to_string());
112+
println!("{foo}{foo}", foo = "foo".to_string());
103113
my_macro!();
104114
println!("error: something failed at {}", my_other_macro!());
115+
// https://github.com/rust-lang/rust-clippy/issues/7903
116+
println!("{foo}{foo:?}", foo = "foo".to_string());
105117
}

tests/ui/format_args.rs

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![allow(unused_variables)]
66
#![allow(clippy::assertions_on_constants)]
77
#![allow(clippy::eq_op)]
8+
#![allow(clippy::print_literal)]
89
#![warn(clippy::to_string_in_format_args)]
910

1011
use std::io::{stdout, Write};
@@ -97,9 +98,20 @@ fn main() {
9798
println!("{}", Z(1).to_string());
9899
println!("{}", x.to_string());
99100
println!("{}", x_ref.to_string());
101+
// https://github.com/rust-lang/rust-clippy/issues/7903
102+
println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar");
103+
println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
104+
println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
105+
println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
100106

107+
// negative tests
101108
println!("error: something failed at {}", Somewhere.to_string());
109+
// The next two tests are negative because caching the string might be faster than calling `<X as
110+
// Display>::fmt` twice.
102111
println!("{} and again {0}", x.to_string());
112+
println!("{foo}{foo}", foo = "foo".to_string());
103113
my_macro!();
104114
println!("error: something failed at {}", my_other_macro!());
115+
// https://github.com/rust-lang/rust-clippy/issues/7903
116+
println!("{foo}{foo:?}", foo = "foo".to_string());
105117
}

tests/ui/format_args.stderr

+42-18
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,130 @@
11
error: `to_string` applied to a type that implements `Display` in `format!` args
2-
--> $DIR/format_args.rs:75:72
2+
--> $DIR/format_args.rs:76:72
33
|
44
LL | let _ = format!("error: something failed at {}", Location::caller().to_string());
55
| ^^^^^^^^^^^^ help: remove this
66
|
77
= note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
88

99
error: `to_string` applied to a type that implements `Display` in `write!` args
10-
--> $DIR/format_args.rs:79:27
10+
--> $DIR/format_args.rs:80:27
1111
|
1212
LL | Location::caller().to_string()
1313
| ^^^^^^^^^^^^ help: remove this
1414

1515
error: `to_string` applied to a type that implements `Display` in `writeln!` args
16-
--> $DIR/format_args.rs:84:27
16+
--> $DIR/format_args.rs:85:27
1717
|
1818
LL | Location::caller().to_string()
1919
| ^^^^^^^^^^^^ help: remove this
2020

2121
error: `to_string` applied to a type that implements `Display` in `print!` args
22-
--> $DIR/format_args.rs:86:63
22+
--> $DIR/format_args.rs:87:63
2323
|
2424
LL | print!("error: something failed at {}", Location::caller().to_string());
2525
| ^^^^^^^^^^^^ help: remove this
2626

2727
error: `to_string` applied to a type that implements `Display` in `println!` args
28-
--> $DIR/format_args.rs:87:65
28+
--> $DIR/format_args.rs:88:65
2929
|
3030
LL | println!("error: something failed at {}", Location::caller().to_string());
3131
| ^^^^^^^^^^^^ help: remove this
3232

3333
error: `to_string` applied to a type that implements `Display` in `eprint!` args
34-
--> $DIR/format_args.rs:88:64
34+
--> $DIR/format_args.rs:89:64
3535
|
3636
LL | eprint!("error: something failed at {}", Location::caller().to_string());
3737
| ^^^^^^^^^^^^ help: remove this
3838

3939
error: `to_string` applied to a type that implements `Display` in `eprintln!` args
40-
--> $DIR/format_args.rs:89:66
40+
--> $DIR/format_args.rs:90:66
4141
|
4242
LL | eprintln!("error: something failed at {}", Location::caller().to_string());
4343
| ^^^^^^^^^^^^ help: remove this
4444

4545
error: `to_string` applied to a type that implements `Display` in `format_args!` args
46-
--> $DIR/format_args.rs:90:77
46+
--> $DIR/format_args.rs:91:77
4747
|
4848
LL | let _ = format_args!("error: something failed at {}", Location::caller().to_string());
4949
| ^^^^^^^^^^^^ help: remove this
5050

5151
error: `to_string` applied to a type that implements `Display` in `assert!` args
52-
--> $DIR/format_args.rs:91:70
52+
--> $DIR/format_args.rs:92:70
5353
|
5454
LL | assert!(true, "error: something failed at {}", Location::caller().to_string());
5555
| ^^^^^^^^^^^^ help: remove this
5656

5757
error: `to_string` applied to a type that implements `Display` in `assert_eq!` args
58-
--> $DIR/format_args.rs:92:73
58+
--> $DIR/format_args.rs:93:73
5959
|
6060
LL | assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string());
6161
| ^^^^^^^^^^^^ help: remove this
6262

6363
error: `to_string` applied to a type that implements `Display` in `assert_ne!` args
64-
--> $DIR/format_args.rs:93:73
64+
--> $DIR/format_args.rs:94:73
6565
|
6666
LL | assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string());
6767
| ^^^^^^^^^^^^ help: remove this
6868

6969
error: `to_string` applied to a type that implements `Display` in `panic!` args
70-
--> $DIR/format_args.rs:94:63
70+
--> $DIR/format_args.rs:95:63
7171
|
7272
LL | panic!("error: something failed at {}", Location::caller().to_string());
7373
| ^^^^^^^^^^^^ help: remove this
7474

7575
error: `to_string` applied to a type that implements `Display` in `println!` args
76-
--> $DIR/format_args.rs:95:20
76+
--> $DIR/format_args.rs:96:20
7777
|
7878
LL | println!("{}", X(1).to_string());
7979
| ^^^^^^^^^^^^^^^^ help: use this: `*X(1)`
8080

8181
error: `to_string` applied to a type that implements `Display` in `println!` args
82-
--> $DIR/format_args.rs:96:20
82+
--> $DIR/format_args.rs:97:20
8383
|
8484
LL | println!("{}", Y(&X(1)).to_string());
8585
| ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))`
8686

8787
error: `to_string` applied to a type that implements `Display` in `println!` args
88-
--> $DIR/format_args.rs:97:24
88+
--> $DIR/format_args.rs:98:24
8989
|
9090
LL | println!("{}", Z(1).to_string());
9191
| ^^^^^^^^^^^^ help: remove this
9292

9393
error: `to_string` applied to a type that implements `Display` in `println!` args
94-
--> $DIR/format_args.rs:98:20
94+
--> $DIR/format_args.rs:99:20
9595
|
9696
LL | println!("{}", x.to_string());
9797
| ^^^^^^^^^^^^^ help: use this: `**x`
9898

9999
error: `to_string` applied to a type that implements `Display` in `println!` args
100-
--> $DIR/format_args.rs:99:20
100+
--> $DIR/format_args.rs:100:20
101101
|
102102
LL | println!("{}", x_ref.to_string());
103103
| ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref`
104104

105-
error: aborting due to 17 previous errors
105+
error: `to_string` applied to a type that implements `Display` in `println!` args
106+
--> $DIR/format_args.rs:102:39
107+
|
108+
LL | println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar");
109+
| ^^^^^^^^^^^^ help: remove this
110+
111+
error: `to_string` applied to a type that implements `Display` in `println!` args
112+
--> $DIR/format_args.rs:103:52
113+
|
114+
LL | println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
115+
| ^^^^^^^^^^^^ help: remove this
116+
117+
error: `to_string` applied to a type that implements `Display` in `println!` args
118+
--> $DIR/format_args.rs:104:39
119+
|
120+
LL | println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
121+
| ^^^^^^^^^^^^ help: remove this
122+
123+
error: `to_string` applied to a type that implements `Display` in `println!` args
124+
--> $DIR/format_args.rs:105:52
125+
|
126+
LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
127+
| ^^^^^^^^^^^^ help: remove this
128+
129+
error: aborting due to 21 previous errors
106130

tests/ui/format_args_unfixable.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fn main() {
5151
assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller()));
5252
panic!("error: {}", format!("something failed at {}", Location::caller()));
5353

54+
// negative tests
5455
println!("error: {}", format_args!("something failed at {}", Location::caller()));
5556
println!("error: {:>70}", format!("something failed at {}", Location::caller()));
5657
println!("error: {} {0}", format!("something failed at {}", Location::caller()));

0 commit comments

Comments
 (0)