[beta][dart2js] Bailout tracing of record fields when record is bailed out
Bug: #52968
Fixes: #53001
Cherry-Pick: https://dart-review.googlesource.com/c/sdk/+/315020
Change-Id: Iad450fa342f33d38a23367bbac280b464a4d618d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/315240
Commit-Queue: Mayank Patke <fishythefish@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index 058042c..6e2106f 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -353,21 +353,24 @@
void analyzeStoredIntoRecord(RecordTypeInformation record) {
inferrer.analyzeRecordAndEnqueue(record);
-
- record.flowsInto.forEach((TypeInformation flow) {
- flow.users.forEach((TypeInformation user) {
- if (user is RecordFieldAccessTypeInformation) {
- final getterIndex =
- record.recordShape.indexOfGetterName(user.getterName);
- if (user.receiver == flow &&
- getterIndex >= 0 &&
- getterIndex < record.fieldTypes.length &&
- record.fieldTypes[getterIndex] == currentUser) {
- addNewEscapeInformation(user);
+ if (record.bailedOut) {
+ bailout('Stored in a record that bailed out');
+ } else {
+ record.flowsInto.forEach((TypeInformation flow) {
+ flow.users.forEach((TypeInformation user) {
+ if (user is RecordFieldAccessTypeInformation) {
+ final getterIndex =
+ record.recordShape.indexOfGetterName(user.getterName);
+ if (user.receiver == flow &&
+ getterIndex >= 0 &&
+ getterIndex < record.fieldTypes.length &&
+ record.fieldTypes[getterIndex] == currentUser) {
+ addNewEscapeInformation(user);
+ }
}
- }
+ });
});
- });
+ }
}
/// Checks whether this is a call to a list adding method. The definition of
diff --git a/tests/web/regress/issue/52968_test.dart b/tests/web/regress/issue/52968_test.dart
new file mode 100644
index 0000000..5c436ea
--- /dev/null
+++ b/tests/web/regress/issue/52968_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2023, 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/expect.dart';
+
+void main() {
+ final validator = createValidator([
+ (validate: isNotEmpty, message: 'Value is required'),
+ ]);
+ Expect.isEmpty(validator('foo'));
+ Expect.isNotEmpty(validator(null));
+}
+
+typedef FieldValidator<T> = List<String> Function(T? value);
+typedef Validator<T> = bool Function(T? value);
+FieldValidator<T> createValidator<T>(
+ List<({Validator<T> validate, String message})> validators) =>
+ (T? value) {
+ return validators
+ .where((validator) => !validator.validate(value))
+ .map((validator) => validator.message)
+ .toList();
+ };
+
+bool isNotEmpty(String? value) => value != null && value.isNotEmpty;