Skip to content

Commit 4d0a43f

Browse files
authored
wasmtime-wit-bindgen: nonfunctional changes to internals (#10578)
* wasmtime-wit-bindgen: transform type printing to return strings keep all used print_ functions, but otherwise NFC refactor to return String instead of push strs to the output. * reusable typedfunc signature prtest:full * clippy
1 parent 6ba6e13 commit 4d0a43f

File tree

2 files changed

+117
-93
lines changed

2 files changed

+117
-93
lines changed

crates/wit-bindgen/src/lib.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3272,23 +3272,18 @@ impl<'a> InterfaceGenerator<'a> {
32723272
}
32733273

32743274
self.src.push_str("let callee = unsafe {\n");
3275-
uwrite!(self.src, "{wt}::component::TypedFunc::<(");
3276-
for (_, ty) in func.params.iter() {
3277-
self.print_ty(ty, param_mode);
3278-
self.push_str(", ");
3279-
}
3280-
self.src.push_str("), (");
3281-
if let Some(ty) = func.result {
3282-
self.print_ty(&ty, TypeMode::Owned);
3283-
self.push_str(", ");
3284-
}
3275+
uwrite!(
3276+
self.src,
3277+
"{wt}::component::TypedFunc::<{}>",
3278+
self.typedfunc_sig(func, param_mode)
3279+
);
32853280
let projection_to_func = match &func.kind {
32863281
FunctionKind::Freestanding => "",
32873282
_ => ".funcs",
32883283
};
32893284
uwriteln!(
32903285
self.src,
3291-
")>::new_unchecked(self{projection_to_func}.{})",
3286+
"::new_unchecked(self{projection_to_func}.{})",
32923287
func_field_name(self.resolve, func),
32933288
);
32943289
self.src.push_str("};\n");

crates/wit-bindgen/src/rust.rs

Lines changed: 111 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -29,48 +29,54 @@ pub trait RustGenerator<'a> {
2929
fn ownership(&self) -> Ownership;
3030

3131
fn print_ty(&mut self, ty: &Type, mode: TypeMode) {
32+
self.push_str(&self.ty(ty, mode))
33+
}
34+
fn ty(&self, ty: &Type, mode: TypeMode) -> String {
3235
match ty {
33-
Type::Id(t) => self.print_tyid(*t, mode),
34-
Type::Bool => self.push_str("bool"),
35-
Type::U8 => self.push_str("u8"),
36-
Type::U16 => self.push_str("u16"),
37-
Type::U32 => self.push_str("u32"),
38-
Type::U64 => self.push_str("u64"),
39-
Type::S8 => self.push_str("i8"),
40-
Type::S16 => self.push_str("i16"),
41-
Type::S32 => self.push_str("i32"),
42-
Type::S64 => self.push_str("i64"),
43-
Type::F32 => self.push_str("f32"),
44-
Type::F64 => self.push_str("f64"),
45-
Type::Char => self.push_str("char"),
36+
Type::Id(t) => self.tyid(*t, mode),
37+
Type::Bool => "bool".to_string(),
38+
Type::U8 => "u8".to_string(),
39+
Type::U16 => "u16".to_string(),
40+
Type::U32 => "u32".to_string(),
41+
Type::U64 => "u64".to_string(),
42+
Type::S8 => "i8".to_string(),
43+
Type::S16 => "i16".to_string(),
44+
Type::S32 => "i32".to_string(),
45+
Type::S64 => "i64".to_string(),
46+
Type::F32 => "f32".to_string(),
47+
Type::F64 => "f64".to_string(),
48+
Type::Char => "char".to_string(),
4649
Type::String => match mode {
4750
TypeMode::AllBorrowed(lt) => {
48-
self.push_str("&");
4951
if lt != "'_" {
50-
self.push_str(lt);
51-
self.push_str(" ");
52+
format!("&{lt} str")
53+
} else {
54+
format!("&str")
5255
}
53-
self.push_str("str");
5456
}
5557
TypeMode::Owned => {
5658
let wt = self.wasmtime_path();
57-
self.push_str(&format!("{wt}::component::__internal::String"))
59+
format!("{wt}::component::__internal::String")
5860
}
5961
},
6062
Type::ErrorContext => {
61-
self.push_str("wasmtime::component::ErrorContext");
63+
let wt = self.wasmtime_path();
64+
format!("{wt}::component::ErrorContext")
6265
}
6366
}
6467
}
6568

6669
fn print_optional_ty(&mut self, ty: Option<&Type>, mode: TypeMode) {
70+
self.push_str(&self.optional_ty(ty, mode))
71+
}
72+
fn optional_ty(&self, ty: Option<&Type>, mode: TypeMode) -> String {
6773
match ty {
68-
Some(ty) => self.print_ty(ty, mode),
69-
None => self.push_str("()"),
74+
Some(ty) => self.ty(ty, mode),
75+
None => "()".to_string(),
7076
}
7177
}
7278

73-
fn print_tyid(&mut self, id: TypeId, mode: TypeMode) {
79+
fn tyid(&self, id: TypeId, mode: TypeMode) -> String {
7480
let info = self.info(id);
7581
let lt = self.lifetime_for(&info, mode);
7682
let ty = &self.resolve().types[id];
@@ -80,12 +86,13 @@ pub trait RustGenerator<'a> {
8086
// context and don't want ownership of the type but we're using an
8187
// owned type definition. Inject a `&` in front to indicate that, at
8288
// the API level, ownership isn't required.
89+
let mut out = String::new();
8390
if info.has_list && lt.is_none() {
8491
if let TypeMode::AllBorrowed(lt) = mode {
85-
self.push_str("&");
8692
if lt != "'_" {
87-
self.push_str(lt);
88-
self.push_str(" ");
93+
out.push_str(&format!("&{lt} "))
94+
} else {
95+
out.push_str("&")
8996
}
9097
}
9198
}
@@ -94,16 +101,16 @@ pub trait RustGenerator<'a> {
94101
} else {
95102
self.result_name(id)
96103
};
97-
self.print_type_name_in_interface(ty.owner, &name);
104+
out.push_str(&self.type_name_in_interface(ty.owner, &name));
98105

99106
// If the type recursively owns data and it's a
100107
// variant/record/list, then we need to place the
101108
// lifetime parameter on the type as well.
102109
if info.has_list && needs_generics(self.resolve(), &ty.kind) {
103-
self.print_generics(lt);
110+
out.push_str(&self.generics(lt));
104111
}
105112

106-
return;
113+
return out;
107114

108115
fn needs_generics(resolve: &Resolve, ty: &TypeDefKind) -> bool {
109116
match ty {
@@ -130,20 +137,16 @@ pub trait RustGenerator<'a> {
130137
}
131138

132139
match &ty.kind {
133-
TypeDefKind::List(t) => self.print_list(t, mode),
140+
TypeDefKind::List(t) => self.list(t, mode),
134141

135142
TypeDefKind::Option(t) => {
136-
self.push_str("Option<");
137-
self.print_ty(t, mode);
138-
self.push_str(">");
143+
format!("Option<{}>", self.ty(t, mode))
139144
}
140145

141146
TypeDefKind::Result(r) => {
142-
self.push_str("Result<");
143-
self.print_optional_ty(r.ok.as_ref(), mode);
144-
self.push_str(",");
145-
self.print_optional_ty(r.err.as_ref(), mode);
146-
self.push_str(">");
147+
let ok = self.optional_ty(r.ok.as_ref(), mode);
148+
let err = self.optional_ty(r.err.as_ref(), mode);
149+
format!("Result<{ok},{err}>")
147150
}
148151

149152
TypeDefKind::Variant(_) => panic!("unsupported anonymous variant"),
@@ -152,12 +155,13 @@ pub trait RustGenerator<'a> {
152155
// types. Note the trailing comma after each member to
153156
// appropriately handle 1-tuples.
154157
TypeDefKind::Tuple(t) => {
155-
self.push_str("(");
158+
let mut out = "(".to_string();
156159
for ty in t.types.iter() {
157-
self.print_ty(ty, mode);
158-
self.push_str(",");
160+
out.push_str(&self.ty(ty, mode));
161+
out.push_str(",");
159162
}
160-
self.push_str(")");
163+
out.push_str(")");
164+
out
161165
}
162166
TypeDefKind::Record(_) => {
163167
panic!("unsupported anonymous type reference: record")
@@ -169,76 +173,86 @@ pub trait RustGenerator<'a> {
169173
panic!("unsupported anonymous type reference: enum")
170174
}
171175
TypeDefKind::Future(ty) => {
172-
self.push_str("wasmtime::component::FutureReader<");
173-
self.print_optional_ty(ty.as_ref(), TypeMode::Owned);
174-
self.push_str(">");
176+
let wt = self.wasmtime_path();
177+
let t = self.optional_ty(ty.as_ref(), TypeMode::Owned);
178+
format!("{wt}::component::FutureReader<{t}>")
175179
}
176180
TypeDefKind::Stream(ty) => {
177-
self.push_str("wasmtime::component::StreamReader<");
178-
self.print_optional_ty(ty.as_ref(), TypeMode::Owned);
179-
self.push_str(">");
180-
}
181-
TypeDefKind::Handle(handle) => {
182-
self.print_handle(handle);
181+
let wt = self.wasmtime_path();
182+
let t = self.optional_ty(ty.as_ref(), TypeMode::Owned);
183+
format!("{wt}::component::StreamReader<{t}>")
183184
}
185+
TypeDefKind::Handle(handle) => self.handle(handle),
184186
TypeDefKind::Resource => unreachable!(),
185187

186-
TypeDefKind::Type(t) => self.print_ty(t, mode),
188+
TypeDefKind::Type(t) => self.ty(t, mode),
187189
TypeDefKind::Unknown => unreachable!(),
188190
}
189191
}
190192

191-
fn print_type_name_in_interface(&mut self, owner: TypeOwner, name: &str) {
193+
fn type_name_in_interface(&self, owner: TypeOwner, name: &str) -> String {
194+
let mut out = String::new();
192195
if let TypeOwner::Interface(id) = owner {
193196
if let Some(path) = self.path_to_interface(id) {
194-
self.push_str(&path);
195-
self.push_str("::");
197+
out.push_str(&path);
198+
out.push_str("::");
196199
}
197200
}
198-
self.push_str(name);
201+
out.push_str(name);
202+
out
199203
}
200204

201205
fn print_list(&mut self, ty: &Type, mode: TypeMode) {
206+
self.push_str(&self.list(ty, mode))
207+
}
208+
fn list(&self, ty: &Type, mode: TypeMode) -> String {
202209
let next_mode = if matches!(self.ownership(), Ownership::Owning) {
203210
TypeMode::Owned
204211
} else {
205212
mode
206213
};
214+
let ty = self.ty(ty, next_mode);
207215
match mode {
208216
TypeMode::AllBorrowed(lt) => {
209-
self.push_str("&");
210217
if lt != "'_" {
211-
self.push_str(lt);
212-
self.push_str(" ");
218+
format!("&{lt} [{ty}]")
219+
} else {
220+
format!("&[{ty}]")
213221
}
214-
self.push_str("[");
215-
self.print_ty(ty, next_mode);
216-
self.push_str("]");
217222
}
218223
TypeMode::Owned => {
219224
let wt = self.wasmtime_path();
220-
self.push_str(&format!("{wt}::component::__internal::Vec<"));
221-
self.print_ty(ty, next_mode);
222-
self.push_str(">");
225+
format!("{wt}::component::__internal::Vec<{ty}>")
223226
}
224227
}
225228
}
226229

227230
fn print_stream(&mut self, ty: Option<&Type>) {
231+
self.push_str(&self.stream(ty))
232+
}
233+
fn stream(&self, ty: Option<&Type>) -> String {
228234
let wt = self.wasmtime_path();
229-
self.push_str(&format!("{wt}::component::StreamReader<"));
230-
self.print_optional_ty(ty, TypeMode::Owned);
231-
self.push_str(">");
235+
let mut out = format!("{wt}::component::StreamReader<");
236+
out.push_str(&self.optional_ty(ty, TypeMode::Owned));
237+
out.push_str(">");
238+
out
232239
}
233240

234241
fn print_future(&mut self, ty: Option<&Type>) {
242+
self.push_str(&self.future(ty))
243+
}
244+
fn future(&self, ty: Option<&Type>) -> String {
235245
let wt = self.wasmtime_path();
236-
self.push_str(&format!("{wt}::component::FutureReader<"));
237-
self.print_optional_ty(ty, TypeMode::Owned);
238-
self.push_str(">");
246+
let mut out = format!("{wt}::component::FutureReader<");
247+
out.push_str(&self.optional_ty(ty, TypeMode::Owned));
248+
out.push_str(">");
249+
out
239250
}
240251

241252
fn print_handle(&mut self, handle: &Handle) {
253+
self.push_str(&self.handle(handle))
254+
}
255+
fn handle(&self, handle: &Handle) -> String {
242256
// Handles are either printed as `ResourceAny` for any guest-defined
243257
// resource or `Resource<T>` for all host-defined resources. This means
244258
// that this function needs to determine if `handle` points to a host
@@ -263,27 +277,27 @@ pub trait RustGenerator<'a> {
263277
};
264278
let wt = self.wasmtime_path();
265279
if is_host_defined {
266-
self.push_str(&format!("{wt}::component::Resource<"));
267-
self.print_type_name_in_interface(
280+
let mut out = format!("{wt}::component::Resource<");
281+
out.push_str(&self.type_name_in_interface(
268282
ty.owner,
269283
&ty.name.as_ref().unwrap().to_upper_camel_case(),
270-
);
271-
self.push_str(">");
284+
));
285+
out.push_str(">");
286+
out
272287
} else {
273-
self.push_str(&format!("{wt}::component::ResourceAny"));
288+
format!("{wt}::component::ResourceAny")
274289
}
275290
}
276291

277292
fn print_generics(&mut self, lifetime: Option<&str>) {
278-
if lifetime.is_none() {
279-
return;
280-
}
281-
self.push_str("<");
293+
self.push_str(&self.generics(lifetime))
294+
}
295+
fn generics(&self, lifetime: Option<&str>) -> String {
282296
if let Some(lt) = lifetime {
283-
self.push_str(lt);
284-
self.push_str(",");
297+
format!("<{lt},>")
298+
} else {
299+
String::new()
285300
}
286-
self.push_str(">");
287301
}
288302

289303
fn modes_of(&self, ty: TypeId) -> Vec<(String, TypeMode)> {
@@ -377,6 +391,21 @@ pub trait RustGenerator<'a> {
377391
None
378392
}
379393
}
394+
395+
fn typedfunc_sig(&self, func: &Function, param_mode: TypeMode) -> String {
396+
let mut out = "(".to_string();
397+
for (_, ty) in func.params.iter() {
398+
out.push_str(&self.ty(ty, param_mode));
399+
out.push_str(", ");
400+
}
401+
out.push_str("), (");
402+
if let Some(ty) = func.result {
403+
out.push_str(&self.ty(&ty, TypeMode::Owned));
404+
out.push_str(", ");
405+
}
406+
out.push_str(")");
407+
out
408+
}
380409
}
381410

382411
/// Translate `name` to a Rust `snake_case` identifier.

0 commit comments

Comments
 (0)