Skip to content

Commit 3a98e5e

Browse files
author
Lukas Markeffsky
committed
suppress fulfillment errors for super projections
1 parent 555ee91 commit 3a98e5e

File tree

5 files changed

+48
-160
lines changed

5 files changed

+48
-160
lines changed

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

+38-31
Original file line numberDiff line numberDiff line change
@@ -1370,38 +1370,45 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
13701370
return true;
13711371
}
13721372

1373-
// FIXME: It should be possible to deal with `ForAll` in a cleaner way.
1374-
let bound_error = error.kind();
1375-
let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) {
1376-
(
1377-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)),
1378-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(error)),
1379-
) => (cond, bound_error.rebind(error)),
1380-
_ => {
1381-
// FIXME: make this work in other cases too.
1382-
return false;
1383-
}
1384-
};
1385-
1386-
for pred in elaborate(self.tcx, std::iter::once(cond)) {
1387-
let bound_predicate = pred.kind();
1388-
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(implication)) =
1389-
bound_predicate.skip_binder()
1390-
{
1391-
let error = error.to_poly_trait_ref();
1392-
let implication = bound_predicate.rebind(implication.trait_ref);
1393-
// FIXME: I'm just not taking associated types at all here.
1394-
// Eventually I'll need to implement param-env-aware
1395-
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
1396-
let param_env = ty::ParamEnv::empty();
1397-
if self.can_sub(param_env, error, implication) {
1398-
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
1399-
return true;
1400-
}
1401-
}
1373+
if let Some(error) = error.to_opt_poly_trait_pred() {
1374+
elaborate(self.tcx, std::iter::once(cond))
1375+
.filter_map(|implied| implied.to_opt_poly_trait_pred())
1376+
.any(|implied| {
1377+
if error.polarity() != implied.polarity() {
1378+
return false;
1379+
}
1380+
let error = error.to_poly_trait_ref();
1381+
let implied = implied.to_poly_trait_ref();
1382+
// FIXME: I'm just not taking associated types at all here.
1383+
// Eventually I'll need to implement param-env-aware
1384+
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
1385+
let param_env = ty::ParamEnv::empty();
1386+
let is_implied = self.can_sub(param_env, error, implied);
1387+
if is_implied {
1388+
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
1389+
}
1390+
is_implied
1391+
})
1392+
} else if let Some(error) = error.to_opt_poly_projection_pred() {
1393+
self.enter_forall(error, |error| {
1394+
elaborate(self.tcx, std::iter::once(cond))
1395+
.filter_map(|implied| implied.to_opt_poly_projection_pred())
1396+
.any(|implied| {
1397+
self.enter_forall(implied, |implied| {
1398+
let param_env = ty::ParamEnv::empty();
1399+
let is_implied =
1400+
self.can_eq(param_env, error.projection_ty, implied.projection_ty)
1401+
&& self.can_eq(param_env, error.term, implied.term);
1402+
if is_implied {
1403+
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
1404+
}
1405+
is_implied
1406+
})
1407+
})
1408+
})
1409+
} else {
1410+
false
14021411
}
1403-
1404-
false
14051412
}
14061413

14071414
#[instrument(skip(self), level = "debug")]

tests/ui/issues/issue-33941.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ use std::collections::HashMap;
55
fn main() {
66
for _ in HashMap::new().iter().cloned() {} //~ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
77
//~^ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
8-
//~| ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
98
}

tests/ui/issues/issue-33941.stderr

+1-11
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,6 @@ LL | for _ in HashMap::new().iter().cloned() {}
2727
= note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
2828
= note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator`
2929

30-
error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
31-
--> $DIR/issue-33941.rs:6:14
32-
|
33-
LL | for _ in HashMap::new().iter().cloned() {}
34-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(&_, &_)`, found `&_`
35-
|
36-
= note: expected tuple `(&_, &_)`
37-
found reference `&_`
38-
= note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
39-
40-
error: aborting due to 3 previous errors
30+
error: aborting due to 2 previous errors
4131

4232
For more information about this error, try `rustc --explain E0271`.

tests/ui/trait-bounds/super-assoc-mismatch.rs

-5
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,17 @@ trait Sub: Super<Assoc = u16> {}
99
trait BoundOnSelf: Sub {}
1010
impl BoundOnSelf for () {}
1111
//~^ ERROR the trait bound `(): Sub` is not satisfied
12-
//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
1312

1413
trait BoundOnParam<T: Sub> {}
1514
impl BoundOnParam<()> for () {}
1615
//~^ ERROR the trait bound `(): Sub` is not satisfied
17-
//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
1816

1917
trait BoundOnAssoc {
2018
type Assoc: Sub;
2119
}
2220
impl BoundOnAssoc for () {
2321
type Assoc = ();
2422
//~^ ERROR the trait bound `(): Sub` is not satisfied
25-
//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
2623
}
2724

2825
trait BoundOnGat where Self::Assoc<u8>: Sub {
@@ -31,11 +28,9 @@ trait BoundOnGat where Self::Assoc<u8>: Sub {
3128
impl BoundOnGat for u8 {
3229
type Assoc<T> = ();
3330
//~^ ERROR the trait bound `(): Sub` is not satisfied
34-
//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
3531
}
3632

3733
fn trivial_bound() where (): Sub {}
3834
//~^ ERROR the trait bound `(): Sub` is not satisfied
39-
//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
4035

4136
fn main() {}

tests/ui/trait-bounds/super-assoc-mismatch.stderr

+9-112
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,8 @@ note: required by a bound in `BoundOnSelf`
1515
LL | trait BoundOnSelf: Sub {}
1616
| ^^^ required by this bound in `BoundOnSelf`
1717

18-
error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
19-
--> $DIR/super-assoc-mismatch.rs:10:22
20-
|
21-
LL | impl BoundOnSelf for () {}
22-
| ^^ type mismatch resolving `<() as Super>::Assoc == u16`
23-
|
24-
note: expected this to be `u16`
25-
--> $DIR/super-assoc-mismatch.rs:5:18
26-
|
27-
LL | type Assoc = u8;
28-
| ^^
29-
note: required for `()` to implement `Sub`
30-
--> $DIR/super-assoc-mismatch.rs:7:7
31-
|
32-
LL | trait Sub: Super<Assoc = u16> {}
33-
| ^^^
34-
note: required by a bound in `BoundOnSelf`
35-
--> $DIR/super-assoc-mismatch.rs:9:20
36-
|
37-
LL | trait BoundOnSelf: Sub {}
38-
| ^^^ required by this bound in `BoundOnSelf`
39-
4018
error[E0277]: the trait bound `(): Sub` is not satisfied
41-
--> $DIR/super-assoc-mismatch.rs:15:27
19+
--> $DIR/super-assoc-mismatch.rs:14:27
4220
|
4321
LL | impl BoundOnParam<()> for () {}
4422
| ^^ the trait `Sub` is not implemented for `()`
@@ -49,35 +27,13 @@ help: this trait has no implementations, consider adding one
4927
LL | trait Sub: Super<Assoc = u16> {}
5028
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5129
note: required by a bound in `BoundOnParam`
52-
--> $DIR/super-assoc-mismatch.rs:14:23
53-
|
54-
LL | trait BoundOnParam<T: Sub> {}
55-
| ^^^ required by this bound in `BoundOnParam`
56-
57-
error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
58-
--> $DIR/super-assoc-mismatch.rs:15:27
59-
|
60-
LL | impl BoundOnParam<()> for () {}
61-
| ^^ type mismatch resolving `<() as Super>::Assoc == u16`
62-
|
63-
note: expected this to be `u16`
64-
--> $DIR/super-assoc-mismatch.rs:5:18
65-
|
66-
LL | type Assoc = u8;
67-
| ^^
68-
note: required for `()` to implement `Sub`
69-
--> $DIR/super-assoc-mismatch.rs:7:7
70-
|
71-
LL | trait Sub: Super<Assoc = u16> {}
72-
| ^^^
73-
note: required by a bound in `BoundOnParam`
74-
--> $DIR/super-assoc-mismatch.rs:14:23
30+
--> $DIR/super-assoc-mismatch.rs:13:23
7531
|
7632
LL | trait BoundOnParam<T: Sub> {}
7733
| ^^^ required by this bound in `BoundOnParam`
7834

7935
error[E0277]: the trait bound `(): Sub` is not satisfied
80-
--> $DIR/super-assoc-mismatch.rs:23:18
36+
--> $DIR/super-assoc-mismatch.rs:21:18
8137
|
8238
LL | type Assoc = ();
8339
| ^^ the trait `Sub` is not implemented for `()`
@@ -88,35 +44,13 @@ help: this trait has no implementations, consider adding one
8844
LL | trait Sub: Super<Assoc = u16> {}
8945
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9046
note: required by a bound in `BoundOnAssoc::Assoc`
91-
--> $DIR/super-assoc-mismatch.rs:20:17
92-
|
93-
LL | type Assoc: Sub;
94-
| ^^^ required by this bound in `BoundOnAssoc::Assoc`
95-
96-
error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
97-
--> $DIR/super-assoc-mismatch.rs:23:18
98-
|
99-
LL | type Assoc = ();
100-
| ^^ type mismatch resolving `<() as Super>::Assoc == u16`
101-
|
102-
note: expected this to be `u16`
103-
--> $DIR/super-assoc-mismatch.rs:5:18
104-
|
105-
LL | type Assoc = u8;
106-
| ^^
107-
note: required for `<() as BoundOnAssoc>::Assoc` to implement `Sub`
108-
--> $DIR/super-assoc-mismatch.rs:7:7
109-
|
110-
LL | trait Sub: Super<Assoc = u16> {}
111-
| ^^^
112-
note: required by a bound in `BoundOnAssoc::Assoc`
113-
--> $DIR/super-assoc-mismatch.rs:20:17
47+
--> $DIR/super-assoc-mismatch.rs:18:17
11448
|
11549
LL | type Assoc: Sub;
11650
| ^^^ required by this bound in `BoundOnAssoc::Assoc`
11751

11852
error[E0277]: the trait bound `(): Sub` is not satisfied
119-
--> $DIR/super-assoc-mismatch.rs:32:21
53+
--> $DIR/super-assoc-mismatch.rs:29:21
12054
|
12155
LL | type Assoc<T> = ();
12256
| ^^ the trait `Sub` is not implemented for `()`, which is required by `<u8 as BoundOnGat>::Assoc<u8>: Sub`
@@ -127,35 +61,13 @@ help: this trait has no implementations, consider adding one
12761
LL | trait Sub: Super<Assoc = u16> {}
12862
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12963
note: required by a bound in `BoundOnGat`
130-
--> $DIR/super-assoc-mismatch.rs:28:41
131-
|
132-
LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
133-
| ^^^ required by this bound in `BoundOnGat`
134-
135-
error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
136-
--> $DIR/super-assoc-mismatch.rs:32:21
137-
|
138-
LL | type Assoc<T> = ();
139-
| ^^ type mismatch resolving `<() as Super>::Assoc == u16`
140-
|
141-
note: expected this to be `u16`
142-
--> $DIR/super-assoc-mismatch.rs:5:18
143-
|
144-
LL | type Assoc = u8;
145-
| ^^
146-
note: required for `<u8 as BoundOnGat>::Assoc<u8>` to implement `Sub`
147-
--> $DIR/super-assoc-mismatch.rs:7:7
148-
|
149-
LL | trait Sub: Super<Assoc = u16> {}
150-
| ^^^
151-
note: required by a bound in `BoundOnGat`
152-
--> $DIR/super-assoc-mismatch.rs:28:41
64+
--> $DIR/super-assoc-mismatch.rs:25:41
15365
|
15466
LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
15567
| ^^^ required by this bound in `BoundOnGat`
15668

15769
error[E0277]: the trait bound `(): Sub` is not satisfied
158-
--> $DIR/super-assoc-mismatch.rs:37:26
70+
--> $DIR/super-assoc-mismatch.rs:33:26
15971
|
16072
LL | fn trivial_bound() where (): Sub {}
16173
| ^^^^^^^ the trait `Sub` is not implemented for `()`
@@ -168,21 +80,6 @@ LL | trait Sub: Super<Assoc = u16> {}
16880
= help: see issue #48214
16981
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
17082

171-
error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
172-
--> $DIR/super-assoc-mismatch.rs:37:26
173-
|
174-
LL | fn trivial_bound() where (): Sub {}
175-
| ^^^^^^^ type mismatch resolving `<() as Super>::Assoc == u16`
176-
|
177-
note: expected this to be `u8`
178-
--> $DIR/super-assoc-mismatch.rs:5:18
179-
|
180-
LL | type Assoc = u8;
181-
| ^^
182-
= help: see issue #48214
183-
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
184-
185-
error: aborting due to 10 previous errors
83+
error: aborting due to 5 previous errors
18684

187-
Some errors have detailed explanations: E0271, E0277.
188-
For more information about an error, try `rustc --explain E0271`.
85+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)