From 54604ccb6b96576c0495db48bd6a450dc69bc90b Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 29 May 2024 16:32:20 +0200 Subject: Fix `Default` impls for AST nodes (#4288) --- crates/typst-syntax/src/ast.rs | 22 ++++++++++++++-------- crates/typst-syntax/src/node.rs | 28 ++++++++++++++++------------ 2 files changed, 30 insertions(+), 20 deletions(-) (limited to 'crates/typst-syntax') diff --git a/crates/typst-syntax/src/ast.rs b/crates/typst-syntax/src/ast.rs index a434e39a..01e0944d 100644 --- a/crates/typst-syntax/src/ast.rs +++ b/crates/typst-syntax/src/ast.rs @@ -24,12 +24,6 @@ pub trait AstNode<'a>: Sized { } } -/// A static syntax node used as a fallback value. This is returned instead of -/// panicking when the syntactical structure isn't valid. In a normal -/// compilation, evaluation isn't attempted on a broken file, but for IDE -/// functionality, it is. -static ARBITRARY: SyntaxNode = SyntaxNode::arbitrary(); - macro_rules! node { ($(#[$attr:meta])* $name:ident) => { #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] @@ -56,7 +50,9 @@ macro_rules! node { impl Default for $name<'_> { #[inline] fn default() -> Self { - Self(&ARBITRARY) + static PLACEHOLDER: SyntaxNode + = SyntaxNode::placeholder(SyntaxKind::$name); + Self(&PLACEHOLDER) } } }; @@ -392,7 +388,7 @@ impl Expr<'_> { impl Default for Expr<'_> { fn default() -> Self { - Expr::Space(Space::default()) + Expr::None(None::default()) } } @@ -2135,3 +2131,13 @@ impl<'a> FuncReturn<'a> { self.0.cast_last_match() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_expr_default() { + assert!(Expr::default().to_untyped().cast::().is_some()); + } +} diff --git a/crates/typst-syntax/src/node.rs b/crates/typst-syntax/src/node.rs index b9efde6e..8e623d51 100644 --- a/crates/typst-syntax/src/node.rs +++ b/crates/typst-syntax/src/node.rs @@ -39,6 +39,21 @@ impl SyntaxNode { Self(Repr::Error(Arc::new(ErrorNode::new(message, text)))) } + /// Create a dummy node of the given kind. + /// + /// Panics if `kind` is `SyntaxKind::Error`. + #[track_caller] + pub const fn placeholder(kind: SyntaxKind) -> Self { + if matches!(kind, SyntaxKind::Error) { + panic!("cannot create error placeholder"); + } + Self(Repr::Leaf(LeafNode { + kind, + text: EcoString::new(), + span: Span::detached(), + })) + } + /// The type of the node. pub fn kind(&self) -> SyntaxKind { match &self.0 { @@ -297,17 +312,6 @@ impl SyntaxNode { Repr::Error(node) => node.error.span.number() + 1, } } - - /// An arbitrary node just for filling a slot in memory. - /// - /// In contrast to `default()`, this is a const fn. - pub(super) const fn arbitrary() -> Self { - Self(Repr::Leaf(LeafNode { - kind: SyntaxKind::End, - text: EcoString::new(), - span: Span::detached(), - })) - } } impl Debug for SyntaxNode { @@ -322,7 +326,7 @@ impl Debug for SyntaxNode { impl Default for SyntaxNode { fn default() -> Self { - Self::arbitrary() + Self::leaf(SyntaxKind::End, EcoString::new()) } } -- cgit v1.2.3