Description
I want to implement a Rust interface for libevent (because an external library I want to use depends on it).
Note that there is an example with working code, code that issues the compiler error and a diff between these two in this gist:
https://gist.github.com/manuels/aaaf1ef5d8a072c19f11
When I define a C callback function for a libevent event:
extern "C"
fn printme(ev: *const c_int, flags: c_short, args: *const c_int) {
// using this as a libevent callback works just fine
println!("hello");
}
the code works fine. Note that args
is a userdefined argument that will be used in the next step.
Relying on callbacks to be defined as "extern C" is a bit clumsy, so I'd like to define an "extern C" wrapper function that calls the rust callback function:
type watch_fd_callback_t = fn(*const c_int, c_short);
extern "C"
fn c_watch_fd_callback(ev:*const c_int, type_:c_short, cb: watch_fd_callback_t) {
// using this as a libevent callback crashes the compiler.
// probably because this "extern C" function indirectly
// calls the non "extern C" function printme() (==cb)
cb(ev, type_)
}
fn printme(ev: *const c_int, flags: i16) {
println!("hello");
}
So when I use the "extern C" wrapper callback c_watch_fd_callback()
that calls the rust callback printme()
the compiler crashes with this backtrace:
error: internal compiler error: unexpected failure
note: the compiler hit an unexpected failure path. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
task 'rustc' failed at 'assertion failed: f.abi == Rust || f.abi == RustCall', /home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/librustc/middle/trans/base.rs:2337
stack backtrace:
1: 0x7fcf4ff31bf0 - rt::backtrace::imp::write::h37a3af22082b7094FKq
2: 0x7fcf4ff34d20 - failure::on_fail::hf01d9f1e1bdb6e5425q
3: 0x7fcf5449db30 - unwind::begin_unwind_inner::h2ec64a9d433f6b868yd
4: 0x7fcf54ae2f20 - unwind::begin_unwind::h16532647071079331256
5: 0x7fcf54f55770 - middle::trans::base::register_fn::habe93b484695cbab1kh
6: 0x7fcf54f58680 - middle::trans::base::register_method::hd6b6a60e17289fdea1h
7: 0x7fcf54e998e0 - middle::trans::base::get_item_val::h87cb1de1e8e4455aeJh
8: 0x7fcf54f53a60 - middle::trans::meth::trans_impl::h061539a782350394U1l
9: 0x7fcf54e98400 - middle::trans::base::trans_item::h8e6f687fd31b992bxdh
10: 0x7fcf54e98400 - middle::trans::base::trans_item::h8e6f687fd31b992bxdh
11: 0x7fcf54f5b030 - middle::trans::base::trans_crate::h1e2bed8778c95c8dkbi
12: 0x7fcf553b43b0 - driver::driver::phase_4_translate_to_llvm::hbdeb13ca358e159eD9z
13: 0x7fcf553ab450 - driver::driver::compile_input::h8a818e073bdb900cyGz
14: 0x7fcf55436950 - driver::run_compiler::h7e400358677f3066StD
15: 0x7fcf55436800 - driver::run::closure.145782
16: 0x7fcf54b1bb70 - task::TaskBuilder<S>::try_future::closure.103164
17: 0x7fcf54b1b950 - task::TaskBuilder<S>::spawn_internal::closure.103135
18: 0x7fcf547e8a30 - task::spawn_opts::closure.8464
19: 0x7fcf544f7aa0 - rust_try_inner
20: 0x7fcf544f7a90 - rust_try
21: 0x7fcf5449b3f0 - unwind::try::h0bc5cc5739b8d3c3Qnd
22: 0x7fcf5449b270 - task::Task::run::h517e4360aedfbf45uDc
23: 0x7fcf547e8770 - task::spawn_opts::closure.8404
24: 0x7fcf5449cb40 - thread::thread_start::h43c1915a7e23212cFXc
25: 0x7fcf4f2ddfe0 - start_thread
26: 0x7fcf5416dbf9 - __clone
27: 0x0 - <unknown>
I'm running Linux 3.16-2-amd64 #1 SMP Debian 3.16.3-2 (2014-09-20) x86_64 GNU/Linux
with rustc 0.13.0-nightly (222ae8b9b 2014-10-18 00:47:22 +0000)
.