dtolnay/cxx

Extern type aliases to a C++ reference are not well supported

Open

#809 opened on Apr 8, 2021

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Rust (253 forks)batch import
help wanted

Repository metrics

Stars
 (4,472 stars)
PR merge metrics
 (Avg merge 8m) (3 merged PRs in 30d)

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)) {}
      |                ~~~~^~~~~

Contributor guide