forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconst-param-has-ty-goal-in-error-implies.rs
41 lines (34 loc) · 1.56 KB
/
const-param-has-ty-goal-in-error-implies.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// compile-flags: -Znext-solver
// Test for a weird diagnostics corner case. In the error reporting code, when reporting
// fulfillment errors for goals A and B, we try to see if elaborating A will result in
// another goal that can equate with B. That would signal that B is "implied by" A,
// allowing us to skip reporting it, which is beneficial for cutting down on the number
// of diagnostics we report. In the new trait solver especially, but even in the old trait
// solver through things like defining opaque type usages, this `can_equate` call was not
// properly taking the param-env of the goals, resulting in nested obligations that had
// empty param-envs. If one of these nested obligations was a `ConstParamHasTy` goal, then
// we would ICE, since those goals are particularly strict about the param-env they're
// evaluated in.
// This is morally a fix for <https://github.com/rust-lang/rust/issues/139314>, but that
// repro uses details about how defining usages in the `check_opaque_well_formed` code
// can spring out of type equality, and will likely stop failing soon coincidentally once
// we start using `PostBorrowck` mode in that check.
trait Foo: Baz<()> {}
trait Baz<T> {}
trait IdentityWithConstArgGoal<const N: usize> {
type Assoc;
}
impl<T, const N: usize> IdentityWithConstArgGoal<N> for T {
type Assoc = T;
}
fn unsatisfied<T, const N: usize>()
where
T: Foo,
T: Baz<<T as IdentityWithConstArgGoal<N>>::Assoc>,
{
}
fn test<const N: usize>() {
unsatisfied::<(), N>();
//~^ ERROR the trait bound `(): Foo` is not satisfied
}
fn main() {}