Skip to content

Commit f321f05

Browse files
author
Pat Hickey
committed
use lifetimes on types that require it
1 parent 29c3ef9 commit f321f05

File tree

5 files changed

+81
-31
lines changed

5 files changed

+81
-31
lines changed

crates/generate/src/funcs.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
22
use quote::quote;
33

44
use crate::names::Names;
5-
use crate::types::struct_is_copy;
5+
use crate::types::{anon_lifetime, struct_is_copy};
66

77
pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
88
let ident = names.func(&func.name);
@@ -58,7 +58,7 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
5858
witx::TypePassedBy::Value(atom) => names.atom_type(atom),
5959
_ => unreachable!("err should always be passed by value"),
6060
};
61-
let err_typename = names.type_ref(&tref);
61+
let err_typename = names.type_ref(&tref, anon_lifetime());
6262
quote! {
6363
let err: #err_typename = ::memory::GuestErrorType::from_error(e, ctx);
6464
return #abi_ret::from(err);
@@ -106,7 +106,7 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
106106
let marshal_rets_post = marshal_rets.map(|(_pre, post)| post);
107107

108108
let success = if let Some(err_type) = err_type {
109-
let err_typename = names.type_ref(&err_type);
109+
let err_typename = names.type_ref(&err_type, anon_lifetime());
110110
quote! {
111111
let success:#err_typename = ::memory::GuestErrorType::success();
112112
#abi_ret::from(success)
@@ -133,7 +133,7 @@ fn marshal_arg(
133133
error_handling: TokenStream,
134134
) -> TokenStream {
135135
let tref = &param.tref;
136-
let interface_typename = names.type_ref(&tref);
136+
let interface_typename = names.type_ref(&tref, anon_lifetime());
137137

138138
let try_into_conversion = {
139139
let name = names.func_param(&param.name);
@@ -180,7 +180,7 @@ fn marshal_arg(
180180
witx::BuiltinType::String => unimplemented!("string types unimplemented"),
181181
},
182182
witx::Type::Pointer(pointee) => {
183-
let pointee_type = names.type_ref(pointee);
183+
let pointee_type = names.type_ref(pointee, anon_lifetime());
184184
let name = names.func_param(&param.name);
185185
quote! {
186186
let #name = match memory.ptr_mut::<#pointee_type>(#name as u32) {
@@ -192,7 +192,7 @@ fn marshal_arg(
192192
}
193193
}
194194
witx::Type::ConstPointer(pointee) => {
195-
let pointee_type = names.type_ref(pointee);
195+
let pointee_type = names.type_ref(pointee, anon_lifetime());
196196
let name = names.func_param(&param.name);
197197
quote! {
198198
let #name = match memory.ptr::<#pointee_type>(#name as u32) {
@@ -204,7 +204,7 @@ fn marshal_arg(
204204
}
205205
}
206206
witx::Type::Struct(s) if struct_is_copy(&s) => {
207-
let pointee_type = names.type_ref(tref);
207+
let pointee_type = names.type_ref(tref, anon_lifetime());
208208
let arg_name = names.func_ptr_binding(&param.name);
209209
let name = names.func_param(&param.name);
210210
quote! {
@@ -222,7 +222,7 @@ fn marshal_arg(
222222
}
223223
}
224224
witx::Type::Struct(s) if !struct_is_copy(&s) => {
225-
let pointee_type = names.type_ref(tref);
225+
let pointee_type = names.type_ref(tref, anon_lifetime());
226226
let arg_name = names.func_ptr_binding(&param.name);
227227
let name = names.func_param(&param.name);
228228
quote! {
@@ -251,7 +251,7 @@ fn marshal_result(
251251
let tref = &result.tref;
252252

253253
let write_val_to_ptr = {
254-
let pointee_type = names.type_ref(tref);
254+
let pointee_type = names.type_ref(tref, anon_lifetime());
255255
// core type is given func_ptr_binding name.
256256
let ptr_name = names.func_ptr_binding(&result.name);
257257
let pre = quote! {

crates/generate/src/module_trait.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use proc_macro2::TokenStream;
22
use quote::quote;
33

44
use crate::names::Names;
5+
use crate::types::anon_lifetime;
56
use witx::Module;
67

78
pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
@@ -10,7 +11,7 @@ pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
1011
let funcname = names.func(&f.name);
1112
let args = f.params.iter().map(|arg| {
1213
let arg_name = names.func_param(&arg.name);
13-
let arg_typename = names.type_ref(&arg.tref);
14+
let arg_typename = names.type_ref(&arg.tref, anon_lifetime());
1415
let arg_type = match arg.tref.type_().passed_by() {
1516
witx::TypePassedBy::Value { .. } => quote!(#arg_typename),
1617
witx::TypePassedBy::Pointer { .. } => quote!(&#arg_typename),
@@ -22,11 +23,11 @@ pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
2223
.results
2324
.iter()
2425
.skip(1)
25-
.map(|ret| names.type_ref(&ret.tref));
26+
.map(|ret| names.type_ref(&ret.tref, anon_lifetime()));
2627
let err = f
2728
.results
2829
.get(0)
29-
.map(|err_result| names.type_ref(&err_result.tref))
30+
.map(|err_result| names.type_ref(&err_result.tref, anon_lifetime()))
3031
.unwrap_or(quote!(()));
3132
quote!(fn #funcname(&mut self, #(#args),*) -> Result<(#(#rets),*), #err>;)
3233
});

crates/generate/src/names.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use proc_macro2::{Ident, TokenStream};
33
use quote::{format_ident, quote};
44
use witx::{AtomType, BuiltinType, Id, TypeRef};
55

6+
use crate::types::type_needs_lifetime;
67
use crate::Config;
78

89
#[derive(Debug, Clone)]
@@ -47,21 +48,25 @@ impl Names {
4748
}
4849
}
4950

50-
pub fn type_ref(&self, tref: &TypeRef) -> TokenStream {
51+
pub fn type_ref(&self, tref: &TypeRef, lifetime: TokenStream) -> TokenStream {
5152
match tref {
5253
TypeRef::Name(nt) => {
5354
let ident = self.type_(&nt.name);
54-
quote!(#ident)
55+
if type_needs_lifetime(&nt.tref) {
56+
quote!(#ident<#lifetime>)
57+
} else {
58+
quote!(#ident)
59+
}
5560
}
5661
TypeRef::Value(ty) => match &**ty {
5762
witx::Type::Builtin(builtin) => self.builtin_type(*builtin),
5863
witx::Type::Pointer(pointee) => {
59-
let pointee_type = self.type_ref(&pointee);
60-
quote!(::memory::GuestPtrMut<#pointee_type>)
64+
let pointee_type = self.type_ref(&pointee, lifetime.clone());
65+
quote!(::memory::GuestPtrMut<#lifetime, #pointee_type>)
6166
}
6267
witx::Type::ConstPointer(pointee) => {
63-
let pointee_type = self.type_ref(&pointee);
64-
quote!(::memory::GuestPtr<#pointee_type>)
68+
let pointee_type = self.type_ref(&pointee, lifetime.clone());
69+
quote!(::memory::GuestPtr<#lifetime, #pointee_type>)
6570
}
6671
_ => unimplemented!("anonymous type ref"),
6772
},

crates/generate/src/types.rs

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,25 @@ pub fn define_datatype(names: &Names, namedtype: &witx::NamedType) -> TokenStrea
2121
witx::Type::Union(_) => unimplemented!("union types"),
2222
witx::Type::Handle(_h) => unimplemented!("handle types"),
2323
witx::Type::Builtin(b) => define_builtin(names, &namedtype.name, *b),
24-
witx::Type::Pointer { .. } => unimplemented!("pointer types"),
25-
witx::Type::ConstPointer { .. } => unimplemented!("constpointer types"),
24+
witx::Type::Pointer(p) => {
25+
define_witx_pointer(names, &namedtype.name, quote!(::memory::GuestPtrMut), p)
26+
}
27+
witx::Type::ConstPointer(p) => {
28+
define_witx_pointer(names, &namedtype.name, quote!(::memory::GuestPtr), p)
29+
}
2630
witx::Type::Array { .. } => unimplemented!("array types"),
2731
},
2832
}
2933
}
3034

3135
fn define_alias(names: &Names, name: &witx::Id, to: &witx::NamedType) -> TokenStream {
3236
let ident = names.type_(name);
33-
let to = names.type_(&to.name);
34-
35-
quote!(pub type #ident = #to;)
37+
let rhs = names.type_(&to.name);
38+
if type_needs_lifetime(&to.tref) {
39+
quote!(pub type #ident<'a> = #rhs<'a>;)
40+
} else {
41+
quote!(pub type #ident = #rhs;)
42+
}
3643
}
3744

3845
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) ->
133140
quote!(pub type #ident = #built;)
134141
}
135142

143+
pub fn type_needs_lifetime(tref: &witx::TypeRef) -> bool {
144+
match &*tref.type_() {
145+
witx::Type::Builtin(b) => match b {
146+
witx::BuiltinType::String => unimplemented!(),
147+
_ => false,
148+
},
149+
witx::Type::Enum { .. }
150+
| witx::Type::Flags { .. }
151+
| witx::Type::Int { .. }
152+
| witx::Type::Handle { .. } => false,
153+
witx::Type::Struct(s) => !struct_is_copy(&s),
154+
witx::Type::Union { .. } => true,
155+
witx::Type::Pointer { .. } | witx::Type::ConstPointer { .. } => true,
156+
witx::Type::Array { .. } => unimplemented!(),
157+
}
158+
}
159+
136160
pub fn struct_is_copy(s: &witx::StructDatatype) -> bool {
137161
s.members.iter().all(|m| match &*m.tref.type_() {
138162
witx::Type::Struct(s) => struct_is_copy(&s),
@@ -158,11 +182,11 @@ fn define_copy_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype)
158182

159183
let member_decls = s.members.iter().map(|m| {
160184
let name = names.struct_member(&m.name);
161-
let type_ = names.type_ref(&m.tref);
185+
let type_ = names.type_ref(&m.tref, anon_lifetime());
162186
quote!(pub #name: #type_)
163187
});
164188
let member_valids = s.member_layout().into_iter().map(|ml| {
165-
let type_ = names.type_ref(&ml.member.tref);
189+
let type_ = names.type_ref(&ml.member.tref, anon_lifetime());
166190
let offset = ml.offset as u32;
167191
let fieldname = names.struct_member(&ml.member.name);
168192
quote! {
@@ -221,11 +245,11 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
221245
witx::TypeRef::Value(ty) => match &**ty {
222246
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
223247
witx::Type::Pointer(pointee) => {
224-
let pointee_type = names.type_ref(&pointee);
248+
let pointee_type = names.type_ref(&pointee, quote!('a));
225249
quote!(::memory::GuestPtrMut<'a, #pointee_type>)
226250
}
227251
witx::Type::ConstPointer(pointee) => {
228-
let pointee_type = names.type_ref(&pointee);
252+
let pointee_type = names.type_ref(&pointee, quote!('a));
229253
quote!(::memory::GuestPtr<'a, #pointee_type>)
230254
}
231255
_ => unimplemented!("other anonymous struct members"),
@@ -239,11 +263,11 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
239263
witx::TypeRef::Value(ty) => match &**ty {
240264
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
241265
witx::Type::Pointer(pointee) => {
242-
let pointee_type = names.type_ref(&pointee);
266+
let pointee_type = names.type_ref(&pointee, anon_lifetime());
243267
quote!(::memory::GuestPtrMut::<#pointee_type>)
244268
}
245269
witx::Type::ConstPointer(pointee) => {
246-
let pointee_type = names.type_ref(&pointee);
270+
let pointee_type = names.type_ref(&pointee, anon_lifetime());
247271
quote!(::memory::GuestPtr::<#pointee_type>)
248272
}
249273
_ => unimplemented!("other anonymous struct members"),
@@ -286,13 +310,13 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
286310
}
287311
}
288312
witx::Type::Pointer(pointee) => {
289-
let pointee_type = names.type_ref(&pointee);
313+
let pointee_type = names.type_ref(&pointee, anon_lifetime());
290314
quote! {
291315
let #name = ::memory::GuestPtrMut::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
292316
}
293317
}
294318
witx::Type::ConstPointer(pointee) => {
295-
let pointee_type = names.type_ref(&pointee);
319+
let pointee_type = names.type_ref(&pointee, anon_lifetime());
296320
quote! {
297321
let #name = ::memory::GuestPtr::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
298322
}
@@ -340,6 +364,19 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
340364
}
341365
}
342366
}
367+
368+
fn define_witx_pointer(
369+
names: &Names,
370+
name: &witx::Id,
371+
pointer_type: TokenStream,
372+
pointee: &witx::TypeRef,
373+
) -> TokenStream {
374+
let ident = names.type_(name);
375+
let pointee_type = names.type_ref(pointee, quote!('a));
376+
377+
quote!(pub type #ident<'a> = #pointer_type<'a, #pointee_type>;)
378+
}
379+
343380
fn int_repr_tokens(int_repr: witx::IntRepr) -> TokenStream {
344381
match int_repr {
345382
witx::IntRepr::U8 => quote!(u8),
@@ -356,3 +393,7 @@ fn atom_token(atom: witx::AtomType) -> TokenStream {
356393
witx::AtomType::F64 => quote!(f64),
357394
}
358395
}
396+
397+
pub fn anon_lifetime() -> TokenStream {
398+
quote!('_)
399+
}

test.witx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
(field $first (@witx const_pointer s32))
2525
(field $second (@witx const_pointer s32))))
2626

27+
(typename $named_ptr (@witx pointer f32))
28+
(typename $named_ptr_to_ptr (@witx pointer (@witx pointer f64)))
29+
2730
(module $foo
2831
(@interface func (export "bar")
2932
(param $an_int u32)

0 commit comments

Comments
 (0)