Skip to content

Receiver when Self = () should have a Scalar ABI, found ScalarPair ... #56806

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
sunchao opened this issue Dec 14, 2018 · 2 comments · Fixed by #57229 or #57354
Closed

Receiver when Self = () should have a Scalar ABI, found ScalarPair ... #56806

sunchao opened this issue Dec 14, 2018 · 2 comments · Fixed by #57229 or #57354

Comments

@sunchao
Copy link

sunchao commented Dec 14, 2018

I was trying this code:

use std::any::Any;

pub trait Foo {
  fn to_any(self: Box<Foo>) -> Box<Any>;
}

pub fn main() {
  println!("GOOD");
}

I know, this doesn't make much sense, but I was expecting a proper error message. Instead, I got:

error[E0307]: invalid `self` type: std::boxed::Box<(dyn Foo + 'static)>
 --> src/bin/test.rs:4:19
  |
4 |   fn to_any(self: Box<Foo>) -> Box<Any>;
  |                   ^^^^^^^^
  |
  = note: type must be `Self` or a type that dereferences to it
  = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`

error: internal compiler error: src/librustc/traits/object_safety.rs:353: Receiver when Self = () should have a Scalar ABI, found ScalarPair(Scalar { value: Pointer, valid_range: 1..=18446744073709551615 }, Scalar { value: Pointer, valid_range: 1..=18446744073709551615 })

thread 'main' panicked at 'Box<Any>', src/librustc_errors/lib.rs:600:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0307`.

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.32.0-nightly (f4a421ee3 2018-12-13) running on x86_64-apple-darwin

note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin

note: some of the compiler flags provided by cargo are hidden
@varkor
Copy link
Member

varkor commented Dec 14, 2018

cc @mikeyhew

It's probably possible to fix this just by replacing the bug!s in virtual_call_violation_for_method with delay_span_bug and returning some new MethodViolationCode that doesn't print addition errors.

@mikeyhew
Copy link
Contributor

@sunchao thanks for reporting this!

@varkor thanks, that seems like the way to go. Since the function returns an Option, I'll just let it return None as usual.

mikeyhew added a commit to mikeyhew/rust that referenced this issue Jan 4, 2019
It's possible that `is_object_safe` is called on a trait that is ill-formed, and we shouldn't ICE unless there are no errors being raised. Using `delay_span_bug` solves this.

fixes rust-lang#56806
kennytm added a commit to kennytm/rust that referenced this issue Jan 5, 2019
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
bors added a commit that referenced this issue Jan 5, 2019
Rollup of 17 pull requests

Successful merges:

 - #57219 (Remove some unused code)
 - #57229 (Fix #56806 by using `delay_span_bug` in object safety layout sanity checks)
 - #57233 (Rename and fix nolink-with-link-args test)
 - #57238 (Fix backtraces for inlined functions on Windows)
 - #57249 (Fix broken links to second edition TRPL.)
 - #57267 (src/jemalloc is gone, remove its mention from COPYRIGHT)
 - #57273 (Update the stdsimd submodule)
 - #57278 (Add Clippy to config.toml.example)
 - #57295 (Fix 'be be' constructs)
 - #57311 (VaList::copy should not require a mutable ref)
 - #57312 (`const fn` is no longer coming soon (const keyword docs))
 - #57313 (Improve Box<T> -> Pin<Box<T>> conversion)
 - #57314 (Fix repeated word typos)
 - #57326 (Doc rewording, use the same name `writer`)
 - #57338 (rustdoc: force binary filename for compiled doctests)
 - #57342 (librustc_mir: Make qualify_min_const_fn module public)
 - #57343 (Calculate privacy access only via query)

Failed merges:

 - #57340 (Use correct tracking issue for c_variadic)

r? @ghost
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
3 participants