dtolnay / cxx

Safe interop between Rust and C++
https://cxx.rs
Apache License 2.0
5.88k stars 333 forks source link

Support calling reference qualified member function from Rust #715

Open dtolnay opened 3 years ago

dtolnay commented 3 years ago

For example, this method from folly::dynamic: https://github.com/facebook/folly/blob/f604b03c5e0305860326f77c4562cba27547db38/folly/dynamic.h#L311

Simplified, the data structure looks like:

struct dynamic {
  double getDouble() const &;
};

If we currently try binding this from CXX as follows, then it fails to compile.

#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        type dynamic;
        fn getDouble(self: &dynamic) -> f64;
    }
}

The generated code contains something along the lines of:

double (dynamic::*getDouble$)() const = &dynamic::getDouble;
main.cc:6:21: error: cannot initialize a variable of type 'double (dynamic::*)() const' with an rvalue of type 'double (dynamic::*)() const &'
  double (dynamic::*getDouble$)() const = &dynamic::getDouble;
                    ^                     ~~~~~~~~~~~~~~~~~~~
dtolnay commented 3 years ago

Maybe like this:

#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        type dynamic;

        #[ref_qualifier = "&"]  // or "&&"
        fn getDouble(&self) -> f64;
    }
}

The attribute uses the terminology from https://en.cppreference.com/w/cpp/language/member_functions#ref-qualified_member_functions.