Merge pull request #957 from oli-obk/needs_borrow

needless_borrow reported on &&T when only &T implements Trait and &Trait is required
This commit is contained in:
Martin Carton 2016-05-27 12:26:00 +02:00
commit ef46015151
2 changed files with 16 additions and 8 deletions

View file

@ -3,9 +3,10 @@
//! This lint is **warn** by default //! This lint is **warn** by default
use rustc::lint::*; use rustc::lint::*;
use rustc::hir::*; use rustc::hir::{ExprAddrOf, Expr, MutImmutable};
use rustc::ty::TyRef; use rustc::ty::TyRef;
use utils::{span_lint, in_macro}; 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 /// **What it does:** This lint checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler
/// ///
@ -36,9 +37,8 @@ impl LateLintPass for NeedlessBorrow {
} }
if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let ExprAddrOf(MutImmutable, ref inner) = e.node {
if let TyRef(..) = cx.tcx.expr_ty(inner).sty { if let TyRef(..) = cx.tcx.expr_ty(inner).sty {
let ty = cx.tcx.expr_ty(e); if let Some(&AdjustDerefRef(ref deref)) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
let adj_ty = cx.tcx.expr_ty_adjusted(e); if deref.autoderefs > 1 && deref.autoref.is_some() {
if ty != adj_ty {
span_lint(cx, span_lint(cx,
NEEDLESS_BORROW, NEEDLESS_BORROW,
e.span, e.span,
@ -48,3 +48,4 @@ impl LateLintPass for NeedlessBorrow {
} }
} }
} }
}

View file

@ -16,6 +16,7 @@ fn main() {
let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]` let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`
let vec = Vec::new(); let vec = Vec::new();
let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]` let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`
h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait`
} }
fn f<T:Copy>(y: &T) -> T { fn f<T:Copy>(y: &T) -> T {
@ -25,3 +26,9 @@ fn f<T:Copy>(y: &T) -> T {
fn g(y: &[u8]) -> u8 { fn g(y: &[u8]) -> u8 {
y[0] y[0]
} }
trait Trait {}
impl<'a> Trait for &'a str {}
fn h(_: &Trait) {}