Skip to content

Commit ee22f0e

Browse files
committed
allow & &* (&T)
1 parent 0eaff09 commit ee22f0e

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

clippy_lints/src/needless_deref.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ declare_clippy_lint! {
1919
/// if you want to deref explicitly, `&** (&T)` is what you need.
2020
/// If you want to reborrow, `&T` is enough (`&T` is Copy).
2121
///
22+
/// ### Known problems
23+
/// false negative on such code:
24+
/// ```
25+
/// let x = &12;
26+
/// let addr_x = &x as *const _ as usize;
27+
/// let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggerd.
28+
/// // But if we apply it, it will assert fail.
29+
/// assert_ne!(addr_x, addr_y);
30+
/// ```
31+
///
2232
/// ### Example
2333
/// ```rust
2434
/// let s = &String::new();
@@ -60,7 +70,7 @@ impl LateLintPass<'_> for NeedlessDeref {
6070
if matches!(deref_expr.kind, ExprKind::Path(..)) {
6171
let parent_node = map.find(parent_hir_id);
6272
if let Some(rustc_hir::Node::Expr(parent_expr)) = parent_node {
63-
if matches!(parent_expr.kind, ExprKind::AddrOf(..)) {
73+
if matches!(parent_expr.kind, ExprKind::AddrOf(_, Mutability::Mut, _)) {
6474
return;
6575
}
6676
if matches!(parent_expr.kind, ExprKind::Unary(UnOp::Deref, ..)) &&
@@ -73,8 +83,8 @@ impl LateLintPass<'_> for NeedlessDeref {
7383

7484
let mut give_2_help = true;
7585

76-
// if has deref trait, give 2 help
77-
// if has no deref trait, give 1 help
86+
// has deref trait -> give 2 help
87+
// doesn't have deref trait -> give 1 help
7888
if let Some(deref_trait_id) = cx.tcx.lang_items().deref_trait(){
7989
if !implements_trait(cx, inner_ty, deref_trait_id, &[]) {
8090
give_2_help = false;

tests/ui/needless_deref.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mod should_not_lint1 {
3434
}
3535

3636
// this mod explains why we should not lint `& &* (&T)`
37-
mod should_not_lint2 {
37+
mod false_negative {
3838
fn foo() {
3939
let x = &12;
4040
let addr_x = &x as *const _ as usize;

tests/ui/needless_deref.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,13 @@ LL | let b = &mut &*bar(a);
2424
|
2525
= help: consider using `bar(a)` if you would like to reborrow
2626

27-
error: aborting due to 3 previous errors
27+
error: deref on an immutable reference
28+
--> $DIR/needless_deref.rs:41:23
29+
|
30+
LL | let addr_y = &&*x as *const _ as usize; // assert ok
31+
| ^^^
32+
|
33+
= help: consider using `x` if you would like to reborrow
34+
35+
error: aborting due to 4 previous errors
2836

0 commit comments

Comments
 (0)