6c58b842d6
Fix #56806 by using `delay_span_bug` in object safety layout sanity checks It's possible that `is_object_safe` is called on a trait method that with an invalid receiver type. This caused an ICE in #56806, because `receiver_is_dispatchable` returns `true` for `self: Box<dyn Trait>`, which causes one of the layout sanity checks in object_safety.rs to fail. Replacing `bug!` with `delay_span_bug` solves this. The fact that `receiver_is_dispatchable` returns `true` here could be considered a bug. It passes the check that the method implements, though: `Box<dyn Trait>` implements `DispatchFromDyn<Box<dyn Trait>>` because `dyn Trait` implements `Unsize<dyn Trait>`. It would be good to hear what @eddyb and @nikomatsakis think. Note that I only added a test for the case encountered in #56806. I could not come up with a case that triggered an ICE from the other check, `bug!("receiver when Self = dyn Trait should be ScalarPair, found Scalar")`. There is no way, to my knowledge, that you can make `receiver_is_dispatchable` return true but still have a `Scalar` ABI when `Self = dyn Trait`. One other case I encountered while debugging #56806 was that if you have a type parameter `T` that implements `Deref<Target=Self>` and `DispatchFromDyn<T>`, and use it as a method receiver, it will cause an ICE during `is_object_safe` because `T` has no layout ([playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d9b7497b3be0ca8382fa7d9497263214)): ```rust trait Trait<T: Deref<Target=Self> + DispatchFromDyn<T>> { fn foo(self: T) -> dyn Trait<T>; } ``` I don't intend to remove the ICE there because it is a pathological case, especially since there is no way to implement `DispatchFromDyn<T>` for `T` — the checks in typeck/coherence/builtin.rs do not allow that. fixes #56806 r? @varkor |
||
---|---|---|
.. | ||
codegen | ||
query | ||
specialize | ||
auto_trait.rs | ||
chalk_fulfill.rs | ||
coherence.rs | ||
engine.rs | ||
error_reporting.rs | ||
fulfill.rs | ||
mod.rs | ||
object_safety.rs | ||
on_unimplemented.rs | ||
project.rs | ||
select.rs | ||
structural_impls.rs | ||
util.rs |