From e15e768a346c30738103d372e8ccf442646628c9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 16 Nov 2022 17:32:32 -0600 Subject: [PATCH] wit-parser: Fix types leaking across interfaces (#822) This fixes an internal bug where types were accidentally leaking across interfaces, panicking when used. This commit fixes the issue by properly fixing the "reset the state" after resolution of each interface and then additionally adds some more testing per-interface to the `ui` tests. --- crates/wit-parser/src/ast/resolve.rs | 3 +- crates/wit-parser/tests/all.rs | 18 +++++++ crates/wit-parser/tests/ui/shared-types.wit | 8 +++ .../tests/ui/shared-types.wit.result | 50 +++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 crates/wit-parser/tests/ui/shared-types.wit create mode 100644 crates/wit-parser/tests/ui/shared-types.wit.result diff --git a/crates/wit-parser/src/ast/resolve.rs b/crates/wit-parser/src/ast/resolve.rs index f6002f32c2..d504044c7e 100644 --- a/crates/wit-parser/src/ast/resolve.rs +++ b/crates/wit-parser/src/ast/resolve.rs @@ -35,7 +35,6 @@ impl Resolver { for interface in document.interfaces() { let name = &interface.name.name; let instance = self.resolve(name, &interface.items, &interface.docs)?; - *self = Resolver::default(); if interface_map.insert(name.to_string(), instance).is_some() { return Err(Error { @@ -174,6 +173,8 @@ impl Resolver { } } + self.anon_types.clear(); + Ok(Interface { name: name.to_string(), docs: self.docs(docs), diff --git a/crates/wit-parser/tests/all.rs b/crates/wit-parser/tests/all.rs index d5c289eb4a..9f86f0c337 100644 --- a/crates/wit-parser/tests/all.rs +++ b/crates/wit-parser/tests/all.rs @@ -116,6 +116,7 @@ impl Runner<'_> { } } else { let instance = result?; + test_world(&instance); to_json(&instance) }; @@ -379,3 +380,20 @@ fn to_json(world: &World) -> String { ty.map(translate_type) } } + +fn test_world(world: &World) { + for (_, interface) in world.imports.iter() { + test_interface(interface); + } + for (_, interface) in world.exports.iter() { + test_interface(interface); + } + if let Some(default) = &world.default { + test_interface(default); + } +} + +fn test_interface(interface: &Interface) { + let mut sizes = SizeAlign::default(); + sizes.fill(interface); +} diff --git a/crates/wit-parser/tests/ui/shared-types.wit b/crates/wit-parser/tests/ui/shared-types.wit new file mode 100644 index 0000000000..362e78719b --- /dev/null +++ b/crates/wit-parser/tests/ui/shared-types.wit @@ -0,0 +1,8 @@ +world foo { + import foo: interface { + a: func() -> list + } + default export interface { + a: func() -> tuple> + } +} diff --git a/crates/wit-parser/tests/ui/shared-types.wit.result b/crates/wit-parser/tests/ui/shared-types.wit.result new file mode 100644 index 0000000000..2f662c15ce --- /dev/null +++ b/crates/wit-parser/tests/ui/shared-types.wit.result @@ -0,0 +1,50 @@ +{ + "name": "foo", + "default": { + "types": [ + { + "idx": 0, + "list": "u8" + }, + { + "idx": 1, + "tuple": { + "types": [ + "type-0" + ] + } + } + ], + "functions": [ + { + "name": "a", + "params": [], + "results": [ + "type-1" + ] + } + ] + }, + "imports": [ + [ + "foo", + { + "types": [ + { + "idx": 0, + "list": "u8" + } + ], + "functions": [ + { + "name": "a", + "params": [], + "results": [ + "type-0" + ] + } + ] + } + ] + ] +} \ No newline at end of file