dtolnay/cxx

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

Aperta

#809 aperta il 8 apr 2021

 (1 commento) (0 reazioni) (0 assegnatari)Rust (253 fork)batch import
help wanted

Metriche repository

Star
 (4472 stelle)
Metriche merge PR
 (Merge medio 8m) (3 PR mergiate in 30 g)

Descrizione

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

Guida contributor