Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Unified Diff: pkg/analyzer/lib/src/generated/type_system.dart

Issue 2655273008: fix #28526 and fix #28527 FutureOr<T> in await and subtype (Closed)
Patch Set: fix Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..b951f4f4dff2f4099045d17b8f5858af7ee0475e 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
@@ -1482,6 +1471,7 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
for (int i = 0; i < fnTypeParams.length; i++) {
TypeParameterType typeParam = fnTypeParams[i];
+ _TypeParameterBound bound = _bounds[typeParam];
// Apply the `extends` clause for the type parameter, if any.
//
@@ -1503,7 +1493,9 @@ 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,
+ // TODO(jmesserly): the order of calling GLB here matters, because of
+ // https://github.com/dart-lang/sdk/issues/28513
+ bound.upper = _typeSystem.getGreatestLowerBound(bound.upper,
Jennifer Messerly 2017/01/27 23:04:49 this fix is new.
declaredUpperBound.substitute2(inferredTypes, fnTypeParams));
}
@@ -1519,7 +1511,6 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
_TypeParameterVariance variance =
new _TypeParameterVariance.from(typeParam, declaredReturnType);
- _TypeParameterBound bound = _bounds[typeParam];
DartType lowerBound = bound.lower;
DartType upperBound = bound.upper;
@@ -1562,8 +1553,19 @@ 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): the trivial constraints are not treated as part of
+ // the constraint set here. This seems incorrect once we are able to pin the
+ // inferred type of a type parameter based on the downwards information.
+ 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 +1593,8 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
return true;
}
}
- return false;
+ return super
+ ._isSubtypeOf(t1, t2, visited, dynamicIsBottom: dynamicIsBottom);
}
}
« no previous file with comments | « pkg/analyzer/lib/src/generated/static_type_analyzer.dart ('k') | pkg/analyzer/test/generated/strong_mode_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698