mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 08:51:21 +00:00
Tweak the subtype rule for Null
Change-Id: I3c1f1af40f5930a02355f8d986a27db606998096 Reviewed-on: https://dart-review.googlesource.com/c/90980 Commit-Queue: Peter von der Ahé <ahe@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
5fbf15d9c4
commit
97cb74cf63
|
@ -1672,12 +1672,7 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
|
||||
/// Modifies a type as appropriate when inferring a closure return type.
|
||||
DartType inferReturnType(DartType returnType) {
|
||||
if (returnType == null) {
|
||||
// Analyzer infers `Null` if there is no `return` expression; the spec
|
||||
// says to return `void`. TODO(paulberry): resolve this difference.
|
||||
return coreTypes.nullClass.rawType;
|
||||
}
|
||||
return returnType;
|
||||
return returnType ?? typeSchemaEnvironment.nullType;
|
||||
}
|
||||
|
||||
/// Performs type inference on the given [statement].
|
||||
|
|
|
@ -151,12 +151,10 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment {
|
|||
}
|
||||
|
||||
// SLB(bottom, T) = SLB(T, bottom) = bottom.
|
||||
if (isBottom(type1)) {
|
||||
return type1;
|
||||
}
|
||||
if (isBottom(type2)) {
|
||||
return type2;
|
||||
}
|
||||
if (type1 is BottomType) return type1;
|
||||
if (type2 is BottomType) return type2;
|
||||
if (type1 == nullType) return type1;
|
||||
if (type2 == nullType) return type2;
|
||||
|
||||
// Function types have structural lower bounds.
|
||||
if (type1 is FunctionType && type2 is FunctionType) {
|
||||
|
@ -224,12 +222,10 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment {
|
|||
}
|
||||
|
||||
// SUB(bottom, T) = SUB(T, bottom) = T.
|
||||
if (isBottom(type1)) {
|
||||
return type2;
|
||||
}
|
||||
if (isBottom(type2)) {
|
||||
return type1;
|
||||
}
|
||||
if (type1 is BottomType) return type2;
|
||||
if (type2 is BottomType) return type1;
|
||||
if (type1 == nullType) return type2;
|
||||
if (type2 == nullType) return type1;
|
||||
|
||||
if (type1 is TypeParameterType || type2 is TypeParameterType) {
|
||||
return _typeParameterStandardUpperBound(type1, type2);
|
||||
|
@ -431,12 +427,10 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment {
|
|||
}
|
||||
|
||||
@override
|
||||
bool isBottom(DartType t) {
|
||||
if (t is UnknownType) {
|
||||
return true;
|
||||
} else {
|
||||
return super.isBottom(t);
|
||||
}
|
||||
bool isSubtypeOf(DartType subtype, DartType supertype) {
|
||||
if (subtype is UnknownType) return true;
|
||||
if (subtype == Null && supertype is UnknownType) return true;
|
||||
return super.isSubtypeOf(subtype, supertype);
|
||||
}
|
||||
|
||||
bool isEmptyContext(DartType context) {
|
||||
|
|
|
@ -165,11 +165,6 @@ abstract class SubtypeTester {
|
|||
|
||||
InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass);
|
||||
|
||||
/// Determines if the given type is at the bottom of the type hierarchy. May
|
||||
/// be overridden in subclasses.
|
||||
bool isBottom(DartType type) =>
|
||||
type is BottomType || (!legacyMode && type == nullType);
|
||||
|
||||
/// Determines if the given type is at the top of the type hierarchy. May be
|
||||
/// overridden in subclasses.
|
||||
bool isTop(DartType type) =>
|
||||
|
@ -180,7 +175,10 @@ abstract class SubtypeTester {
|
|||
subtype = subtype.unalias;
|
||||
supertype = supertype.unalias;
|
||||
if (identical(subtype, supertype)) return true;
|
||||
if (isBottom(subtype)) return true;
|
||||
if (subtype is BottomType) return true;
|
||||
if (subtype == nullType) {
|
||||
return supertype is! BottomType;
|
||||
}
|
||||
if (isTop(supertype)) return true;
|
||||
|
||||
// Handle FutureOr<T> union type.
|
||||
|
|
Loading…
Reference in a new issue