]> git.lizzy.rs Git - rust.git/blob - tests/compile-fail/methods.rs
Extend escape analysis to arguments
[rust.git] / tests / compile-fail / methods.rs
1 #![feature(plugin)]
2 #![plugin(clippy)]
3
4 #![allow(unused)]
5 #![deny(clippy, clippy_pedantic)]
6
7 use std::ops::Mul;
8
9 struct T;
10
11 impl T {
12     fn add(self, other: T) -> T { self } //~ERROR defining a method called `add`
13     fn drop(&mut self) { } //~ERROR defining a method called `drop`
14
15     fn sub(&self, other: T) -> &T { self } // no error, self is a ref
16     fn div(self) -> T { self } // no error, different #arguments
17     fn rem(self, other: T) { } // no error, wrong return type
18
19     fn into_u32(self) -> u32 { 0 } // fine
20     fn into_u16(&self) -> u16 { 0 } //~ERROR methods called `into_*` usually take self by value
21
22     fn to_something(self) -> u32 { 0 } //~ERROR methods called `to_*` usually take self by reference
23 }
24
25 #[derive(Clone,Copy)]
26 struct U;
27
28 impl U {
29     fn to_something(self) -> u32 { 0 } // ok because U is Copy
30 }
31
32 impl Mul<T> for T {
33     type Output = T;
34     fn mul(self, other: T) -> T { self } // no error, obviously
35 }
36
37 /// Utility macro to test linting behavior in `option_methods()`
38 /// The lints included in `option_methods()` should not lint if the call to map is partially
39 /// within a macro
40 macro_rules! opt_map {
41     ($opt:expr, $map:expr) => {($opt).map($map)};
42 }
43
44 /// Checks implementation of the following lints:
45 /// OPTION_MAP_UNWRAP_OR
46 /// OPTION_MAP_UNWRAP_OR_ELSE
47 fn option_methods() {
48     let opt = Some(1);
49
50     // Check OPTION_MAP_UNWRAP_OR
51     // single line case
52     let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or(a)`
53                                //~| NOTE replace this
54                .unwrap_or(0); // should lint even though this call is on a separate line
55     // multi line cases
56     let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or(a)`
57                         x + 1
58                     }
59               ).unwrap_or(0);
60     let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or(a)`
61                .unwrap_or({
62                     0
63                 });
64     // macro case
65     let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint
66
67     // Check OPTION_MAP_UNWRAP_OR_ELSE
68     // single line case
69     let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or_else(g)`
70                                //~| NOTE replace this
71                .unwrap_or_else(|| 0); // should lint even though this call is on a separate line
72     // multi line cases
73     let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or_else(g)`
74                         x + 1
75                     }
76               ).unwrap_or_else(|| 0);
77     let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or_else(g)`
78                .unwrap_or_else(||
79                     0
80                 );
81     // macro case
82     let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint
83
84 }
85
86 fn main() {
87     use std::io;
88
89     let opt = Some(0);
90     let _ = opt.unwrap();  //~ERROR used unwrap() on an Option
91
92     let res: Result<i32, ()> = Ok(0);
93     let _ = res.unwrap();  //~ERROR used unwrap() on a Result
94
95     let _ = "str".to_string();  //~ERROR `"str".to_owned()` is faster
96
97     let v = &"str";
98     let string = v.to_string();  //~ERROR `(*v).to_owned()` is faster
99     let _again = string.to_string();  //~ERROR `String.to_string()` is a no-op
100
101     res.ok().expect("disaster!"); //~ERROR called `ok().expect()`
102     // the following should not warn, since `expect` isn't implemented unless
103     // the error type implements `Debug`
104     let res2: Result<i32, MyError> = Ok(0);
105     res2.ok().expect("oh noes!");
106     // we currently don't warn if the error type has a type parameter
107     // (but it would be nice if we did)
108     let res3: Result<u32, MyErrorWithParam<u8>>= Ok(0);
109     res3.ok().expect("whoof");
110     let res4: Result<u32, io::Error> = Ok(0);
111     res4.ok().expect("argh"); //~ERROR called `ok().expect()`
112     let res5: io::Result<u32> = Ok(0);
113     res5.ok().expect("oops"); //~ERROR called `ok().expect()`
114     let res6: Result<u32, &str> = Ok(0);
115     res6.ok().expect("meh"); //~ERROR called `ok().expect()`
116 }
117
118 struct MyError(()); // doesn't implement Debug
119
120 #[derive(Debug)]
121 struct MyErrorWithParam<T> {
122     x: T
123 }