-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-ZSTArea: Zero-sized types (ZSTs).Area: Zero-sized types (ZSTs).A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-raw-pointersArea: raw pointers, MaybeUninit, NonNullArea: raw pointers, MaybeUninit, NonNullC-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
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
Metadata
Metadata
Assignees
Labels
A-ZSTArea: Zero-sized types (ZSTs).Area: Zero-sized types (ZSTs).A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-raw-pointersArea: raw pointers, MaybeUninit, NonNullArea: raw pointers, MaybeUninit, NonNullC-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.