Skip to content

Commit ef46015

Browse files
committed
Merge pull request #957 from oli-obk/needs_borrow
needless_borrow reported on &&T when only &T implements Trait and &Trait is required
2 parents 8ac545d + 5eca097 commit ef46015

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

src/needless_borrow.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
//! This lint is **warn** by default
44
55
use rustc::lint::*;
6-
use rustc::hir::*;
6+
use rustc::hir::{ExprAddrOf, Expr, MutImmutable};
77
use rustc::ty::TyRef;
88
use utils::{span_lint, in_macro};
9+
use rustc::ty::adjustment::AutoAdjustment::AdjustDerefRef;
910

1011
/// **What it does:** This lint checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler
1112
///
@@ -36,13 +37,13 @@ impl LateLintPass for NeedlessBorrow {
3637
}
3738
if let ExprAddrOf(MutImmutable, ref inner) = e.node {
3839
if let TyRef(..) = cx.tcx.expr_ty(inner).sty {
39-
let ty = cx.tcx.expr_ty(e);
40-
let adj_ty = cx.tcx.expr_ty_adjusted(e);
41-
if ty != adj_ty {
42-
span_lint(cx,
43-
NEEDLESS_BORROW,
44-
e.span,
45-
"this expression borrows a reference that is immediately dereferenced by the compiler");
40+
if let Some(&AdjustDerefRef(ref deref)) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
41+
if deref.autoderefs > 1 && deref.autoref.is_some() {
42+
span_lint(cx,
43+
NEEDLESS_BORROW,
44+
e.span,
45+
"this expression borrows a reference that is immediately dereferenced by the compiler");
46+
}
4647
}
4748
}
4849
}

tests/compile-fail/needless_borrow.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fn main() {
1616
let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`
1717
let vec = Vec::new();
1818
let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`
19+
h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait`
1920
}
2021

2122
fn f<T:Copy>(y: &T) -> T {
@@ -25,3 +26,9 @@ fn f<T:Copy>(y: &T) -> T {
2526
fn g(y: &[u8]) -> u8 {
2627
y[0]
2728
}
29+
30+
trait Trait {}
31+
32+
impl<'a> Trait for &'a str {}
33+
34+
fn h(_: &Trait) {}

0 commit comments

Comments
 (0)