1 #![cfg(not(miri))]
2
3 use super::{Param, Type, make_echo_component, make_echo_component_with_params};
4 use wasmtime::Result;
5 use wasmtime::component::types::{self, Case, ComponentItem, Field};
6 use wasmtime::component::{Component, Linker, ResourceType, Val};
7 use wasmtime::{Module, Store};
8 use wasmtime_component_util::REALLOC_AND_FREE;
9
10 #[test]
primitives() -> Result<()>11 fn primitives() -> Result<()> {
12 let engine = super::engine();
13 let mut store = Store::new(&engine, ());
14 let mut output = [Val::Bool(false)];
15
16 for (input, ty, param) in [
17 (Val::Bool(true), "bool", Param(Type::U8, Some(0))),
18 (Val::S8(-42), "s8", Param(Type::S8, Some(0))),
19 (Val::U8(42), "u8", Param(Type::U8, Some(0))),
20 (Val::S16(-4242), "s16", Param(Type::S16, Some(0))),
21 (Val::U16(4242), "u16", Param(Type::U16, Some(0))),
22 (Val::S32(-314159265), "s32", Param(Type::I32, Some(0))),
23 (Val::U32(314159265), "u32", Param(Type::I32, Some(0))),
24 (Val::S64(-31415926535897), "s64", Param(Type::I64, Some(0))),
25 (Val::U64(31415926535897), "u64", Param(Type::I64, Some(0))),
26 (
27 Val::Float32(3.14159265),
28 "float32",
29 Param(Type::F32, Some(0)),
30 ),
31 (
32 Val::Float64(3.14159265),
33 "float64",
34 Param(Type::F64, Some(0)),
35 ),
36 (Val::Char(''), "char", Param(Type::I32, Some(0))),
37 ] {
38 let component = Component::new(&engine, make_echo_component_with_params(ty, &[param]))?;
39 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
40 let func = instance.get_func(&mut store, "echo").unwrap();
41 func.call(&mut store, &[input.clone()], &mut output)?;
42
43 assert_eq!(input, output[0]);
44 }
45
46 // Sad path: type mismatch
47
48 let component = Component::new(
49 &engine,
50 make_echo_component_with_params("float64", &[Param(Type::F64, Some(0))]),
51 )?;
52 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
53 let func = instance.get_func(&mut store, "echo").unwrap();
54 let err = func
55 .call(&mut store, &[Val::U64(42)], &mut output)
56 .unwrap_err();
57
58 assert!(err.to_string().contains("type mismatch"), "{err}");
59
60 // Sad path: arity mismatch (too many)
61
62 let err = func
63 .call(
64 &mut store,
65 &[Val::Float64(3.14159265), Val::Float64(3.14159265)],
66 &mut output,
67 )
68 .unwrap_err();
69
70 assert!(
71 err.to_string().contains("expected 1 argument(s), got 2"),
72 "{err}"
73 );
74
75 // Sad path: arity mismatch (too few)
76
77 let err = func.call(&mut store, &[], &mut output).unwrap_err();
78 assert!(
79 err.to_string().contains("expected 1 argument(s), got 0"),
80 "{err}"
81 );
82
83 let err = func.call(&mut store, &output, &mut []).unwrap_err();
84 assert!(
85 err.to_string().contains("expected 1 result(s), got 0"),
86 "{err}"
87 );
88
89 Ok(())
90 }
91
92 #[test]
strings() -> Result<()>93 fn strings() -> Result<()> {
94 let engine = super::engine();
95 let mut store = Store::new(&engine, ());
96
97 let component = Component::new(&engine, make_echo_component("string", 8))?;
98 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
99 let func = instance.get_func(&mut store, "echo").unwrap();
100 let input = Val::String("hello, component!".into());
101 let mut output = [Val::Bool(false)];
102 func.call(&mut store, &[input.clone()], &mut output)?;
103 assert_eq!(input, output[0]);
104
105 Ok(())
106 }
107
108 #[test]
lists() -> Result<()>109 fn lists() -> Result<()> {
110 let engine = super::engine();
111 let mut store = Store::new(&engine, ());
112
113 let component = Component::new(&engine, make_echo_component("(list u32)", 8))?;
114 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
115 let func = instance.get_func(&mut store, "echo").unwrap();
116 let input = Val::List(vec![
117 Val::U32(32343),
118 Val::U32(79023439),
119 Val::U32(2084037802),
120 ]);
121 let mut output = [Val::Bool(false)];
122 func.call(&mut store, &[input.clone()], &mut output)?;
123
124 assert_eq!(input, output[0]);
125
126 // Sad path: type mismatch
127
128 let err = Val::List(vec![
129 Val::U32(32343),
130 Val::U32(79023439),
131 Val::Float32(3.14159265),
132 ]);
133 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
134 assert!(err.to_string().contains("type mismatch"), "{err}");
135
136 Ok(())
137 }
138
139 #[test]
maps() -> Result<()>140 fn maps() -> Result<()> {
141 let engine = super::map_engine();
142 let mut store = Store::new(&engine, ());
143
144 let component = Component::new(&engine, make_echo_component("(map u32 string)", 8))?;
145 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
146 let func = instance.get_func(&mut store, "echo").unwrap();
147
148 let input_map = vec![
149 (Val::U32(1), Val::String("one".into())),
150 (Val::U32(2), Val::String("two".into())),
151 (Val::U32(3), Val::String("three".into())),
152 ];
153 let input = Val::Map(input_map);
154
155 let mut output = [Val::Bool(false)];
156 func.call(&mut store, &[input.clone()], &mut output)?;
157
158 // Maps should round-trip correctly
159 match &output[0] {
160 Val::Map(output_map) => {
161 assert_eq!(output_map.len(), 3);
162 assert!(
163 output_map
164 .iter()
165 .any(|(k, v)| *k == Val::U32(1) && *v == Val::String("one".into()))
166 );
167 assert!(
168 output_map
169 .iter()
170 .any(|(k, v)| *k == Val::U32(2) && *v == Val::String("two".into()))
171 );
172 assert!(
173 output_map
174 .iter()
175 .any(|(k, v)| *k == Val::U32(3) && *v == Val::String("three".into()))
176 );
177 }
178 _ => panic!("expected map"),
179 }
180
181 // Sad path: type mismatch (wrong key type)
182 // Need to create a fresh instance because errors can leave the instance in a bad state
183 let mut store2 = Store::new(&engine, ());
184 let instance2 = Linker::new(&engine).instantiate(&mut store2, &component)?;
185 let func2 = instance2.get_func(&mut store2, "echo").unwrap();
186
187 let err_map = vec![(Val::String("key".into()), Val::String("value".into()))];
188 let err = Val::Map(err_map);
189 let err = func2.call(&mut store2, &[err], &mut output).unwrap_err();
190 assert!(err.to_string().contains("type mismatch"), "{err}");
191
192 // Sad path: type mismatch (wrong value type)
193 let mut store3 = Store::new(&engine, ());
194 let instance3 = Linker::new(&engine).instantiate(&mut store3, &component)?;
195 let func3 = instance3.get_func(&mut store3, "echo").unwrap();
196
197 let err_map2 = vec![(Val::U32(1), Val::U32(42))];
198 let err = Val::Map(err_map2);
199 let err = func3.call(&mut store3, &[err], &mut output).unwrap_err();
200 assert!(err.to_string().contains("type mismatch"), "{err}");
201
202 // Test empty map
203 let empty_map = vec![];
204 let input = Val::Map(empty_map);
205 func.call(&mut store, &[input.clone()], &mut output)?;
206 match &output[0] {
207 Val::Map(output_map) => assert_eq!(output_map.len(), 0),
208 _ => panic!("expected map"),
209 }
210
211 Ok(())
212 }
213
214 #[test]
maps_complex_types() -> Result<()>215 fn maps_complex_types() -> Result<()> {
216 let engine = super::map_engine();
217 let mut store = Store::new(&engine, ());
218
219 // Test map<string, list<u32>>
220 let component = Component::new(&engine, make_echo_component("(map string (list u32))", 8))?;
221 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
222 let func = instance.get_func(&mut store, "echo").unwrap();
223
224 let input_map = vec![
225 (
226 Val::String("first".into()),
227 Val::List(vec![Val::U32(1), Val::U32(2), Val::U32(3)]),
228 ),
229 (
230 Val::String("second".into()),
231 Val::List(vec![Val::U32(4), Val::U32(5)]),
232 ),
233 ];
234 let input = Val::Map(input_map);
235
236 let mut output = [Val::Bool(false)];
237 func.call(&mut store, &[input.clone()], &mut output)?;
238
239 // Verify round-trip
240 match &output[0] {
241 Val::Map(output_map) => {
242 assert_eq!(output_map.len(), 2);
243 // Check first entry
244 let first_entry = output_map
245 .iter()
246 .find(|(k, _)| *k == Val::String("first".into()));
247 match first_entry {
248 Some((_, Val::List(list))) => {
249 assert_eq!(list.len(), 3);
250 assert_eq!(list[0], Val::U32(1));
251 assert_eq!(list[1], Val::U32(2));
252 assert_eq!(list[2], Val::U32(3));
253 }
254 _ => panic!("expected list"),
255 }
256 // Check second entry
257 let second_entry = output_map
258 .iter()
259 .find(|(k, _)| *k == Val::String("second".into()));
260 match second_entry {
261 Some((_, Val::List(list))) => {
262 assert_eq!(list.len(), 2);
263 assert_eq!(list[0], Val::U32(4));
264 assert_eq!(list[1], Val::U32(5));
265 }
266 _ => panic!("expected list"),
267 }
268 }
269 _ => panic!("expected map"),
270 }
271
272 Ok(())
273 }
274
275 #[test]
maps_equality() -> Result<()>276 fn maps_equality() -> Result<()> {
277 let map1 = vec![
278 (Val::U32(1), Val::String("one".into())),
279 (Val::U32(2), Val::String("two".into())),
280 ];
281
282 let map2 = vec![
283 (Val::U32(1), Val::String("one".into())),
284 (Val::U32(2), Val::String("two".into())),
285 ];
286
287 // Maps with same content in same order should be equal
288 assert_eq!(Val::Map(map1.clone()), Val::Map(map2));
289
290 // Different values should not be equal
291 let map3 = vec![
292 (Val::U32(1), Val::String("different".into())),
293 (Val::U32(2), Val::String("two".into())),
294 ];
295 assert_ne!(Val::Map(map1.clone()), Val::Map(map3));
296
297 // Different keys should not be equal
298 let map4 = vec![
299 (Val::U32(3), Val::String("one".into())),
300 (Val::U32(2), Val::String("two".into())),
301 ];
302 assert_ne!(Val::Map(map1), Val::Map(map4));
303
304 // Empty maps should be equal
305 let empty1: Vec<(Val, Val)> = vec![];
306 let empty2: Vec<(Val, Val)> = vec![];
307 assert_eq!(Val::Map(empty1), Val::Map(empty2));
308
309 Ok(())
310 }
311
312 #[test]
maps_duplicate_keys() -> Result<()>313 fn maps_duplicate_keys() -> Result<()> {
314 let engine = super::map_engine();
315 let mut store = Store::new(&engine, ());
316
317 let component = Component::new(&engine, make_echo_component("(map u32 string)", 8))?;
318 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
319 let func = instance.get_func(&mut store, "echo").unwrap();
320
321 // Create a map with duplicate keys - Vec preserves all entries
322 let input_map = vec![
323 (Val::U32(1), Val::String("first".into())),
324 (Val::U32(1), Val::String("last".into())), // Duplicate key
325 (Val::U32(2), Val::String("two".into())),
326 ];
327 let input = Val::Map(input_map);
328
329 let mut output = [Val::Bool(false)];
330 func.call(&mut store, &[input.clone()], &mut output)?;
331
332 // Verify all entries are preserved (Vec doesn't deduplicate)
333 match &output[0] {
334 Val::Map(output_map) => {
335 // Should have 3 entries (Vec preserves duplicates)
336 assert_eq!(output_map.len(), 3);
337 }
338 _ => panic!("expected map"),
339 }
340
341 Ok(())
342 }
343
344 #[test]
maps_all_primitive_types() -> Result<()>345 fn maps_all_primitive_types() -> Result<()> {
346 let engine = super::map_engine();
347 let mut store = Store::new(&engine, ());
348
349 // Test map<u32, u32>
350 let component = Component::new(&engine, make_echo_component("(map u32 u32)", 8))?;
351 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
352 let func = instance.get_func(&mut store, "echo").unwrap();
353
354 let input_map = vec![(Val::U32(1), Val::U32(100)), (Val::U32(2), Val::U32(200))];
355 let input = Val::Map(input_map);
356
357 let mut output = [Val::Bool(false)];
358 func.call(&mut store, &[input.clone()], &mut output)?;
359 assert_eq!(input, output[0]);
360
361 // Test map<string, u32>
362 let component = Component::new(&engine, make_echo_component("(map string u32)", 8))?;
363 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
364 let func = instance.get_func(&mut store, "echo").unwrap();
365
366 let input_map = vec![
367 (Val::String("one".into()), Val::U32(1)),
368 (Val::String("two".into()), Val::U32(2)),
369 ];
370 let input = Val::Map(input_map);
371
372 func.call(&mut store, &[input.clone()], &mut output)?;
373 assert_eq!(input, output[0]);
374
375 Ok(())
376 }
377
378 #[test]
maps_alignment() -> Result<()>379 fn maps_alignment() -> Result<()> {
380 let engine = super::map_engine();
381 let mut store = Store::new(&engine, ());
382
383 // Test map<u8, u64> - key_size=1, value_align=8
384 // This would fail with the alignment bug because value would be at offset 1 instead of 8
385 let component = Component::new(&engine, make_echo_component("(map u8 u64)", 8))?;
386 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
387 let func = instance.get_func(&mut store, "echo").unwrap();
388
389 let input_map = vec![
390 (Val::U8(1), Val::U64(100)),
391 (Val::U8(2), Val::U64(200)),
392 (Val::U8(3), Val::U64(300)),
393 ];
394 let input = Val::Map(input_map);
395
396 let mut output = [Val::Bool(false)];
397 func.call(&mut store, &[input.clone()], &mut output)?;
398 assert_eq!(input, output[0]);
399
400 // Test map<u32, u64> - key_size=4, value_align=8
401 // This would fail with the alignment bug because value would be at offset 4 instead of 8
402 let component = Component::new(&engine, make_echo_component("(map u32 u64)", 8))?;
403 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
404 let func = instance.get_func(&mut store, "echo").unwrap();
405
406 let input_map = vec![(Val::U32(1), Val::U64(1000)), (Val::U32(2), Val::U64(2000))];
407 let input = Val::Map(input_map);
408
409 func.call(&mut store, &[input.clone()], &mut output)?;
410 assert_eq!(input, output[0]);
411
412 // Test map<u8, u32> - key_size=1, value_align=4
413 // This would fail with the alignment bug because value would be at offset 1 instead of 4
414 let component = Component::new(&engine, make_echo_component("(map u8 u32)", 8))?;
415 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
416 let func = instance.get_func(&mut store, "echo").unwrap();
417
418 let input_map = vec![(Val::U8(10), Val::U32(100)), (Val::U8(20), Val::U32(200))];
419 let input = Val::Map(input_map);
420
421 func.call(&mut store, &[input.clone()], &mut output)?;
422 assert_eq!(input, output[0]);
423
424 // Test map<u16, u64> - key_size=2, value_align=8
425 // This would fail with the alignment bug because value would be at offset 2 instead of 8
426 let component = Component::new(&engine, make_echo_component("(map u16 u64)", 8))?;
427 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
428 let func = instance.get_func(&mut store, "echo").unwrap();
429
430 let input_map = vec![
431 (Val::U16(1), Val::U64(10000)),
432 (Val::U16(2), Val::U64(20000)),
433 ];
434 let input = Val::Map(input_map);
435
436 func.call(&mut store, &[input.clone()], &mut output)?;
437 assert_eq!(input, output[0]);
438
439 Ok(())
440 }
441
442 #[test]
maps_large() -> Result<()>443 fn maps_large() -> Result<()> {
444 let engine = super::map_engine();
445 let mut store = Store::new(&engine, ());
446
447 let component = Component::new(&engine, make_echo_component("(map u32 string)", 8))?;
448 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
449 let func = instance.get_func(&mut store, "echo").unwrap();
450
451 // Create a map with many entries
452 let input_map: Vec<(Val, Val)> = (0..100)
453 .map(|i| (Val::U32(i), Val::String(format!("value_{i}"))))
454 .collect();
455 let input = Val::Map(input_map);
456
457 let mut output = [Val::Bool(false)];
458 func.call(&mut store, &[input.clone()], &mut output)?;
459
460 // Verify all entries are present
461 match &output[0] {
462 Val::Map(output_map) => {
463 assert_eq!(output_map.len(), 100);
464 for i in 0..100 {
465 assert!(output_map.iter().any(|(k, v)| {
466 *k == Val::U32(i) && *v == Val::String(format!("value_{i}"))
467 }));
468 }
469 }
470 _ => panic!("expected map"),
471 }
472
473 Ok(())
474 }
475
476 #[test]
records() -> Result<()>477 fn records() -> Result<()> {
478 let engine = super::engine();
479 let mut store = Store::new(&engine, ());
480
481 let component = Component::new(
482 &engine,
483 make_echo_component_with_params(
484 r#"
485 (type $c' (record
486 (field "D" bool)
487 (field "E" u32)
488 ))
489 (export $c "c" (type $c'))
490 (type $Foo' (record
491 (field "A" u32)
492 (field "B" float64)
493 (field "C" $c)
494 ))
495 "#,
496 &[
497 Param(Type::I32, Some(0)),
498 Param(Type::F64, Some(8)),
499 Param(Type::U8, Some(16)),
500 Param(Type::I32, Some(20)),
501 ],
502 ),
503 )?;
504 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
505 let func = instance.get_func(&mut store, "echo").unwrap();
506 let input = Val::Record(vec![
507 ("A".into(), Val::U32(32343)),
508 ("B".into(), Val::Float64(3.14159265)),
509 (
510 "C".into(),
511 Val::Record(vec![
512 ("D".into(), Val::Bool(false)),
513 ("E".into(), Val::U32(2084037802)),
514 ]),
515 ),
516 ]);
517 let mut output = [Val::Bool(false)];
518 func.call(&mut store, &[input.clone()], &mut output)?;
519
520 assert_eq!(input, output[0]);
521
522 // Sad path: type mismatch
523
524 let err = Val::Record(vec![
525 ("A".into(), Val::S32(32343)),
526 ("B".into(), Val::Float64(3.14159265)),
527 (
528 "C".into(),
529 Val::Record(vec![
530 ("D".into(), Val::Bool(false)),
531 ("E".into(), Val::U32(2084037802)),
532 ]),
533 ),
534 ]);
535 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
536 let func = instance.get_func(&mut store, "echo").unwrap();
537 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
538 assert!(err.to_string().contains("type mismatch"), "{err}");
539
540 // Sad path: too many fields
541
542 let err = Val::Record(vec![
543 ("A".into(), Val::U32(32343)),
544 ("B".into(), Val::Float64(3.14159265)),
545 (
546 "C".into(),
547 Val::Record(vec![
548 ("D".into(), Val::Bool(false)),
549 ("E".into(), Val::U32(2084037802)),
550 ]),
551 ),
552 ("F".into(), Val::Bool(true)),
553 ]);
554 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
555 let func = instance.get_func(&mut store, "echo").unwrap();
556 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
557 assert!(
558 err.to_string().contains("expected 3 fields, got 4"),
559 "{err}"
560 );
561
562 // Sad path: too few fields
563
564 let err = Val::Record(vec![
565 ("A".into(), Val::U32(32343)),
566 ("B".into(), Val::Float64(3.14159265)),
567 ]);
568 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
569 let func = instance.get_func(&mut store, "echo").unwrap();
570 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
571 assert!(
572 err.to_string().contains("expected 3 fields, got 2"),
573 "{err}"
574 );
575
576 Ok(())
577 }
578
579 #[test]
variants() -> Result<()>580 fn variants() -> Result<()> {
581 let engine = super::engine();
582 let mut store = Store::new(&engine, ());
583
584 let fragment = r#"
585 (type $c' (record (field "D" bool) (field "E" u32)))
586 (export $c "c" (type $c'))
587 (type $Foo' (variant
588 (case "A" u32)
589 (case "B" float64)
590 (case "C" $c)
591 ))
592 "#;
593
594 let component = Component::new(
595 &engine,
596 make_echo_component_with_params(
597 fragment,
598 &[
599 Param(Type::U8, Some(0)),
600 Param(Type::I64, Some(8)),
601 Param(Type::I32, None),
602 ],
603 ),
604 )?;
605 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
606 let func = instance.get_func(&mut store, "echo").unwrap();
607 let input = Val::Variant("B".into(), Some(Box::new(Val::Float64(3.14159265))));
608 let mut output = [Val::Bool(false)];
609 func.call(&mut store, &[input.clone()], &mut output)?;
610
611 assert_eq!(input, output[0]);
612
613 // Do it again, this time using case "C"
614
615 let component = Component::new(
616 &engine,
617 make_echo_component_with_params(
618 fragment,
619 &[
620 Param(Type::U8, Some(0)),
621 Param(Type::I64, Some(8)),
622 Param(Type::I32, Some(12)),
623 ],
624 ),
625 )?;
626 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
627 let func = instance.get_func(&mut store, "echo").unwrap();
628 let input = Val::Variant(
629 "C".into(),
630 Some(Box::new(Val::Record(vec![
631 ("D".into(), Val::Bool(true)),
632 ("E".into(), Val::U32(314159265)),
633 ]))),
634 );
635 func.call(&mut store, &[input.clone()], &mut output)?;
636
637 assert_eq!(input, output[0]);
638
639 // Sad path: type mismatch
640
641 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
642 let func = instance.get_func(&mut store, "echo").unwrap();
643 let err = Val::Variant("B".into(), Some(Box::new(Val::U64(314159265))));
644 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
645 assert!(err.to_string().contains("type mismatch"), "{err}");
646
647 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
648 let func = instance.get_func(&mut store, "echo").unwrap();
649 let err = Val::Variant("B".into(), None);
650 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
651 assert!(
652 err.to_string().contains("expected a payload for case `B`"),
653 "{err}"
654 );
655
656 // Sad path: unknown case
657
658 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
659 let func = instance.get_func(&mut store, "echo").unwrap();
660 let err = Val::Variant("D".into(), Some(Box::new(Val::U64(314159265))));
661 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
662 assert!(err.to_string().contains("unknown variant case"), "{err}");
663
664 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
665 let func = instance.get_func(&mut store, "echo").unwrap();
666 let err = Val::Variant("D".into(), None);
667 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
668 assert!(err.to_string().contains("unknown variant case"), "{err}");
669
670 // Make sure we lift variants which have cases of different sizes with the correct alignment
671
672 let component = Component::new(
673 &engine,
674 make_echo_component_with_params(
675 r#"
676 (type $c' (record (field "D" bool) (field "E" u32)))
677 (export $c "c" (type $c'))
678 (type $a' (variant
679 (case "A" u32)
680 (case "B" float64)
681 (case "C" $c)
682 ))
683 (export $a "a" (type $a'))
684 (type $Foo' (record
685 (field "A" $a)
686 (field "B" u32)
687 ))
688 "#,
689 &[
690 Param(Type::U8, Some(0)),
691 Param(Type::I64, Some(8)),
692 Param(Type::I32, None),
693 Param(Type::I32, Some(16)),
694 ],
695 ),
696 )?;
697 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
698 let func = instance.get_func(&mut store, "echo").unwrap();
699 let input = Val::Record(vec![
700 (
701 "A".into(),
702 Val::Variant("A".into(), Some(Box::new(Val::U32(314159265)))),
703 ),
704 ("B".into(), Val::U32(628318530)),
705 ]);
706 func.call(&mut store, &[input.clone()], &mut output)?;
707
708 assert_eq!(input, output[0]);
709
710 Ok(())
711 }
712
713 #[test]
flags() -> Result<()>714 fn flags() -> Result<()> {
715 let engine = super::engine();
716 let mut store = Store::new(&engine, ());
717
718 let component = Component::new(
719 &engine,
720 make_echo_component_with_params(
721 r#"(flags "A" "B" "C" "D" "E")"#,
722 &[Param(Type::U8, Some(0))],
723 ),
724 )?;
725 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
726 let func = instance.get_func(&mut store, "echo").unwrap();
727 let input = Val::Flags(vec!["B".into(), "D".into()]);
728 let mut output = [Val::Bool(false)];
729 func.call(&mut store, &[input.clone()], &mut output)?;
730
731 assert_eq!(input, output[0]);
732
733 // Sad path: unknown flags
734
735 let err = Val::Flags(vec!["B".into(), "D".into(), "F".into()]);
736 let err = func.call(&mut store, &[err], &mut output).unwrap_err();
737 assert!(err.to_string().contains("unknown flag"), "{err}");
738
739 Ok(())
740 }
741
742 #[test]
everything() -> Result<()>743 fn everything() -> Result<()> {
744 // This serves to test both nested types and storing parameters on the heap (i.e. exceeding `MAX_STACK_PARAMS`)
745
746 let engine = super::engine();
747 let mut store = Store::new(&engine, ());
748
749 let component = Component::new(
750 &engine,
751 make_echo_component_with_params(
752 r#"
753 (type $b' (enum "a" "b"))
754 (export $b "b" (type $b'))
755 (type $c' (record (field "D" bool) (field "E" u32)))
756 (export $c "c" (type $c'))
757 (type $f' (flags "G" "H" "I"))
758 (export $f "f" (type $f'))
759 (type $m' (record (field "N" bool) (field "O" u32)))
760 (export $m "m" (type $m'))
761 (type $j' (variant
762 (case "K" u32)
763 (case "L" float64)
764 (case "M" $m)
765 ))
766 (export $j "j" (type $j'))
767
768 (type $Foo' (record
769 (field "A" u32)
770 (field "B" $b)
771 (field "C" $c)
772 (field "F" (list $f))
773 (field "J" $j)
774 (field "P" s8)
775 (field "Q" s16)
776 (field "R" s32)
777 (field "S" s64)
778 (field "T" float32)
779 (field "U" float64)
780 (field "V" string)
781 (field "W" char)
782 (field "Y" (tuple u32 u32))
783 (field "AA" (option u32))
784 (field "BB" (result string (error string)))
785 ))
786 "#,
787 &[
788 Param(Type::I32, Some(0)),
789 Param(Type::U8, Some(4)),
790 Param(Type::U8, Some(5)),
791 Param(Type::I32, Some(8)),
792 Param(Type::I32, Some(12)),
793 Param(Type::I32, Some(16)),
794 Param(Type::U8, Some(20)),
795 Param(Type::I64, Some(28)),
796 Param(Type::I32, Some(32)),
797 Param(Type::S8, Some(36)),
798 Param(Type::S16, Some(38)),
799 Param(Type::I32, Some(40)),
800 Param(Type::I64, Some(48)),
801 Param(Type::F32, Some(56)),
802 Param(Type::F64, Some(64)),
803 Param(Type::I32, Some(72)),
804 Param(Type::I32, Some(76)),
805 Param(Type::I32, Some(80)),
806 Param(Type::I32, Some(84)),
807 Param(Type::I32, Some(88)),
808 Param(Type::I64, Some(96)),
809 Param(Type::U8, Some(104)),
810 Param(Type::I32, Some(108)),
811 Param(Type::U8, Some(112)),
812 Param(Type::I32, Some(116)),
813 Param(Type::I32, Some(120)),
814 ],
815 ),
816 )?;
817 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
818 let func = instance.get_func(&mut store, "echo").unwrap();
819 let input = Val::Record(vec![
820 ("A".into(), Val::U32(32343)),
821 ("B".into(), Val::Enum("b".to_string())),
822 (
823 "C".into(),
824 Val::Record(vec![
825 ("D".to_string(), Val::Bool(false)),
826 ("E".to_string(), Val::U32(2084037802)),
827 ]),
828 ),
829 (
830 "F".into(),
831 Val::List(vec![Val::Flags(vec!["G".to_string(), "I".to_string()])]),
832 ),
833 (
834 "J".into(),
835 Val::Variant("L".to_string(), Some(Box::new(Val::Float64(3.14159265)))),
836 ),
837 ("P".into(), Val::S8(42)),
838 ("Q".into(), Val::S16(4242)),
839 ("R".into(), Val::S32(42424242)),
840 ("S".into(), Val::S64(424242424242424242)),
841 ("T".into(), Val::Float32(3.14159265)),
842 ("U".into(), Val::Float64(3.14159265)),
843 ("V".into(), Val::String("wow, nice types".to_string())),
844 ("W".into(), Val::Char('')),
845 ("Y".into(), Val::Tuple(vec![Val::U32(42), Val::U32(24)])),
846 (
847 "AA".into(),
848 Val::Option(Some(Box::new(Val::U32(314159265)))),
849 ),
850 (
851 "BB".into(),
852 Val::Result(Ok(Some(Box::new(Val::String("no problem".to_string()))))),
853 ),
854 ]);
855 let mut output = [Val::Bool(false)];
856 func.call(&mut store, &[input.clone()], &mut output)?;
857
858 assert_eq!(input, output[0]);
859
860 Ok(())
861 }
862
863 #[test]
introspection() -> Result<()>864 fn introspection() -> Result<()> {
865 let engine = super::engine();
866
867 let component = Component::new(
868 &engine,
869 format!(
870 r#"
871 (component
872 (import "res" (type $res (sub resource)))
873
874 (import "ai" (instance $i))
875 (import "bi" (instance $i2 (export "m" (core module))))
876
877 (alias export $i2 "m" (core module $m))
878
879 (type $t (func (param "a" u32) (result u32)))
880 (component $a
881 (core module $m
882 (func (export "add-five") (param i32) (result i32)
883 local.get 0
884 i32.const 5
885 i32.add)
886 )
887 (core instance $m (instantiate $m))
888 (func (export "add-five") (type $t) (canon lift (core func $m "add-five")))
889 )
890 (component $b
891 (import "interface-v1" (instance $i
892 (export "add-five" (func (type $t)))))
893 (core module $m
894 (func $add-five (import "interface-0.1.0" "add-five") (param i32) (result i32))
895 (func) ;; causes index out of bounds
896 (func (export "run") (result i32) i32.const 0 call $add-five)
897 )
898 (core func $add-five (canon lower (func $i "add-five")))
899 (core instance $i (instantiate 0
900 (with "interface-0.1.0" (instance
901 (export "add-five" (func $add-five))
902 ))
903 ))
904 (func (result u32) (canon lift (core func $i "run")))
905 (export "run" (func 1))
906 )
907 (instance $a (instantiate $a))
908 (instance $b (instantiate $b (with "interface-v1" (instance $a))))
909 (export "run" (func $b "run"))
910
911 (component $c
912 (component $c
913 (export "m" (core module $m))
914 )
915 (instance $c (instantiate $c))
916 (export "i" (instance $c))
917 )
918 (instance $c (instantiate $c))
919 (export "i" (instance $c))
920 (export "r" (instance $i))
921 (export "r2" (instance $i2))
922
923 (type $b' (enum "a" "b"))
924 (export $b "b" (type $b'))
925 (type $c' (record (field "D" bool) (field "E" u32)))
926 (export $c "c" (type $c'))
927 (type $f' (flags "G" "H" "I"))
928 (export $f "f" (type $f'))
929 (type $m' (record (field "N" bool) (field "O" u32)))
930 (export $m "m" (type $m'))
931 (type $j' (variant
932 (case "K" u32)
933 (case "L" float64)
934 (case "M" $m)
935 ))
936 (export $j "j" (type $j'))
937
938 (type $Foo' (record
939 (field "A" u32)
940 (field "B" $b)
941 (field "C" $c)
942 (field "F" (list $f))
943 (field "J" $j)
944 (field "P" s8)
945 (field "Q" s16)
946 (field "R" s32)
947 (field "S" s64)
948 (field "T" float32)
949 (field "U" float64)
950 (field "V" string)
951 (field "W" char)
952 (field "Y" (tuple u32 u32))
953 (field "AA" (option u32))
954 (field "BB" (result string (error string)))
955 (field "CC" (own $res))
956 ))
957 (export $Foo "foo" (type $Foo'))
958
959 (core module $m2
960 (func (export "f") (param i32) (result i32)
961 local.get 0
962 )
963 (memory (export "memory") 1)
964 {REALLOC_AND_FREE}
965 )
966 (core instance $i3 (instantiate $m2))
967
968 (func (export "fn") (param "x" (option $Foo)) (result (option (tuple u32 u32)))
969 (canon lift
970 (core func $i3 "f")
971 (memory $i3 "memory")
972 (realloc (func $i3 "realloc"))
973 )
974 )
975 )
976 "#
977 ),
978 )?;
979
980 struct MyType;
981
982 let mut linker = Linker::<()>::new(&engine);
983 linker
984 .root()
985 .resource("res", ResourceType::host::<MyType>(), |_, _| Ok(()))?;
986 linker.instance("ai")?;
987 linker
988 .instance("bi")?
989 .module("m", &Module::new(&engine, "(module)")?)?;
990
991 let component_ty = linker.substituted_component_type(&component)?;
992
993 let mut imports = component_ty.imports(linker.engine());
994 assert_eq!(imports.len(), 3);
995 let (name, res_ty) = imports.next().unwrap();
996 assert_eq!(name, "res");
997 let ComponentItem::Resource(res_ty) = res_ty else {
998 panic!("`res` import item of wrong type")
999 };
1000 assert_eq!(res_ty, ResourceType::host::<MyType>());
1001
1002 let (name, ai_ty) = imports.next().unwrap();
1003 assert_eq!(name, "ai");
1004 let ComponentItem::ComponentInstance(ai_ty) = ai_ty else {
1005 panic!("`ai` import item of wrong type")
1006 };
1007 assert_eq!(ai_ty.exports(linker.engine()).len(), 0);
1008
1009 let (name, bi_ty) = imports.next().unwrap();
1010 assert_eq!(name, "bi");
1011 let ComponentItem::ComponentInstance(bi_ty) = bi_ty else {
1012 panic!("`bi` import item of wrong type")
1013 };
1014 let mut bi_exports = bi_ty.exports(linker.engine());
1015 assert_eq!(bi_exports.len(), 1);
1016 let (name, bi_m_ty) = bi_exports.next().unwrap();
1017 assert_eq!(name, "m");
1018 let ComponentItem::Module(bi_m_ty) = bi_m_ty else {
1019 panic!("`bi.m` import item of wrong type")
1020 };
1021 assert_eq!(bi_m_ty.imports(linker.engine()).len(), 0);
1022 assert_eq!(bi_m_ty.exports(linker.engine()).len(), 0);
1023
1024 let mut exports = component_ty.exports(linker.engine());
1025 assert_eq!(exports.len(), 11);
1026
1027 let (name, run_ty) = exports.next().unwrap();
1028 assert_eq!(name, "run");
1029 let ComponentItem::ComponentFunc(run_ty) = run_ty else {
1030 panic!("`run` export item of wrong type")
1031 };
1032 assert_eq!(run_ty.params().len(), 0);
1033
1034 let mut run_results = run_ty.results();
1035 assert_eq!(run_results.len(), 1);
1036 assert_eq!(run_results.next().unwrap(), types::Type::U32);
1037
1038 let (name, i_ty) = exports.next().unwrap();
1039 assert_eq!(name, "i");
1040 let ComponentItem::ComponentInstance(i_ty) = i_ty else {
1041 panic!("`i` export item of wrong type")
1042 };
1043 let mut i_ty_exports = i_ty.exports(linker.engine());
1044 assert_eq!(i_ty_exports.len(), 1);
1045 let (name, i_i_ty) = i_ty_exports.next().unwrap();
1046 assert_eq!(name, "i");
1047 let ComponentItem::ComponentInstance(i_i_ty) = i_i_ty else {
1048 panic!("`i.i` import item of wrong type")
1049 };
1050 let mut i_i_ty_exports = i_i_ty.exports(linker.engine());
1051 assert_eq!(i_i_ty_exports.len(), 1);
1052 let (name, i_i_m_ty) = i_i_ty_exports.next().unwrap();
1053 assert_eq!(name, "m");
1054 let ComponentItem::Module(i_i_m_ty) = i_i_m_ty else {
1055 panic!("`i.i.m` import item of wrong type")
1056 };
1057 assert_eq!(i_i_m_ty.imports(linker.engine()).len(), 0);
1058 assert_eq!(i_i_m_ty.exports(linker.engine()).len(), 0);
1059
1060 let (name, r_ty) = exports.next().unwrap();
1061 assert_eq!(name, "r");
1062 let ComponentItem::ComponentInstance(r_ty) = r_ty else {
1063 panic!("`r` export item of wrong type")
1064 };
1065 assert_eq!(r_ty.exports(linker.engine()).len(), 0);
1066
1067 let (name, r2_ty) = exports.next().unwrap();
1068 assert_eq!(name, "r2");
1069 let ComponentItem::ComponentInstance(r2_ty) = r2_ty else {
1070 panic!("`r2` export item of wrong type")
1071 };
1072 let mut r2_exports = r2_ty.exports(linker.engine());
1073 assert_eq!(r2_exports.len(), 1);
1074 let (name, r2_m_ty) = r2_exports.next().unwrap();
1075 assert_eq!(name, "m");
1076 let ComponentItem::Module(r2_m_ty) = r2_m_ty else {
1077 panic!("`r2.m` export item of wrong type")
1078 };
1079 assert_eq!(r2_m_ty.imports(linker.engine()).len(), 0);
1080 assert_eq!(r2_m_ty.exports(linker.engine()).len(), 0);
1081
1082 let (name, b_ty) = exports.next().unwrap();
1083 assert_eq!(name, "b");
1084 let ComponentItem::Type(b_ty) = b_ty else {
1085 panic!("`b` export item of wrong type")
1086 };
1087 assert_eq!(b_ty.unwrap_enum().names().collect::<Vec<_>>(), ["a", "b"]);
1088
1089 let (name, c_ty) = exports.next().unwrap();
1090 assert_eq!(name, "c");
1091 let ComponentItem::Type(c_ty) = c_ty else {
1092 panic!("`c` export item of wrong type")
1093 };
1094 let mut fields = c_ty.unwrap_record().fields();
1095 {
1096 let Field { name, ty } = fields.next().unwrap();
1097 assert_eq!(name, "D");
1098 assert_eq!(ty, types::Type::Bool);
1099 let Field { name, ty } = fields.next().unwrap();
1100 assert_eq!(name, "E");
1101 assert_eq!(ty, types::Type::U32);
1102 }
1103
1104 let (name, f_ty) = exports.next().unwrap();
1105 assert_eq!(name, "f");
1106 let ComponentItem::Type(f_ty) = f_ty else {
1107 panic!("`f` export item of wrong type")
1108 };
1109 assert_eq!(
1110 f_ty.unwrap_flags().names().collect::<Vec<_>>(),
1111 ["G", "H", "I"]
1112 );
1113
1114 let (name, m_ty) = exports.next().unwrap();
1115 assert_eq!(name, "m");
1116 let ComponentItem::Type(m_ty) = m_ty else {
1117 panic!("`m` export item of wrong type")
1118 };
1119 {
1120 let mut fields = m_ty.unwrap_record().fields();
1121 let Field { name, ty } = fields.next().unwrap();
1122 assert_eq!(name, "N");
1123 assert_eq!(ty, types::Type::Bool);
1124 let Field { name, ty } = fields.next().unwrap();
1125 assert_eq!(name, "O");
1126 assert_eq!(ty, types::Type::U32);
1127 }
1128
1129 let (name, j_ty) = exports.next().unwrap();
1130 assert_eq!(name, "j");
1131 let ComponentItem::Type(j_ty) = j_ty else {
1132 panic!("`j` export item of wrong type")
1133 };
1134 let mut cases = j_ty.unwrap_variant().cases();
1135 {
1136 let Case { name, ty } = cases.next().unwrap();
1137 assert_eq!(name, "K");
1138 assert_eq!(ty, Some(types::Type::U32));
1139 let Case { name, ty } = cases.next().unwrap();
1140 assert_eq!(name, "L");
1141 assert_eq!(ty, Some(types::Type::Float64));
1142 let Case { name, ty } = cases.next().unwrap();
1143 assert_eq!(name, "M");
1144 assert_eq!(ty, Some(m_ty));
1145 }
1146
1147 let (name, foo_ty) = exports.next().unwrap();
1148 assert_eq!(name, "foo");
1149 let ComponentItem::Type(foo_ty) = foo_ty else {
1150 panic!("`foo` export item of wrong type")
1151 };
1152 {
1153 let mut fields = foo_ty.unwrap_record().fields();
1154 assert_eq!(fields.len(), 17);
1155 let Field { name, ty } = fields.next().unwrap();
1156 assert_eq!(name, "A");
1157 assert_eq!(ty, types::Type::U32);
1158 let Field { name, ty } = fields.next().unwrap();
1159 assert_eq!(name, "B");
1160 assert_eq!(ty, b_ty);
1161 let Field { name, ty } = fields.next().unwrap();
1162 assert_eq!(name, "C");
1163 assert_eq!(ty, c_ty);
1164 let Field { name, ty } = fields.next().unwrap();
1165 assert_eq!(name, "F");
1166 let ty = ty.unwrap_list();
1167 assert_eq!(ty.ty(), f_ty);
1168 let Field { name, ty } = fields.next().unwrap();
1169 assert_eq!(name, "J");
1170 assert_eq!(ty, j_ty);
1171 let Field { name, ty } = fields.next().unwrap();
1172 assert_eq!(name, "P");
1173 assert_eq!(ty, types::Type::S8);
1174 let Field { name, ty } = fields.next().unwrap();
1175 assert_eq!(name, "Q");
1176 assert_eq!(ty, types::Type::S16);
1177 let Field { name, ty } = fields.next().unwrap();
1178 assert_eq!(name, "R");
1179 assert_eq!(ty, types::Type::S32);
1180 let Field { name, ty } = fields.next().unwrap();
1181 assert_eq!(name, "S");
1182 assert_eq!(ty, types::Type::S64);
1183 let Field { name, ty } = fields.next().unwrap();
1184 assert_eq!(name, "T");
1185 assert_eq!(ty, types::Type::Float32);
1186 let Field { name, ty } = fields.next().unwrap();
1187 assert_eq!(name, "U");
1188 assert_eq!(ty, types::Type::Float64);
1189 let Field { name, ty } = fields.next().unwrap();
1190 assert_eq!(name, "V");
1191 assert_eq!(ty, types::Type::String);
1192 let Field { name, ty } = fields.next().unwrap();
1193 assert_eq!(name, "W");
1194 assert_eq!(ty, types::Type::Char);
1195 let Field { name, ty } = fields.next().unwrap();
1196 assert_eq!(name, "Y");
1197 assert_eq!(
1198 ty.unwrap_tuple().types().collect::<Vec<_>>(),
1199 [types::Type::U32, types::Type::U32]
1200 );
1201 let Field { name, ty } = fields.next().unwrap();
1202 assert_eq!(name, "AA");
1203 assert_eq!(ty.unwrap_option().ty(), types::Type::U32);
1204 let Field { name, ty } = fields.next().unwrap();
1205 assert_eq!(name, "BB");
1206 let ty = ty.unwrap_result();
1207 assert_eq!(ty.ok(), Some(types::Type::String));
1208 assert_eq!(ty.err(), Some(types::Type::String));
1209 let Field { name, ty } = fields.next().unwrap();
1210 assert_eq!(name, "CC");
1211 assert_eq!(*ty.unwrap_own(), res_ty);
1212 }
1213
1214 let (name, fn_ty) = exports.next().unwrap();
1215 assert_eq!(name, "fn");
1216 let ComponentItem::ComponentFunc(fn_ty) = fn_ty else {
1217 panic!("`fn` export item of wrong type")
1218 };
1219 let mut params = fn_ty.params();
1220 assert_eq!(params.len(), 1);
1221 let (name, param) = params.next().unwrap();
1222 assert_eq!(name, "x");
1223 assert_eq!(param.unwrap_option().ty(), foo_ty);
1224
1225 let mut results = fn_ty.results();
1226 assert_eq!(results.len(), 1);
1227 assert_eq!(
1228 results
1229 .next()
1230 .unwrap()
1231 .unwrap_option()
1232 .ty()
1233 .unwrap_tuple()
1234 .types()
1235 .collect::<Vec<_>>(),
1236 [types::Type::U32, types::Type::U32]
1237 );
1238 Ok(())
1239 }
1240
1241 #[test]
flags_beyond_end() -> Result<()>1242 fn flags_beyond_end() -> Result<()> {
1243 let engine = super::engine();
1244
1245 let component = Component::new(
1246 &engine,
1247 r#"
1248 (component
1249 (type $f' (flags "a" "b"))
1250 (export $f "f" (type $f'))
1251
1252 (core module $m
1253 (func (export "r") (param i32) (result i32) local.get 0)
1254 )
1255 (core instance $i (instantiate $m))
1256 (func (export "run") (param "x" u32) (result $f)
1257 (canon lift (core func $i "r")))
1258 )
1259 "#,
1260 )?;
1261 let mut store = Store::new(&engine, ());
1262 let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
1263 let run = instance.get_func(&mut store, "run").unwrap();
1264
1265 let mut output = [Val::Bool(false)];
1266 run.call(&mut store, &[Val::U32(0)], &mut output)?;
1267 assert_eq!(output[0], Val::Flags(vec![]));
1268
1269 let mut output = [Val::Bool(false)];
1270 run.call(&mut store, &[Val::U32(1)], &mut output)?;
1271 assert_eq!(output[0], Val::Flags(vec!["a".to_string()]));
1272
1273 let mut output = [Val::Bool(false)];
1274 run.call(&mut store, &[Val::U32(2)], &mut output)?;
1275 assert_eq!(output[0], Val::Flags(vec!["b".to_string()]));
1276
1277 let mut output = [Val::Bool(false)];
1278 run.call(&mut store, &[Val::U32(3)], &mut output)?;
1279 assert_eq!(
1280 output[0],
1281 Val::Flags(vec!["a".to_string(), "b".to_string()])
1282 );
1283 let mut output = [Val::Bool(false)];
1284
1285 run.call(&mut store, &[Val::U32(4)], &mut output)?;
1286 assert_eq!(output[0], Val::Flags(vec![]));
1287
1288 run.call(&mut store, &[Val::U32(5)], &mut output)?;
1289 assert_eq!(output[0], Val::Flags(vec!["a".to_string()]));
1290
1291 wasmtime::component::flags! {
1292 F {
1293 #[component(name = "a")]
1294 const A;
1295 #[component(name = "b")]
1296 const B;
1297 }
1298 }
1299
1300 let run = instance.get_typed_func::<(u32,), (F,)>(&mut store, "run")?;
1301 assert_eq!(run.call(&mut store, (0,))?, (F::empty(),));
1302 assert_eq!(run.call(&mut store, (1,))?, (F::A,));
1303 assert_eq!(run.call(&mut store, (2,))?, (F::B,));
1304 assert_eq!(run.call(&mut store, (3,))?, (F::A | F::B,));
1305 assert_eq!(run.call(&mut store, (4,))?, (F::empty(),));
1306 assert_eq!(run.call(&mut store, (5,))?, (F::A,));
1307 Ok(())
1308 }
1309