mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2025-02-17 15:09:41 +00:00
Expand derives manually where allowed
This commit is contained in:
parent
652cb50e33
commit
4a0c53a7b0
@ -1,14 +0,0 @@
|
||||
use crate::syntax::Derive;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
|
||||
pub struct DeriveAttribute<'a>(pub &'a [Derive]);
|
||||
|
||||
impl<'a> ToTokens for DeriveAttribute<'a> {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
if !self.0.is_empty() {
|
||||
let derives = self.0;
|
||||
tokens.extend(quote!(#[derive(#(#derives),*)]));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
use crate::derive::DeriveAttribute;
|
||||
use crate::syntax::atom::Atom::{self, *};
|
||||
use crate::syntax::file::Module;
|
||||
use crate::syntax::report::Errors;
|
||||
use crate::syntax::symbol::Symbol;
|
||||
use crate::syntax::{
|
||||
self, check, mangle, Api, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Signature,
|
||||
Struct, Type, TypeAlias, Types,
|
||||
self, check, mangle, Api, Derive, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName,
|
||||
Signature, Struct, Type, TypeAlias, Types,
|
||||
};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||
@ -127,7 +126,6 @@ fn expand(ffi: Module, apis: &[Api], types: &Types) -> TokenStream {
|
||||
fn expand_struct(strct: &Struct) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let doc = &strct.doc;
|
||||
let derives = DeriveAttribute(&strct.derives);
|
||||
let type_id = type_id(&strct.name);
|
||||
let fields = strct.fields.iter().map(|field| {
|
||||
// This span on the pub makes "private type in public interface" errors
|
||||
@ -136,9 +134,8 @@ fn expand_struct(strct: &Struct) -> TokenStream {
|
||||
quote!(#vis #field)
|
||||
});
|
||||
|
||||
quote! {
|
||||
let mut expanded = quote! {
|
||||
#doc
|
||||
#derives
|
||||
#[repr(C)]
|
||||
pub struct #ident {
|
||||
#(#fields,)*
|
||||
@ -148,7 +145,37 @@ fn expand_struct(strct: &Struct) -> TokenStream {
|
||||
type Id = #type_id;
|
||||
type Kind = ::cxx::kind::Trivial;
|
||||
}
|
||||
};
|
||||
|
||||
let is_copy = strct.derives.contains(&Derive::Copy);
|
||||
for derive in &strct.derives {
|
||||
match derive {
|
||||
Derive::Copy => {
|
||||
expanded.extend(quote! {
|
||||
impl ::std::marker::Copy for #ident {}
|
||||
});
|
||||
}
|
||||
Derive::Clone => {
|
||||
let body = if is_copy {
|
||||
quote!(*self)
|
||||
} else {
|
||||
let fields = strct.fields.iter().map(|field| &field.ident);
|
||||
quote!(#ident {
|
||||
#(#fields: ::std::clone::Clone::clone(&self.#fields),)*
|
||||
})
|
||||
};
|
||||
expanded.extend(quote! {
|
||||
impl ::std::clone::Clone for #ident {
|
||||
fn clone(&self) -> Self {
|
||||
#body
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expanded
|
||||
}
|
||||
|
||||
fn expand_enum(enm: &Enum) -> TokenStream {
|
||||
@ -166,7 +193,7 @@ fn expand_enum(enm: &Enum) -> TokenStream {
|
||||
|
||||
quote! {
|
||||
#doc
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(PartialEq, Eq)] // required to be derived in order to be usable in patterns
|
||||
#[repr(transparent)]
|
||||
pub struct #ident {
|
||||
pub repr: #repr,
|
||||
@ -181,6 +208,14 @@ fn expand_enum(enm: &Enum) -> TokenStream {
|
||||
type Id = #type_id;
|
||||
type Kind = ::cxx::kind::Trivial;
|
||||
}
|
||||
|
||||
impl ::std::marker::Copy for #ident {}
|
||||
|
||||
impl ::std::clone::Clone for #ident {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
mod derive;
|
||||
mod expand;
|
||||
mod syntax;
|
||||
mod type_id;
|
||||
|
@ -15,12 +15,3 @@ impl Derive {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for Derive {
|
||||
fn as_ref(&self) -> &str {
|
||||
match self {
|
||||
Derive::Clone => "Clone",
|
||||
Derive::Copy => "Copy",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::syntax::atom::Atom::*;
|
||||
use crate::syntax::{
|
||||
Array, Atom, Derive, Enum, ExternFn, ExternType, Impl, Receiver, Ref, ResolvableName,
|
||||
Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
|
||||
Array, Atom, Enum, ExternFn, ExternType, Impl, Receiver, Ref, ResolvableName, Signature,
|
||||
SliceRef, Struct, Ty1, Type, TypeAlias, Var,
|
||||
};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{quote_spanned, ToTokens};
|
||||
@ -93,12 +93,6 @@ impl ToTokens for Array {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Derive {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Atom {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens);
|
||||
|
@ -7,4 +7,4 @@ error[E0119]: conflicting implementations of trait `std::clone::Clone` for type
|
||||
| first implementation here
|
||||
| conflicting implementation for `ffi::Struct`
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
Loading…
x
Reference in New Issue
Block a user