Skip to content

Commit bc1b04b

Browse files
committed
Auto merge of #4570 - lzutao:call_site_toplevel_ref_arg, r=phansch
Fix macro expansion in toplevel_ref_arg lint changelog: Fix macro expansion in toplevel_ref_arg lint
2 parents 1366629 + 5639639 commit bc1b04b

File tree

4 files changed

+53
-40
lines changed

4 files changed

+53
-40
lines changed

clippy_lints/src/misc.rs

+20-15
Original file line numberDiff line numberDiff line change
@@ -261,60 +261,65 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
261261
}
262262
}
263263

264-
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, s: &'tcx Stmt) {
264+
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
265265
if_chain! {
266-
if let StmtKind::Local(ref l) = s.node;
267-
if let PatKind::Binding(an, .., i, None) = l.pat.node;
268-
if let Some(ref init) = l.init;
266+
if let StmtKind::Local(ref local) = stmt.node;
267+
if let PatKind::Binding(an, .., name, None) = local.pat.node;
268+
if let Some(ref init) = local.init;
269269
then {
270270
if an == BindingAnnotation::Ref || an == BindingAnnotation::RefMut {
271-
let sugg_init = Sugg::hir(cx, init, "..");
272-
let (mutopt,initref) = if an == BindingAnnotation::RefMut {
271+
let sugg_init = if init.span.from_expansion() {
272+
Sugg::hir_with_macro_callsite(cx, init, "..")
273+
} else {
274+
Sugg::hir(cx, init, "..")
275+
};
276+
let (mutopt, initref) = if an == BindingAnnotation::RefMut {
273277
("mut ", sugg_init.mut_addr())
274278
} else {
275279
("", sugg_init.addr())
276280
};
277-
let tyopt = if let Some(ref ty) = l.ty {
281+
let tyopt = if let Some(ref ty) = local.ty {
278282
format!(": &{mutopt}{ty}", mutopt=mutopt, ty=snippet(cx, ty.span, "_"))
279283
} else {
280284
String::new()
281285
};
282-
span_lint_hir_and_then(cx,
286+
span_lint_hir_and_then(
287+
cx,
283288
TOPLEVEL_REF_ARG,
284289
init.hir_id,
285-
l.pat.span,
290+
local.pat.span,
286291
"`ref` on an entire `let` pattern is discouraged, take a reference with `&` instead",
287292
|db| {
288293
db.span_suggestion(
289-
s.span,
294+
stmt.span,
290295
"try",
291296
format!(
292297
"let {name}{tyopt} = {initref};",
293-
name=snippet(cx, i.span, "_"),
298+
name=snippet(cx, name.span, "_"),
294299
tyopt=tyopt,
295300
initref=initref,
296301
),
297-
Applicability::MachineApplicable, // snippet
302+
Applicability::MachineApplicable,
298303
);
299304
}
300305
);
301306
}
302307
}
303308
};
304309
if_chain! {
305-
if let StmtKind::Semi(ref expr) = s.node;
310+
if let StmtKind::Semi(ref expr) = stmt.node;
306311
if let ExprKind::Binary(ref binop, ref a, ref b) = expr.node;
307312
if binop.node == BinOpKind::And || binop.node == BinOpKind::Or;
308313
if let Some(sugg) = Sugg::hir_opt(cx, a);
309314
then {
310315
span_lint_and_then(cx,
311316
SHORT_CIRCUIT_STATEMENT,
312-
s.span,
317+
stmt.span,
313318
"boolean short circuit operator in statement may be clearer using an explicit test",
314319
|db| {
315320
let sugg = if binop.node == BinOpKind::Or { !sugg } else { sugg };
316321
db.span_suggestion(
317-
s.span,
322+
stmt.span,
318323
"replace it with",
319324
format!(
320325
"if {} {{ {}; }}",

tests/ui/toplevel_ref_arg.fixed

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
// run-rustfix
22

33
#![warn(clippy::toplevel_ref_arg)]
4-
#![allow(unused)]
54

65
fn main() {
76
// Closures should not warn
87
let y = |ref x| println!("{:?}", x);
98
y(1u8);
109

11-
let x = &1;
10+
let _x = &1;
1211

13-
let y: &(&_, u8) = &(&1, 2);
12+
let _y: &(&_, u8) = &(&1, 2);
1413

15-
let z = &(1 + 2);
14+
let _z = &(1 + 2);
1615

17-
let z = &mut (1 + 2);
16+
let _z = &mut (1 + 2);
1817

1918
let (ref x, _) = (1, 2); // ok, not top level
2019
println!("The answer is {}.", x);
2120

21+
let _x = &vec![1, 2, 3];
22+
2223
// Make sure that allowing the lint works
2324
#[allow(clippy::toplevel_ref_arg)]
24-
let ref mut x = 1_234_543;
25+
let ref mut _x = 1_234_543;
2526
}

tests/ui/toplevel_ref_arg.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
// run-rustfix
22

33
#![warn(clippy::toplevel_ref_arg)]
4-
#![allow(unused)]
54

65
fn main() {
76
// Closures should not warn
87
let y = |ref x| println!("{:?}", x);
98
y(1u8);
109

11-
let ref x = 1;
10+
let ref _x = 1;
1211

13-
let ref y: (&_, u8) = (&1, 2);
12+
let ref _y: (&_, u8) = (&1, 2);
1413

15-
let ref z = 1 + 2;
14+
let ref _z = 1 + 2;
1615

17-
let ref mut z = 1 + 2;
16+
let ref mut _z = 1 + 2;
1817

1918
let (ref x, _) = (1, 2); // ok, not top level
2019
println!("The answer is {}.", x);
2120

21+
let ref _x = vec![1, 2, 3];
22+
2223
// Make sure that allowing the lint works
2324
#[allow(clippy::toplevel_ref_arg)]
24-
let ref mut x = 1_234_543;
25+
let ref mut _x = 1_234_543;
2526
}

tests/ui/toplevel_ref_arg.stderr

+19-13
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
2-
--> $DIR/toplevel_ref_arg.rs:11:9
2+
--> $DIR/toplevel_ref_arg.rs:10:9
33
|
4-
LL | let ref x = 1;
5-
| ----^^^^^----- help: try: `let x = &1;`
4+
LL | let ref _x = 1;
5+
| ----^^^^^^----- help: try: `let _x = &1;`
66
|
77
= note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`
88

99
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
10-
--> $DIR/toplevel_ref_arg.rs:13:9
10+
--> $DIR/toplevel_ref_arg.rs:12:9
1111
|
12-
LL | let ref y: (&_, u8) = (&1, 2);
13-
| ----^^^^^--------------------- help: try: `let y: &(&_, u8) = &(&1, 2);`
12+
LL | let ref _y: (&_, u8) = (&1, 2);
13+
| ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);`
1414

1515
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
16-
--> $DIR/toplevel_ref_arg.rs:15:9
16+
--> $DIR/toplevel_ref_arg.rs:14:9
1717
|
18-
LL | let ref z = 1 + 2;
19-
| ----^^^^^--------- help: try: `let z = &(1 + 2);`
18+
LL | let ref _z = 1 + 2;
19+
| ----^^^^^^--------- help: try: `let _z = &(1 + 2);`
2020

2121
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
22-
--> $DIR/toplevel_ref_arg.rs:17:9
22+
--> $DIR/toplevel_ref_arg.rs:16:9
2323
|
24-
LL | let ref mut z = 1 + 2;
25-
| ----^^^^^^^^^--------- help: try: `let z = &mut (1 + 2);`
24+
LL | let ref mut _z = 1 + 2;
25+
| ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);`
2626

27-
error: aborting due to 4 previous errors
27+
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
28+
--> $DIR/toplevel_ref_arg.rs:21:9
29+
|
30+
LL | let ref _x = vec![1, 2, 3];
31+
| ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];`
32+
33+
error: aborting due to 5 previous errors
2834

0 commit comments

Comments
 (0)