Skip to content

Commit

Permalink
[beta][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: I1911346ac2551f1b0eb8587e49675a2ac8f3232b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312710
Reviewed-by: Sigmund Cherem <[email protected]>
Commit-Queue: Nicholas Shahan <[email protected]>
  • Loading branch information
nshahan committed Jul 11, 2023
1 parent e261c46 commit 1b6421a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
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 1b6421a

Please sign in to comment.