rust/tests/ui/needless_borrow_pat.rs

164 lines
3.7 KiB
Rust
Raw Normal View History

// FIXME: run-rustfix waiting on multi-span suggestions
#![warn(clippy::needless_borrow)]
#![allow(clippy::needless_borrowed_reference, clippy::explicit_auto_deref)]
fn f1(_: &str) {}
macro_rules! m1 {
($e:expr) => {
f1($e)
};
}
macro_rules! m3 {
($i:ident) => {
Some(ref $i)
};
}
macro_rules! if_chain {
(if $e:expr; $($rest:tt)*) => {
if $e {
if_chain!($($rest)*)
}
};
(if let $p:pat = $e:expr; $($rest:tt)*) => {
if let $p = $e {
if_chain!($($rest)*)
}
};
(then $b:block) => {
$b
};
}
#[allow(dead_code)]
fn main() {
let x = String::new();
// Ok, reference to a String.
let _: &String = match Some(x.clone()) {
Some(ref x) => x,
None => return,
};
// Ok, reference to a &mut String
let _: &&mut String = match Some(&mut x.clone()) {
Some(ref x) => x,
None => return,
};
// Ok, the pattern is from a macro
let _: &String = match Some(&x) {
m3!(x) => x,
None => return,
};
// Err, reference to a &String
let _: &String = match Some(&x) {
Some(ref x) => x,
//~^ ERROR: this pattern creates a reference to a reference
//~| NOTE: `-D clippy::needless-borrow` implied by `-D warnings`
None => return,
};
// Err, reference to a &String.
let _: &String = match Some(&x) {
Some(ref x) => *x,
//~^ ERROR: this pattern creates a reference to a reference
None => return,
};
// Err, reference to a &String
let _: &String = match Some(&x) {
Some(ref x) => {
//~^ ERROR: this pattern creates a reference to a reference
f1(x);
f1(*x);
x
},
None => return,
};
// Err, reference to a &String
match Some(&x) {
Some(ref x) => m1!(x),
//~^ ERROR: this pattern creates a reference to a reference
None => return,
};
// Err, reference to a &String
let _ = |&ref x: &&String| {
//~^ ERROR: this pattern creates a reference to a reference
let _: &String = x;
};
// Err, reference to a &String
let (ref y,) = (&x,);
//~^ ERROR: this pattern creates a reference to a reference
let _: &String = *y;
let y = &&x;
// Ok, different y
let _: &String = *y;
let x = (0, 0);
// Err, reference to a &u32. Don't suggest adding a reference to the field access.
let _: u32 = match Some(&x) {
Some(ref x) => x.0,
//~^ ERROR: this pattern creates a reference to a reference
None => return,
};
enum E {
A(&'static u32),
B(&'static u32),
}
// Err, reference to &u32.
let _: &u32 = match E::A(&0) {
E::A(ref x) | E::B(ref x) => *x,
//~^ ERROR: this pattern creates a reference to a reference
};
// Err, reference to &String.
if_chain! {
if true;
if let Some(ref x) = Some(&String::new());
//~^ ERROR: this pattern creates a reference to a reference
then {
f1(x);
}
}
}
// Err, reference to a &String
fn f2<'a>(&ref x: &&'a String) -> &'a String {
//~^ ERROR: this pattern creates a reference to a reference
let _: &String = x;
*x
}
trait T1 {
// Err, reference to a &String
fn f(&ref x: &&String) {
//~^ ERROR: this pattern creates a reference to a reference
let _: &String = x;
}
}
struct S;
impl T1 for S {
// Err, reference to a &String
fn f(&ref x: &&String) {
//~^ ERROR: this pattern creates a reference to a reference
let _: &String = *x;
}
}
// Ok - used to error due to rustc bug
#[allow(dead_code)]
#[derive(Debug)]
enum Foo<'a> {
Str(&'a str),
}