Unnamed repository; edit this file 'description' to name the repository.
Rollup merge of #153513 - fmease:gate-eq-pred, r=jackh726
Syntactically reject equality predicates
### Background (History)
Equality predicates have been *syntactically* valid since PR rust-lang/rust#39158 / nightly-2017-02-02 / 1.16 (released 2017-03-16, 9 years ago), both forms that is: `$ty = $ty` *and* `$ty == $ty`. They're not registered as an unstable feature despite having a tracking issue (rust-lang/rust#20041). Naturally, they don't have a feature gate. Of course, we reject them post-expansion, so they are still semantically invalid.
Parser scaffolding for `$ident = $ty` was added in RUST-19391 (2014) which was then generalized to `$ty = $ty` in RUST-20002 (2014) and extended to additionally cover `$ty == $ty` in RUST-39158 (2017). As mentioned, the last PR also made them grammatical.
RUST-87471 (2021) attempted to start impl'ing typeck'ing but it was closed due to concerns: https://github.com/rust-lang/rust/pull/87471#issuecomment-889831233 (already back in 2017 there were concerns: https://github.com/rust-lang/rust/pull/39158/changes#r97811244).
In 2022, T-lang discussed this feature during a meeting and raised concerns: https://github.com/rust-lang/rust/issues/20041#issuecomment-1062456506. However, they were inclined to accept a restricted form, namely `T::AssocTy = $ty` (`T` is a (self) ty param or a self ty alias) and `<$ty as Trait>::AssocTy = $ty` since that's trivial to support in HIR ty lowering (this is still accurate).
### Change
This renders equality predicates `$ty = $ty` and `$ty == $ty` syntactically invalid again. On stable, they're merely semantically invalid. This is motivated by the fact that
1. their syntax isn't even decided upon
1. should it be `=` or `==`?
2. should the LHS be syntactically restricted to (possibly qualified) paths (i.e., *TypePath | QualifiedPathInType*), only semantically or not at all?
* "syntactically" could indeed make sense since we might want to generalize types to so-called *terms* here (i.e., *Type | GenericArgsConst*) for [mGCA](https://github.com/rust-lang/rust/issues/132980) but we can't generalize `$ty = $ty` to `$term = $term` due to ambiguities [^1] that would require backtracking whereas `$typepath = $term` wouldn't have that problem
2. we might (decide to) never impl this feature
* after all, implementation concerns were raised as early as 9 years ago which are still relevant today even with the next-gen trait solver on the horizon
3. the compiler + tools contain a bunch of code for dealing with these predicates
* like lowering, name resolution, rustfmt and Clippy
* that's entirely useless since they get unconditionally rejected anyway
* this code doesn't need to exist (for now)
I've merely upgraded the semantic hard error to a syntactic hard error, I've intentionally not introduced an unstable feature under which equality predicates become legal.
That's because a hard error is easier to push through procedurally, it's an important first step (we can always turn it into a feature gate error later on) and since this potential feature isn't backed by any official lang experiment.
I don't consider T-lang's message https://github.com/rust-lang/rust/issues/20041#issuecomment-1062456506 from 2022 to be sufficient because it doesn't answer questions like (1.i), (1.ii) or whether code like `T: Trait<A>, <T as Trait<B>>::AssocTy = Ty` (`A` ≠ `B`) or `T: Trait<'r>, for<'a> <T as Trait<'a>>::AssocTy = Ty` should be legal (which would be more powerful / could lead to typechecking issues, idk) or not assuming we're going with the restricted form ofc (we would need input from T-types).
### Lang nomination
https://github.com/rust-lang/rust/pull/153513#issuecomment-4069728773
[^1]: Code like `fn f() -> i32 where { 0 }` is intentionally legal today but if we had `$term = $term` the `{ 0 }` could then also be the start of an equality predicate like `{ 0 } = 0`.