Skip to content

Commit 87faaec

Browse files
committed
add needless_borrow lint
1 parent d70e7bb commit 87faaec

File tree

6 files changed

+84
-1
lines changed

6 files changed

+84
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ All notable changes to this project will be documented in this file.
149149
[`mutex_atomic`]: https://github.com/Manishearth/rust-clippy/wiki#mutex_atomic
150150
[`mutex_integer`]: https://github.com/Manishearth/rust-clippy/wiki#mutex_integer
151151
[`needless_bool`]: https://github.com/Manishearth/rust-clippy/wiki#needless_bool
152+
[`needless_borrow`]: https://github.com/Manishearth/rust-clippy/wiki#needless_borrow
152153
[`needless_lifetimes`]: https://github.com/Manishearth/rust-clippy/wiki#needless_lifetimes
153154
[`needless_range_loop`]: https://github.com/Manishearth/rust-clippy/wiki#needless_range_loop
154155
[`needless_return`]: https://github.com/Manishearth/rust-clippy/wiki#needless_return

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Table of contents:
1717

1818
## Lints
1919

20-
There are 146 lints included in this crate:
20+
There are 147 lints included in this crate:
2121

2222
name | default | meaning
2323
---------------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -97,6 +97,7 @@ name
9797
[mutex_atomic](https://github.com/Manishearth/rust-clippy/wiki#mutex_atomic) | warn | using a Mutex where an atomic value could be used instead
9898
[mutex_integer](https://github.com/Manishearth/rust-clippy/wiki#mutex_integer) | allow | using a Mutex for an integer type
9999
[needless_bool](https://github.com/Manishearth/rust-clippy/wiki#needless_bool) | warn | if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`
100+
[needless_borrow](https://github.com/Manishearth/rust-clippy/wiki#needless_borrow) | warn | taking a reference that is going to be automatically dereferenced
100101
[needless_lifetimes](https://github.com/Manishearth/rust-clippy/wiki#needless_lifetimes) | warn | using explicit lifetimes for references in function arguments when elision rules would allow omitting them
101102
[needless_range_loop](https://github.com/Manishearth/rust-clippy/wiki#needless_range_loop) | warn | for-looping over a range of indices where an iterator over items would do
102103
[needless_return](https://github.com/Manishearth/rust-clippy/wiki#needless_return) | warn | using a return statement like `return expr;` where an expression would suffice

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub mod mut_mut;
9696
pub mod mut_reference;
9797
pub mod mutex_atomic;
9898
pub mod needless_bool;
99+
pub mod needless_borrow;
99100
pub mod needless_update;
100101
pub mod neg_multiply;
101102
pub mod new_without_default;
@@ -210,6 +211,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
210211
reg.register_late_lint_pass(box zero_div_zero::ZeroDivZeroPass);
211212
reg.register_late_lint_pass(box mutex_atomic::MutexAtomic);
212213
reg.register_late_lint_pass(box needless_update::NeedlessUpdatePass);
214+
reg.register_late_lint_pass(box needless_borrow::NeedlessBorrow);
213215
reg.register_late_lint_pass(box no_effect::NoEffectPass);
214216
reg.register_late_lint_pass(box map_clone::MapClonePass);
215217
reg.register_late_lint_pass(box temporary_assignment::TemporaryAssignmentPass);
@@ -364,6 +366,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
364366
mutex_atomic::MUTEX_ATOMIC,
365367
needless_bool::BOOL_COMPARISON,
366368
needless_bool::NEEDLESS_BOOL,
369+
needless_borrow::NEEDLESS_BORROW,
367370
needless_update::NEEDLESS_UPDATE,
368371
neg_multiply::NEG_MULTIPLY,
369372
new_without_default::NEW_WITHOUT_DEFAULT,

src/needless_borrow.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//! Checks for needless address of operations (`&`)
2+
//!
3+
//! This lint is **warn** by default
4+
5+
use rustc::lint::*;
6+
use rustc::hir::*;
7+
use rustc::ty::TyRef;
8+
use utils::{span_lint, in_macro};
9+
10+
/// **What it does:** This lint checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler
11+
///
12+
/// **Why is this bad?** Suggests that the receiver of the expression borrows the expression
13+
///
14+
/// **Known problems:**
15+
///
16+
/// **Example:** `let x: &i32 = &&&&&&5;`
17+
declare_lint! {
18+
pub NEEDLESS_BORROW,
19+
Warn,
20+
"taking a reference that is going to be automatically dereferenced"
21+
}
22+
23+
#[derive(Copy,Clone)]
24+
pub struct NeedlessBorrow;
25+
26+
impl LintPass for NeedlessBorrow {
27+
fn get_lints(&self) -> LintArray {
28+
lint_array!(NEEDLESS_BORROW)
29+
}
30+
}
31+
32+
impl LateLintPass for NeedlessBorrow {
33+
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
34+
if in_macro(cx, e.span) {
35+
return;
36+
}
37+
if let ExprAddrOf(MutImmutable, ref inner) = e.node {
38+
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");
46+
}
47+
}
48+
}
49+
}
50+
}

tests/compile-fail/eta.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fn main() {
1818
//~| SUGGESTION let c = Some(1u8).map({1+2; foo});
1919
let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
2020
all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
21+
//~^ WARN needless_borrow
2122
unsafe {
2223
Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn
2324
}

tests/compile-fail/needless_borrow.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![feature(plugin)]
2+
#![plugin(clippy)]
3+
4+
fn x(y: &i32) -> i32 {
5+
*y
6+
}
7+
8+
#[deny(clippy)]
9+
#[allow(unused_variables)]
10+
fn main() {
11+
let a = 5;
12+
let b = x(&a);
13+
let c = x(&&a); //~ ERROR: needless_borrow
14+
let s = &String::from("hi");
15+
let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not
16+
let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`
17+
let vec = Vec::new();
18+
let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`
19+
}
20+
21+
fn f<T:Copy>(y: &T) -> T {
22+
*y
23+
}
24+
25+
fn g(y: &[u8]) -> u8 {
26+
y[0]
27+
}

0 commit comments

Comments
 (0)