Skip to content

Commit 688ff51

Browse files
committed
Improve subtype check.
This commit improves the subtype checking logic and the error messages it produces. It fixes a bug where the `targets` check was not properly performing checks against imports, which should be contravariant. Also fixes a warning relating to a deprecated function call; the fix is to not remove from the collection as we no longer have to since the bytes of a package are behind an `Arc`.
1 parent b294ae0 commit 688ff51

17 files changed

Lines changed: 414 additions & 154 deletions

crates/wac-parser/src/ast/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl<'a> Parse<'a> for Expr<'a> {
3838

3939
let start = primary.span();
4040
let len = postfix.last().map_or(start.len(), |p| {
41-
start.offset() + p.span().offset() + p.span().len()
41+
p.span().offset() + p.span().len() - start.offset()
4242
});
4343

4444
Ok(Self {

crates/wac-parser/src/resolution/ast.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,8 +1534,8 @@ impl<'a> AstResolver<'a> {
15341534
hash_map::Entry::Occupied(e) => Ok(*e.get()),
15351535
hash_map::Entry::Vacant(e) => {
15361536
log::debug!("resolving package `{name}`");
1537-
let bytes = match self.packages.remove(&PackageKey { name, version }) {
1538-
Some(bytes) => bytes,
1537+
let bytes = match self.packages.get(&PackageKey { name, version }) {
1538+
Some(bytes) => bytes.clone(),
15391539
None => {
15401540
return Err(Error::UnknownPackage {
15411541
name: name.to_string(),
@@ -1788,7 +1788,7 @@ impl<'a> AstResolver<'a> {
17881788
);
17891789

17901790
SubtypeChecker::new(&self.definitions, &state.packages)
1791-
.is_subtype(*expected, state.current.items[*item].kind())
1791+
.is_subtype(state.current.items[*item].kind(), *expected)
17921792
.map_err(|e| Error::MismatchedInstantiationArg {
17931793
name: name.clone(),
17941794
span: *span,
@@ -1965,10 +1965,10 @@ impl<'a> AstResolver<'a> {
19651965

19661966
match (
19671967
checker
1968-
.is_subtype(*target_kind, *source_kind)
1968+
.is_subtype(*source_kind, *target_kind)
19691969
.with_context(|| format!("mismatched type for export `{name}`")),
19701970
checker
1971-
.is_subtype(*source_kind, *target_kind)
1971+
.is_subtype(*target_kind, *source_kind)
19721972
.with_context(|| format!("mismatched type for export `{name}`")),
19731973
) {
19741974
(Ok(_), Ok(_)) => {
@@ -2273,6 +2273,7 @@ impl<'a> AstResolver<'a> {
22732273
let mut checker = SubtypeChecker::new(&self.definitions, &state.packages);
22742274

22752275
// The output is allowed to import a subset of the world's imports
2276+
checker.invert();
22762277
for (name, import) in &state.imports {
22772278
let expected = world
22782279
.imports
@@ -2297,6 +2298,8 @@ impl<'a> AstResolver<'a> {
22972298
})?;
22982299
}
22992300

2301+
checker.revert();
2302+
23002303
// The output must export every export in the world
23012304
for (name, expected) in &world.exports {
23022305
let export = state
@@ -2311,8 +2314,8 @@ impl<'a> AstResolver<'a> {
23112314

23122315
checker
23132316
.is_subtype(
2314-
expected.promote(),
23152317
state.root_scope().items[export.item].kind(),
2318+
expected.promote(),
23162319
)
23172320
.map_err(|e| Error::TargetMismatch {
23182321
kind: ExternKind::Export,

0 commit comments

Comments
 (0)