dtolnay/cxx
View on GitHubExtern type aliases to a C++ reference are not well supported
Open
#809 opened on Apr 8, 2021
help wanted
Description
With pointers, the following works perfectly:
// include/repro.h
#pragma once
struct Thing;
using Ref = Thing *;
// src/lib.rs
use cxx::{type_id, ExternType};
#[cxx::bridge]
mod ffi {
extern "C++" {
include!("example/include/repro.h");
type Ref = crate::Ref;
}
extern "Rust" {
fn f(r: Ref);
}
}
fn f(_r: Ref) {}
#[repr(transparent)]
pub struct Ref(*mut ());
unsafe impl ExternType for Ref {
type Id = type_id!("Ref");
type Kind = cxx::kind::Trivial;
}
However with Ref as a C++ reference rather than a C++ pointer, we generate C++ code that does not compile.
- using Ref = Thing *;
+ using Ref = Thing &;
cxxbridge/sources/example/src/lib.rs.cc:60:26: error: cannot declare pointer to ‘using Ref = struct Thing&’ {aka ‘struct Thing&’}
60 | void cxxbridge1$f(::Ref *r) noexcept;
| ^
cxxbridge/sources/example/src/lib.rs.cc: In instantiation of ‘union rust::cxxbridge1::ManuallyDrop<Thing&>’:
cxxbridge/sources/example/src/lib.rs.cc:48:5: error: non-static data member ‘rust::cxxbridge1::ManuallyDrop<Thing&>::value’ in a union may not have reference type ‘Thing&’
48 | T value;
| ^~~~~
cxxbridge/sources/example/src/lib.rs.cc: In function ‘void f(Ref)’:
cxxbridge/sources/example/src/lib.rs.cc:64:45: error: cannot bind non-const lvalue reference of type ‘Thing&’ to an rvalue of type ‘std::remove_reference<Thing&>::type’ {aka ‘Thing’}
64 | ::rust::ManuallyDrop<::Ref> r$(::std::move(r));
| ~~~~~~~~~~~^~~
cxxbridge/sources/example/src/lib.rs.cc:49:20: note: initializing argument 1 of ‘rust::cxxbridge1::ManuallyDrop<T>::ManuallyDrop(T&&) [with T = Thing&]’
49 | ManuallyDrop(T &&value) : value(::std::move(value)) {}
| ~~~~^~~~~