[cfe] Implement TypedefTearOffConstant.== using assumptions
Change-Id: Id329259ce95ceaa8c4a7418de487c8595f5ea7e9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/205522
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 4a2284a..a8a2a04 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -13025,15 +13025,19 @@
if (other.tearOffConstant != tearOffConstant) return false;
if (other.parameters.length != parameters.length) return false;
if (parameters.isNotEmpty) {
- Map<TypeParameter, DartType> substitutionMap =
- <TypeParameter, DartType>{};
- for (int i = 0; i < parameters.length; ++i) {
- substitutionMap[parameters[i]] = new TypeParameterType.forAlphaRenaming(
- other.parameters[i], parameters[i]);
+ Assumptions assumptions = new Assumptions();
+ for (int index = 0; index < parameters.length; index++) {
+ assumptions.assume(parameters[index], other.parameters[index]);
}
- Substitution substitution = Substitution.fromMap(substitutionMap);
- for (int i = 0; i < parameters.length; ++i) {
- if (types[i] != substitution.substituteType(other.types[i])) {
+ for (int index = 0; index < parameters.length; index++) {
+ if (!parameters[index]
+ .bound
+ .equals(other.parameters[index].bound, assumptions)) {
+ return false;
+ }
+ }
+ for (int i = 0; i < types.length; ++i) {
+ if (!types[i].equals(other.types[i], assumptions)) {
return false;
}
}
diff --git a/pkg/kernel/test/constant_equals_test.dart b/pkg/kernel/test/constant_equals_test.dart
new file mode 100644
index 0000000..689ae71
--- /dev/null
+++ b/pkg/kernel/test/constant_equals_test.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2021, 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:kernel/ast.dart';
+
+testEquals(Constant a, Constant b) {
+ if (a != b) {
+ throw 'Expected $a and $b to be equal.';
+ }
+}
+
+testNotEquals(Constant a, Constant b) {
+ if (a == b) {
+ throw 'Expected $a and $b to be not equal.';
+ }
+}
+
+main() {
+ Uri uri = Uri.parse('test:uri');
+ Procedure procedure1 = new Procedure(
+ new Name('foo'), ProcedureKind.Method, new FunctionNode(null),
+ fileUri: uri, isStatic: true);
+ Procedure procedure2 = new Procedure(
+ new Name('foo'), ProcedureKind.Method, new FunctionNode(null),
+ fileUri: uri, isStatic: true);
+ Procedure procedure3 = new Procedure(
+ new Name('foo'),
+ ProcedureKind.Method,
+ new FunctionNode(null, typeParameters: [
+ new TypeParameter('X', const DynamicType(), const DynamicType())
+ ]),
+ fileUri: uri,
+ isStatic: true);
+
+ TearOffConstant tearOffConstant1a = new StaticTearOffConstant(procedure1);
+ TearOffConstant tearOffConstant1b = new StaticTearOffConstant(procedure1);
+ TearOffConstant tearOffConstant2 = new StaticTearOffConstant(procedure2);
+ TearOffConstant tearOffConstant3 = new StaticTearOffConstant(procedure3);
+
+ // foo() {}
+ // const a = foo;
+ // const b = foo;
+ // a == b
+ testEquals(tearOffConstant1a, tearOffConstant1b);
+
+ // foo() {} // from lib1;
+ // foo() {} // from lib2;
+ // lib1.foo != lib2.foo
+ testNotEquals(tearOffConstant1a, tearOffConstant2);
+
+ // foo() {}
+ // typedef F = foo;
+ // typedef G = foo;
+ // F == G
+ testEquals(new TypedefTearOffConstant([], tearOffConstant1a, []),
+ new TypedefTearOffConstant([], tearOffConstant1b, []));
+
+ // foo() {} // from lib1;
+ // foo() {} // from lib2;
+ // typedef F = lib1.foo;
+ // typedef G = lib2.foo;
+ // F != G
+ testNotEquals(new TypedefTearOffConstant([], tearOffConstant1a, []),
+ new TypedefTearOffConstant([], tearOffConstant2, []));
+
+ // foo() {}
+ // typedef F<T> = foo;
+ // typedef G<S> = foo;
+ // F == G
+ testEquals(
+ new TypedefTearOffConstant(
+ [new TypeParameter('T', const DynamicType(), const DynamicType())],
+ tearOffConstant1a,
+ []),
+ new TypedefTearOffConstant(
+ [new TypeParameter('S', const DynamicType(), const DynamicType())],
+ tearOffConstant1b,
+ []));
+
+ // foo() {}
+ // typedef F<T1, T2> = foo;
+ // typedef G<S> = foo;
+ // F != G
+ testNotEquals(
+ new TypedefTearOffConstant(
+ [
+ new TypeParameter('T1', const DynamicType(), const DynamicType()),
+ new TypeParameter('T2', const DynamicType(), const DynamicType())
+ ],
+ tearOffConstant1a,
+ []),
+ new TypedefTearOffConstant(
+ [new TypeParameter('S', const DynamicType(), const DynamicType())],
+ tearOffConstant1b,
+ []));
+
+ // foo() {}
+ // typedef F<T extends void> = foo;
+ // typedef G<S> = foo;
+ // F != G
+ testNotEquals(
+ new TypedefTearOffConstant(
+ [new TypeParameter('T', const VoidType(), const DynamicType())],
+ tearOffConstant1a,
+ []),
+ new TypedefTearOffConstant(
+ [new TypeParameter('S', const DynamicType(), const DynamicType())],
+ tearOffConstant1b,
+ []));
+ {
+ TypeParameter typeParameter1 =
+ new TypeParameter('T', const DynamicType(), const DynamicType());
+ TypeParameter typeParameter2 =
+ new TypeParameter('S', const DynamicType(), const DynamicType());
+
+ // foo<X>() {}
+ // typedef F<T> = foo<T>;
+ // typedef G<S> = foo<S>;
+ // F == G
+ testEquals(
+ new TypedefTearOffConstant([typeParameter1], tearOffConstant3,
+ [new TypeParameterType(typeParameter1, Nullability.nullable)]),
+ new TypedefTearOffConstant([typeParameter2], tearOffConstant3,
+ [new TypeParameterType(typeParameter2, Nullability.nullable)]));
+ }
+ {
+ TypeParameter typeParameter1a =
+ new TypeParameter('T1', const DynamicType(), const DynamicType());
+ TypeParameter typeParameter1b =
+ new TypeParameter('T2', const DynamicType(), const DynamicType());
+ TypeParameter typeParameter2a =
+ new TypeParameter('S1', const DynamicType(), const DynamicType());
+ TypeParameter typeParameter2b =
+ new TypeParameter('S2', const DynamicType(), const DynamicType());
+
+ // foo<X>() {}
+ // typedef F<T1, T2> = foo<T1>;
+ // typedef G<S1, S2> = foo<S1>;
+ // F == G
+ testEquals(
+ new TypedefTearOffConstant(
+ [typeParameter1a, typeParameter1b],
+ tearOffConstant3,
+ [new TypeParameterType(typeParameter1a, Nullability.nullable)]),
+ new TypedefTearOffConstant(
+ [typeParameter2a, typeParameter2b],
+ tearOffConstant3,
+ [new TypeParameterType(typeParameter2a, Nullability.nullable)]));
+
+ // foo<X>() {}
+ // typedef F<T1, T2> = foo<T1>;
+ // typedef G<S1, S2> = foo<S2>;
+ // F != G
+ testNotEquals(
+ new TypedefTearOffConstant(
+ [typeParameter1a, typeParameter1b],
+ tearOffConstant3,
+ [new TypeParameterType(typeParameter1a, Nullability.nullable)]),
+ new TypedefTearOffConstant(
+ [typeParameter2a, typeParameter2b],
+ tearOffConstant3,
+ [new TypeParameterType(typeParameter2b, Nullability.nullable)]));
+ }
+}