Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Minimized a bit
Okay so this works: this fails:
<details<summaryAnother even more minimized example</summary</detailsOkay, so ultimately, this ends up being very similar to . At some point or another, depending on specific variations of this test, we require that is . This is hairy (I'll get to that shortly), but basically, we can't. This is a problem, and we run into a layout error here: We probably should be giving a smarter error here; enums should always be sized. Okay, so now to explain why we can't prove that is : So looks like to prove this is , we only have to prove that is . Let's imagine the where clause wasn't there. Then, it might be obvious that we could get a recursive cycle (it's a bit complicated, but we do). However, supposedly that where clause is supposed to help us, right? There's a few problems here. But one problem is that when we collect the size predicates, we try to eagerly normalize them . That alone isn't a problem, but it means we can't use that where clause. But, to normalize, we have to check that , we also require that , so ; so, even projecting gives us problems! A simple solution here is to change the associated type definition to be I'm not sure removing the eager normalization call above would itself be enough. We theoretically can normalize, we specifically don't want to (and anywhere else that tries will run into more problems; this includes if the attempts to normalize before proving the sized predicate!).
No longer ICEs since
Woah. Unexpected.

Discussion:
<ins> // check-pass // // regression test for #88071 #![feature(const_btree_new)] #![feature(const_fn_trait_bound)] use std::collections::BTreeMap; pub struct CustomMap<K, V>(BTreeMap<K, V>); impl<K, V> CustomMap<K, V> where K: Ord, { pub const fn new() -> Self { CustomMap(BTreeMap::new()) } } fn main() {} </ins>

<ins> #![feature(generic_associated_types)] trait PointerFamily { type Pointer<T>; } struct Rc<T>(Box<T>); struct RcFamily; impl PointerFamily for RcFamily { type Pointer<T> = Rc<T>; } #[allow(dead_code)] enum Node<T, P: PointerFamily> where P::Pointer<Node<T, P>>: Sized { Cons(P::Pointer<Node<T, P>>), } fn main() { let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>; //~^ ERROR overflow evaluating the requirement `Node<i32, RcFamily>: Sized` } </ins>

<ins> error[E0275]: overflow evaluating the requirement `Node<i32, RcFamily>: Sized` --> $DIR/issue-87750.rs:20:16 | LL |     let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>; |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0275`. </ins>

<ins> // check-fail // // regression test for issue 52893 trait At<Name> { type AtRes; fn at(self) -> Self::AtRes; } trait Push<T> { type PushRes; fn push(self, other: T) -> Self::PushRes; } trait AddClass<Name, F> { type AddRes; fn init(self, func: F); } trait ToRef { type RefRes; fn to_ref(&self) -> Self::RefRes; } struct Class<P>(P); impl<P> Class<P> { fn with<Name, F>(self) -> <Self as AddClass<Name, F>>::AddRes where Self: AddClass<Name, F>, { todo!() } fn from<F>(self) -> <Self as AddClass<P, F>>::AddRes where Self: AddClass<P, F>, { todo!() } } impl<F, Name, P> AddClass<Name, F> for Class<P> where Self: At<Name>, <Self as At<Name>>::AtRes: Push<F>, <<Self as At<Name>>::AtRes as Push<F>>::PushRes: ToRef<RefRes = Self> + Push<F>, { type AddRes = (); fn init(self, func: F) { let builder = self.at().push(func); let output = builder.to_ref(); builder.push(output); //~ ERROR mismatched types [E0308] } } fn main() {} </ins>

<ins> error[E0308]: mismatched types --> $DIR/issue-52893.rs:53:22 | LL | impl<F, Name, P> AddClass<Name, F> for Class<P> |      - this type parameter ... LL |         builder.push(output); |                      ^^^^^^ expected type parameter `F`, found struct `Class` | = note: expected type parameter `F` found struct `Class<P>` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>

<ins> // check-fail // // regression test for #68295 struct Matrix<R, C, S>(R, C, S); impl<R, C, S> Matrix<R, C, S> { fn into_owned(self) -> Matrix<R, C, Owned<R, C, ()>> where (): Allocator<R, C>, { unimplemented!() } } impl<D, S> Matrix<D, D, S> { fn hermitian_part(&self) -> Matrix<D, D, Owned<D, D, ()>> where (): Allocator<D, D>, { unimplemented!() } } trait Allocator<R, C> { type Buffer; } trait Trait<R, C, A> { type Power; } impl<R, C, A: Allocator<R, C>> Trait<R, C, A> for () { type Power = A::Buffer; } type Owned<R, C, G> = <G as Trait<R, C, ()>>::Power; fn crash<R, C>(input: Matrix<R, C, ()>) -> Matrix<R, C, u32> where (): Allocator<R, C>, { input.into_owned() //~^ ERROR mismatched types [E0308] } fn main() {} </ins>

<ins> error[E0308]: mismatched types --> $DIR/issue-68295.rs:43:5 | LL | fn crash<R, C>(input: Matrix<R, C, ()>) -> Matrix<R, C, u32> |                                            ----------------- expected `Matrix<R, C, u32>` because of return type ... LL |     input.into_owned() |     ^^^^^^^^^^^^^^^^^^ expected `u32`, found associated type | = note: expected struct `Matrix<_, _, u32>` found struct `Matrix<_, _, <() as Allocator<R, C>>::Buffer>` = help: consider constraining the associated type `<() as Allocator<R, C>>::Buffer` to `u32` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>