| 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 6516d96eed48994fd46ef7a81a6768e2f1325036..0f3aa13bca90da8ee0acfc5c6584e0f56ae4af41 100644
|
| --- a/pkg/compiler/lib/src/types/flat_type_mask.dart
|
| +++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
|
| @@ -358,6 +358,53 @@ class FlatTypeMask implements TypeMask {
|
| }
|
| }
|
|
|
| + bool isDisjoint(TypeMask other, ClassWorld classWorld) {
|
| + if (other is! FlatTypeMask) return other.isDisjoint(this, classWorld);
|
| + FlatTypeMask flatOther = other;
|
| +
|
| + if (isNullable && flatOther.isNullable) return false;
|
| + if (isEmpty || flatOther.isEmpty) return true;
|
| + if (base == flatOther.base) return false;
|
| + if (isExact && flatOther.isExact) return true;
|
| +
|
| + // normalization guarantees that isExact === !isSubclass && !isSubtype
|
| + if (classWorld.isSubclassOf(flatOther.base, base)) return isExact;
|
| + if (classWorld.isSubclassOf(base, flatOther.base)) {
|
| + return flatOther.isExact;
|
| + }
|
| +
|
| + // Two different base classes have no common subclass unless one is a
|
| + // subclass of the other (checked above).
|
| + if (isSubclass && flatOther.isSubclass) return true;
|
| +
|
| + if (classWorld.isSubtypeOf(flatOther.base, base)) return !isSubtype;
|
| + if (classWorld.isSubtypeOf(base, flatOther.base)) {
|
| + return !flatOther.isSubtype;
|
| + }
|
| +
|
| + // By now we know they are not subtypes of each other, so if either is
|
| + // exact, we are done.
|
| + if (isExact || flatOther.isExact) return true;
|
| +
|
| + return _isDisjointHelper(this, flatOther, classWorld);
|
| + }
|
| +
|
| + static bool _isDisjointHelper(
|
| + FlatTypeMask a, FlatTypeMask b, ClassWorld classWorld) {
|
| + if (!a.isSubclass && b.isSubclass) {
|
| + return _isDisjointHelper(b, a, classWorld);
|
| + }
|
| + assert(a.isSubclass || a.isSubtype);
|
| + assert(b.isSubtype);
|
| + var elements = a.isSubclass
|
| + ? classWorld.strictSubclassesOf(a.base)
|
| + : classWorld.strictSubtypesOf(a.base);
|
| + for (var element in elements) {
|
| + if (classWorld.isSubtypeOf(element, b.base)) return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| TypeMask intersectionSame(FlatTypeMask other, ClassWorld classWorld) {
|
| assert(base == other.base);
|
| // The two masks share the base type, so we must chose the most
|
|
|