Summary
The #711 fix disambiguates a nested-block let/const that shadows an enclosing binding by giving it its own storage — except when the shadowed name is also referenced by a nested closure (arrow/function/class) in the same generator. Those names are deliberately left untouched because the closure-capture machinery keys captured variables by source name and the #711 rename does not rewrite closure interiors; renaming a captured name would desync the capture. So this residual case still leaks.
Repro
function* g(): Generator<number> {
const r = 100;
{
const r = 5;
const f = () => r; // arrow captures the inner r → name "r" is off-limits to the #711 rename
yield f();
}
yield r;
}
console.log([...g()]);
- Interpreted:
[5, 100] (correct)
- Compiled:
[5, 5] (wrong — outer r leaked to 5 via the shared field/DC)
Notes
A proper fix needs precise per-binding capture analysis (which arrow captures which lexical binding) so a shadowing binding can be renamed and its capturing closures updated consistently — rather than the current conservative "skip if the name appears in any closure" guard in GeneratorBlockScopeRenamer. Astronomically rare; low priority. Found while implementing #711.
Summary
The #711 fix disambiguates a nested-block
let/constthat shadows an enclosing binding by giving it its own storage — except when the shadowed name is also referenced by a nested closure (arrow/function/class) in the same generator. Those names are deliberately left untouched because the closure-capture machinery keys captured variables by source name and the #711 rename does not rewrite closure interiors; renaming a captured name would desync the capture. So this residual case still leaks.Repro
[5, 100](correct)[5, 5](wrong — outerrleaked to 5 via the shared field/DC)Notes
A proper fix needs precise per-binding capture analysis (which arrow captures which lexical binding) so a shadowing binding can be renamed and its capturing closures updated consistently — rather than the current conservative "skip if the name appears in any closure" guard in
GeneratorBlockScopeRenamer. Astronomically rare; low priority. Found while implementing #711.