Index: pkg/analyzer/lib/src/generated/type_system.dart |
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart |
index 2b6012a4eb8e61022de5e507ac72e31364719341..f9e5e7d427611c40b255117cde2e97d8499a958c 100644 |
--- a/pkg/analyzer/lib/src/generated/type_system.dart |
+++ b/pkg/analyzer/lib/src/generated/type_system.dart |
@@ -696,13 +696,6 @@ class StrongTypeSystemImpl extends TypeSystem { |
}; |
} |
- /// If [t1] or [t2] is a type parameter we are inferring, update its bound. |
- /// Returns `true` if we could possibly find a compatible type, |
- /// otherwise `false`. |
- bool _inferTypeParameterSubtypeOf(DartType t1, DartType t2) { |
- return false; |
- } |
- |
/** |
* This currently does not implement a very complete least upper bound |
* algorithm, but handles a couple of the very common cases that are |
@@ -840,28 +833,7 @@ class StrongTypeSystemImpl extends TypeSystem { |
// Trivially false. |
if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) || |
_isBottom(t2, dynamicIsBottom: dynamicIsBottom)) { |
- return _inferTypeParameterSubtypeOf(t1, t2); |
- } |
- |
- // S <: T where S is a type variable |
- // T is not dynamic or object (handled above) |
- // True if T == S |
- // Or true if bound of S is S' and S' <: T |
- if (t1 is TypeParameterType) { |
- if (t2 is TypeParameterType && |
- t1.definition == t2.definition && |
- guardedSubtype(t1.bound, t2.bound, visited)) { |
- return true; |
- } |
- if (_inferTypeParameterSubtypeOf(t1, t2)) { |
- return true; |
- } |
- DartType bound = t1.element.bound; |
- return bound == null ? false : guardedSubtype(bound, t2, visited); |
- } |
- |
- if (t2 is TypeParameterType) { |
- return _inferTypeParameterSubtypeOf(t1, t2); |
+ return false; |
} |
// Handle FutureOr<T> union type. |
@@ -887,6 +859,23 @@ class StrongTypeSystemImpl extends TypeSystem { |
return isSubtypeOf(t1, t2Future) || isSubtypeOf(t1, t2TypeArg); |
} |
+ // S <: T where S is a type variable |
+ // T is not dynamic or object (handled above) |
+ // True if T == S |
+ // Or true if bound of S is S' and S' <: T |
+ if (t1 is TypeParameterType) { |
+ if (t2 is TypeParameterType && |
+ t1.definition == t2.definition && |
+ guardedSubtype(t1.bound, t2.bound, visited)) { |
+ return true; |
+ } |
+ DartType bound = t1.element.bound; |
+ return bound == null ? false : guardedSubtype(bound, t2, visited); |
+ } |
+ if (t2 is TypeParameterType) { |
+ return false; |
+ } |
+ |
// Void only appears as the return type of a function, and we handle it |
// directly in the function subtype rules. We should not get to a point |
// where we're doing a subtype test on a "bare" void, but just in case we |
@@ -1503,8 +1492,8 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl { |
DartType declaredUpperBound = typeParam.element.bound; |
if (declaredUpperBound != null) { |
// Assert that the type parameter is a subtype of its bound. |
- _inferTypeParameterSubtypeOf(typeParam, |
- declaredUpperBound.substitute2(inferredTypes, fnTypeParams)); |
+ _isSubtypeOf(typeParam, |
+ declaredUpperBound.substitute2(inferredTypes, fnTypeParams), null); |
} |
// Now we've computed lower and upper bounds for each type parameter. |
@@ -1562,8 +1551,18 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl { |
} |
@override |
- bool _inferTypeParameterSubtypeOf(DartType t1, DartType t2) { |
+ bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited, |
+ {bool dynamicIsBottom: false}) { |
+ // TODO(jmesserly): to match old behavior, the trivial constraints are |
Leaf
2017/01/27 21:34:54
What's the thing to be done in in this TODO?
Jennifer Messerly
2017/01/27 22:39:19
it's not right once we pin based on downward const
|
+ // not treated as adding to the constraint set. |
+ if (identical(t1, t2) || |
+ _isTop(t2, dynamicIsBottom: dynamicIsBottom) || |
+ _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) { |
+ return true; |
+ } |
+ |
if (t1 is TypeParameterType) { |
+ // TODO(jmesserly): we ignore `dynamicIsBottom` here, is that correct? |
_TypeParameterBound bound = _bounds[t1]; |
if (bound != null) { |
// Ensure T1 <: T2, where T1 is a type parameter we are inferring. |
@@ -1591,7 +1590,8 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl { |
return true; |
} |
} |
- return false; |
+ return super |
+ ._isSubtypeOf(t1, t2, visited, dynamicIsBottom: dynamicIsBottom); |
} |
} |