Chromium Code Reviews| 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 ff4eaf445fa7c4461ed3dd5aa2f59323e164d557..a7b7858b4159362fe08959c7e63b3a70fa147a28 100644 |
| --- a/pkg/analyzer/lib/src/generated/type_system.dart |
| +++ b/pkg/analyzer/lib/src/generated/type_system.dart |
| @@ -503,13 +503,35 @@ class StrongTypeSystemImpl extends TypeSystem { |
| /// - we know the function types are strict arrows, |
| /// - it allows opt-in covariant parameters. |
| bool isOverrideSubtypeOf(FunctionType f1, FunctionType f2) { |
| - return FunctionTypeImpl.relate( |
| - f1, |
| - f2, |
| - (t1, t2, t1Covariant, _) => |
| - isSubtypeOf(t2, t1) || t1Covariant && isSubtypeOf(t1, t2), |
| - instantiateToBounds, |
| - returnRelation: isSubtypeOf); |
| + return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds, |
| + parameterRelation: _isOverrideSubtypeOfParameter); |
| + } |
| + |
| + bool _isOverrideSubtypeOfParameter(ParameterElement p1, ParameterElement p2) { |
| + return isSubtypeOf(p2.type, p1.type) || |
| + p1.isCovariant && isSubtypeOf(p1.type, p2.type); |
| + } |
| + |
| + /// Given the [f1] of a member override and the [f2] of the |
|
Leaf
2017/06/28 18:12:29
"Given the type [f1]... and the type [f2]"?
Jennifer Messerly
2017/07/05 20:11:20
fixed in the moved/refactored code
|
| + /// base member, calls [visit] if it encounters any parameter from [f1] that |
| + /// needs a covariance check. |
|
Leaf
2017/06/28 18:12:29
Clarify is this "covariant generic covariance chec
Jennifer Messerly
2017/07/05 20:11:20
fixed in the moved/refactored code
|
| + void visitCovariantParameters( |
|
Leaf
2017/06/28 18:12:29
Ok, after reading the code in checker.dart, I thin
Jennifer Messerly
2017/07/05 20:11:20
moved!
|
| + FunctionType f1, |
| + FunctionType f2, |
| + visitTypeFormal(TypeParameterElement p), |
| + visitParameter(ParameterElement p)) { |
| + var fresh = FunctionTypeImpl.relateTypeFormals(f1, f2, (b2, b1, p2, p1) { |
| + if (!isSubtypeOf(b2, b1)) visitTypeFormal(p1); |
|
Leaf
2017/06/28 18:12:29
Not sure I understand this.
Jennifer Messerly
2017/07/05 20:11:20
I've added a large example and doc comment to the
|
| + return true; |
| + }); |
| + if (fresh != null) { |
| + f1 = f1.instantiate(fresh); |
| + f2 = f2.instantiate(fresh); |
| + } |
| + FunctionTypeImpl.relateParameters(f1.parameters, f2.parameters, (p1, p2) { |
| + if (!_isOverrideSubtypeOfParameter(p1, p2)) visitParameter(p1); |
| + return true; |
| + }); |
| } |
| @override |
| @@ -789,13 +811,10 @@ class StrongTypeSystemImpl extends TypeSystem { |
| /// that dynamic parameters of f1 and f2 are treated as bottom. |
| bool _isFunctionSubtypeOf( |
| FunctionType f1, FunctionType f2, Set<TypeImpl> visitedTypes) { |
| - return FunctionTypeImpl.relate( |
| - f1, |
| - f2, |
| - (t1, t2, _, __) => |
| - _isSubtypeOf(t2, t1, visitedTypes, dynamicIsBottom: true), |
| - instantiateToBounds, |
| - returnRelation: isSubtypeOf); |
| + return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds, |
| + parameterRelation: (p1, p2) => _isSubtypeOf( |
| + p2.type, p1.type, visitedTypes, |
| + dynamicIsBottom: true)); |
| } |
| bool _isInterfaceSubtypeOf( |
| @@ -2178,14 +2197,16 @@ class _GenericInferrer { |
| FunctionTypeImpl.relate( |
| t1, |
| t2, |
| - (t1, t2, _, __) { |
| - _matchSubtypeOf(t2, t1, null, origin, |
| - covariant: !covariant, dynamicIsBottom: true); |
| + (t1, t2) { |
| + // TODO(jmesserly): should we flip covariance when we're relating |
| + // type formal bounds? They're more like parameters. |
| + matchSubtype(t1, t2); |
| return true; |
| }, |
| _typeSystem.instantiateToBounds, |
| - returnRelation: (t1, t2) { |
| - matchSubtype(t1, t2); |
| + parameterRelation: (p1, p2) { |
| + _matchSubtypeOf(p2.type, p1.type, null, origin, |
| + covariant: !covariant, dynamicIsBottom: true); |
| return true; |
| }); |
| } |