anchor.diff:          // recursive call can only occur a finite number of times before
           // reaching a shrinking recursive call (or terminating).
           // TODO(dmitryas): Replace it with one recursive descent instead of two.
  -        if (!isSubtypeOf(superParameter.bound, subBound) ||
  -            !isSubtypeOf(subBound, superParameter.bound)) {
  -          return IsSubtypeOf.never;
  +        if (!performNullabilityAwareSubtypeCheck(superParameter.bound, subBound)
  +                .isSubtypeWhenIgnoringNullabilities() ||
  +            !performNullabilityAwareSubtypeCheck(subBound, superParameter.bound)
  +                .isSubtypeWhenIgnoringNullabilities()) {
  +          return const IsSubtypeOf.never();
           }
         }
         subtype = substitute(subtype.withoutTypeParameters, substitution);
       }
  -    if (!isSubtypeOf(subtype.returnType, supertype.returnType)) {
  -      return IsSubtypeOf.never;
  +    if (!performNullabilityAwareSubtypeCheck(
  +            subtype.returnType, supertype.returnType)
  +        .isSubtypeWhenIgnoringNullabilities()) {
  +      return const IsSubtypeOf.never();
       }
       for (int i = 0; i < supertype.positionalParameters.length; ++i) {
         var supertypeParameter = supertype.positionalParameters[i];
         var subtypeParameter = subtype.positionalParameters[i];
         // Termination: Both types shrink in size.
  -      if (!isSubtypeOf(supertypeParameter, subtypeParameter)) {
  -        return IsSubtypeOf.never;
  +      if (!performNullabilityAwareSubtypeCheck(
  +              supertypeParameter, subtypeParameter)
  +          .isSubtypeWhenIgnoringNullabilities()) {
  +        return const IsSubtypeOf.never();
         }
       }
       int subtypeNameIndex = 0;
  
positive.code:       return performNullabilityAwareSubtypeCheck(subtype.bound, supertype);
      }
      if (subtype is FunctionType) {
        if (supertype == functionLegacyRawType) return IsSubtypeOf.always;
        if (supertype is FunctionType) {
          return _performNullabilityAwareFunctionSubtypeCheck(subtype, supertype);
        }
      }
      return IsSubtypeOf.never;
    }
  
    IsSubtypeOf _performNullabilityAwareFunctionSubtypeCheck(
        FunctionType subtype, FunctionType supertype) {
      if (subtype.requiredParameterCount > supertype.requiredParameterCount) {
        return IsSubtypeOf.never;
      }
      if (subtype.positionalParameters.length <
          supertype.positionalParameters.length) {
        return IsSubtypeOf.never;
      }
      if (subtype.typeParameters.length != supertype.typeParameters.length) {
        return IsSubtypeOf.never;
      }
      if (subtype.typeParameters.isNotEmpty) {
        var substitution = <TypeParameter, DartType>{};
  
negative.code:           // Promoted bound should always be a subtype of the declared bound.
            assert(subtype.promotedBound == null ||
                performNullabilityAwareSubtypeCheck(
                        subtype.bound, supertype.bound)
                    .isSubtypeWhenIgnoringNullabilities());
            return const IsSubtypeOf.always();
          }
        }
        // Termination: if there are no cyclically bound type parameters, this
  