// 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 , 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 {} trait IdentityWithConstArgGoal { type Assoc; } impl IdentityWithConstArgGoal for T { type Assoc = T; } fn unsatisfied() where T: Foo, T: Baz<>::Assoc>, { } fn test() { unsatisfied::<(), N>(); //~^ ERROR the trait bound `(): Foo` is not satisfied } fn main() {}