Description
The following code causes an ICE, Error: the type `T` has an unknown layout
:
#![feature(arbitrary_self_types, dispatch_from_dyn)]
use std::ops::{Deref, DispatchFromDyn};
trait Trait<T: Deref<Target=Self> + DispatchFromDyn<T>> {
fn foo(self: T) -> dyn Trait<T>;
}
Similar to #56806, receiver_is_dispatchable
succeeds, and then there is an ICE during the layout sanity checks. In this case, it is because the method receiver is a type parameter and has no layout.
receiver_is_dispatchable
checks that the following predicate holds:
forall (U: Trait + ?Sized) {
if (Self: Unsize<U>) {
Receiver: DispatchFromDyn<Receiver[Self => U]>
}
}
In this case, it reduces to T: DispatchFromDyn<T>
, which is provided by a where clause. In #56806, it reduced to Box<dyn Trait>: DispatchFromDyn<Box<dyn Trait>>
. The check passes in both cases, and then there is an ICE during the layout sanity checks.
One way to fix both of these cases would be to add an extra requirement to receiver_is_dispatchable
: that Receiver
and Receiver[Self => U]
are not the same type. I'm not sure if there are any edge cases that that doesn't cover.