| Index: sdk/lib/_internal/compiler/implementation/dart_types.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
|
| index b6d3234f3258d9d6ba55e8a303bb6028029209d4..56db7fa8c6fb88ee42960ea170c74df5d3fb1b7a 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
|
| @@ -1207,6 +1207,16 @@ class SubtypeVisitor extends MoreSpecificVisitor {
|
| }
|
| }
|
|
|
| +/**
|
| + * Callback used to check whether the [typeArgument] of [type] is a valid
|
| + * substitute for the bound of [typeVariable]. [bound] holds the bound against
|
| + * which [typeArgument] should be checked.
|
| + */
|
| +typedef void CheckTypeVariableBound(GenericType type,
|
| + DartType typeArgument,
|
| + TypeVariableType typeVariable,
|
| + DartType bound);
|
| +
|
| class Types {
|
| final Compiler compiler;
|
| // TODO(karlklose): should we have a class Void?
|
| @@ -1250,6 +1260,16 @@ class Types {
|
| return subtypeVisitor.isAssignable(r, s);
|
| }
|
|
|
| + static const int IS_SUBTYPE = 1;
|
| + static const int MAYBE_SUBTYPE = 0;
|
| + static const int NOT_SUBTYPE = -1;
|
| +
|
| + int computeSubtypeRelation(DartType t, DartType s) {
|
| + // TODO(johnniwinther): Compute this directly in [isPotentialSubtype].
|
| + if (isSubtype(t, s)) return IS_SUBTYPE;
|
| + return isPotentialSubtype(t, s) ? MAYBE_SUBTYPE : NOT_SUBTYPE;
|
| + }
|
| +
|
| bool isPotentialSubtype(DartType t, DartType s) {
|
| // TODO(johnniwinther): Return a set of variable points in the positive
|
| // cases.
|
| @@ -1257,6 +1277,28 @@ class Types {
|
| }
|
|
|
| /**
|
| + * Checks the type arguments of [type] against the type variable bounds
|
| + * declared on [element]. Calls [checkTypeVariableBound] on each type
|
| + * argument and bound.
|
| + */
|
| + void checkTypeVariableBounds(GenericType type,
|
| + CheckTypeVariableBound checkTypeVariableBound) {
|
| + TypeDeclarationElement element = type.element;
|
| + Link<DartType> typeArguments = type.typeArguments;
|
| + Link<DartType> typeVariables = element.typeVariables;
|
| + while (!typeVariables.isEmpty && !typeArguments.isEmpty) {
|
| + TypeVariableType typeVariable = typeVariables.head;
|
| + DartType bound = typeVariable.element.bound.subst(
|
| + type.typeArguments, element.typeVariables);
|
| + DartType typeArgument = typeArguments.head;
|
| + checkTypeVariableBound(type, typeArgument, typeVariable, bound);
|
| + typeVariables = typeVariables.tail;
|
| + typeArguments = typeArguments.tail;
|
| + }
|
| + assert(typeVariables.isEmpty && typeArguments.isEmpty);
|
| + }
|
| +
|
| + /**
|
| * Helper method for performing substitution of a linked list of types.
|
| *
|
| * If no types are changed by the substitution, the [types] is returned
|
|
|