dtolnay/cxx

Support moving into an rvalue reference argument

Open

#561 opened on Dec 11, 2020

View on GitHub
 (0 comments) (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

Consider this code:

// src/lib.rs

#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        include!("example/include/example.h");
        type Thing;
        fn f(thing: UniquePtr<Thing>);
    }
}
#pragma once
#include <memory>

struct Thing {};

void f(std::unique_ptr<Thing> &&);

This would currently fail to build, with:

example-760540e262f31cef/out/cxxbridge/sources/example/src/main.rs.cc: In function ‘void cxxbridge1$f(Thing*)’:
example-760540e262f31cef/out/cxxbridge/sources/example/src/main.rs.cc:34:46: error: invalid conversion from ‘void (*)(std::unique_ptr<Thing>&&)’ to ‘void (*)(std::unique_ptr<Thing>)’ [-fpermissive]
   34 |   void (*f$)(::std::unique_ptr<::Thing>) = ::f;
      |                                            ~~^
      |                                              |
      |                                              void (*)(std::unique_ptr<Thing>&&

because the cxx C++ code generator is expecting a signature void f(std::unique_ptr<Thing>) whereas the actual signature is void f(std::unique_ptr<Thing> &&).

It would be good to support this better and interoperate between a Rust by-value argument and a C++ rvalue reference argument.

Maybe like:

extern "C++" {
    fn f(thing: #[move] UniquePtr<Thing>);
}

or this bastardization of C++ rvalue syntax:

extern "C++" {
    fn f(&&thing: UniquePtr<Thing>);
}

Contributor guide