dtolnay/cxx

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

Open

#809 创建于 2021年4月8日

在 GitHub 查看
 (1 评论) (0 反应) (0 负责人)Rust (4,472 star) (253 fork)batch import
help wanted

描述

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

贡献者指南