From 5eca09793e9e6969ce960601d83300e1d6065d97 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 27 May 2016 12:12:38 +0200 Subject: [PATCH] needless_borrow reported on &&T when only &T implements Trait and &Trait is required --- src/needless_borrow.rs | 17 +++++++++-------- tests/compile-fail/needless_borrow.rs | 7 +++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/needless_borrow.rs b/src/needless_borrow.rs index 294a12dad..033811841 100644 --- a/src/needless_borrow.rs +++ b/src/needless_borrow.rs @@ -3,9 +3,10 @@ //! This lint is **warn** by default use rustc::lint::*; -use rustc::hir::*; +use rustc::hir::{ExprAddrOf, Expr, MutImmutable}; use rustc::ty::TyRef; use utils::{span_lint, in_macro}; +use rustc::ty::adjustment::AutoAdjustment::AdjustDerefRef; /// **What it does:** This lint checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler /// @@ -36,13 +37,13 @@ impl LateLintPass for NeedlessBorrow { } if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let TyRef(..) = cx.tcx.expr_ty(inner).sty { - let ty = cx.tcx.expr_ty(e); - let adj_ty = cx.tcx.expr_ty_adjusted(e); - if ty != adj_ty { - span_lint(cx, - NEEDLESS_BORROW, - e.span, - "this expression borrows a reference that is immediately dereferenced by the compiler"); + if let Some(&AdjustDerefRef(ref deref)) = cx.tcx.tables.borrow().adjustments.get(&e.id) { + if deref.autoderefs > 1 && deref.autoref.is_some() { + span_lint(cx, + NEEDLESS_BORROW, + e.span, + "this expression borrows a reference that is immediately dereferenced by the compiler"); + } } } } diff --git a/tests/compile-fail/needless_borrow.rs b/tests/compile-fail/needless_borrow.rs index 242691aa2..602e1e085 100644 --- a/tests/compile-fail/needless_borrow.rs +++ b/tests/compile-fail/needless_borrow.rs @@ -16,6 +16,7 @@ fn main() { let g_val = g(&Vec::new()); // should not error, because `&Vec` derefs to `&[T]` let vec = Vec::new(); let vec_val = g(&vec); // should not error, because `&Vec` derefs to `&[T]` + h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait` } fn f(y: &T) -> T { @@ -25,3 +26,9 @@ fn f(y: &T) -> T { fn g(y: &[u8]) -> u8 { y[0] } + +trait Trait {} + +impl<'a> Trait for &'a str {} + +fn h(_: &Trait) {}