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

trying to implement type erasure causes type validation error in miri. #711

Closed
rodrimati1992 opened this issue Apr 23, 2019 · 2 comments
Closed

Comments

@rodrimati1992
Copy link

Trying to test my abi_stable crate in miri causes a type validation error in code that implements type erasure for ffi-safe trait objects.

A simplified version of what I am trying to do is this:

use std::{marker::PhantomData, mem::transmute, os::raw::c_void};

#[repr(transparent)]
struct ForAbi<T> {
    ptr_: *const c_void,
    type_: PhantomData<T>,
}

impl<'a, T> ForAbi<&'a T> {
    fn new(val: &'a T) -> Self {
        Self {
            ptr_: val as *const T as *const c_void,
            type_: PhantomData,
        }
    }

    fn into_inner(self) -> &'a T {
        unsafe { &*(self.ptr_ as *const T) }
    }
}

extern "C" fn what<T>(ptr_: ForAbi<&T>)
where
    T: std::fmt::Debug,
{
    let val = ptr_.into_inner();
    println!("{:?}", val);
}

fn main() {
    let val = ForAbi::new(&102);
    let (func, val) = unsafe {
        transmute::<
            (extern "C" fn(ForAbi<&i32>), ForAbi<&i32>),
            (extern "C" fn(ForAbi<&()>), ForAbi<&()>),
        >((what::<i32>, val))
    };

    func(val);
}

The error it prints:

   Compiling playground v0.0.1 (/playground)
error[E0080]: constant evaluation error: tried to call a function with argument of type ForAbi<&i32> passing data of type ForAbi<&()>
  --> src/main.rs:45:5
   |
45 |     func(val);
   |     ^^^^^^^^^ tried to call a function with argument of type ForAbi<&i32> passing data of type ForAbi<&()>
   |
   = note: inside call to `main` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:64:34
   = note: inside call to closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:52:53
   = note: inside call to closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panicking.rs:293:40
   = note: inside call to `std::panicking::try::do_call::<[closure@DefId(1/1:1834 ~ std[82ff]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panicking.rs:289:5
   = note: inside call to `std::panicking::try::<i32, [closure@DefId(1/1:1834 ~ std[82ff]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe]>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panic.rs:388:9
   = note: inside call to `std::panic::catch_unwind::<[closure@DefId(1/1:1834 ~ std[82ff]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:52:25
   = note: inside call to `std::rt::lang_start_internal` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:64:5
   = note: inside call to `std::rt::lang_start::<()>`
@rodrimati1992
Copy link
Author

I've decided to take the approach that the standard library takes with RawWakerVTable instead.

@RalfJung
Copy link
Member

tried to call a function with argument of type ForAbi<&i32> passing data of type ForAbi<&()>

This is currently rejected by Miri but might well be legal -- the rules for this are not set yet. Practically speaking, rust-lang/rust#56166 tracks changing the way we pass arguments in Miri to enable more realistic checking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants