Skip to content

Commit 2492235

Browse files
committed
Consider lifetimes when comparing assoc types in method chain
Do not say "Type changed to X here" when the only difference is caused by lifetimes.
1 parent 3b938f7 commit 2492235

File tree

3 files changed

+44
-14
lines changed

3 files changed

+44
-14
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3333,7 +3333,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
33333333
let ty_str = with_forced_trimmed_paths!(self.ty_to_string(ty));
33343334

33353335
let assoc = with_forced_trimmed_paths!(self.tcx.def_path_str(assoc));
3336-
if ty != *prev_ty {
3336+
if self.can_eq(param_env, ty, *prev_ty).is_err() {
33373337
if type_diffs.iter().any(|diff| {
33383338
let Sorts(expected_found) = diff else { return false; };
33393339
self.can_eq(param_env, expected_found.found, ty).is_ok()

src/test/ui/iterators/invalid-iterator-chain.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
use std::collections::hash_set::Iter;
2+
use std::collections::HashSet;
3+
4+
fn iter_to_vec<'b, X>(i: Iter<'b, X>) -> Vec<X> {
5+
let i = i.map(|x| x.clone());
6+
i.collect() //~ ERROR E0277
7+
}
8+
19
fn main() {
210
let scores = vec![(0, 0)]
311
.iter()
@@ -38,4 +46,8 @@ fn main() {
3846
});
3947
let f = e.filter(|_| false);
4048
let g: Vec<i32> = f.collect(); //~ ERROR E0277
49+
50+
let mut s = HashSet::new();
51+
s.insert(1u8);
52+
println!("{:?}", iter_to_vec(s.iter()));
4153
}

src/test/ui/iterators/invalid-iterator-chain.stderr

+31-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
1+
error[E0277]: a value of type `Vec<X>` cannot be built from an iterator over elements of type `&X`
2+
--> $DIR/invalid-iterator-chain.rs:6:7
3+
|
4+
LL | i.collect()
5+
| ^^^^^^^ value of type `Vec<X>` cannot be built from `std::iter::Iterator<Item=&X>`
6+
|
7+
= help: the trait `FromIterator<&X>` is not implemented for `Vec<X>`
8+
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
9+
note: the method call chain might not have had the expected associated types
10+
--> $DIR/invalid-iterator-chain.rs:4:26
11+
|
12+
LL | fn iter_to_vec<'b, X>(i: Iter<'b, X>) -> Vec<X> {
13+
| ^^^^^^^^^^^ `Iterator::Item` is `&X` here
14+
LL | let i = i.map(|x| x.clone());
15+
| ------------------ `Iterator::Item` remains `&X` here
16+
note: required by a bound in `collect`
17+
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
18+
119
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
2-
--> $DIR/invalid-iterator-chain.rs:7:27
20+
--> $DIR/invalid-iterator-chain.rs:15:27
321
|
422
LL | println!("{}", scores.sum::<i32>());
523
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
@@ -9,7 +27,7 @@ LL | println!("{}", scores.sum::<i32>());
927
<i32 as Sum<&'a i32>>
1028
<i32 as Sum>
1129
note: the method call chain might not have had the expected associated types
12-
--> $DIR/invalid-iterator-chain.rs:4:10
30+
--> $DIR/invalid-iterator-chain.rs:12:10
1331
|
1432
LL | let scores = vec![(0, 0)]
1533
| ------------ this expression has type `Vec<({integer}, {integer})>`
@@ -24,7 +42,7 @@ note: required by a bound in `std::iter::Iterator::sum`
2442
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
2543

2644
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
27-
--> $DIR/invalid-iterator-chain.rs:18:14
45+
--> $DIR/invalid-iterator-chain.rs:26:14
2846
|
2947
LL | .sum::<i32>(),
3048
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
@@ -34,7 +52,7 @@ LL | .sum::<i32>(),
3452
<i32 as Sum<&'a i32>>
3553
<i32 as Sum>
3654
note: the method call chain might not have had the expected associated types
37-
--> $DIR/invalid-iterator-chain.rs:12:14
55+
--> $DIR/invalid-iterator-chain.rs:20:14
3856
|
3957
LL | vec![0, 1]
4058
| ---------- this expression has type `Vec<{integer}>`
@@ -56,7 +74,7 @@ note: required by a bound in `std::iter::Iterator::sum`
5674
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
5775

5876
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `f64`
59-
--> $DIR/invalid-iterator-chain.rs:28:14
77+
--> $DIR/invalid-iterator-chain.rs:36:14
6078
|
6179
LL | .sum::<i32>(),
6280
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=f64>`
@@ -66,7 +84,7 @@ LL | .sum::<i32>(),
6684
<i32 as Sum<&'a i32>>
6785
<i32 as Sum>
6886
note: the method call chain might not have had the expected associated types
69-
--> $DIR/invalid-iterator-chain.rs:24:14
87+
--> $DIR/invalid-iterator-chain.rs:32:14
7088
|
7189
LL | vec![0, 1]
7290
| ---------- this expression has type `Vec<{integer}>`
@@ -84,7 +102,7 @@ note: required by a bound in `std::iter::Iterator::sum`
84102
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
85103

86104
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
87-
--> $DIR/invalid-iterator-chain.rs:30:54
105+
--> $DIR/invalid-iterator-chain.rs:38:54
88106
|
89107
LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
90108
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
@@ -94,7 +112,7 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
94112
<i32 as Sum<&'a i32>>
95113
<i32 as Sum>
96114
note: the method call chain might not have had the expected associated types
97-
--> $DIR/invalid-iterator-chain.rs:30:38
115+
--> $DIR/invalid-iterator-chain.rs:38:38
98116
|
99117
LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
100118
| ---------- ------ ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
@@ -105,7 +123,7 @@ note: required by a bound in `std::iter::Iterator::sum`
105123
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
106124

107125
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()`
108-
--> $DIR/invalid-iterator-chain.rs:31:40
126+
--> $DIR/invalid-iterator-chain.rs:39:40
109127
|
110128
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
111129
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
@@ -115,7 +133,7 @@ LL | println!("{}", vec![(), ()].iter().sum::<i32>());
115133
<i32 as Sum<&'a i32>>
116134
<i32 as Sum>
117135
note: the method call chain might not have had the expected associated types
118-
--> $DIR/invalid-iterator-chain.rs:31:33
136+
--> $DIR/invalid-iterator-chain.rs:39:33
119137
|
120138
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
121139
| ------------ ^^^^^^ `Iterator::Item` is `&()` here
@@ -125,15 +143,15 @@ note: required by a bound in `std::iter::Iterator::sum`
125143
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
126144

127145
error[E0277]: a value of type `Vec<i32>` cannot be built from an iterator over elements of type `()`
128-
--> $DIR/invalid-iterator-chain.rs:40:25
146+
--> $DIR/invalid-iterator-chain.rs:48:25
129147
|
130148
LL | let g: Vec<i32> = f.collect();
131149
| ^^^^^^^ value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=()>`
132150
|
133151
= help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
134152
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
135153
note: the method call chain might not have had the expected associated types
136-
--> $DIR/invalid-iterator-chain.rs:36:15
154+
--> $DIR/invalid-iterator-chain.rs:44:15
137155
|
138156
LL | let a = vec![0];
139157
| ------- this expression has type `Vec<{integer}>`
@@ -153,6 +171,6 @@ LL | let f = e.filter(|_| false);
153171
note: required by a bound in `collect`
154172
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
155173

156-
error: aborting due to 6 previous errors
174+
error: aborting due to 7 previous errors
157175

158176
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)