Repository: rust
Issue: feature(generic_const_exprs) / cycle detected when building an abstract representation for the const argument
Labels: T-compiler,C-bug,requires-nightly,F-generic_const_exprs,requires-incomplete-features,I-cycle

It's not possible to implement the trait PartialEq with RHS set to a type with a constant parameter for the type of that parameter.

I tried this code (condensed from a more elaborate code base):

```rust
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![feature(associated_type_bounds)]

pub trait True {}
pub struct PrecLimitCheck<const CHECK: bool> {}
impl True for PrecLimitCheck<true> {}

pub const MAX_PREC: u8 = 9;

#[derive(Copy, Clone)]
pub struct Decimal<const P: u8>
where
    PrecLimitCheck<{ P <= MAX_PREC }>: True,
{
    coeff: i128,
}

impl<const P: u8, const Q: u8> PartialEq<Decimal<Q>> for Decimal<P>
where
    PrecLimitCheck<{ P <= MAX_PREC }>: True,
    PrecLimitCheck<{ Q <= MAX_PREC }>: True,
{
    fn eq(&self, other: &Decimal<Q>) -> bool {
        // real impl is different!
        self.coeff == other.coeff
    }
}

impl<const P: u8> PartialEq<u8> for Decimal<P>
where
    PrecLimitCheck<{ P <= MAX_PREC }>: True,
{
    fn eq(&self, other: &u8) -> bool {
        // real impl is different!
        self.coeff == *other as i128
    }
}

impl<const P: u8> PartialEq<Decimal<P>> for u8
where
    PrecLimitCheck<{ P <= MAX_PREC }>: True,
{
    fn eq(&self, other: &Decimal<P>) -> bool {
        // real impl is different!
        *self as i128 == (*other).coeff
    }
}

fn main() {}
```

I expected to see this happen: compiles without error.

Instead, the compiler gave the following error message:
``` 
error[E0391]: cycle detected when building an abstract representation for the const argument <impl at src/main.rs:42:1: 50:2>::{constant#0}
  --> src/main.rs:44:20
   |
44 |     PrecLimitCheck<{ P <= MAX_PREC }>: True,
   |                    ^^^^^^^^^^^^^^^^^
   |
note: ...which requires building THIR for `<impl at src/main.rs:42:1: 50:2>::{constant#0}`...
  --> src/main.rs:44:20
   |
44 |     PrecLimitCheck<{ P <= MAX_PREC }>: True,
   |                    ^^^^^^^^^^^^^^^^^
note: ...which requires type-checking the const argument `<impl at src/main.rs:42:1: 50:2>::{constant#0}`...
  --> src/main.rs:44:20
   |
44 |     PrecLimitCheck<{ P <= MAX_PREC }>: True,
   |                    ^^^^^^^^^^^^^^^^^
note: ...which requires trying to unify the generic constants <impl at src/main.rs:42:1: 50:2>::{constant#0} and <impl at src/main.rs:42:1: 50:2>::{constant#0}...
  --> src/main.rs:44:20
   |
44 |     PrecLimitCheck<{ P <= MAX_PREC }>: True,
   |                    ^^^^^^^^^^^^^^^^^
   = note: ...which again requires building an abstract representation for the const argument <impl at src/main.rs:42:1: 50:2>::{constant#0}, completing the cycle
note: cycle used when trying to unify the generic constants <impl at src/main.rs:42:1: 50:2>::{constant#0} and <impl at src/main.rs:21:1: 30:2>::{constant#1}
  --> src/main.rs:44:20
   |
44 |     PrecLimitCheck<{ P <= MAX_PREC }>: True,
   |                    ^^^^^^^^^^^^^^^^^
```

Especially the part "... to unify the generic constants <impl at src/main.rs:42:1: 50:2>::{constant#0} and <impl at src/main.rs:42:1: 50:2>::{constant#0}" seems odd.

Implementing PartialEq works for any integer type other than the type of the constant type parameter.

Implementing other traits (for example Add and Mul) in a similar way works without an error.

### Meta

`rustc --version --verbose`:
```
rustc 1.58.0-nightly (29b124802 2021-10-25)
binary: rustc
commit-hash: 29b1248025b19bd132c8047fc710ea9314b9b76b
commit-date: 2021-10-25
host: x86_64-unknown-linux-gnu
release: 1.58.0-nightly
LLVM version: 13.0.0
```

Running with RUST_BACKTRACE=1 does not provide more details than the error message shown above.