Skip to content

Commit 89a3c19

Browse files
committed
Be more lax in .into_iter() suggestion when encountering Iterator methods on non-Iterator
``` error[E0599]: no method named `map` found for struct `Vec<bool>` in the current scope --> $DIR/vec-on-unimplemented.rs:3:23 | LL | vec![true, false].map(|v| !v).collect::<Vec<_>>(); | ^^^ `Vec<bool>` is not an iterator | help: call `.into_iter()` first | LL | vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>(); | ++++++++++++ ``` We used to provide some help through `rustc_on_unimplemented` on non-`impl Trait` and non-type-params, but this lets us get rid of some otherwise unnecessary conditions in the annotation on `Iterator`.
1 parent f0c9311 commit 89a3c19

File tree

10 files changed

+38
-37
lines changed

10 files changed

+38
-37
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
166166
return false;
167167
}
168168

169-
match ty.kind() {
169+
match ty.peel_refs().kind() {
170170
ty::Param(param) => {
171171
let generics = self.tcx.generics_of(self.body_id);
172172
let generic_param = generics.type_param(&param, self.tcx);
@@ -184,7 +184,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
184184
}
185185
}
186186
}
187-
ty::Alias(ty::AliasKind::Opaque, _) => {
187+
ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::AliasKind::Opaque, _) => {
188188
for unsatisfied in unsatisfied_predicates.iter() {
189189
if is_iterator_predicate(unsatisfied.0, self.tcx) {
190190
return true;

library/core/src/iter/traits/iterator.rs

-9
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
3434
_Self = "core::ops::range::RangeToInclusive<Idx>",
3535
note = "you might have meant to use a bounded `RangeInclusive`"
3636
),
37-
on(
38-
_Self = "[]",
39-
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
40-
),
41-
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
42-
on(
43-
_Self = "alloc::vec::Vec<T, A>",
44-
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
45-
),
4637
label = "`{Self}` is not an iterator",
4738
message = "`{Self}` is not an iterator"
4839
)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//@ run-rustfix
2+
fn main() {
3+
let _ = vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>();
4+
//~^ ERROR no method named `map` found for struct `Vec<bool>` in the current scope
5+
}
+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1+
//@ run-rustfix
12
fn main() {
2-
vec![true, false].map(|v| !v).collect::<Vec<_>>();
3-
//~^ ERROR `Vec<bool>` is not an iterator
3+
let _ = vec![true, false].map(|v| !v).collect::<Vec<_>>();
4+
//~^ ERROR no method named `map` found for struct `Vec<bool>` in the current scope
45
}

tests/ui/iterators/vec-on-unimplemented.stderr

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
error[E0599]: `Vec<bool>` is not an iterator
2-
--> $DIR/vec-on-unimplemented.rs:2:23
1+
error[E0599]: no method named `map` found for struct `Vec<bool>` in the current scope
2+
--> $DIR/vec-on-unimplemented.rs:3:31
33
|
4-
LL | vec![true, false].map(|v| !v).collect::<Vec<_>>();
5-
| ^^^ `Vec<bool>` is not an iterator; try calling `.into_iter()` or `.iter()`
4+
LL | let _ = vec![true, false].map(|v| !v).collect::<Vec<_>>();
5+
| ^^^ `Vec<bool>` is not an iterator
66
|
7-
= note: the following trait bounds were not satisfied:
8-
`Vec<bool>: Iterator`
9-
which is required by `&mut Vec<bool>: Iterator`
10-
`[bool]: Iterator`
11-
which is required by `&mut [bool]: Iterator`
7+
help: call `.into_iter()` first
8+
|
9+
LL | let _ = vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>();
10+
| ++++++++++++
1211

1312
error: aborting due to 1 previous error
1413

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ run-rustfix
2+
fn get_slice() -> &'static [i32] {
3+
&[1, 2, 3, 4]
4+
}
5+
6+
fn main() {
7+
let _sqsum: i32 = get_slice().into_iter().map(|i| i * i).sum(); //~ ERROR [E0599]
8+
}
+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
//@ run-rustfix
12
fn get_slice() -> &'static [i32] {
23
&[1, 2, 3, 4]
34
}
45

56
fn main() {
6-
let sqsum = get_slice().map(|i| i * i).sum(); //~ ERROR [E0599]
7+
let _sqsum: i32 = get_slice().map(|i| i * i).sum(); //~ ERROR [E0599]
78
}

tests/ui/methods/issues/issue-94581.stderr

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
error[E0599]: `&'static [i32]` is not an iterator
2-
--> $DIR/issue-94581.rs:6:29
1+
error[E0599]: no method named `map` found for reference `&'static [i32]` in the current scope
2+
--> $DIR/issue-94581.rs:7:35
33
|
4-
LL | let sqsum = get_slice().map(|i| i * i).sum();
5-
| ^^^ `&'static [i32]` is not an iterator; try calling `.iter()`
4+
LL | let _sqsum: i32 = get_slice().map(|i| i * i).sum();
5+
| ^^^ `&'static [i32]` is not an iterator
66
|
7-
= note: the following trait bounds were not satisfied:
8-
`&'static [i32]: Iterator`
9-
which is required by `&mut &'static [i32]: Iterator`
10-
`[i32]: Iterator`
11-
which is required by `&mut [i32]: Iterator`
7+
help: call `.into_iter()` first
8+
|
9+
LL | let _sqsum: i32 = get_slice().into_iter().map(|i| i * i).sum();
10+
| ++++++++++++
1211

1312
error: aborting due to 1 previous error
1413

tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct PriorityQueueEntry<T> {
1414
//~^ ERROR can't compare `PriorityQueue<T>` with `PriorityQueue<T>`
1515
//~| ERROR the trait bound `PriorityQueue<T>: Eq` is not satisfied
1616
//~| ERROR can't compare `T` with `T`
17-
//~| ERROR `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator
17+
//~| ERROR no method named `cmp` found for struct `BinaryHeap<PriorityQueueEntry<T>>`
1818
//~| ERROR no field `height` on type `&PriorityQueue<T>`
1919

2020
struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);

tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr

+1-4
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,12 @@ LL | struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);
4646
= help: the trait `PartialOrd<_>` is not implemented for `BinaryHeap<PriorityQueueEntry<T>>`
4747
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
4848

49-
error[E0599]: `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator
49+
error[E0599]: no method named `cmp` found for struct `BinaryHeap<PriorityQueueEntry<T>>` in the current scope
5050
--> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22
5151
|
5252
LL | #[derive(PartialOrd, AddImpl)]
5353
| ^^^^^^^ `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator
5454
|
55-
= note: the following trait bounds were not satisfied:
56-
`BinaryHeap<PriorityQueueEntry<T>>: Iterator`
57-
which is required by `&mut BinaryHeap<PriorityQueueEntry<T>>: Iterator`
5855
= note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info)
5956

6057
error[E0609]: no field `height` on type `&PriorityQueue<T>`

0 commit comments

Comments
 (0)