Skip to content

Commit

Permalink
fix(semantic)!: ensure program outlives semantic (#8455)
Browse files Browse the repository at this point in the history
fixes: #8437 

In semantic builder make sure `Program` reference has a lifetime of the
Arena.

---------

Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
  • Loading branch information
valeneiko and overlookmotel authored Jan 16, 2025
1 parent 250bbd1 commit 4ce6329
Show file tree
Hide file tree
Showing 9 changed files with 18 additions and 20 deletions.
10 changes: 3 additions & 7 deletions crates/oxc/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,7 @@ pub trait CompilerInterface {
ControlFlow::Continue(())
}

fn after_semantic(
&mut self,
_program: &mut Program<'_>,
_semantic_return: &mut SemanticBuilderReturn,
) -> ControlFlow<()> {
fn after_semantic(&mut self, _semantic_return: &mut SemanticBuilderReturn) -> ControlFlow<()> {
ControlFlow::Continue(())
}

Expand Down Expand Up @@ -148,7 +144,7 @@ pub trait CompilerInterface {
self.handle_errors(semantic_return.errors);
return;
}
if self.after_semantic(&mut program, &mut semantic_return).is_break() {
if self.after_semantic(&mut semantic_return).is_break() {
return;
}

Expand Down Expand Up @@ -235,7 +231,7 @@ pub trait CompilerInterface {
Parser::new(allocator, source_text, source_type).with_options(self.parse_options()).parse()
}

fn semantic<'a>(&self, program: &Program<'a>) -> SemanticBuilderReturn<'a> {
fn semantic<'a>(&self, program: &'a Program<'a>) -> SemanticBuilderReturn<'a> {
let mut builder = SemanticBuilder::new();

if self.transform_options().is_some() {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/service/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ impl Runtime {
.with_scope_tree_child_ids(true)
.with_build_jsdoc(true)
.with_check_syntax_error(check_syntax_errors)
.build(&ret.program);
.build(allocator.alloc(ret.program));

if !semantic_ret.errors.is_empty() {
return semantic_ret.errors.into_iter().map(|err| Message::new(err, None)).collect();
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ impl<'a> SemanticBuilder<'a> {
/// Finalize the builder.
///
/// # Panics
pub fn build(mut self, program: &Program<'a>) -> SemanticBuilderReturn<'a> {
pub fn build(mut self, program: &'a Program<'a>) -> SemanticBuilderReturn<'a> {
self.source_text = program.source_text;
self.source_type = program.source_type;
if self.build_jsdoc {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/jsdoc/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ mod test {
) -> Semantic<'a> {
let source_type = source_type.unwrap_or_default();
let ret = Parser::new(allocator, source_text, source_type).parse();
SemanticBuilder::new().with_build_jsdoc(true).build(&ret.program).semantic
SemanticBuilder::new().with_build_jsdoc(true).build(allocator.alloc(ret.program)).semantic
}

fn get_jsdocs<'a>(
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/jsdoc/parser/jsdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ mod test {
fn build_semantic<'a>(allocator: &'a Allocator, source_text: &'a str) -> Semantic<'a> {
let source_type = SourceType::default();
let ret = Parser::new(allocator, source_text, source_type).parse();
SemanticBuilder::new().with_build_jsdoc(true).build(&ret.program).semantic
SemanticBuilder::new().with_build_jsdoc(true).build(allocator.alloc(ret.program)).semantic
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/jsdoc/parser/jsdoc_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ mod test {
fn build_semantic<'a>(allocator: &'a Allocator, source_text: &'a str) -> Semantic<'a> {
let source_type = SourceType::default();
let ret = Parser::new(allocator, source_text, source_type).parse();
SemanticBuilder::new().with_build_jsdoc(true).build(&ret.program).semantic
SemanticBuilder::new().with_build_jsdoc(true).build(allocator.alloc(ret.program)).semantic
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ mod tests {
) -> Semantic<'s> {
let parse = oxc_parser::Parser::new(allocator, source, source_type).parse();
assert!(parse.errors.is_empty());
let semantic = SemanticBuilder::new().build(&parse.program);
let semantic = SemanticBuilder::new().build(allocator.alloc(parse.program));
assert!(semantic.errors.is_empty(), "Parse error: {}", semantic.errors[0]);
semantic.semantic
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/tests/integration/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl<'a> SemanticTester<'a> {
.with_check_syntax_error(true)
.with_cfg(self.cfg)
.with_scope_tree_child_ids(self.scope_tree_child_ids)
.build(&parse.program)
.build(self.allocator.alloc(parse.program))
}

pub fn basic_blocks_count(&self) -> usize {
Expand Down
14 changes: 8 additions & 6 deletions tasks/coverage/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_hash::FxHashSet;

use oxc::{
allocator::Allocator,
ast::{ast::Program, Comment},
ast::{ast::Program, AstKind, Comment},
codegen::{CodegenOptions, CodegenReturn},
diagnostics::OxcDiagnostic,
minifier::CompressOptions,
Expand Down Expand Up @@ -80,12 +80,14 @@ impl CompilerInterface for Driver {
ControlFlow::Continue(())
}

fn after_semantic(
&mut self,
program: &mut Program<'_>,
ret: &mut SemanticBuilderReturn,
) -> ControlFlow<()> {
fn after_semantic(&mut self, ret: &mut SemanticBuilderReturn) -> ControlFlow<()> {
if self.check_semantic {
let Some(root_node) = ret.semantic.nodes().root_node() else {
return ControlFlow::Break(());
};
let AstKind::Program(program) = root_node.kind() else {
return ControlFlow::Break(());
};
if let Some(errors) = check_semantic_ids(program) {
self.errors.extend(errors);
return ControlFlow::Break(());
Expand Down

0 comments on commit 4ce6329

Please sign in to comment.