fix(semantic): ScopeTree::rename_binding preserve order of bindings (#7870)

`ScopeTree::rename_binding` was previously altering the order of bindings in the `FxIndexMap`. Order of bindings matters in the mangler. Reimplement `rename_binding` to preserve original order.
This commit is contained in:
overlookmotel 2024-12-14 04:28:53 +00:00
parent 1cf8f8f2ca
commit 492407386b
2 changed files with 26 additions and 5 deletions

View file

@ -352,10 +352,31 @@ impl ScopeTree {
}
/// Rename a binding to a new name.
pub fn rename_binding(&mut self, scope_id: ScopeId, old_name: &str, new_name: CompactStr) {
if let Some(symbol_id) = self.bindings[scope_id].shift_remove(old_name) {
self.bindings[scope_id].insert(new_name, symbol_id);
}
///
/// Preserves order of bindings.
///
/// The following must be true for successful operation:
/// * Binding exists in specified scope for `old_name`.
/// * Existing binding is for specified `symbol_id`.
/// * No binding already exists for `new_name`.
///
/// Panics in debug mode if any of the above are not true.
pub fn rename_binding(
&mut self,
scope_id: ScopeId,
symbol_id: SymbolId,
old_name: &str,
new_name: CompactStr,
) {
let bindings = &mut self.bindings[scope_id];
// Insert on end
let existing_symbol_id = bindings.insert(new_name, symbol_id);
debug_assert!(existing_symbol_id.is_none());
// Remove old entry. `swap_remove` swaps the last entry into the place of removed entry.
// We just inserted the new entry as last, so the new entry takes the place of the old.
// Order of entries is same as before, only the key has changed.
let old_symbol_id = bindings.swap_remove(old_name);
debug_assert_eq!(old_symbol_id, Some(symbol_id));
}
/// Reserve memory for an `additional` number of scopes.

View file

@ -906,7 +906,7 @@ impl<'a> ArrowFunctionConverter<'a> {
fn rename_arguments_symbol(symbol_id: SymbolId, name: CompactStr, ctx: &mut TraverseCtx<'a>) {
let scope_id = ctx.symbols().get_scope_id(symbol_id);
ctx.symbols_mut().set_name(symbol_id, name.clone());
ctx.scopes_mut().rename_binding(scope_id, "arguments", name);
ctx.scopes_mut().rename_binding(scope_id, symbol_id, "arguments", name);
}
/// Transform the identifier reference for `arguments` if it's affected after transformation.