dtolnay/cxx

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

Aberta

#809 aberto em 8 de abr. de 2021

 (1 comentário) (0 reação) (0 responsável)Rust (253 forks)batch import
help wanted

Métricas do repositório

Stars
 (4.472 estrelas)
Métricas de merge de PR
 (Mesclagem média 8m) (3 fundiu PRs em 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)) {}
      |                ~~~~^~~~~

Guia do colaborador