Skip to content

Commit d7b9a84

Browse files
author
Lukas Markeffsky
committed
new_ret_no_self: walk associated types in impl Trait return types
1 parent c55d38e commit d7b9a84

File tree

3 files changed

+43
-24
lines changed

3 files changed

+43
-24
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,11 +1070,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
10701070
(Predicate::Projection(poly_projection_predicate), _) => {
10711071
let binder = poly_projection_predicate.ty();
10721072
let associated_type = binder.skip_binder();
1073-
let associated_type_is_self_type = same_tys(cx, ty, associated_type);
10741073

1075-
// if the associated type is self, early return and do not trigger lint
1076-
if associated_type_is_self_type {
1077-
return;
1074+
// walk the associated type and check for Self
1075+
for inner_type in associated_type.walk() {
1076+
if same_tys(cx, ty, inner_type) {
1077+
return;
1078+
}
10781079
}
10791080
},
10801081
(_, _) => {},

tests/ui/methods.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ use std::collections::BTreeMap;
2323
use std::collections::HashMap;
2424
use std::collections::HashSet;
2525
use std::collections::VecDeque;
26+
use std::future::Future;
2627
use std::iter::FromIterator;
2728
use std::ops::Mul;
29+
use std::pin::Pin;
2830
use std::rc::{self, Rc};
2931
use std::sync::{self, Arc};
32+
use std::task::{Context, Poll};
3033

3134
use option_helpers::IteratorFalsePositives;
3235

@@ -138,6 +141,21 @@ impl<T> V<T> {
138141
}
139142
}
140143

144+
struct AsyncNew;
145+
146+
impl AsyncNew {
147+
fn new() -> impl Future<Output = Option<Self>> {
148+
struct F;
149+
impl Future for F {
150+
type Output = Option<AsyncNew>;
151+
fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
152+
unimplemented!()
153+
}
154+
}
155+
F
156+
}
157+
}
158+
141159
impl Mul<T> for T {
142160
type Output = T;
143161
// No error, obviously.

tests/ui/methods.stderr

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: defining a method called `add` on this type; consider implementing the `std::ops::Add` trait or choosing a less ambiguous name
2-
--> $DIR/methods.rs:36:5
2+
--> $DIR/methods.rs:39:5
33
|
44
LL | / pub fn add(self, other: T) -> T {
55
LL | | self
@@ -9,7 +9,7 @@ LL | | }
99
= note: `-D clippy::should-implement-trait` implied by `-D warnings`
1010

1111
error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead
12-
--> $DIR/methods.rs:158:13
12+
--> $DIR/methods.rs:176:13
1313
|
1414
LL | let _ = opt.map(|x| x + 1)
1515
| _____________^
@@ -21,7 +21,7 @@ LL | | .unwrap_or(0);
2121
= note: replace `map(|x| x + 1).unwrap_or(0)` with `map_or(0, |x| x + 1)`
2222

2323
error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead
24-
--> $DIR/methods.rs:162:13
24+
--> $DIR/methods.rs:180:13
2525
|
2626
LL | let _ = opt.map(|x| {
2727
| _____________^
@@ -31,7 +31,7 @@ LL | | ).unwrap_or(0);
3131
| |____________________________^
3232

3333
error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead
34-
--> $DIR/methods.rs:166:13
34+
--> $DIR/methods.rs:184:13
3535
|
3636
LL | let _ = opt.map(|x| x + 1)
3737
| _____________^
@@ -41,15 +41,15 @@ LL | | });
4141
| |__________________^
4242

4343
error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead
44-
--> $DIR/methods.rs:171:13
44+
--> $DIR/methods.rs:189:13
4545
|
4646
LL | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);
4747
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4848
|
4949
= note: replace `map(|x| Some(x + 1)).unwrap_or(None)` with `and_then(|x| Some(x + 1))`
5050

5151
error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead
52-
--> $DIR/methods.rs:173:13
52+
--> $DIR/methods.rs:191:13
5353
|
5454
LL | let _ = opt.map(|x| {
5555
| _____________^
@@ -59,7 +59,7 @@ LL | | ).unwrap_or(None);
5959
| |_____________________^
6060

6161
error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead
62-
--> $DIR/methods.rs:177:13
62+
--> $DIR/methods.rs:195:13
6363
|
6464
LL | let _ = opt
6565
| _____________^
@@ -70,15 +70,15 @@ LL | | .unwrap_or(None);
7070
= note: replace `map(|x| Some(x + 1)).unwrap_or(None)` with `and_then(|x| Some(x + 1))`
7171

7272
error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead
73-
--> $DIR/methods.rs:188:13
73+
--> $DIR/methods.rs:206:13
7474
|
7575
LL | let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id);
7676
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7777
|
7878
= note: replace `map(|p| format!("{}.", p)).unwrap_or(id)` with `map_or(id, |p| format!("{}.", p))`
7979

8080
error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead
81-
--> $DIR/methods.rs:192:13
81+
--> $DIR/methods.rs:210:13
8282
|
8383
LL | let _ = opt.map(|x| x + 1)
8484
| _____________^
@@ -90,7 +90,7 @@ LL | | .unwrap_or_else(|| 0);
9090
= note: replace `map(|x| x + 1).unwrap_or_else(|| 0)` with `map_or_else(|| 0, |x| x + 1)`
9191

9292
error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead
93-
--> $DIR/methods.rs:196:13
93+
--> $DIR/methods.rs:214:13
9494
|
9595
LL | let _ = opt.map(|x| {
9696
| _____________^
@@ -100,7 +100,7 @@ LL | | ).unwrap_or_else(|| 0);
100100
| |____________________________________^
101101

102102
error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead
103-
--> $DIR/methods.rs:200:13
103+
--> $DIR/methods.rs:218:13
104104
|
105105
LL | let _ = opt.map(|x| x + 1)
106106
| _____________^
@@ -110,7 +110,7 @@ LL | | );
110110
| |_________________^
111111

112112
error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead.
113-
--> $DIR/methods.rs:230:13
113+
--> $DIR/methods.rs:248:13
114114
|
115115
LL | let _ = v.iter().filter(|&x| *x < 0).next();
116116
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -119,7 +119,7 @@ LL | let _ = v.iter().filter(|&x| *x < 0).next();
119119
= note: replace `filter(|&x| *x < 0).next()` with `find(|&x| *x < 0)`
120120

121121
error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead.
122-
--> $DIR/methods.rs:233:13
122+
--> $DIR/methods.rs:251:13
123123
|
124124
LL | let _ = v.iter().filter(|&x| {
125125
| _____________^
@@ -129,7 +129,7 @@ LL | | ).next();
129129
| |___________________________^
130130

131131
error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`.
132-
--> $DIR/methods.rs:249:13
132+
--> $DIR/methods.rs:267:13
133133
|
134134
LL | let _ = v.iter().find(|&x| *x < 0).is_some();
135135
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,7 +138,7 @@ LL | let _ = v.iter().find(|&x| *x < 0).is_some();
138138
= note: replace `find(|&x| *x < 0).is_some()` with `any(|x| *x < 0)`
139139

140140
error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`.
141-
--> $DIR/methods.rs:252:13
141+
--> $DIR/methods.rs:270:13
142142
|
143143
LL | let _ = v.iter().find(|&x| {
144144
| _____________^
@@ -148,15 +148,15 @@ LL | | ).is_some();
148148
| |______________________________^
149149

150150
error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`.
151-
--> $DIR/methods.rs:258:13
151+
--> $DIR/methods.rs:276:13
152152
|
153153
LL | let _ = v.iter().position(|&x| x < 0).is_some();
154154
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
155155
|
156156
= note: replace `position(|&x| x < 0).is_some()` with `any(|&x| x < 0)`
157157

158158
error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`.
159-
--> $DIR/methods.rs:261:13
159+
--> $DIR/methods.rs:279:13
160160
|
161161
LL | let _ = v.iter().position(|&x| {
162162
| _____________^
@@ -166,15 +166,15 @@ LL | | ).is_some();
166166
| |______________________________^
167167

168168
error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`.
169-
--> $DIR/methods.rs:267:13
169+
--> $DIR/methods.rs:285:13
170170
|
171171
LL | let _ = v.iter().rposition(|&x| x < 0).is_some();
172172
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
173173
|
174174
= note: replace `rposition(|&x| x < 0).is_some()` with `any(|&x| x < 0)`
175175

176176
error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`.
177-
--> $DIR/methods.rs:270:13
177+
--> $DIR/methods.rs:288:13
178178
|
179179
LL | let _ = v.iter().rposition(|&x| {
180180
| _____________^
@@ -184,7 +184,7 @@ LL | | ).is_some();
184184
| |______________________________^
185185

186186
error: used unwrap() on an Option value. If you don't want to handle the None case gracefully, consider using expect() to provide a better panic message
187-
--> $DIR/methods.rs:285:13
187+
--> $DIR/methods.rs:303:13
188188
|
189189
LL | let _ = opt.unwrap();
190190
| ^^^^^^^^^^^^

0 commit comments

Comments
 (0)