| Index: pkg/compiler/lib/src/types/flat_type_mask.dart
|
| diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
|
| index 914e6733ca5167cb3408230a254dedd7fc608e35..b73a930c62af8ebf0c3157014386c1f63cab1b98 100644
|
| --- a/pkg/compiler/lib/src/types/flat_type_mask.dart
|
| +++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
|
| @@ -67,7 +67,9 @@ class FlatTypeMask implements TypeMask {
|
| () => new FlatTypeMask.internal(base, flags));
|
| }
|
|
|
| - bool get isEmpty => (flags >> 1) == EMPTY;
|
| + bool get isEmpty => isEmptyOrNull && !isNullable;
|
| + bool get isNull => isEmptyOrNull && isNullable;
|
| + bool get isEmptyOrNull => (flags >> 1) == EMPTY;
|
| bool get isExact => (flags >> 1) == EXACT;
|
| bool get isNullable => (flags & 1) != 0;
|
|
|
| @@ -94,7 +96,7 @@ class FlatTypeMask implements TypeMask {
|
|
|
| bool contains(ClassElement type, ClassWorld classWorld) {
|
| assert(type.isDeclaration);
|
| - if (isEmpty) {
|
| + if (isEmptyOrNull) {
|
| return false;
|
| } else if (identical(base, type)) {
|
| return true;
|
| @@ -137,10 +139,9 @@ class FlatTypeMask implements TypeMask {
|
| }
|
|
|
| bool isInMask(TypeMask other, ClassWorld classWorld) {
|
| - // null is treated separately, so the empty mask might still contain it.
|
| - if (isEmpty) return isNullable ? other.isNullable : true;
|
| + if (isEmptyOrNull) return isNullable ? other.isNullable : true;
|
| // The empty type contains no classes.
|
| - if (other.isEmpty) return false;
|
| + if (other.isEmptyOrNull) return false;
|
| // Quick check whether to handle null.
|
| if (isNullable && !other.isNullable) return false;
|
| other = TypeMask.nonForwardingMask(other);
|
| @@ -215,7 +216,7 @@ class FlatTypeMask implements TypeMask {
|
|
|
| bool satisfies(ClassElement cls, ClassWorld classWorld) {
|
| assert(cls.isDeclaration);
|
| - if (isEmpty) return false;
|
| + if (isEmptyOrNull) return false;
|
| if (classWorld.isSubtypeOf(base, cls)) return true;
|
| return false;
|
| }
|
| @@ -225,7 +226,7 @@ class FlatTypeMask implements TypeMask {
|
| * otherwise returns `null`. This method is conservative.
|
| */
|
| ClassElement singleClass(ClassWorld classWorld) {
|
| - if (isEmpty) return null;
|
| + if (isEmptyOrNull) return null;
|
| if (isNullable) return null; // It is Null and some other class.
|
| if (isExact) {
|
| return base;
|
| @@ -241,7 +242,7 @@ class FlatTypeMask implements TypeMask {
|
| * Returns whether or not this type mask contains all types.
|
| */
|
| bool containsAll(ClassWorld classWorld) {
|
| - if (isEmpty || isExact) return false;
|
| + if (isEmptyOrNull || isExact) return false;
|
| return identical(base, classWorld.objectClass);
|
| }
|
|
|
| @@ -251,9 +252,9 @@ class FlatTypeMask implements TypeMask {
|
| assert(TypeMask.assertIsNormalized(other, classWorld));
|
| if (other is! FlatTypeMask) return other.union(this, classWorld);
|
| FlatTypeMask flatOther = other;
|
| - if (isEmpty) {
|
| + if (isEmptyOrNull) {
|
| return isNullable ? flatOther.nullable() : flatOther;
|
| - } else if (flatOther.isEmpty) {
|
| + } else if (flatOther.isEmptyOrNull) {
|
| return flatOther.isNullable ? nullable() : this;
|
| } else if (base == flatOther.base) {
|
| return unionSame(flatOther, classWorld);
|
| @@ -339,9 +340,9 @@ class FlatTypeMask implements TypeMask {
|
| assert(TypeMask.assertIsNormalized(this, classWorld));
|
| assert(TypeMask.assertIsNormalized(other, classWorld));
|
| FlatTypeMask flatOther = other;
|
| - if (isEmpty) {
|
| + if (isEmptyOrNull) {
|
| return flatOther.isNullable ? this : nonNullable();
|
| - } else if (flatOther.isEmpty) {
|
| + } else if (flatOther.isEmptyOrNull) {
|
| return isNullable ? flatOther : other.nonNullable();
|
| } else if (base == flatOther.base) {
|
| return intersectionSame(flatOther, classWorld);
|
| @@ -363,7 +364,7 @@ class FlatTypeMask implements TypeMask {
|
| FlatTypeMask flatOther = other;
|
|
|
| if (isNullable && flatOther.isNullable) return false;
|
| - if (isEmpty || flatOther.isEmpty) return true;
|
| + if (isEmptyOrNull || flatOther.isEmptyOrNull) return true;
|
| if (base == flatOther.base) return false;
|
| if (isExact && flatOther.isExact) return true;
|
|
|
| @@ -539,8 +540,8 @@ class FlatTypeMask implements TypeMask {
|
| bool canHit(Element element, Selector selector, ClassWorld classWorld) {
|
| Backend backend = classWorld.backend;
|
| assert(element.name == selector.name);
|
| - if (isEmpty) {
|
| - if (!isNullable) return false;
|
| + if (isEmpty) return false;
|
| + if (isNull) {
|
| return hasElementIn(backend.nullImplementation, selector, element);
|
| }
|
|
|
| @@ -603,7 +604,7 @@ class FlatTypeMask implements TypeMask {
|
| bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld) {
|
| // A call on an empty type mask is either dead code, or a call on
|
| // `null`.
|
| - if (isEmpty) return false;
|
| + if (isEmptyOrNull) return false;
|
| // A call on an exact mask for an abstract class is dead code.
|
| if (isExact && base.isAbstract) return false;
|
| // If the receiver is guaranteed to have a member that
|
| @@ -684,7 +685,7 @@ class FlatTypeMask implements TypeMask {
|
| Element locateSingleElement(Selector selector,
|
| TypeMask mask,
|
| Compiler compiler) {
|
| - if (isEmpty) return null;
|
| + if (isEmptyOrNull) return null;
|
| Iterable<Element> targets =
|
| compiler.world.allFunctions.filter(selector, mask);
|
| if (targets.length != 1) return null;
|
|
|