]>
Commit | Line | Data |
---|---|---|
abe05a73 XL |
1 | |
2 | ||
ea8adc8c XL |
3 | |
4 | #![warn(len_without_is_empty, len_zero)] | |
5 | #![allow(dead_code, unused)] | |
6 | ||
7 | pub struct PubOne; | |
8 | ||
9 | impl PubOne { | |
10 | pub fn len(self: &Self) -> isize { | |
11 | 1 | |
12 | } | |
13 | } | |
14 | ||
15 | impl PubOne { // A second impl for this struct - the error span shouldn't mention this | |
16 | pub fn irrelevant(self: &Self) -> bool { | |
17 | false | |
18 | } | |
19 | } | |
20 | ||
21 | // Identical to PubOne, but with an allow attribute on the impl complaining len | |
22 | pub struct PubAllowed; | |
23 | ||
24 | #[allow(len_without_is_empty)] | |
25 | impl PubAllowed { | |
26 | pub fn len(self: &Self) -> isize { | |
27 | 1 | |
28 | } | |
29 | } | |
30 | ||
31 | // No allow attribute on this impl block, but that doesn't matter - we only require one on the | |
32 | // impl containing len. | |
33 | impl PubAllowed { | |
34 | pub fn irrelevant(self: &Self) -> bool { | |
35 | false | |
36 | } | |
37 | } | |
38 | ||
39 | struct NotPubOne; | |
40 | ||
41 | impl NotPubOne { | |
42 | pub fn len(self: &Self) -> isize { // no error, len is pub but `NotPubOne` is not exported anyway | |
43 | 1 | |
44 | } | |
45 | } | |
46 | ||
47 | struct One; | |
48 | ||
49 | impl One { | |
50 | fn len(self: &Self) -> isize { // no error, len is private, see #1085 | |
51 | 1 | |
52 | } | |
53 | } | |
54 | ||
55 | pub trait PubTraitsToo { | |
56 | fn len(self: &Self) -> isize; | |
57 | } | |
58 | ||
59 | impl PubTraitsToo for One { | |
60 | fn len(self: &Self) -> isize { | |
61 | 0 | |
62 | } | |
63 | } | |
64 | ||
65 | trait TraitsToo { | |
66 | fn len(self: &Self) -> isize; // no error, len is private, see #1085 | |
67 | } | |
68 | ||
69 | impl TraitsToo for One { | |
70 | fn len(self: &Self) -> isize { | |
71 | 0 | |
72 | } | |
73 | } | |
74 | ||
75 | struct HasPrivateIsEmpty; | |
76 | ||
77 | impl HasPrivateIsEmpty { | |
78 | pub fn len(self: &Self) -> isize { | |
79 | 1 | |
80 | } | |
81 | ||
82 | fn is_empty(self: &Self) -> bool { | |
83 | false | |
84 | } | |
85 | } | |
86 | ||
87 | pub struct HasIsEmpty; | |
88 | ||
89 | impl HasIsEmpty { | |
90 | pub fn len(self: &Self) -> isize { | |
91 | 1 | |
92 | } | |
93 | ||
94 | fn is_empty(self: &Self) -> bool { | |
95 | false | |
96 | } | |
97 | } | |
98 | ||
99 | struct Wither; | |
100 | ||
101 | pub trait WithIsEmpty { | |
102 | fn len(self: &Self) -> isize; | |
103 | fn is_empty(self: &Self) -> bool; | |
104 | } | |
105 | ||
106 | impl WithIsEmpty for Wither { | |
107 | fn len(self: &Self) -> isize { | |
108 | 1 | |
109 | } | |
110 | ||
111 | fn is_empty(self: &Self) -> bool { | |
112 | false | |
113 | } | |
114 | } | |
115 | ||
116 | pub struct HasWrongIsEmpty; | |
117 | ||
118 | impl HasWrongIsEmpty { | |
119 | pub fn len(self: &Self) -> isize { | |
120 | 1 | |
121 | } | |
122 | ||
123 | pub fn is_empty(self: &Self, x : u32) -> bool { | |
124 | false | |
125 | } | |
126 | } | |
127 | ||
128 | pub trait Empty { | |
129 | fn is_empty(&self) -> bool; | |
130 | } | |
131 | ||
132 | pub trait InheritingEmpty: Empty { //must not trigger LEN_WITHOUT_IS_EMPTY | |
133 | fn len(&self) -> isize; | |
134 | } | |
135 | ||
136 | ||
137 | ||
138 | fn main() { | |
139 | let x = [1, 2]; | |
140 | if x.len() == 0 { | |
141 | println!("This should not happen!"); | |
142 | } | |
143 | ||
144 | if "".len() == 0 { | |
145 | } | |
146 | ||
147 | let y = One; | |
148 | if y.len() == 0 { //no error because One does not have .is_empty() | |
149 | println!("This should not happen either!"); | |
150 | } | |
151 | ||
152 | let z : &TraitsToo = &y; | |
153 | if z.len() > 0 { //no error, because TraitsToo has no .is_empty() method | |
154 | println!("Nor should this!"); | |
155 | } | |
156 | ||
157 | let has_is_empty = HasIsEmpty; | |
158 | if has_is_empty.len() == 0 { | |
159 | println!("Or this!"); | |
160 | } | |
161 | if has_is_empty.len() != 0 { | |
162 | println!("Or this!"); | |
163 | } | |
164 | if has_is_empty.len() > 0 { | |
165 | println!("Or this!"); | |
166 | } | |
167 | assert!(!has_is_empty.is_empty()); | |
168 | ||
169 | let with_is_empty: &WithIsEmpty = &Wither; | |
170 | if with_is_empty.len() == 0 { | |
171 | println!("Or this!"); | |
172 | } | |
173 | assert!(!with_is_empty.is_empty()); | |
174 | ||
175 | let has_wrong_is_empty = HasWrongIsEmpty; | |
176 | if has_wrong_is_empty.len() == 0 { //no error as HasWrongIsEmpty does not have .is_empty() | |
177 | println!("Or this!"); | |
178 | } | |
179 | } | |
180 | ||
181 | fn test_slice(b: &[u8]) { | |
182 | if b.len() != 0 { | |
183 | } | |
184 | } | |
abe05a73 XL |
185 | |
186 | // this used to ICE | |
187 | pub trait Foo: Sized {} | |
188 | ||
189 | pub trait DependsOnFoo: Foo { | |
190 | fn len(&mut self) -> usize; | |
191 | } |