diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index efe3237990d..2dfb947b5eb 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -1,3 +1,4 @@ +use crate::utils::sugg::Sugg; use crate::utils::{in_macro, snippet_opt, snippet_with_applicability, span_lint_and_sugg}; use if_chain::if_chain; use rustc_ast::ast::{Expr, ExprKind, Mutability, UnOp}; @@ -124,14 +125,19 @@ impl EarlyLintPass for RefInDeref { if let ExprKind::Paren(ref parened) = object.kind; if let ExprKind::AddrOf(_, _, ref inner) = parened.kind; then { - let mut applicability = Applicability::MachineApplicable; + let applicability = if inner.span.from_expansion() { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + }; + let sugg = Sugg::ast(cx, inner, "_").maybe_par(); span_lint_and_sugg( cx, REF_IN_DEREF, object.span, "creating a reference that is immediately dereferenced", "try this", - snippet_with_applicability(cx, inner.span, "_", &mut applicability).to_string(), + sugg.to_string(), applicability, ); } diff --git a/tests/ui/unnecessary_ref.fixed b/tests/ui/unnecessary_ref.fixed index f7b94118d4e..d927bae976f 100644 --- a/tests/ui/unnecessary_ref.fixed +++ b/tests/ui/unnecessary_ref.fixed @@ -1,7 +1,7 @@ // run-rustfix #![feature(stmt_expr_attributes)] -#![allow(unused_variables)] +#![allow(unused_variables, dead_code)] struct Outer { inner: u32, @@ -12,3 +12,12 @@ fn main() { let outer = Outer { inner: 0 }; let inner = outer.inner; } + +struct Apple; +impl Apple { + fn hello(&self) {} +} +struct Package(pub *const Apple); +fn foobar(package: *const Package) { + unsafe { &*(*package).0 }.hello(); +} diff --git a/tests/ui/unnecessary_ref.rs b/tests/ui/unnecessary_ref.rs index 4e585b9b96b..86bfb76ec26 100644 --- a/tests/ui/unnecessary_ref.rs +++ b/tests/ui/unnecessary_ref.rs @@ -1,7 +1,7 @@ // run-rustfix #![feature(stmt_expr_attributes)] -#![allow(unused_variables)] +#![allow(unused_variables, dead_code)] struct Outer { inner: u32, @@ -12,3 +12,12 @@ fn main() { let outer = Outer { inner: 0 }; let inner = (&outer).inner; } + +struct Apple; +impl Apple { + fn hello(&self) {} +} +struct Package(pub *const Apple); +fn foobar(package: *const Package) { + unsafe { &*(&*package).0 }.hello(); +} diff --git a/tests/ui/unnecessary_ref.stderr b/tests/ui/unnecessary_ref.stderr index d0a0f219097..436f4bcf738 100644 --- a/tests/ui/unnecessary_ref.stderr +++ b/tests/ui/unnecessary_ref.stderr @@ -10,5 +10,13 @@ note: the lint level is defined here LL | #[deny(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: creating a reference that is immediately dereferenced + --> $DIR/unnecessary_ref.rs:22:16 + | +LL | unsafe { &*(&*package).0 }.hello(); + | ^^^^^^^^^^^ help: try this: `(*package)` + | + = note: `-D clippy::ref-in-deref` implied by `-D warnings` + +error: aborting due to 2 previous errors