Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants