[ddc] Fix capture issue with temp names within async scopes.
`needsCapture` will ensure that any variables used within an async scope get included in the 'asyncScope' object that's created for that scope. The variables used to lower Dart late variables in particular get emitted separately. But they can still be used across async scopes so they need the special capture logic as well. Bug: https://github.com/dart-lang/sdk/issues/60748 Change-Id: I2486fce41f88f186fd799029c2cc59635f7ad8f5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429780 Reviewed-by: Nicholas Shahan <nshahan@google.com> Commit-Queue: Nate Biggs <natebiggs@google.com>
This commit is contained in:
@@ -4918,7 +4918,8 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
||||
if (_isTemporaryVariable(v)) {
|
||||
var name = _debuggerFriendlyTemporaryVariableName(v);
|
||||
name ??= 't\$${_tempVariables.length}';
|
||||
return _tempVariables.putIfAbsent(v, () => _emitScopedId(name!));
|
||||
return _tempVariables.putIfAbsent(
|
||||
v, () => _emitScopedId(name!, needsCapture: true));
|
||||
}
|
||||
var name = v.name!;
|
||||
if (isLateLoweredLocal(v)) {
|
||||
|
||||
@@ -5403,7 +5403,8 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
||||
if (_isTemporaryVariable(v)) {
|
||||
var name = _debuggerFriendlyTemporaryVariableName(v);
|
||||
name ??= 't\$${_tempVariables.length}';
|
||||
return _tempVariables.putIfAbsent(v, () => _emitScopedId(name!));
|
||||
return _tempVariables.putIfAbsent(
|
||||
v, () => _emitScopedId(name!, needsCapture: true));
|
||||
}
|
||||
var name = v.name!;
|
||||
if (isLateLoweredLocal(v)) {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:expect/async_helper.dart';
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
asyncStart();
|
||||
List<Object Function()> callbacks = [];
|
||||
List<int> expectedHashCodes = [];
|
||||
|
||||
void save(Object o) {
|
||||
expectedHashCodes.add(o.hashCode);
|
||||
}
|
||||
|
||||
void check(Object o, int i) {
|
||||
Expect.equals(expectedHashCodes[i], o.hashCode);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
late Object o = Object();
|
||||
o;
|
||||
Object record() => o;
|
||||
callbacks.add(record);
|
||||
save(record());
|
||||
}
|
||||
|
||||
for (int i = callbacks.length - 1; i >= 0; i--) {
|
||||
check(callbacks[i](), i);
|
||||
}
|
||||
asyncEnd();
|
||||
}
|
||||
Reference in New Issue
Block a user