diff --git a/crates/oxc_semantic/src/node.rs b/crates/oxc_semantic/src/node.rs index 989495cbb72ed..a503fc1bf5252 100644 --- a/crates/oxc_semantic/src/node.rs +++ b/crates/oxc_semantic/src/node.rs @@ -98,7 +98,6 @@ impl GetAddress for AstNode<'_> { /// Untyped AST nodes flattened into an vec #[derive(Debug, Default)] pub struct AstNodes<'a> { - program: Option<&'a Program<'a>>, nodes: IndexVec>, /// `node` -> `parent` parent_ids: IndexVec, @@ -187,8 +186,13 @@ impl<'a> AstNodes<'a> { /// Get the [`Program`] that's also the root of the AST. #[inline] pub fn program(&self) -> &'a Program<'a> { - #[expect(clippy::missing_panics_doc, reason = "self.program is always `Some`")] - self.program.as_ref().unwrap() + if let Some(node) = self.nodes.first() { + if let AstKind::Program(program) = node.kind { + return program; + } + } + + unreachable!(); } /// Create and add an [`AstNode`] to the [`AstNodes`] tree and get its [`NodeId`]. @@ -215,7 +219,7 @@ impl<'a> AstNodes<'a> { /// /// # Panics /// - /// Panics if this is not the first node being added to the AST + /// Panics if this is not the first node being added to the AST. pub fn add_program_node( &mut self, kind: AstKind<'a>, @@ -224,14 +228,13 @@ impl<'a> AstNodes<'a> { flags: NodeFlags, ) -> NodeId { assert!(self.parent_ids.is_empty(), "Program node must be the first node in the AST."); - let AstKind::Program(program) = kind else { - panic!("Program node must be of kind `AstKind::Program`."); - }; - self.program = Some(program); - let node_id = self.parent_ids.push(NodeId::ROOT); - let node = AstNode::new(kind, scope_id, cfg_id, flags, node_id); - self.nodes.push(node); - node_id + debug_assert!( + matches!(kind, AstKind::Program(_)), + "Program node must be of kind `AstKind::Program`" + ); + self.parent_ids.push(NodeId::ROOT); + self.nodes.push(AstNode::new(kind, scope_id, cfg_id, flags, NodeId::ROOT)); + NodeId::ROOT } /// Reserve space for at least `additional` more nodes.