Skip to content

Commit 608d49a

Browse files
committed
Check for bound variables when reporting type error
`can_eq` ICEs if it's passed types with escaping bound variables, so we need to handle for them, even in error reporting.
1 parent 8365fcb commit 608d49a

File tree

3 files changed

+69
-9
lines changed

3 files changed

+69
-9
lines changed

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4076,16 +4076,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
40764076
})
40774077
} else if let Some(where_pred) = where_pred.as_projection_clause()
40784078
&& let Some(failed_pred) = failed_pred.as_projection_clause()
4079-
&& let Some(found) = failed_pred.skip_binder().term.as_type()
40804079
{
4081-
type_diffs = vec![TypeError::Sorts(ty::error::ExpectedFound {
4082-
expected: where_pred
4083-
.skip_binder()
4084-
.projection_term
4085-
.expect_ty(self.tcx)
4086-
.to_ty(self.tcx),
4087-
found,
4088-
})];
4080+
self.enter_forall(failed_pred, |failed_pred| {
4081+
if let Some(found) = failed_pred.term.as_type() {
4082+
let where_pred = self.instantiate_binder_with_fresh_vars(
4083+
expr.span,
4084+
BoundRegionConversionTime::HigherRankedType,
4085+
where_pred,
4086+
);
4087+
type_diffs = vec![TypeError::Sorts(ty::error::ExpectedFound {
4088+
expected: where_pred
4089+
.projection_term
4090+
.expect_ty(self.tcx)
4091+
.to_ty(self.tcx),
4092+
found,
4093+
})];
4094+
}
4095+
});
40894096
}
40904097
}
40914098
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Regression test for #145631
2+
3+
pub struct Foo {}
4+
5+
fn foo(foos: Vec<Foo>) {
6+
let foos = foos.iter().collect::<Vec<_>>();
7+
let bar = Bar {};
8+
bar.bar(foos);
9+
//~^ ERROR type mismatch resolving `<&Vec<&Foo> as IntoIterator>::Item == &Foo`
10+
}
11+
12+
struct Bar {}
13+
14+
impl Bar {
15+
pub fn bar<I>(&self, iter: I)
16+
where
17+
for<'a> &'a I: IntoIterator<Item = &'a Foo>,
18+
{
19+
}
20+
}
21+
22+
fn main() {}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0271]: type mismatch resolving `<&Vec<&Foo> as IntoIterator>::Item == &Foo`
2+
--> $DIR/mismatched-bound-projection-predicate.rs:8:13
3+
|
4+
LL | bar.bar(foos);
5+
| --- ^^^^ expected `&Foo`, found `&&Foo`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= note: expected reference `&Foo`
10+
found reference `&&Foo`
11+
note: the method call chain might not have had the expected associated types
12+
--> $DIR/mismatched-bound-projection-predicate.rs:6:21
13+
|
14+
LL | fn foo(foos: Vec<Foo>) {
15+
| -------- `IntoIterator::Item` is `Foo` here
16+
LL | let foos = foos.iter().collect::<Vec<_>>();
17+
| ^^^^^^ ------------------- `IntoIterator::Item` remains `&Foo` here
18+
| |
19+
| `IntoIterator::Item` changed to `&Foo` here
20+
note: required by a bound in `Bar::bar`
21+
--> $DIR/mismatched-bound-projection-predicate.rs:17:37
22+
|
23+
LL | pub fn bar<I>(&self, iter: I)
24+
| --- required by a bound in this associated function
25+
LL | where
26+
LL | for<'a> &'a I: IntoIterator<Item = &'a Foo>,
27+
| ^^^^^^^^^^^^^^ required by this bound in `Bar::bar`
28+
29+
error: aborting due to 1 previous error
30+
31+
For more information about this error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)