diff --git a/crates/oxc_semantic/src/binder.rs b/crates/oxc_semantic/src/binder.rs index 1a54d593c..cba1854af 100644 --- a/crates/oxc_semantic/src/binder.rs +++ b/crates/oxc_semantic/src/binder.rs @@ -71,6 +71,7 @@ impl<'a> Binder<'a> for VariableDeclarator<'a> { // avoid same symbols appear in multi-scopes builder.scope.remove_binding(*scope_id, &name); builder.scope.add_binding(target_scope_id, name, symbol_id); + builder.symbols.scope_ids[symbol_id] = target_scope_id; break; } } diff --git a/crates/oxc_semantic/tests/integration/scopes.rs b/crates/oxc_semantic/tests/integration/scopes.rs index be50154e2..ce32fd663 100644 --- a/crates/oxc_semantic/tests/integration/scopes.rs +++ b/crates/oxc_semantic/tests/integration/scopes.rs @@ -138,3 +138,18 @@ fn test_catch_clause_parameters() { .has_number_of_references(1) .test(); } + +#[test] +fn var_hoisting() { + SemanticTester::js( + " + try {} catch (e) { + var e = 0; + } + ", + ) + .has_root_symbol("e") + // `e` was hoisted to the top scope so the symbol's scope is also the top scope + .is_in_scope(ScopeFlags::Top) + .test(); +}