Skip to content

Commit 6c58b84

Browse files
authored
Rollup merge of rust-lang#57229 - mikeyhew:fix-56806, r=varkor
Fix rust-lang#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 rust-lang#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 rust-lang#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 rust-lang#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 rust-lang#56806 r? @varkor
2 parents aa83481 + 2433526 commit 6c58b84

File tree

3 files changed

+37
-5
lines changed

3 files changed

+37
-5
lines changed

src/librustc/traits/object_safety.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,15 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
359359

360360
match abi_of_ty(unit_receiver_ty) {
361361
&Abi::Scalar(..) => (),
362-
abi => bug!("Receiver when Self = () should have a Scalar ABI, found {:?}", abi)
362+
abi => {
363+
self.sess.delay_span_bug(
364+
self.def_span(method.def_id),
365+
&format!(
366+
"Receiver when Self = () should have a Scalar ABI, found {:?}",
367+
abi
368+
),
369+
);
370+
}
363371
}
364372

365373
let trait_object_ty = self.object_ty_for_trait(
@@ -373,10 +381,15 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
373381

374382
match abi_of_ty(trait_object_receiver) {
375383
&Abi::ScalarPair(..) => (),
376-
abi => bug!(
377-
"Receiver when Self = {} should have a ScalarPair ABI, found {:?}",
378-
trait_object_ty, abi
379-
)
384+
abi => {
385+
self.sess.delay_span_bug(
386+
self.def_span(method.def_id),
387+
&format!(
388+
"Receiver when Self = {} should have a ScalarPair ABI, found {:?}",
389+
trait_object_ty, abi
390+
),
391+
);
392+
}
380393
}
381394
}
382395
}

src/test/ui/issues/issue-56806.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub trait Trait {
2+
fn dyn_instead_of_self(self: Box<dyn Trait>);
3+
//~^ ERROR invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
4+
}
5+
6+
pub fn main() {
7+
}

src/test/ui/issues/issue-56806.stderr

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0307]: invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
2+
--> $DIR/issue-56806.rs:2:34
3+
|
4+
LL | fn dyn_instead_of_self(self: Box<dyn Trait>);
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: type must be `Self` or a type that dereferences to it
8+
= help: consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0307`.

0 commit comments

Comments
 (0)