Skip to content

Commit 97b226f

Browse files
authored
Allow import/export overlap in wit-parser (#1400)
Updates to WebAssembly/component-model#259 by relaxing some checks here and there. Closes #1396
1 parent 97f4a1f commit 97b226f

14 files changed

+219
-49
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,11 +591,12 @@ impl<'a> Resolver<'a> {
591591

592592
let mut export_spans = Vec::new();
593593
let mut import_spans = Vec::new();
594-
let mut used_names = HashMap::new();
594+
let mut import_names = HashMap::new();
595+
let mut export_names = HashMap::new();
595596
for (name, (item, span)) in self.type_lookup.iter() {
596597
match *item {
597598
TypeOrItem::Type(id) => {
598-
let prev = used_names.insert(*name, "import");
599+
let prev = import_names.insert(*name, "import");
599600
if let Some(prev) = prev {
600601
return Err(Error {
601602
span: *span,
@@ -617,20 +618,22 @@ impl<'a> Resolver<'a> {
617618
let mut imported_interfaces = HashSet::new();
618619
let mut exported_interfaces = HashSet::new();
619620
for item in world.items.iter() {
620-
let (docs, kind, desc, spans, interfaces) = match item {
621+
let (docs, kind, desc, spans, interfaces, names) = match item {
621622
ast::WorldItem::Import(import) => (
622623
&import.docs,
623624
&import.kind,
624625
"import",
625626
&mut import_spans,
626627
&mut imported_interfaces,
628+
&mut import_names,
627629
),
628630
ast::WorldItem::Export(export) => (
629631
&export.docs,
630632
&export.kind,
631633
"export",
632634
&mut export_spans,
633635
&mut exported_interfaces,
636+
&mut export_names,
634637
),
635638

636639
ast::WorldItem::Type(ast::TypeDef {
@@ -659,7 +662,7 @@ impl<'a> Resolver<'a> {
659662
};
660663
let key = match kind {
661664
ast::ExternKind::Interface(name, _) | ast::ExternKind::Func(name, _) => {
662-
let prev = used_names.insert(name.name, desc);
665+
let prev = names.insert(name.name, desc);
663666
if let Some(prev) = prev {
664667
return Err(Error {
665668
span: kind.span(),

crates/wit-parser/src/resolve.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,14 +1463,6 @@ impl Remap {
14631463
span,
14641464
})
14651465
}
1466-
1467-
// check if this type has name conflict with any of the exported item.
1468-
if world.exports.contains_key(&WorldKey::Name(name.clone())) {
1469-
bail!(Error {
1470-
msg: format!("import type `{name}` conflicts with prior export of interface",),
1471-
span,
1472-
})
1473-
}
14741466
}
14751467

14761468
for (name, func, span) in import_funcs {
@@ -1485,40 +1477,20 @@ impl Remap {
14851477
span,
14861478
})
14871479
}
1488-
1489-
// check if this function has name conflict with any of the exported item.
1490-
if world.exports.contains_key(&WorldKey::Name(name.clone())) {
1491-
bail!(Error {
1492-
msg: format!(
1493-
"import of function `{name}` conflicts with prior export of interface",
1494-
),
1495-
span,
1496-
})
1497-
}
14981480
}
14991481

15001482
for (name, func, span) in export_funcs {
15011483
let prev = world
15021484
.exports
15031485
.insert(WorldKey::Name(name.clone()), WorldItem::Function(func));
1504-
if prev.is_some() || world.imports.contains_key(&WorldKey::Name(name.clone())) {
1486+
if prev.is_some() {
15051487
bail!(Error {
15061488
msg: format!(
15071489
"export of function `{name}` shadows previously exported interface"
15081490
),
15091491
span,
15101492
})
15111493
}
1512-
1513-
// check if this function has name conflict with any of the import item.
1514-
if world.imports.contains_key(&WorldKey::Name(name.clone())) {
1515-
bail!(Error {
1516-
msg: format!(
1517-
"export of function `{name}` conflicts with prior import of interface",
1518-
),
1519-
span,
1520-
})
1521-
}
15221494
}
15231495

15241496
// After all that sort functions in exports to come before interfaces in
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"worlds": [
3+
{
4+
"name": "foo",
5+
"imports": {
6+
"a": {
7+
"function": {
8+
"name": "a",
9+
"kind": "freestanding",
10+
"params": [],
11+
"results": []
12+
}
13+
}
14+
},
15+
"exports": {
16+
"a": {
17+
"function": {
18+
"name": "a",
19+
"kind": "freestanding",
20+
"params": [],
21+
"results": []
22+
}
23+
}
24+
},
25+
"package": 0
26+
}
27+
],
28+
"interfaces": [],
29+
"types": [],
30+
"packages": [
31+
{
32+
"name": "foo:foo",
33+
"interfaces": {},
34+
"worlds": {
35+
"foo": 0
36+
}
37+
}
38+
]
39+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"worlds": [
3+
{
4+
"name": "foo",
5+
"imports": {
6+
"a": {
7+
"function": {
8+
"name": "a",
9+
"kind": "freestanding",
10+
"params": [],
11+
"results": []
12+
}
13+
}
14+
},
15+
"exports": {
16+
"a": {
17+
"interface": 0
18+
}
19+
},
20+
"package": 0
21+
}
22+
],
23+
"interfaces": [
24+
{
25+
"name": null,
26+
"types": {},
27+
"functions": {},
28+
"package": 0
29+
}
30+
],
31+
"types": [],
32+
"packages": [
33+
{
34+
"name": "foo:foo",
35+
"interfaces": {},
36+
"worlds": {
37+
"foo": 0
38+
}
39+
}
40+
]
41+
}

crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit.result

Lines changed: 0 additions & 5 deletions
This file was deleted.

crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit.result

Lines changed: 0 additions & 5 deletions
This file was deleted.

crates/wit-parser/tests/ui/parse-fail/union-fuzz-2.wit.result

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package demo:greeter;
2+
3+
world greeter {
4+
import greet: func() -> string;
5+
export greet: func() -> string;
6+
}

0 commit comments

Comments
 (0)