[cfe] Introduce ExtensionType into isSubtypeOf
Change-Id: Iea88e7355d7eee9d82c0c41247407fe1178ee049
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195068
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index bc3f745..bdf54c8 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -364,51 +364,12 @@
DartType subtype, DartType supertype) {
if (subtype is UnknownType) return const IsSubtypeOf.always();
- // For now, extension types are only related to themselves, top types, and
- // bottom types.
- // TODO(dmitryas): Implement subtyping rules for extension types.
- if (subtype is ExtensionType) {
- if (coreTypes.isTop(supertype)) {
- return const IsSubtypeOf.always();
- } else if (supertype is ExtensionType &&
- subtype.extension == supertype.extension) {
- assert(subtype.typeArguments.length == supertype.typeArguments.length);
- IsSubtypeOf result = const IsSubtypeOf.always();
- for (int i = 0; i < subtype.typeArguments.length; ++i) {
- result.and(performNullabilityAwareMutualSubtypesCheck(
- subtype.typeArguments[i], supertype.typeArguments[i]));
- }
- return result;
- } else {
- return const IsSubtypeOf.never();
- }
- }
-
DartType unwrappedSupertype = supertype;
while (unwrappedSupertype is FutureOrType) {
unwrappedSupertype = (unwrappedSupertype as FutureOrType).typeArgument;
}
if (unwrappedSupertype is UnknownType) {
return const IsSubtypeOf.always();
- } else if (unwrappedSupertype is ExtensionType) {
- // For now, extension types are only related to themselves, top types, and
- // bottom types.
- // TODO(dmitryas): Implement subtyping rules for extension types.
- if (coreTypes.isBottom(subtype)) {
- return const IsSubtypeOf.always();
- } else if (subtype is ExtensionType &&
- subtype.extension == unwrappedSupertype.extension) {
- assert(subtype.typeArguments.length ==
- unwrappedSupertype.typeArguments.length);
- IsSubtypeOf result = const IsSubtypeOf.always();
- for (int i = 0; i < subtype.typeArguments.length; ++i) {
- result.and(performNullabilityAwareMutualSubtypesCheck(
- subtype.typeArguments[i], unwrappedSupertype.typeArguments[i]));
- }
- return result;
- } else {
- return const IsSubtypeOf.never();
- }
}
return super.performNullabilityAwareSubtypeCheck(subtype, supertype);
}
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index 357af4c..0c4abbc 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -2,25 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import '../ast.dart'
- show
- Class,
- DartType,
- DynamicType,
- FunctionType,
- FutureOrType,
- InterfaceType,
- InvalidType,
- Library,
- NamedType,
- NeverType,
- NullType,
- Nullability,
- TypeParameter,
- TypeParameterType,
- TypedefType,
- Variance,
- VoidType;
+import '../ast.dart';
import '../class_hierarchy.dart' show ClassHierarchyBase;
@@ -350,6 +332,8 @@
IsSubtypeOf isTypeParameterRelated(TypeParameterType s, T t, Types types);
IsSubtypeOf isTypedefRelated(TypedefType s, T t, Types types);
+
+ IsSubtypeOf isExtensionRelated(ExtensionType s, T t, Types types);
}
class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
@@ -421,6 +405,13 @@
IsSubtypeOf isVoidRelated(VoidType s, InterfaceType t, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, InterfaceType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
@@ -596,6 +587,12 @@
IsSubtypeOf isVoidRelated(VoidType s, FunctionType t, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, FunctionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
@@ -676,6 +673,13 @@
IsSubtypeOf isVoidRelated(VoidType s, TypeParameterType t, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, TypeParameterType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsTypedefSubtypeOf extends TypeRelation<TypedefType> {
@@ -722,6 +726,12 @@
IsSubtypeOf isVoidRelated(VoidType s, TypedefType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, TypedefType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsFutureOrSubtypeOf extends TypeRelation<FutureOrType> {
@@ -849,6 +859,12 @@
IsSubtypeOf isTypedefRelated(TypedefType s, FutureOrType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, FutureOrType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
@@ -908,37 +924,51 @@
VoidType s, TypeParameterType intersection, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, TypeParameterType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsNullTypeSubtypeOf implements TypeRelation<NullType> {
const IsNullTypeSubtypeOf();
+ @override
IsSubtypeOf isDynamicRelated(DynamicType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isVoidRelated(VoidType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isInterfaceRelated(InterfaceType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, NullType t, Types types) {
return types.performNullabilityAwareMutualSubtypesCheck(
intersection.promotedBound!, t);
}
+ @override
IsSubtypeOf isFunctionRelated(FunctionType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isFutureOrRelated(FutureOrType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isTypeParameterRelated(
TypeParameterType s, NullType t, Types types) {
// We don't need to combine the check of the bound against [t] with the
@@ -947,40 +977,54 @@
return types.performNullabilityAwareSubtypeCheck(s.bound, t);
}
+ @override
IsSubtypeOf isTypedefRelated(TypedefType s, NullType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, NullType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsNeverTypeSubtypeOf implements TypeRelation<NeverType> {
const IsNeverTypeSubtypeOf();
+ @override
IsSubtypeOf isDynamicRelated(DynamicType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isVoidRelated(VoidType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isInterfaceRelated(InterfaceType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, NeverType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(
intersection.promotedBound!, t);
}
+ @override
IsSubtypeOf isFunctionRelated(FunctionType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isFutureOrRelated(FutureOrType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isTypeParameterRelated(
TypeParameterType s, NeverType t, Types types) {
return types
@@ -988,7 +1032,82 @@
.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
}
+ @override
IsSubtypeOf isTypedefRelated(TypedefType s, NeverType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, NeverType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+}
+
+class IsExtensionTypeSubtypeOf implements TypeRelation<ExtensionType> {
+ const IsExtensionTypeSubtypeOf();
+
+ @override
+ IsSubtypeOf isDynamicRelated(DynamicType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isVoidRelated(VoidType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isInterfaceRelated(
+ InterfaceType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isIntersectionRelated(
+ TypeParameterType intersection, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isFunctionRelated(FunctionType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isFutureOrRelated(FutureOrType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isTypeParameterRelated(
+ TypeParameterType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isTypedefRelated(TypedefType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ if (s.extension != t.extension) {
+ return const IsSubtypeOf.never();
+ }
+ return types
+ .areTypeArgumentsOfSubtypeKernel(
+ s.typeArguments, t.typeArguments, t.extension.typeParameters)
+ .and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
+ }
}