use lifetimes on types that require it
This commit is contained in:
@@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
use crate::names::Names;
|
||||
use crate::types::struct_is_copy;
|
||||
use crate::types::{anon_lifetime, struct_is_copy};
|
||||
|
||||
pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
||||
let ident = names.func(&func.name);
|
||||
@@ -58,7 +58,7 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
||||
witx::TypePassedBy::Value(atom) => names.atom_type(atom),
|
||||
_ => unreachable!("err should always be passed by value"),
|
||||
};
|
||||
let err_typename = names.type_ref(&tref);
|
||||
let err_typename = names.type_ref(&tref, anon_lifetime());
|
||||
quote! {
|
||||
let err: #err_typename = ::memory::GuestErrorType::from_error(e, ctx);
|
||||
return #abi_ret::from(err);
|
||||
@@ -106,7 +106,7 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
||||
let marshal_rets_post = marshal_rets.map(|(_pre, post)| post);
|
||||
|
||||
let success = if let Some(err_type) = err_type {
|
||||
let err_typename = names.type_ref(&err_type);
|
||||
let err_typename = names.type_ref(&err_type, anon_lifetime());
|
||||
quote! {
|
||||
let success:#err_typename = ::memory::GuestErrorType::success();
|
||||
#abi_ret::from(success)
|
||||
@@ -133,7 +133,7 @@ fn marshal_arg(
|
||||
error_handling: TokenStream,
|
||||
) -> TokenStream {
|
||||
let tref = ¶m.tref;
|
||||
let interface_typename = names.type_ref(&tref);
|
||||
let interface_typename = names.type_ref(&tref, anon_lifetime());
|
||||
|
||||
let try_into_conversion = {
|
||||
let name = names.func_param(¶m.name);
|
||||
@@ -180,7 +180,7 @@ fn marshal_arg(
|
||||
witx::BuiltinType::String => unimplemented!("string types unimplemented"),
|
||||
},
|
||||
witx::Type::Pointer(pointee) => {
|
||||
let pointee_type = names.type_ref(pointee);
|
||||
let pointee_type = names.type_ref(pointee, anon_lifetime());
|
||||
let name = names.func_param(¶m.name);
|
||||
quote! {
|
||||
let #name = match memory.ptr_mut::<#pointee_type>(#name as u32) {
|
||||
@@ -192,7 +192,7 @@ fn marshal_arg(
|
||||
}
|
||||
}
|
||||
witx::Type::ConstPointer(pointee) => {
|
||||
let pointee_type = names.type_ref(pointee);
|
||||
let pointee_type = names.type_ref(pointee, anon_lifetime());
|
||||
let name = names.func_param(¶m.name);
|
||||
quote! {
|
||||
let #name = match memory.ptr::<#pointee_type>(#name as u32) {
|
||||
@@ -204,7 +204,7 @@ fn marshal_arg(
|
||||
}
|
||||
}
|
||||
witx::Type::Struct(s) if struct_is_copy(&s) => {
|
||||
let pointee_type = names.type_ref(tref);
|
||||
let pointee_type = names.type_ref(tref, anon_lifetime());
|
||||
let arg_name = names.func_ptr_binding(¶m.name);
|
||||
let name = names.func_param(¶m.name);
|
||||
quote! {
|
||||
@@ -222,7 +222,7 @@ fn marshal_arg(
|
||||
}
|
||||
}
|
||||
witx::Type::Struct(s) if !struct_is_copy(&s) => {
|
||||
let pointee_type = names.type_ref(tref);
|
||||
let pointee_type = names.type_ref(tref, anon_lifetime());
|
||||
let arg_name = names.func_ptr_binding(¶m.name);
|
||||
let name = names.func_param(¶m.name);
|
||||
quote! {
|
||||
@@ -251,7 +251,7 @@ fn marshal_result(
|
||||
let tref = &result.tref;
|
||||
|
||||
let write_val_to_ptr = {
|
||||
let pointee_type = names.type_ref(tref);
|
||||
let pointee_type = names.type_ref(tref, anon_lifetime());
|
||||
// core type is given func_ptr_binding name.
|
||||
let ptr_name = names.func_ptr_binding(&result.name);
|
||||
let pre = quote! {
|
||||
|
||||
@@ -2,6 +2,7 @@ use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
use crate::names::Names;
|
||||
use crate::types::anon_lifetime;
|
||||
use witx::Module;
|
||||
|
||||
pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
||||
@@ -10,7 +11,7 @@ pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
||||
let funcname = names.func(&f.name);
|
||||
let args = f.params.iter().map(|arg| {
|
||||
let arg_name = names.func_param(&arg.name);
|
||||
let arg_typename = names.type_ref(&arg.tref);
|
||||
let arg_typename = names.type_ref(&arg.tref, anon_lifetime());
|
||||
let arg_type = match arg.tref.type_().passed_by() {
|
||||
witx::TypePassedBy::Value { .. } => quote!(#arg_typename),
|
||||
witx::TypePassedBy::Pointer { .. } => quote!(&#arg_typename),
|
||||
@@ -22,11 +23,11 @@ pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
||||
.results
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|ret| names.type_ref(&ret.tref));
|
||||
.map(|ret| names.type_ref(&ret.tref, anon_lifetime()));
|
||||
let err = f
|
||||
.results
|
||||
.get(0)
|
||||
.map(|err_result| names.type_ref(&err_result.tref))
|
||||
.map(|err_result| names.type_ref(&err_result.tref, anon_lifetime()))
|
||||
.unwrap_or(quote!(()));
|
||||
quote!(fn #funcname(&mut self, #(#args),*) -> Result<(#(#rets),*), #err>;)
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use witx::{AtomType, BuiltinType, Id, TypeRef};
|
||||
|
||||
use crate::types::type_needs_lifetime;
|
||||
use crate::Config;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -47,21 +48,25 @@ impl Names {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_ref(&self, tref: &TypeRef) -> TokenStream {
|
||||
pub fn type_ref(&self, tref: &TypeRef, lifetime: TokenStream) -> TokenStream {
|
||||
match tref {
|
||||
TypeRef::Name(nt) => {
|
||||
let ident = self.type_(&nt.name);
|
||||
if type_needs_lifetime(&nt.tref) {
|
||||
quote!(#ident<#lifetime>)
|
||||
} else {
|
||||
quote!(#ident)
|
||||
}
|
||||
}
|
||||
TypeRef::Value(ty) => match &**ty {
|
||||
witx::Type::Builtin(builtin) => self.builtin_type(*builtin),
|
||||
witx::Type::Pointer(pointee) => {
|
||||
let pointee_type = self.type_ref(&pointee);
|
||||
quote!(::memory::GuestPtrMut<#pointee_type>)
|
||||
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
||||
quote!(::memory::GuestPtrMut<#lifetime, #pointee_type>)
|
||||
}
|
||||
witx::Type::ConstPointer(pointee) => {
|
||||
let pointee_type = self.type_ref(&pointee);
|
||||
quote!(::memory::GuestPtr<#pointee_type>)
|
||||
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
||||
quote!(::memory::GuestPtr<#lifetime, #pointee_type>)
|
||||
}
|
||||
_ => unimplemented!("anonymous type ref"),
|
||||
},
|
||||
|
||||
@@ -21,8 +21,12 @@ pub fn define_datatype(names: &Names, namedtype: &witx::NamedType) -> TokenStrea
|
||||
witx::Type::Union(_) => unimplemented!("union types"),
|
||||
witx::Type::Handle(_h) => unimplemented!("handle types"),
|
||||
witx::Type::Builtin(b) => define_builtin(names, &namedtype.name, *b),
|
||||
witx::Type::Pointer { .. } => unimplemented!("pointer types"),
|
||||
witx::Type::ConstPointer { .. } => unimplemented!("constpointer types"),
|
||||
witx::Type::Pointer(p) => {
|
||||
define_witx_pointer(names, &namedtype.name, quote!(::memory::GuestPtrMut), p)
|
||||
}
|
||||
witx::Type::ConstPointer(p) => {
|
||||
define_witx_pointer(names, &namedtype.name, quote!(::memory::GuestPtr), p)
|
||||
}
|
||||
witx::Type::Array { .. } => unimplemented!("array types"),
|
||||
},
|
||||
}
|
||||
@@ -30,9 +34,12 @@ pub fn define_datatype(names: &Names, namedtype: &witx::NamedType) -> TokenStrea
|
||||
|
||||
fn define_alias(names: &Names, name: &witx::Id, to: &witx::NamedType) -> TokenStream {
|
||||
let ident = names.type_(name);
|
||||
let to = names.type_(&to.name);
|
||||
|
||||
quote!(pub type #ident = #to;)
|
||||
let rhs = names.type_(&to.name);
|
||||
if type_needs_lifetime(&to.tref) {
|
||||
quote!(pub type #ident<'a> = #rhs<'a>;)
|
||||
} else {
|
||||
quote!(pub type #ident = #rhs;)
|
||||
}
|
||||
}
|
||||
|
||||
fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenStream {
|
||||
@@ -133,6 +140,23 @@ fn define_builtin(names: &Names, name: &witx::Id, builtin: witx::BuiltinType) ->
|
||||
quote!(pub type #ident = #built;)
|
||||
}
|
||||
|
||||
pub fn type_needs_lifetime(tref: &witx::TypeRef) -> bool {
|
||||
match &*tref.type_() {
|
||||
witx::Type::Builtin(b) => match b {
|
||||
witx::BuiltinType::String => unimplemented!(),
|
||||
_ => false,
|
||||
},
|
||||
witx::Type::Enum { .. }
|
||||
| witx::Type::Flags { .. }
|
||||
| witx::Type::Int { .. }
|
||||
| witx::Type::Handle { .. } => false,
|
||||
witx::Type::Struct(s) => !struct_is_copy(&s),
|
||||
witx::Type::Union { .. } => true,
|
||||
witx::Type::Pointer { .. } | witx::Type::ConstPointer { .. } => true,
|
||||
witx::Type::Array { .. } => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_is_copy(s: &witx::StructDatatype) -> bool {
|
||||
s.members.iter().all(|m| match &*m.tref.type_() {
|
||||
witx::Type::Struct(s) => struct_is_copy(&s),
|
||||
@@ -158,11 +182,11 @@ fn define_copy_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype)
|
||||
|
||||
let member_decls = s.members.iter().map(|m| {
|
||||
let name = names.struct_member(&m.name);
|
||||
let type_ = names.type_ref(&m.tref);
|
||||
let type_ = names.type_ref(&m.tref, anon_lifetime());
|
||||
quote!(pub #name: #type_)
|
||||
});
|
||||
let member_valids = s.member_layout().into_iter().map(|ml| {
|
||||
let type_ = names.type_ref(&ml.member.tref);
|
||||
let type_ = names.type_ref(&ml.member.tref, anon_lifetime());
|
||||
let offset = ml.offset as u32;
|
||||
let fieldname = names.struct_member(&ml.member.name);
|
||||
quote! {
|
||||
@@ -221,11 +245,11 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
||||
witx::TypeRef::Value(ty) => match &**ty {
|
||||
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
|
||||
witx::Type::Pointer(pointee) => {
|
||||
let pointee_type = names.type_ref(&pointee);
|
||||
let pointee_type = names.type_ref(&pointee, quote!('a));
|
||||
quote!(::memory::GuestPtrMut<'a, #pointee_type>)
|
||||
}
|
||||
witx::Type::ConstPointer(pointee) => {
|
||||
let pointee_type = names.type_ref(&pointee);
|
||||
let pointee_type = names.type_ref(&pointee, quote!('a));
|
||||
quote!(::memory::GuestPtr<'a, #pointee_type>)
|
||||
}
|
||||
_ => unimplemented!("other anonymous struct members"),
|
||||
@@ -239,11 +263,11 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
||||
witx::TypeRef::Value(ty) => match &**ty {
|
||||
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
|
||||
witx::Type::Pointer(pointee) => {
|
||||
let pointee_type = names.type_ref(&pointee);
|
||||
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||
quote!(::memory::GuestPtrMut::<#pointee_type>)
|
||||
}
|
||||
witx::Type::ConstPointer(pointee) => {
|
||||
let pointee_type = names.type_ref(&pointee);
|
||||
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||
quote!(::memory::GuestPtr::<#pointee_type>)
|
||||
}
|
||||
_ => unimplemented!("other anonymous struct members"),
|
||||
@@ -286,13 +310,13 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
||||
}
|
||||
}
|
||||
witx::Type::Pointer(pointee) => {
|
||||
let pointee_type = names.type_ref(&pointee);
|
||||
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||
quote! {
|
||||
let #name = ::memory::GuestPtrMut::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
|
||||
}
|
||||
}
|
||||
witx::Type::ConstPointer(pointee) => {
|
||||
let pointee_type = names.type_ref(&pointee);
|
||||
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||
quote! {
|
||||
let #name = ::memory::GuestPtr::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
|
||||
}
|
||||
@@ -340,6 +364,19 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn define_witx_pointer(
|
||||
names: &Names,
|
||||
name: &witx::Id,
|
||||
pointer_type: TokenStream,
|
||||
pointee: &witx::TypeRef,
|
||||
) -> TokenStream {
|
||||
let ident = names.type_(name);
|
||||
let pointee_type = names.type_ref(pointee, quote!('a));
|
||||
|
||||
quote!(pub type #ident<'a> = #pointer_type<'a, #pointee_type>;)
|
||||
}
|
||||
|
||||
fn int_repr_tokens(int_repr: witx::IntRepr) -> TokenStream {
|
||||
match int_repr {
|
||||
witx::IntRepr::U8 => quote!(u8),
|
||||
@@ -356,3 +393,7 @@ fn atom_token(atom: witx::AtomType) -> TokenStream {
|
||||
witx::AtomType::F64 => quote!(f64),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn anon_lifetime() -> TokenStream {
|
||||
quote!('_)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user