anchor.diff:        // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
         var supertypeArg = supertype.typeArguments[0];
         var supertypeFuture = futureType(supertypeArg);
  -      return performNullabilityAwareSubtypeCheck(subtype, supertypeFuture) ==
  -                  IsSubtypeOf.always ||
  -              performNullabilityAwareSubtypeCheck(subtype, supertypeArg) ==
  -                  IsSubtypeOf.always
  -          ? IsSubtypeOf.always
  -          : IsSubtypeOf.never;
  +      return performNullabilityAwareSubtypeCheck(subtype, supertypeFuture)
  +                  .isSubtypeWhenIgnoringNullabilities() ||
  +              performNullabilityAwareSubtypeCheck(subtype, supertypeArg)
  +                  .isSubtypeWhenIgnoringNullabilities()
  +          ? const IsSubtypeOf.always()
  +          : const IsSubtypeOf.never();
       }
   
       if (subtype is InterfaceType && supertype is InterfaceType) {
         var upcastType = getTypeAsInstanceOf(subtype, supertype.classNode);
  -      if (upcastType == null) return IsSubtypeOf.never;
  +      if (upcastType == null) return const IsSubtypeOf.never();
         for (int i = 0; i < upcastType.typeArguments.length; ++i) {
           // Termination: the 'supertype' parameter decreases in size.
  -        if (!isSubtypeOf(
  -            upcastType.typeArguments[i], supertype.typeArguments[i])) {
  -          return IsSubtypeOf.never;
  +        if (!performNullabilityAwareSubtypeCheck(
  +                upcastType.typeArguments[i], supertype.typeArguments[i])
  +            .isSubtypeWhenIgnoringNullabilities()) {
  +          return const IsSubtypeOf.never();
           }
         }
  -      return IsSubtypeOf.always;
  +      return const IsSubtypeOf.always();
       }
       if (subtype is TypeParameterType) {
         if (supertype is TypeParameterType &&
  
positive.code:         ++subtypeNameIndex;
        }
        if (subtypeNameIndex == subtype.namedParameters.length) {
          return IsSubtypeOf.never;
        }
        NamedType subtypeParameter = subtype.namedParameters[subtypeNameIndex];
        // Termination: Both types shrink in size.
        if (!isSubtypeOf(supertypeParameter.type, subtypeParameter.type)) {
          return IsSubtypeOf.never;
        }
      }
      return IsSubtypeOf.always;
    }
  }
  
negative.code: /// mode).  By contraposition, if a subtype check fails for two types when the
  /// nullability markers are ignored, it should also fail for those types in
  /// full-NNBD mode.
  class IsSubtypeOf {
    final _IsSubtypeOfValues _value;
  
    /// Subtype check succeeds in both modes.
    const IsSubtypeOf.always() : _value = _IsSubtypeOfValues.always;
  
    /// Subtype check succeeds only if the nullability markers are ignored.
    ///
    /// This implies that if the nullability markers aren't ignored, the subtype
    /// check fails.
    const IsSubtypeOf.onlyIfIgnoringNullabilities()
        : _value = _IsSubtypeOfValues.onlyIfIgnoringNullabilities;
  
    /// Subtype check fails in both modes.
    const IsSubtypeOf.never() : _value = _IsSubtypeOfValues.never;
  
    bool isSubtypeWhenIgnoringNullabilities() {
      return _value != _IsSubtypeOfValues.never;
    }
  
    bool isSubtypeWhenUsingNullabilities() {
      return _value == _IsSubtypeOfValues.always;
    }
  }
  
  /// The part of [TypeEnvironment] that deals with subtype tests.
  