Open
Description
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