mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 01:34:21 +00:00
Merge pull request #1861 from CBenoit/master
Add example for needless borrowed ref lint and register it
This commit is contained in:
commit
23bc6508bb
@ -264,6 +264,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
||||
reg.register_late_lint_pass(box mutex_atomic::MutexAtomic);
|
||||
reg.register_late_lint_pass(box needless_update::Pass);
|
||||
reg.register_late_lint_pass(box needless_borrow::NeedlessBorrow);
|
||||
reg.register_late_lint_pass(box needless_borrowed_ref::NeedlessBorrowedRef);
|
||||
reg.register_late_lint_pass(box no_effect::Pass);
|
||||
reg.register_late_lint_pass(box map_clone::Pass);
|
||||
reg.register_late_lint_pass(box temporary_assignment::Pass);
|
||||
|
@ -4,16 +4,31 @@
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::hir::{MutImmutable, Pat, PatKind, BindingAnnotation};
|
||||
use rustc::ty;
|
||||
use utils::{span_lint, in_macro};
|
||||
use utils::{span_lint_and_then, in_macro, snippet};
|
||||
|
||||
/// **What it does:** Checks for useless borrowed references.
|
||||
///
|
||||
/// **Why is this bad?** It is completely useless and make the code look more
|
||||
/// complex than it
|
||||
/// **Why is this bad?** It is mostly useless and make the code look more complex than it
|
||||
/// actually is.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
/// **Known problems:** It seems that the `&ref` pattern is sometimes useful.
|
||||
/// For instance in the following snippet:
|
||||
/// ```rust
|
||||
/// enum Animal {
|
||||
/// Cat(u64),
|
||||
/// Dog(u64),
|
||||
/// }
|
||||
///
|
||||
/// fn foo(a: &Animal, b: &Animal) {
|
||||
/// match (a, b) {
|
||||
/// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime mismatch error
|
||||
/// (&Animal::Dog(ref c), &Animal::Dog(_)) => ()
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// There is a lifetime mismatch error for `k` (indeed a and b have distinct lifetime).
|
||||
/// This can be fixed by using the `&ref` pattern.
|
||||
/// However, the code can also be fixed by much cleaner ways
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
@ -47,15 +62,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrowedRef {
|
||||
}
|
||||
|
||||
if_let_chain! {[
|
||||
// Pat is a pattern whose node
|
||||
// is a binding which "involves" a immutable reference...
|
||||
let PatKind::Binding(BindingAnnotation::Ref, ..) = pat.node,
|
||||
// Pattern's type is a reference. Get the type and mutability of referenced value (tam: TypeAndMut).
|
||||
let ty::TyRef(_, ref tam) = cx.tables.pat_ty(pat).sty,
|
||||
// This is an immutable reference.
|
||||
tam.mutbl == MutImmutable,
|
||||
// Only lint immutable refs, because `&mut ref T` may be useful.
|
||||
let PatKind::Ref(ref sub_pat, MutImmutable) = pat.node,
|
||||
|
||||
// Check sub_pat got a `ref` keyword (excluding `ref mut`).
|
||||
let PatKind::Binding(BindingAnnotation::Ref, _, spanned_name, ..) = sub_pat.node,
|
||||
], {
|
||||
span_lint(cx, NEEDLESS_BORROWED_REFERENCE, pat.span, "this pattern takes a reference on something that is being de-referenced")
|
||||
span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, pat.span,
|
||||
"this pattern takes a reference on something that is being de-referenced",
|
||||
|db| {
|
||||
let hint = snippet(cx, spanned_name.span, "..").into_owned();
|
||||
db.span_suggestion(pat.span, "try removing the `&ref` part and just keep", hint);
|
||||
});
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
48
clippy_tests/examples/needless_borrowed_ref.rs
Normal file
48
clippy_tests/examples/needless_borrowed_ref.rs
Normal file
@ -0,0 +1,48 @@
|
||||
#![feature(plugin)]
|
||||
#![plugin(clippy)]
|
||||
|
||||
#[warn(needless_borrowed_reference)]
|
||||
#[allow(unused_variables)]
|
||||
fn main() {
|
||||
let mut v = Vec::<String>::new();
|
||||
let _ = v.iter_mut().filter(|&ref a| a.is_empty());
|
||||
// ^ should be linted
|
||||
|
||||
let var = 3;
|
||||
let thingy = Some(&var);
|
||||
if let Some(&ref v) = thingy {
|
||||
// ^ should be linted
|
||||
}
|
||||
|
||||
let mut var2 = 5;
|
||||
let thingy2 = Some(&mut var2);
|
||||
if let Some(&mut ref mut v) = thingy2 {
|
||||
// ^ should *not* be linted
|
||||
// v is borrowed as mutable.
|
||||
*v = 10;
|
||||
}
|
||||
if let Some(&mut ref v) = thingy2 {
|
||||
// ^ should *not* be linted
|
||||
// here, v is borrowed as immutable.
|
||||
// can't do that:
|
||||
//*v = 15;
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
enum Animal {
|
||||
Cat(u64),
|
||||
Dog(u64),
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[allow(dead_code)]
|
||||
fn foo(a: &Animal, b: &Animal) {
|
||||
match (a, b) {
|
||||
(&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
|
||||
// ^ and ^ should *not* be linted
|
||||
(&Animal::Dog(ref a), &Animal::Dog(_)) => ()
|
||||
// ^ should *not* be linted
|
||||
}
|
||||
}
|
||||
|
38
clippy_tests/examples/needless_borrowed_ref.stderr
Normal file
38
clippy_tests/examples/needless_borrowed_ref.stderr
Normal file
@ -0,0 +1,38 @@
|
||||
error: this pattern takes a reference on something that is being de-referenced
|
||||
--> needless_borrowed_ref.rs:8:34
|
||||
|
|
||||
8 | let _ = v.iter_mut().filter(|&ref a| a.is_empty());
|
||||
| ^^^^^^ help: try removing the `&ref` part and just keep `a`
|
||||
|
|
||||
= note: `-D needless-borrowed-reference` implied by `-D warnings`
|
||||
= help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#needless_borrowed_reference
|
||||
|
||||
error: this pattern takes a reference on something that is being de-referenced
|
||||
--> needless_borrowed_ref.rs:13:17
|
||||
|
|
||||
13 | if let Some(&ref v) = thingy {
|
||||
| ^^^^^^ help: try removing the `&ref` part and just keep `v`
|
||||
|
|
||||
= help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#needless_borrowed_reference
|
||||
|
||||
error: this pattern takes a reference on something that is being de-referenced
|
||||
--> needless_borrowed_ref.rs:42:27
|
||||
|
|
||||
42 | (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
|
||||
| ^^^^^^ help: try removing the `&ref` part and just keep `k`
|
||||
|
|
||||
= help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#needless_borrowed_reference
|
||||
|
||||
error: this pattern takes a reference on something that is being de-referenced
|
||||
--> needless_borrowed_ref.rs:42:38
|
||||
|
|
||||
42 | (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
|
||||
| ^^^^^^ help: try removing the `&ref` part and just keep `k`
|
||||
|
|
||||
= help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#needless_borrowed_reference
|
||||
|
||||
error: aborting due to previous error(s)
|
||||
|
||||
error: Could not compile `clippy_tests`.
|
||||
|
||||
To learn more, run the command again with --verbose.
|
@ -18,11 +18,25 @@ error: this expression borrows a reference that is immediately dereferenced by t
|
||||
27 | 46 => &&a,
|
||||
| ^^^
|
||||
|
||||
error: this pattern takes a reference on something that is being de-referenced
|
||||
--> $DIR/needless_borrow.rs:49:34
|
||||
|
|
||||
49 | let _ = v.iter_mut().filter(|&ref a| a.is_empty());
|
||||
| ^^^^^^ help: try removing the `&ref` part and just keep: `a`
|
||||
|
|
||||
= note: `-D needless-borrowed-reference` implied by `-D warnings`
|
||||
|
||||
error: this pattern takes a reference on something that is being de-referenced
|
||||
--> $DIR/needless_borrow.rs:50:30
|
||||
|
|
||||
50 | let _ = v.iter().filter(|&ref a| a.is_empty());
|
||||
| ^^^^^^ help: try removing the `&ref` part and just keep: `a`
|
||||
|
||||
error: this pattern creates a reference to a reference
|
||||
--> $DIR/needless_borrow.rs:50:31
|
||||
|
|
||||
50 | let _ = v.iter().filter(|&ref a| a.is_empty());
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user