Skip to content

Commit a41e2d0

Browse files
authored
Fix referring to resources in dependencies (#1079)
* Fix referring to resources in dependencies This commit fixes an issue in `wit-parser` where resources may be referred to from dependency packages rather than defined locally. In these situations the requirement that these types are resources is propagated to when `UnresolvedPackage`s are pushed into a `Resolve` to get finalized at that time. * Improve error message
1 parent 8914883 commit a41e2d0

File tree

12 files changed

+58
-5
lines changed

12 files changed

+58
-5
lines changed

crates/wit-parser/src/ast/resolve.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ pub struct Resolver<'a> {
7878
foreign_dep_spans: Vec<Span>,
7979

8080
foreign_world_spans: Vec<Span>,
81+
82+
/// A list of `TypeDefKind::Unknown` types which are required to be
83+
/// resources when this package is resolved against its dependencies.
84+
required_resource_types: Vec<(TypeId, Span)>,
8185
}
8286

8387
#[derive(PartialEq, Eq, Hash)]
@@ -209,6 +213,7 @@ impl<'a> Resolver<'a> {
209213
foreign_dep_spans: mem::take(&mut self.foreign_dep_spans),
210214
source_map: SourceMap::default(),
211215
foreign_world_spans: mem::take(&mut self.foreign_world_spans),
216+
required_resource_types: mem::take(&mut self.required_resource_types),
212217
})
213218
}
214219

@@ -1203,9 +1208,13 @@ impl<'a> Resolver<'a> {
12031208
match self.types[cur].kind {
12041209
TypeDefKind::Resource => break Ok(id),
12051210
TypeDefKind::Type(Type::Id(ty)) => cur = ty,
1211+
TypeDefKind::Unknown => {
1212+
self.required_resource_types.push((cur, name.span));
1213+
break Ok(id);
1214+
}
12061215
_ => bail!(Error {
12071216
span: name.span,
1208-
msg: format!("type `{}` is not a resource", name.name),
1217+
msg: format!("type `{}` used in a handle must be a resource", name.name),
12091218
}),
12101219
}
12111220
}

crates/wit-parser/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub struct UnresolvedPackage {
9595
foreign_dep_spans: Vec<Span>,
9696
source_map: SourceMap,
9797
foreign_world_spans: Vec<Span>,
98+
required_resource_types: Vec<(TypeId, Span)>,
9899
}
99100

100101
#[derive(Debug, Copy, Clone)]

crates/wit-parser/src/resolve.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,20 @@ impl Remap {
744744
// what they map to.
745745
self.process_foreign_types(unresolved, resolve)?;
746746

747+
for (id, span) in unresolved.required_resource_types.iter() {
748+
let mut id = self.types[id.index()];
749+
loop {
750+
match resolve.types[id].kind {
751+
TypeDefKind::Type(Type::Id(i)) => id = i,
752+
TypeDefKind::Resource => break,
753+
_ => bail!(Error {
754+
span: *span,
755+
msg: format!("type used in a handle must be a resource"),
756+
}),
757+
}
758+
}
759+
}
760+
747761
Ok(())
748762
}
749763

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package some:dep
2+
3+
interface foo {
4+
resource r
5+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package foo:bar
2+
3+
interface foo {
4+
use some:dep/foo.{r}
5+
6+
type t = own<r>
7+
}

crates/wit-parser/tests/ui/parse-fail/bad-resource13.wit.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type `foo` is not a resource
1+
type `foo` used in a handle must be a resource
22
--> tests/ui/parse-fail/bad-resource13.wit:5:16
33
|
44
5 | type t = own<foo>

crates/wit-parser/tests/ui/parse-fail/bad-resource14.wit.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type `t` is not a resource
1+
type `t` used in a handle must be a resource
22
--> tests/ui/parse-fail/bad-resource14.wit:6:16
33
|
44
6 | type b = own<t>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type used in a handle must be a resource
2+
--> tests/ui/parse-fail/bad-resource15/foo.wit:6:16
3+
|
4+
6 | type t = own<r>
5+
| ^
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package some:dep
2+
3+
interface foo {
4+
type r = u32
5+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package foo:bar
2+
3+
interface foo {
4+
use some:dep/foo.{r}
5+
6+
type t = own<r>
7+
}

0 commit comments

Comments
 (0)