Skip to content

Commit 92f1411

Browse files
committed
Include the borrow in the suggestion for explicit_auto_deref
1 parent 8da2790 commit 92f1411

File tree

4 files changed

+98
-101
lines changed

4 files changed

+98
-101
lines changed

clippy_lints/src/dereference.rs

+34-45
Original file line numberDiff line numberDiff line change
@@ -183,24 +183,24 @@ enum State {
183183
},
184184
DerefedBorrow(DerefedBorrow),
185185
ExplicitDeref {
186-
// Span and id of the top-level deref expression if the parent expression is a borrow.
187-
deref_span_id: Option<(Span, HirId)>,
186+
mutability: Option<Mutability>,
188187
},
189188
ExplicitDerefField {
190189
name: Symbol,
191190
},
192191
Reborrow {
193-
deref_span: Span,
194-
deref_hir_id: HirId,
192+
mutability: Mutability,
193+
},
194+
Borrow {
195+
mutability: Mutability,
195196
},
196-
Borrow,
197197
}
198198

199199
// A reference operation considered by this lint pass
200200
enum RefOp {
201201
Method(Mutability),
202202
Deref,
203-
AddrOf,
203+
AddrOf(Mutability),
204204
}
205205

206206
struct RefPat {
@@ -263,7 +263,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
263263
));
264264
} else if position.is_deref_stable() {
265265
self.state = Some((
266-
State::ExplicitDeref { deref_span_id: None },
266+
State::ExplicitDeref { mutability: None },
267267
StateData { span: expr.span, hir_id: expr.hir_id, position },
268268
));
269269
}
@@ -289,7 +289,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
289289
},
290290
));
291291
},
292-
RefOp::AddrOf => {
292+
RefOp::AddrOf(mutability) => {
293293
// Find the number of times the borrow is auto-derefed.
294294
let mut iter = adjustments.iter();
295295
let mut deref_count = 0usize;
@@ -359,7 +359,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
359359
));
360360
} else if position.is_deref_stable() {
361361
self.state = Some((
362-
State::Borrow,
362+
State::Borrow { mutability },
363363
StateData {
364364
span: expr.span,
365365
hir_id: expr.hir_id,
@@ -395,7 +395,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
395395
data,
396396
));
397397
},
398-
(Some((State::DerefedBorrow(state), data)), RefOp::AddrOf) if state.count != 0 => {
398+
(Some((State::DerefedBorrow(state), data)), RefOp::AddrOf(_)) if state.count != 0 => {
399399
self.state = Some((
400400
State::DerefedBorrow(DerefedBorrow {
401401
count: state.count - 1,
@@ -404,12 +404,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
404404
data,
405405
));
406406
},
407-
(Some((State::DerefedBorrow(state), data)), RefOp::AddrOf) => {
407+
(Some((State::DerefedBorrow(state), data)), RefOp::AddrOf(mutability)) => {
408408
let position = data.position;
409409
report(cx, expr, State::DerefedBorrow(state), data);
410410
if position.is_deref_stable() {
411411
self.state = Some((
412-
State::Borrow,
412+
State::Borrow { mutability },
413413
StateData {
414414
span: expr.span,
415415
hir_id: expr.hir_id,
@@ -430,43 +430,28 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
430430
));
431431
} else if position.is_deref_stable() {
432432
self.state = Some((
433-
State::ExplicitDeref { deref_span_id: None },
433+
State::ExplicitDeref { mutability: None },
434434
StateData { span: expr.span, hir_id: expr.hir_id, position },
435435
));
436436
}
437437
},
438438

439-
(Some((State::Borrow, data)), RefOp::Deref) => {
439+
(Some((State::Borrow { mutability }, data)), RefOp::Deref) => {
440440
if typeck.expr_ty(sub_expr).is_ref() {
441-
self.state = Some((
442-
State::Reborrow {
443-
deref_span: expr.span,
444-
deref_hir_id: expr.hir_id,
445-
},
446-
data,
447-
));
441+
self.state = Some((State::Reborrow { mutability }, data));
448442
} else {
449443
self.state = Some((
450444
State::ExplicitDeref {
451-
deref_span_id: Some((expr.span, expr.hir_id)),
445+
mutability: Some(mutability),
452446
},
453447
data,
454448
));
455449
}
456450
},
457-
(
458-
Some((
459-
State::Reborrow {
460-
deref_span,
461-
deref_hir_id,
462-
},
463-
data,
464-
)),
465-
RefOp::Deref,
466-
) => {
451+
(Some((State::Reborrow { mutability }, data)), RefOp::Deref) => {
467452
self.state = Some((
468453
State::ExplicitDeref {
469-
deref_span_id: Some((deref_span, deref_hir_id)),
454+
mutability: Some(mutability),
470455
},
471456
data,
472457
));
@@ -573,7 +558,7 @@ fn try_parse_ref_op<'tcx>(
573558
ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_unsafe_ptr() => {
574559
return Some((RefOp::Deref, sub_expr));
575560
},
576-
ExprKind::AddrOf(BorrowKind::Ref, _, sub_expr) => return Some((RefOp::AddrOf, sub_expr)),
561+
ExprKind::AddrOf(BorrowKind::Ref, mutability, sub_expr) => return Some((RefOp::AddrOf(mutability), sub_expr)),
577562
_ => return None,
578563
};
579564
if tcx.is_diagnostic_item(sym::deref_method, def_id) {
@@ -1074,7 +1059,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
10741059
diag.span_suggestion(data.span, "change this to", sugg, app);
10751060
});
10761061
},
1077-
State::ExplicitDeref { deref_span_id } => {
1062+
State::ExplicitDeref { mutability } => {
10781063
if matches!(
10791064
expr.kind,
10801065
ExprKind::Block(..)
@@ -1088,29 +1073,33 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
10881073
return;
10891074
}
10901075

1091-
let (span, hir_id, precedence) = if let Some((span, hir_id)) = deref_span_id
1076+
let (prefix, precedence) = if let Some(mutability) = mutability
10921077
&& !cx.typeck_results().expr_ty(expr).is_ref()
10931078
{
1094-
(span, hir_id, PREC_PREFIX)
1079+
let prefix = match mutability {
1080+
Mutability::Not => "&",
1081+
Mutability::Mut => "&mut ",
1082+
};
1083+
(prefix, 0)
10951084
} else {
1096-
(data.span, data.hir_id, data.position.precedence())
1085+
("", data.position.precedence())
10971086
};
10981087
span_lint_hir_and_then(
10991088
cx,
11001089
EXPLICIT_AUTO_DEREF,
1101-
hir_id,
1102-
span,
1090+
data.hir_id,
1091+
data.span,
11031092
"deref which would be done by auto-deref",
11041093
|diag| {
11051094
let mut app = Applicability::MachineApplicable;
1106-
let (snip, snip_is_macro) = snippet_with_context(cx, expr.span, span.ctxt(), "..", &mut app);
1095+
let (snip, snip_is_macro) = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app);
11071096
let sugg =
11081097
if !snip_is_macro && expr.precedence().order() < precedence && !has_enclosing_paren(&snip) {
1109-
format!("({})", snip)
1098+
format!("{}({})", prefix, snip)
11101099
} else {
1111-
snip.into()
1100+
format!("{}{}", prefix, snip)
11121101
};
1113-
diag.span_suggestion(span, "try this", sugg, app);
1102+
diag.span_suggestion(data.span, "try this", sugg, app);
11141103
},
11151104
);
11161105
},
@@ -1141,7 +1130,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
11411130
},
11421131
);
11431132
},
1144-
State::Borrow | State::Reborrow { .. } => (),
1133+
State::Borrow { .. } | State::Reborrow { .. } => (),
11451134
}
11461135
}
11471136

tests/ui/explicit_auto_deref.fixed

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ fn main() {
6868

6969
let _: &str = &s;
7070
let _: &str = &{ String::new() };
71+
let _: &str = &mut { String::new() };
7172
let _ = &*s; // Don't lint. Inferred type would change.
7273
let _: &_ = &*s; // Don't lint. Inferred type would change.
7374

tests/ui/explicit_auto_deref.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ fn main() {
6868

6969
let _: &str = &*s;
7070
let _: &str = &*{ String::new() };
71+
let _: &str = &mut *{ String::new() };
7172
let _ = &*s; // Don't lint. Inferred type would change.
7273
let _: &_ = &*s; // Don't lint. Inferred type would change.
7374

0 commit comments

Comments
 (0)