Skip to content

Commit 11fadcf

Browse files
committed
Fix macro expansion in toplevel_ref_arg lint
1 parent 3b9e5df commit 11fadcf

File tree

3 files changed

+26
-14
lines changed

3 files changed

+26
-14
lines changed

clippy_lints/src/misc.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -261,36 +261,40 @@ 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
};
282286
span_lint_hir_and_then(cx,
283287
TOPLEVEL_REF_ARG,
284288
init.hir_id,
285-
l.pat.span,
289+
local.pat.span,
286290
"`ref` on an entire `let` pattern is discouraged, take a reference with `&` instead",
287291
|db| {
288292
db.span_suggestion(
289-
s.span,
293+
stmt.span,
290294
"try",
291295
format!(
292296
"let {name}{tyopt} = {initref};",
293-
name=snippet(cx, i.span, "_"),
297+
name=snippet(cx, name.span, "_"),
294298
tyopt=tyopt,
295299
initref=initref,
296300
),
@@ -302,19 +306,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
302306
}
303307
};
304308
if_chain! {
305-
if let StmtKind::Semi(ref expr) = s.node;
309+
if let StmtKind::Semi(ref expr) = stmt.node;
306310
if let ExprKind::Binary(ref binop, ref a, ref b) = expr.node;
307311
if binop.node == BinOpKind::And || binop.node == BinOpKind::Or;
308312
if let Some(sugg) = Sugg::hir_opt(cx, a);
309313
then {
310314
span_lint_and_then(cx,
311315
SHORT_CIRCUIT_STATEMENT,
312-
s.span,
316+
stmt.span,
313317
"boolean short circuit operator in statement may be clearer using an explicit test",
314318
|db| {
315319
let sugg = if binop.node == BinOpKind::Or { !sugg } else { sugg };
316320
db.span_suggestion(
317-
s.span,
321+
stmt.span,
318322
"replace it with",
319323
format!(
320324
"if {} {{ {}; }}",

tests/ui/toplevel_ref_arg.fixed

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ fn main() {
1919
let (ref x, _) = (1, 2); // ok, not top level
2020
println!("The answer is {}.", x);
2121

22+
let x = &vec![1, 2, 3];
23+
2224
// Make sure that allowing the lint works
2325
#[allow(clippy::toplevel_ref_arg)]
2426
let ref mut x = 1_234_543;

tests/ui/toplevel_ref_arg.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,11 @@ error: `ref` on an entire `let` pattern is discouraged, take a reference with `&
2424
LL | let ref mut z = 1 + 2;
2525
| ----^^^^^^^^^--------- 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:22: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)