Change:
<ins> error: constant expression depends on a generic parameter --> $DIR/issue-64494.rs:14:53 | LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} |                                                     ^^^^ | = note: this may fail depending on what value the parameter takes error: constant expression depends on a generic parameter --> $DIR/issue-64494.rs:16:53 | LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} |                                                     ^^^^ | = note: this may fail depending on what value the parameter takes error: aborting due to 2 previous errors </ins>

Discussion:
Consider the following code: Coherence checking needs to determine whether the two impls can ever overlap. This requires determining (among other things) if and will ever have the same value - if they do, then the impls will overlap. In this case, we can see that and can never both be true. However, in the general case, we could have an expression like . Coherence checking would need to determine if two const functions will ever produce the same value for a given input. This seems impossible without radically extending the Rust language and/or the abilities of the compiler. One solution would be to ban any const projections within clauses. That is, would be allowed, but would not be. This would ensure that it's always possible to fully const-eval an expression during coherence checking, which allows us to be certain about whether or not two impls overlap.
I think we actually need to ban all generic parameters from const expressions in trait impl clauses. Consider this code: This would require coherence checking to determine if any other impls have a const equal to the name of the type the trait is implelented on - or in general, any of the name. While this introduces an unfortunate inconsistency in const generics (these kinds of clauses are perfectly fine on functions), I don't sees any way around it.
Actually, there is one alternative: for the purposes of coherence checking, deliberately over approximate the cases where this kind of impl can apply. That is, we would treat an impl like as though the user had written That is, we treat the clause as always applying, which means that this impl would be considered to conflict with any other impl of . The impl would not actually apply for all - attempting to use it in any other code will cause the full impl to be used. I believe this would be sufficient to ensure that coherence never needs to 'invert' arbitrary const expressions.
It would be sensible for now to forbid arbitrary const expressions in clauses, and just allow generic parameters. We could extend this later once we've figured out all the subtleties.
Note to self: the example in the first post is a good test candidate for using the correct , as it currently fails.
It turns out that - it's generating impls of the form , , etc. We could add some kind of opt-out for libcore, but that seems like it could be more trouble than it's worth.

I think it would make sense to ban anything other than a plain const parameter (e.g. ) or const expressions that don't involve any generics whatsover (e.g. ). In the future, we could consider allowing some expressions involving const paramters, once we decide on how that will interact with coherence checking.
I feel like this issue is somewhat outdated and would go ahead and close this. is there something we should do here?
Looking at the original example: From what I know we do not reason about generic consts, so and will remain opaque during coherence checking (causing this example to fail). I will go ahead and mark this as so we don't accidentally allow this in the future and then close this. I do not think reasoning about generic consts is something we want to do in the near future.