Skip to content

Commit

Permalink
[stable][kernel] Fix record type equivalence
Browse files Browse the repository at this point in the history
- Increment index to avoid infinite loop when the first named elements
  in the two record types are equivalent.
- Add some test cases for record types.

Fixes: #52817
Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/311929
Change-Id: Iaa4dbf7d2659deeac1eab642cc3aefad9a08f67e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312709
Commit-Queue: Nicholas Shahan <[email protected]>
Reviewed-by: Sigmund Cherem <[email protected]>
Reviewed-by: Kevin Chisholm <[email protected]>
  • Loading branch information
nshahan authored and Commit Queue committed Jul 11, 2023
1 parent 9024e2b commit 59d6206
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ This is a patch release that:

- Fixes a flow in flow analysis that causes it to sometimes ignore destructuring
assignments (issue [#52767]).
- Fixes an infinite loop in some web development compiles that include `is` or
`as` expressions involving record types with named fields (issue [#52869]).
- Fixes a memory leak in Dart analyzer's file-watching (issue [#52791]).
- Fixes a memory leak of file system watcher related data structures (issue [#52793]).

[#52767]: https://github.com/dart-lang/sdk/issues/52767
[#52869]: https://github.com/dart-lang/sdk/issues/52869
[#52791]: https://github.com/dart-lang/sdk/issues/52791
[#52793]: https://github.com/dart-lang/sdk/issues/52793

Expand Down
15 changes: 8 additions & 7 deletions pkg/kernel/lib/src/dart_type_equivalence.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,19 @@ class DartTypeEquivalence implements DartTypeVisitor1<bool, DartType> {
}
}

// The named fields of [RecordType]s are supposed to be sorted, so we can
// use a linear search to compare them.
int nodeIndex = 0;
int otherIndex = 0;
while (result && nodeIndex < node.named.length) {
NamedType nodeNamedType = node.named[nodeIndex];
NamedType otherNamedType = other.named[otherIndex];
// The named fields of [RecordType]s are supposed to be sorted and we know
// there are the same number of named fields, so we can use a linear
// search to compare them.
int i = 0;
while (result && i < node.named.length) {
NamedType nodeNamedType = node.named[i];
NamedType otherNamedType = other.named[i];
if (nodeNamedType.name != otherNamedType.name) {
result = false;
} else {
result = nodeNamedType.type.accept1(this, otherNamedType.type);
}
i++;
}

return result;
Expand Down
16 changes: 16 additions & 0 deletions pkg/kernel/test/dart_type_equivalence_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,22 @@ void run() {
notEqual("Typedef<Object?>?", "Typedef<dynamic>", equateTopTypes: true);
areEqual("Typedef<Object?>?", "Typedef<dynamic>",
equateTopTypes: true, ignoreTopLevelNullability: true);

// Record types.
areEqual("(int, bool)", "(int, bool)");
notEqual("(int, bool)", "(int?, bool)");
notEqual("(int, bool)", "(int, bool?)");
notEqual("(int, bool)", "({int i, bool b})");
areEqual("({int i, bool b})", "({int i, bool b})");
areEqual("({int i, bool b})", "({bool b ,int i})");
notEqual("({int i, bool b})", "({int? i, bool b})");
notEqual("({int i, bool b})", "({int i, bool? b})");
notEqual("({int i, bool b})", "({int n, bool b})");
notEqual("({int i, bool b})", "({int i, bool t})");
areEqual("(int, {bool b})", "(int, {bool b})");
notEqual("(int, {bool b})", "(int?, {bool b})");
notEqual("(int, {bool b})", "(int, {bool? b})");
notEqual("(int, {bool b})", "(int, {bool t})");
}

void areEqual(String type1, String type2,
Expand Down

0 comments on commit 59d6206

Please sign in to comment.