1// run-rustfix
2
3#![allow(unused_variables, clippy::clone_double_ref)]
4#![warn(clippy::explicit_deref_methods)]
5
6use std::ops::{Deref, DerefMut};
7
8fn concat(deref_str: &str) -> String {
9    format!("{}bar", deref_str)
10}
11
12fn just_return(deref_str: &str) -> &str {
13    deref_str
14}
15
16struct CustomVec(Vec<u8>);
17impl Deref for CustomVec {
18    type Target = Vec<u8>;
19
20    fn deref(&self) -> &Vec<u8> {
21        &self.0
22    }
23}
24
25fn main() {
26    let a: &mut String = &mut String::from("foo");
27
28    // these should require linting
29
30    let b: &str = &*a;
31
32    let b: &mut str = &mut **a;
33
34    // both derefs should get linted here
35    let b: String = format!("{}, {}", &*a, &*a);
36
37    println!("{}", &*a);
38
39    #[allow(clippy::match_single_binding)]
40    match &*a {
41        _ => (),
42    }
43
44    let b: String = concat(&*a);
45
46    let b = just_return(a);
47
48    let b: String = concat(just_return(a));
49
50    let b: &str = &**a;
51
52    let opt_a = Some(a.clone());
53    let b = &*opt_a.unwrap();
54
55    // following should not require linting
56
57    let cv = CustomVec(vec![0, 42]);
58    let c = cv.deref()[0];
59
60    let b: &str = &*a.deref();
61
62    let b: String = a.deref().clone();
63
64    let b: usize = a.deref_mut().len();
65
66    let b: &usize = &a.deref().len();
67
68    let b: &str = &*a;
69
70    let b: &mut str = &mut *a;
71
72    macro_rules! expr_deref {
73        ($body:expr) => {
74            $body.deref()
75        };
76    }
77    let b: &str = expr_deref!(a);
78
79    let b: &str = expr_deref!(&*a);
80
81    // The struct does not implement Deref trait
82    #[derive(Copy, Clone)]
83    struct NoLint(u32);
84    impl NoLint {
85        pub fn deref(self) -> u32 {
86            self.0
87        }
88        pub fn deref_mut(self) -> u32 {
89            self.0
90        }
91    }
92    let no_lint = NoLint(42);
93    let b = no_lint.deref();
94    let b = no_lint.deref_mut();
95}
96