Fix more-specific for interface types with call functions.
R=ahe@google.com
Review URL: https://codereview.chromium.org/2307873002 .
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index 271d09f..4482d34 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -1027,6 +1027,8 @@
bool invalidTypeVariableBounds(DartType bound, DartType s);
+ bool invalidCallableType(DartType callType, DartType s);
+
/// Handle as dynamic for both subtype and more specific relation to avoid
/// spurious errors from malformed types.
bool visitMalformedType(MalformedType t, DartType s) => true;
@@ -1050,10 +1052,19 @@
if (s is InterfaceType) {
InterfaceType instance = t.asInstanceOf(s.element);
- return instance != null && checkTypeArguments(instance, s);
- } else {
- return false;
+ if (instance != null && checkTypeArguments(instance, s)) {
+ return true;
+ }
}
+
+ if (s == coreTypes.functionType && t.element.callType != null) {
+ return true;
+ } else if (s is FunctionType) {
+ FunctionType callType = t.callType;
+ return callType != null && !invalidCallableType(callType, s);
+ }
+
+ return false;
}
bool visitFunctionType(FunctionType t, DartType s) {
@@ -1223,6 +1234,10 @@
bool invalidTypeVariableBounds(DartType bound, DartType s) {
return !isMoreSpecific(bound, s);
}
+
+ bool invalidCallableType(DartType callType, DartType s) {
+ return !isMoreSpecific(callType, s);
+ }
}
/**
@@ -1255,16 +1270,8 @@
return !isSubtype(bound, s);
}
- bool visitInterfaceType(InterfaceType t, DartType s) {
- if (super.visitInterfaceType(t, s)) return true;
-
- if (s == coreTypes.functionType && t.element.callType != null) {
- return true;
- } else if (s is FunctionType) {
- FunctionType callType = t.callType;
- return callType != null && isSubtype(callType, s);
- }
- return false;
+ bool invalidCallableType(DartType callType, DartType s) {
+ return !isSubtype(callType, s);
}
}
diff --git a/tests/compiler/dart2js/subtype_test.dart b/tests/compiler/dart2js/subtype_test.dart
index bdd9e66..b31e2d8 100644
--- a/tests/compiler/dart2js/subtype_test.dart
+++ b/tests/compiler/dart2js/subtype_test.dart
@@ -277,18 +277,21 @@
ClassElement classA = env.getElement('A');
DartType A = classA.rawType;
DartType function = env['Function'];
+ DartType call = env.getMemberType(classA, 'call');
DartType m1 = env.getMemberType(classA, 'm1');
DartType m2 = env.getMemberType(classA, 'm2');
DartType m3 = env.getMemberType(classA, 'm3');
DartType m4 = env.getMemberType(classA, 'm4');
DartType m5 = env.getMemberType(classA, 'm5');
- expect(true, A, function, expectMoreSpecific: false);
- expect(true, A, m1, expectMoreSpecific: false);
+ expect(true, A, function);
+ expect(true, A, call);
+ expect(true, call, m1);
+ expect(true, A, m1);
expect(true, A, m2, expectMoreSpecific: false);
expect(false, A, m3);
expect(false, A, m4);
- expect(true, A, m5, expectMoreSpecific: false);
+ expect(true, A, m5);
}));
}