Type alias code generation
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 6eac0d9..e3026ba 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -3,7 +3,7 @@
use crate::syntax::report::Errors;
use crate::syntax::symbol::Symbol;
use crate::syntax::{
- self, check, mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, Types,
+ self, check, mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, TypeAlias, Types,
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, ToTokens};
@@ -46,7 +46,7 @@
Api::Enum(enm) => expanded.extend(expand_enum(enm)),
Api::CxxType(ety) => {
if !types.enums.contains_key(&ety.ident) {
- expanded.extend(expand_cxx_type(ety));
+ expanded.extend(expand_cxx_type(namespace, ety));
}
}
Api::CxxFunction(efn) => {
@@ -55,7 +55,10 @@
Api::RustFunction(efn) => {
hidden.extend(expand_rust_function_shim(namespace, efn, types))
}
- Api::TypeAlias(_alias) => unimplemented!(),
+ Api::TypeAlias(alias) => {
+ expanded.extend(expand_type_alias(alias));
+ hidden.extend(expand_type_alias_verify(namespace, alias));
+ }
}
}
@@ -162,15 +165,21 @@
}
}
-fn expand_cxx_type(ety: &ExternType) -> TokenStream {
+fn expand_cxx_type(namespace: &Namespace, ety: &ExternType) -> TokenStream {
let ident = &ety.ident;
let doc = &ety.doc;
+ let type_id = type_id(namespace, ident);
+
quote! {
#doc
#[repr(C)]
pub struct #ident {
_private: ::cxx::private::Opaque,
}
+
+ unsafe impl ::cxx::ExternType for #ident {
+ type Id = #type_id;
+ }
}
}
@@ -555,6 +564,35 @@
}
}
+fn expand_type_alias(alias: &TypeAlias) -> TokenStream {
+ let ident = &alias.ident;
+ let ty = &alias.ty;
+ quote! {
+ pub type #ident = #ty;
+ }
+}
+
+fn expand_type_alias_verify(namespace: &Namespace, alias: &TypeAlias) -> TokenStream {
+ let ident = &alias.ident;
+ let type_id = type_id(namespace, ident);
+ quote! {
+ const _: fn() = ::cxx::private::verify_extern_type::<#ident, #type_id>;
+ }
+}
+
+fn type_id(namespace: &Namespace, ident: &Ident) -> TokenStream {
+ let mut path = String::new();
+ for name in namespace {
+ path += &name.to_string();
+ path += "::";
+ }
+ path += &ident.to_string();
+
+ quote! {
+ ::cxx::type_id!(#path)
+ }
+}
+
fn expand_rust_box(namespace: &Namespace, ident: &Ident) -> TokenStream {
let link_prefix = format!("cxxbridge03$box${}{}$", namespace, ident);
let link_uninit = format!("{}uninit", link_prefix);
diff --git a/src/extern_type.rs b/src/extern_type.rs
new file mode 100644
index 0000000..f7c376b
--- /dev/null
+++ b/src/extern_type.rs
@@ -0,0 +1,6 @@
+pub unsafe trait ExternType {
+ type Id;
+}
+
+#[doc(hidden)]
+pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
diff --git a/src/lib.rs b/src/lib.rs
index 39b1ecc..d15d441 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -369,6 +369,7 @@
mod cxx_string;
mod cxx_vector;
mod exception;
+mod extern_type;
mod function;
mod opaque;
mod result;
@@ -386,6 +387,7 @@
pub use crate::cxx_string::CxxString;
pub use crate::cxx_vector::CxxVector;
pub use crate::exception::Exception;
+pub use crate::extern_type::ExternType;
pub use crate::unique_ptr::UniquePtr;
pub use cxxbridge_macro::{bridge, type_id};
@@ -393,6 +395,7 @@
#[doc(hidden)]
pub mod private {
pub use crate::cxx_vector::VectorElement;
+ pub use crate::extern_type::verify_extern_type;
pub use crate::function::FatFunction;
pub use crate::opaque::Opaque;
pub use crate::result::{r#try, Result};