dtolnay/cxx

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

Ouverte

#809 ouverte le 8 avr. 2021

 (1 commentaire) (0 réaction) (0 personne assignée)Rust (253 forks)batch import
help wanted

Métriques du dépôt

Stars
 (4 472 étoiles)
Métriques de merge PR
 (Merge moyen 8m) (3 PRs mergées en 30 j)

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

Guide contributeur