Skip to content

Commit 07d33c6

Browse files
committed
Fix span reported with "duplicate import" errors.
When the imported item was an interface by package path, the span of the import was for the local identifier and not for the package path. Fixes #15.
1 parent 2edd75b commit 07d33c6

6 files changed

Lines changed: 55 additions & 15 deletions

File tree

crates/wac-parser/src/resolution.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,9 @@ pub enum Error {
646646
/// The span where the error occurred.
647647
#[label("previous {kind} here")]
648648
previous: SourceSpan,
649+
/// The help of the error.
650+
#[help]
651+
help: Option<String>,
649652
},
650653
/// An invalid extern name was encountered.
651654
#[error("{kind} name `{name}` is not valid")]

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

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,20 @@ impl<'a> AstResolver<'a> {
208208
"resolving import statement for id `{id}`",
209209
id = stmt.id.string
210210
);
211-
let kind = match &stmt.ty {
212-
ast::ImportType::Package(p) => self.resolve_package_export(state, p)?,
213-
ast::ImportType::Func(ty) => ItemKind::Func(self.func_type(
214-
state,
215-
&ty.params,
216-
&ty.results,
217-
FuncKind::Free,
218-
None,
219-
)?),
220-
ast::ImportType::Interface(i) => self.inline_interface(state, i)?,
221-
ast::ImportType::Ident(id) => state.local_item(id)?.1.kind(),
211+
let (kind, span) = match &stmt.ty {
212+
ast::ImportType::Package(p) => (self.resolve_package_export(state, p)?, p.span),
213+
ast::ImportType::Func(ty) => (
214+
ItemKind::Func(self.func_type(
215+
state,
216+
&ty.params,
217+
&ty.results,
218+
FuncKind::Free,
219+
None,
220+
)?),
221+
stmt.id.span,
222+
),
223+
ast::ImportType::Interface(i) => (self.inline_interface(state, i)?, stmt.id.span),
224+
ast::ImportType::Ident(id) => (state.local_item(id)?.1.kind(), stmt.id.span),
222225
};
223226

224227
// Promote function types, instance types, and component types to functions, instances, and components
@@ -230,17 +233,18 @@ impl<'a> AstResolver<'a> {
230233
};
231234

232235
let (name, span) = if let Some(name) = stmt.name {
236+
// Override the span to the `as` clause string
233237
(name.value, name.span)
234238
} else {
235239
// If the item is an instance with an id, use the id
236240
if let ItemKind::Instance(id) = kind {
237241
if let Some(id) = &self.definitions.interfaces[id].id {
238-
(id.as_str(), stmt.id.span)
242+
(id.as_str(), span)
239243
} else {
240-
(stmt.id.string, stmt.id.span)
244+
(stmt.id.string, span)
241245
}
242246
} else {
243-
(stmt.id.string, stmt.id.span)
247+
(stmt.id.string, span)
244248
}
245249
};
246250

@@ -275,12 +279,16 @@ impl<'a> AstResolver<'a> {
275279
});
276280
}
277281

278-
// TODO: should use prev_span with this error
279282
return Err(Error::DuplicateExternName {
280283
name: name.to_owned(),
281284
kind: ExternKind::Import,
282285
span,
283286
previous: existing.span,
287+
help: if stmt.name.is_some() {
288+
None
289+
} else {
290+
Some("consider using an `as` clause to use a different name".into())
291+
},
284292
});
285293
}
286294
_ => unreachable!(),
@@ -412,6 +420,11 @@ impl<'a> AstResolver<'a> {
412420
kind: ExternKind::Export,
413421
span,
414422
previous: existing.span,
423+
help: if stmt.name.is_some() {
424+
None
425+
} else {
426+
Some("consider using an `as` clause to use a different name".into())
427+
},
415428
});
416429
}
417430

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package test:comp;
2+
3+
import env-foo: wasi:cli/environment;
4+
5+
import env-bar: wasi:cli/environment;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
failed to resolve document
2+
3+
× duplicate import `wasi:cli/environment`
4+
╭─[tests/resolution/fail/import-id-span.wac:5:17]
5+
2 │
6+
3 │ import env-foo: wasi:cli/environment;
7+
· ──────────┬─────────
8+
· ╰── previous import here
9+
4 │
10+
5 │ import env-bar: wasi:cli/environment;
11+
· ──────────┬─────────
12+
· ╰── duplicate import name `wasi:cli/environment`
13+
╰────
14+
help: consider using an `as` clause to use a different name
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package wasi:cli;
2+
3+
interface environment {
4+
}

crates/wac-parser/tests/resolution/fail/windows-file.wac.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ failed to resolve document
1010
· ┬
1111
· ╰── duplicate import name `x`
1212
╰────
13+
help: consider using an `as` clause to use a different name

0 commit comments

Comments
 (0)