diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-03-01 21:37:56 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2024-03-03 18:53:36 +0000 |
| commit | 89a3c198321f33b5c9efb54eb48d354c4bd5c614 (patch) | |
| tree | 498f39225184c75fbf778d1a8e83f39987f137d2 | |
| parent | f0c93117ed0551392860ae049507d388272a052d (diff) | |
| download | rust-89a3c198321f33b5c9efb54eb48d354c4bd5c614.tar.gz rust-89a3c198321f33b5c9efb54eb48d354c4bd5c614.zip | |
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`.
| -rw-r--r-- | compiler/rustc_hir_typeck/src/method/suggest.rs | 4 | ||||
| -rw-r--r-- | library/core/src/iter/traits/iterator.rs | 9 | ||||
| -rw-r--r-- | tests/ui/iterators/vec-on-unimplemented.fixed | 5 | ||||
| -rw-r--r-- | tests/ui/iterators/vec-on-unimplemented.rs | 5 | ||||
| -rw-r--r-- | tests/ui/iterators/vec-on-unimplemented.stderr | 17 | ||||
| -rw-r--r-- | tests/ui/methods/issues/issue-94581.fixed | 8 | ||||
| -rw-r--r-- | tests/ui/methods/issues/issue-94581.rs | 3 | ||||
| -rw-r--r-- | tests/ui/methods/issues/issue-94581.stderr | 17 | ||||
| -rw-r--r-- | tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs | 2 | ||||
| -rw-r--r-- | tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr | 5 |
10 files changed, 38 insertions, 37 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 440d0ad1140..893b3f9534d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -166,7 +166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - match ty.kind() { + match ty.peel_refs().kind() { ty::Param(param) => { let generics = self.tcx.generics_of(self.body_id); let generic_param = generics.type_param(¶m, self.tcx); @@ -184,7 +184,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - ty::Alias(ty::AliasKind::Opaque, _) => { + ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::AliasKind::Opaque, _) => { for unsatisfied in unsatisfied_predicates.iter() { if is_iterator_predicate(unsatisfied.0, self.tcx) { return true; diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 74f9e7f9446..e1904ed220c 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -34,15 +34,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} _Self = "core::ops::range::RangeToInclusive<Idx>", note = "you might have meant to use a bounded `RangeInclusive`" ), - on( - _Self = "[]", - label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`" - ), - on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"), - on( - _Self = "alloc::vec::Vec<T, A>", - label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`" - ), label = "`{Self}` is not an iterator", message = "`{Self}` is not an iterator" )] diff --git a/tests/ui/iterators/vec-on-unimplemented.fixed b/tests/ui/iterators/vec-on-unimplemented.fixed new file mode 100644 index 00000000000..cc46bd67f9a --- /dev/null +++ b/tests/ui/iterators/vec-on-unimplemented.fixed @@ -0,0 +1,5 @@ +//@ run-rustfix +fn main() { + let _ = vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>(); + //~^ ERROR no method named `map` found for struct `Vec<bool>` in the current scope +} diff --git a/tests/ui/iterators/vec-on-unimplemented.rs b/tests/ui/iterators/vec-on-unimplemented.rs index 42b5d36bfad..7367fd4c9cd 100644 --- a/tests/ui/iterators/vec-on-unimplemented.rs +++ b/tests/ui/iterators/vec-on-unimplemented.rs @@ -1,4 +1,5 @@ +//@ run-rustfix fn main() { - vec![true, false].map(|v| !v).collect::<Vec<_>>(); - //~^ ERROR `Vec<bool>` is not an iterator + let _ = vec![true, false].map(|v| !v).collect::<Vec<_>>(); + //~^ ERROR no method named `map` found for struct `Vec<bool>` in the current scope } diff --git a/tests/ui/iterators/vec-on-unimplemented.stderr b/tests/ui/iterators/vec-on-unimplemented.stderr index 29b19d5e3b4..d6f4bfa1cde 100644 --- a/tests/ui/iterators/vec-on-unimplemented.stderr +++ b/tests/ui/iterators/vec-on-unimplemented.stderr @@ -1,14 +1,13 @@ -error[E0599]: `Vec<bool>` is not an iterator - --> $DIR/vec-on-unimplemented.rs:2:23 +error[E0599]: no method named `map` found for struct `Vec<bool>` in the current scope + --> $DIR/vec-on-unimplemented.rs:3:31 | -LL | vec![true, false].map(|v| !v).collect::<Vec<_>>(); - | ^^^ `Vec<bool>` is not an iterator; try calling `.into_iter()` or `.iter()` +LL | let _ = vec![true, false].map(|v| !v).collect::<Vec<_>>(); + | ^^^ `Vec<bool>` is not an iterator | - = note: the following trait bounds were not satisfied: - `Vec<bool>: Iterator` - which is required by `&mut Vec<bool>: Iterator` - `[bool]: Iterator` - which is required by `&mut [bool]: Iterator` +help: call `.into_iter()` first + | +LL | let _ = vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>(); + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/methods/issues/issue-94581.fixed b/tests/ui/methods/issues/issue-94581.fixed new file mode 100644 index 00000000000..ff2bbeba27c --- /dev/null +++ b/tests/ui/methods/issues/issue-94581.fixed @@ -0,0 +1,8 @@ +//@ run-rustfix +fn get_slice() -> &'static [i32] { + &[1, 2, 3, 4] +} + +fn main() { + let _sqsum: i32 = get_slice().into_iter().map(|i| i * i).sum(); //~ ERROR [E0599] +} diff --git a/tests/ui/methods/issues/issue-94581.rs b/tests/ui/methods/issues/issue-94581.rs index df393e91db0..535d3249eb9 100644 --- a/tests/ui/methods/issues/issue-94581.rs +++ b/tests/ui/methods/issues/issue-94581.rs @@ -1,7 +1,8 @@ +//@ run-rustfix fn get_slice() -> &'static [i32] { &[1, 2, 3, 4] } fn main() { - let sqsum = get_slice().map(|i| i * i).sum(); //~ ERROR [E0599] + let _sqsum: i32 = get_slice().map(|i| i * i).sum(); //~ ERROR [E0599] } diff --git a/tests/ui/methods/issues/issue-94581.stderr b/tests/ui/methods/issues/issue-94581.stderr index ae7446d4833..d04d6ca5e3c 100644 --- a/tests/ui/methods/issues/issue-94581.stderr +++ b/tests/ui/methods/issues/issue-94581.stderr @@ -1,14 +1,13 @@ -error[E0599]: `&'static [i32]` is not an iterator - --> $DIR/issue-94581.rs:6:29 +error[E0599]: no method named `map` found for reference `&'static [i32]` in the current scope + --> $DIR/issue-94581.rs:7:35 | -LL | let sqsum = get_slice().map(|i| i * i).sum(); - | ^^^ `&'static [i32]` is not an iterator; try calling `.iter()` +LL | let _sqsum: i32 = get_slice().map(|i| i * i).sum(); + | ^^^ `&'static [i32]` is not an iterator | - = note: the following trait bounds were not satisfied: - `&'static [i32]: Iterator` - which is required by `&mut &'static [i32]: Iterator` - `[i32]: Iterator` - which is required by `&mut [i32]: Iterator` +help: call `.into_iter()` first + | +LL | let _sqsum: i32 = get_slice().into_iter().map(|i| i * i).sum(); + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs index 8567d812e4f..29793e9f734 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs @@ -14,7 +14,7 @@ struct PriorityQueueEntry<T> { //~^ ERROR can't compare `PriorityQueue<T>` with `PriorityQueue<T>` //~| ERROR the trait bound `PriorityQueue<T>: Eq` is not satisfied //~| ERROR can't compare `T` with `T` -//~| ERROR `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator +//~| ERROR no method named `cmp` found for struct `BinaryHeap<PriorityQueueEntry<T>>` //~| ERROR no field `height` on type `&PriorityQueue<T>` struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>); diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index 6fa639877d3..0fe560afcb5 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -46,15 +46,12 @@ LL | struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>); = help: the trait `PartialOrd<_>` is not implemented for `BinaryHeap<PriorityQueueEntry<T>>` = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0599]: `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator +error[E0599]: no method named `cmp` found for struct `BinaryHeap<PriorityQueueEntry<T>>` in the current scope --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator | - = note: the following trait bounds were not satisfied: - `BinaryHeap<PriorityQueueEntry<T>>: Iterator` - which is required by `&mut BinaryHeap<PriorityQueueEntry<T>>: Iterator` = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0609]: no field `height` on type `&PriorityQueue<T>` |
