@@ -1501,6 +1501,9 @@ abstract class AbstractTypeRelation<T extends DartType>
15011501 /// Returns the declared bound of [element] .
15021502 DartType getTypeVariableBound (TypeVariableEntity element);
15031503
1504+ /// Returns the variances for each type parameter in [cls] .
1505+ List <Variance > getTypeVariableVariances (ClassEntity cls);
1506+
15041507 @override
15051508 bool visitType (T t, T s) {
15061509 throw 'internal error: unknown type ${t }' ;
@@ -1529,10 +1532,25 @@ abstract class AbstractTypeRelation<T extends DartType>
15291532 bool checkTypeArguments (InterfaceType instance, InterfaceType other) {
15301533 List <T > tTypeArgs = instance.typeArguments;
15311534 List <T > sTypeArgs = other.typeArguments;
1535+ List <Variance > tVariances = getTypeVariableVariances (instance.element);
15321536 assert (tTypeArgs.length == sTypeArgs.length);
1537+ assert (tTypeArgs.length == tVariances.length);
15331538 for (int i = 0 ; i < tTypeArgs.length; i++ ) {
1534- if (invalidTypeArguments (tTypeArgs[i], sTypeArgs[i])) {
1535- return false ;
1539+ switch (tVariances[i]) {
1540+ case Variance .legacyCovariant:
1541+ case Variance .covariant :
1542+ if (invalidTypeArguments (tTypeArgs[i], sTypeArgs[i])) return false ;
1543+ break ;
1544+ case Variance .contravariant:
1545+ if (invalidTypeArguments (sTypeArgs[i], tTypeArgs[i])) return false ;
1546+ break ;
1547+ case Variance .invariant:
1548+ if (invalidTypeArguments (tTypeArgs[i], sTypeArgs[i]) ||
1549+ invalidTypeArguments (sTypeArgs[i], tTypeArgs[i])) return false ;
1550+ break ;
1551+ default :
1552+ throw StateError (
1553+ "Invalid variance ${tVariances [i ]} used for subtype check." );
15361554 }
15371555 }
15381556 return true ;
0 commit comments