Skip to content

Transmute from one function pointer to another produces "can't transmute zero-sized type" #75959

Open
@belkadan

Description

@belkadan

Compiling the following cursed code:

use std::ffi::CStr;

#[repr(C)]
struct ObjCObject {
  isa: isize
}

#[repr(transparent)]
#[derive(Clone,Copy)]
struct Selector(*const u8);

#[link(name = "objc")]
extern "C" {
  fn sel_registerName(name: *const u8) -> Selector;
  fn objc_getClass(name: *const u8) -> Option<&'static ObjCObject>;
  fn objc_msgSend(); // see below
}

fn main() {
  #[link(name = "Foundation", kind = "framework")]
  extern {}

  unsafe {
    let url_class = objc_getClass("NSURL\0".as_ptr()).unwrap();
    let description_sel = sel_registerName("description\0".as_ptr());
    let description_method = std::mem::transmute::<_, unsafe extern "C" fn(_, _) -> _>(objc_msgSend);
    let description_obj: *const ObjCObject = description_method(url_class, description_sel);

    let utf8_sel = sel_registerName("UTF8String\0".as_ptr());
    let utf8_method = std::mem::transmute::<_, unsafe extern "C" fn(_, _) -> _>(objc_msgSend);
    let utf8_ptr = utf8_method(description_obj, utf8_sel);
    println!("{}", CStr::from_ptr(utf8_ptr).to_string_lossy());
  }
}

Produces the following opaque error:

error[E0591]: can't transmute zero-sized type
  --> <anon>:26:30
   |
26 | ...hod = std::mem::transmute::<_, unsafe extern "C" fn(_, _) -> _>(objc_...
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: source type: unsafe extern "C" fn() {objc_msgSend}
   = note: target type: unsafe extern "C" fn(&ObjCObject, Selector) -> *const ObjCObject
   = help: cast with `as` to a pointer instead

I'm not exactly sure why transmute won't let me go from one function pointer type to another, but even if that restriction remains, the error message could be more helpful. (My workaround was to use as isize before invoking transmute.)

Meta

rustc --version --verbose:

rustc 1.47.0-nightly (5180f3da5 2020-08-23)
binary: rustc
commit-hash: 5180f3da5fd72627a8d38558ad1297df38793acd
commit-date: 2020-08-23
host: x86_64-apple-darwin
release: 1.47.0-nightly
LLVM version: 11.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-raw-pointersArea: raw pointers, MaybeUninit, NonNullA-zstArea: Zero-sized types (ZSTs).C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions