diff --git a/crates/wit-component/src/printing.rs b/crates/wit-component/src/printing.rs index 49e4058b09..13e03ce0c6 100644 --- a/crates/wit-component/src/printing.rs +++ b/crates/wit-component/src/printing.rs @@ -5,7 +5,7 @@ use std::mem; use wit_parser::*; // NB: keep in sync with `crates/wit-parser/src/ast/lex.rs` -const PRINT_F32_F64_DEFAULT: bool = false; +const PRINT_F32_F64_DEFAULT: bool = true; /// A utility for printing WebAssembly interface definitions to a string. pub struct WitPrinter { diff --git a/crates/wit-parser/src/ast.rs b/crates/wit-parser/src/ast.rs index 9d8d7716a1..8b49f2a760 100644 --- a/crates/wit-parser/src/ast.rs +++ b/crates/wit-parser/src/ast.rs @@ -1772,13 +1772,15 @@ impl SourceMap { bail!("{msg}") } - if let Some(sort) = err.downcast_ref::() { - let span = match sort { - toposort::Error::NonexistentDep { span, .. } - | toposort::Error::Cycle { span, .. } => *span, - }; - let msg = self.highlight_err(span.start, Some(span.end), sort); - bail!("{msg}") + if let Some(sort) = err.downcast_mut::() { + if sort.highlighted().is_none() { + let span = match sort { + toposort::Error::NonexistentDep { span, .. } + | toposort::Error::Cycle { span, .. } => *span, + }; + let highlighted = self.highlight_err(span.start, Some(span.end), &sort); + sort.set_highlighted(highlighted); + } } Err(err) diff --git a/crates/wit-parser/src/ast/lex.rs b/crates/wit-parser/src/ast/lex.rs index 76886d8547..a3a59cb945 100644 --- a/crates/wit-parser/src/ast/lex.rs +++ b/crates/wit-parser/src/ast/lex.rs @@ -116,7 +116,7 @@ pub enum Error { } // NB: keep in sync with `crates/wit-component/src/printing.rs`. -const REQUIRE_F32_F64_BY_DEFAULT: bool = false; +const REQUIRE_F32_F64_BY_DEFAULT: bool = true; impl<'a> Tokenizer<'a> { pub fn new( diff --git a/crates/wit-parser/src/ast/resolve.rs b/crates/wit-parser/src/ast/resolve.rs index 4a51aacce3..f32b502331 100644 --- a/crates/wit-parser/src/ast/resolve.rs +++ b/crates/wit-parser/src/ast/resolve.rs @@ -903,7 +903,7 @@ impl<'a> Resolver<'a> { } } } - let order = toposort("type", &type_deps)?; + let order = toposort("type", &type_deps).map_err(attach_old_float_type_context)?; for ty in order { let def = match type_defs.swap_remove(&ty).unwrap() { Some(def) => def, @@ -922,7 +922,27 @@ impl<'a> Resolver<'a> { self.type_spans.push(def.name.span); self.define_interface_name(&def.name, TypeOrItem::Type(id))?; } - Ok(()) + return Ok(()); + + fn attach_old_float_type_context(err: ast::toposort::Error) -> anyhow::Error { + let name = match &err { + ast::toposort::Error::NonexistentDep { name, .. } => name, + _ => return err.into(), + }; + let new = match name.as_str() { + "float32" => "f32", + "float64" => "f64", + _ => return err.into(), + }; + + let context = format!( + "the `{name}` type has been renamed to `{new}` and is \ + no longer accepted, but the `WIT_REQUIRE_F32_F64=0` \ + environment variable can be used to temporarily \ + disable this error" + ); + anyhow::Error::from(err).context(context) + } } fn resolve_use(&mut self, owner: TypeOwner, u: &ast::Use<'a>) -> Result<()> { diff --git a/crates/wit-parser/src/ast/toposort.rs b/crates/wit-parser/src/ast/toposort.rs index 0a43dc0325..4a4486c2d2 100644 --- a/crates/wit-parser/src/ast/toposort.rs +++ b/crates/wit-parser/src/ast/toposort.rs @@ -55,6 +55,7 @@ pub fn toposort<'a>( span: edge.span, name: edge.name.to_string(), kind: kind.to_string(), + highlighted: None, })?; states[j].reverse_deps.push(i); } @@ -115,6 +116,7 @@ pub fn toposort<'a>( span: dep.span, name: dep.name.to_string(), kind: kind.to_string(), + highlighted: None, }); } } @@ -128,16 +130,38 @@ pub enum Error { span: Span, name: String, kind: String, + highlighted: Option, }, Cycle { span: Span, name: String, kind: String, + highlighted: Option, }, } +impl Error { + pub(crate) fn highlighted(&self) -> Option<&str> { + match self { + Error::NonexistentDep { highlighted, .. } | Error::Cycle { highlighted, .. } => { + highlighted.as_deref() + } + } + } + pub(crate) fn set_highlighted(&mut self, string: String) { + match self { + Error::NonexistentDep { highlighted, .. } | Error::Cycle { highlighted, .. } => { + *highlighted = Some(string); + } + } + } +} + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(s) = self.highlighted() { + return f.write_str(s); + } match self { Error::NonexistentDep { kind, name, .. } => { write!(f, "{kind} `{name}` does not exist") diff --git a/crates/wit-parser/tests/ui/parse-fail/old-float-types.wit b/crates/wit-parser/tests/ui/parse-fail/old-float-types.wit new file mode 100644 index 0000000000..d74caac16a --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/old-float-types.wit @@ -0,0 +1,5 @@ +package foo:bar; + +interface a { + type t1 = float32; +} diff --git a/crates/wit-parser/tests/ui/parse-fail/old-float-types.wit.result b/crates/wit-parser/tests/ui/parse-fail/old-float-types.wit.result new file mode 100644 index 0000000000..e3a34fd62e --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/old-float-types.wit.result @@ -0,0 +1,5 @@ +the `float32` type has been renamed to `f32` and is no longer accepted, but the `WIT_REQUIRE_F32_F64=0` environment variable can be used to temporarily disable this error: type `float32` does not exist + --> tests/ui/parse-fail/old-float-types.wit:4:13 + | + 4 | type t1 = float32; + | ^------ \ No newline at end of file