Skip to content

Commit 1620954

Browse files
authored
wit-parser package not found: explain error better (#1875)
* wit-parser: provide more context in package not found error * better error reports
1 parent 3458fe1 commit 1620954

File tree

5 files changed

+74
-7
lines changed

5 files changed

+74
-7
lines changed

crates/wit-parser/src/ast.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Error, UnresolvedPackageGroup};
1+
use crate::{Error, PackageNotFoundError, UnresolvedPackageGroup};
22
use anyhow::{bail, Context, Result};
33
use lex::{Span, Token, Tokenizer};
44
use semver::Version;
@@ -1758,6 +1758,19 @@ impl SourceMap {
17581758
if let Some(_) = err.downcast_mut::<Error>() {
17591759
return Err(err);
17601760
}
1761+
if let Some(notfound) = err.downcast_mut::<PackageNotFoundError>() {
1762+
if notfound.highlighted.is_none() {
1763+
let msg = self.highlight_err(
1764+
notfound.span.start,
1765+
Some(notfound.span.end),
1766+
&format!("{notfound}"),
1767+
);
1768+
notfound.highlighted = Some(msg);
1769+
}
1770+
}
1771+
if let Some(_) = err.downcast_mut::<PackageNotFoundError>() {
1772+
return Err(err);
1773+
}
17611774

17621775
if let Some(lex) = err.downcast_ref::<lex::Error>() {
17631776
let pos = match lex {

crates/wit-parser/src/lib.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,52 @@ impl fmt::Display for Error {
273273

274274
impl std::error::Error for Error {}
275275

276+
#[derive(Debug)]
277+
struct PackageNotFoundError {
278+
span: Span,
279+
requested: PackageName,
280+
known: Vec<PackageName>,
281+
highlighted: Option<String>,
282+
}
283+
284+
impl PackageNotFoundError {
285+
pub fn new(span: Span, requested: PackageName, known: Vec<PackageName>) -> Self {
286+
Self {
287+
span,
288+
requested,
289+
known,
290+
highlighted: None,
291+
}
292+
}
293+
}
294+
295+
impl fmt::Display for PackageNotFoundError {
296+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
297+
if let Some(highlighted) = &self.highlighted {
298+
return highlighted.fmt(f);
299+
}
300+
if self.known.is_empty() {
301+
write!(
302+
f,
303+
"package '{}' not found. no known packages.",
304+
self.requested
305+
)?;
306+
} else {
307+
write!(
308+
f,
309+
"package '{}' not found. known packages:\n",
310+
self.requested
311+
)?;
312+
for known in self.known.iter() {
313+
write!(f, " {known}\n")?;
314+
}
315+
}
316+
Ok(())
317+
}
318+
}
319+
320+
impl std::error::Error for PackageNotFoundError {}
321+
276322
impl UnresolvedPackageGroup {
277323
/// Parses the given string as a wit document.
278324
///

crates/wit-parser/src/resolve.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use crate::ast::{parse_use_path, ParsedUsePath};
1818
use crate::serde_::{serialize_arena, serialize_id_map};
1919
use crate::{
2020
AstItem, Docs, Error, Function, FunctionKind, Handle, IncludeName, Interface, InterfaceId,
21-
InterfaceSpan, Mangling, PackageName, Results, SourceMap, Stability, Type, TypeDef,
22-
TypeDefKind, TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage, UnresolvedPackageGroup,
23-
World, WorldId, WorldItem, WorldKey, WorldSpan,
21+
InterfaceSpan, Mangling, PackageName, PackageNotFoundError, Results, SourceMap, Stability,
22+
Type, TypeDef, TypeDefKind, TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage,
23+
UnresolvedPackageGroup, World, WorldId, WorldItem, WorldKey, WorldSpan,
2424
};
2525

2626
mod clone;
@@ -2846,7 +2846,13 @@ impl Remap {
28462846
.package_names
28472847
.get(pkg_name)
28482848
.copied()
2849-
.ok_or_else(|| Error::new(span, "package not found"))?;
2849+
.ok_or_else(|| {
2850+
PackageNotFoundError::new(
2851+
span,
2852+
pkg_name.clone(),
2853+
resolve.package_names.keys().cloned().collect(),
2854+
)
2855+
})?;
28502856

28512857
// Functions can't be imported so this should be empty.
28522858
assert!(unresolved_iface.functions.is_empty());

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
failed to resolve directory while parsing WIT for path [tests/ui/parse-fail/bad-pkg6]: package not found
1+
failed to resolve directory while parsing WIT for path [tests/ui/parse-fail/bad-pkg6]: package 'foo:bar' not found. known packages:
2+
foo:baz
3+
24
--> tests/ui/parse-fail/bad-pkg6/root.wit:3:7
35
|
46
3 | use foo:bar/baz.{};

crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package not found
1+
package 'some:dependency' not found. no known packages.
22
--> tests/ui/parse-fail/unresolved-interface4.wit:6:10
33
|
44
6 | import some:dependency/iface;

0 commit comments

Comments
 (0)