static bool unrelatedTypes()

in lib/src/util/dart_type_utilities.dart [478:542]


  static bool unrelatedTypes(
      TypeSystem typeSystem, DartType? leftType, DartType? rightType) {
    // If we don't have enough information, or can't really compare the types,
    // return false as they _might_ be related.
    if (leftType == null ||
        leftType.isBottom ||
        leftType.isDynamic ||
        rightType == null ||
        rightType.isBottom ||
        rightType.isDynamic) {
      return false;
    }
    var promotedLeftType = typeSystem.promoteToNonNull(leftType);
    var promotedRightType = typeSystem.promoteToNonNull(rightType);
    if (promotedLeftType == promotedRightType ||
        typeSystem.isSubtypeOf(promotedLeftType, promotedRightType) ||
        typeSystem.isSubtypeOf(promotedRightType, promotedLeftType)) {
      return false;
    }
    if (promotedLeftType is InterfaceType &&
        promotedRightType is InterfaceType) {
      // In this case, [leftElement] and [rightElement] each represent
      // the same class, like `int`, or `Iterable<String>`.
      var leftElement = promotedLeftType.element;
      var rightElement = promotedRightType.element;
      if (leftElement == rightElement) {
        // In this case, [leftElement] and [rightElement] represent the same
        // class, modulo generics, e.g. `List<int>` and `List<dynamic>`. Now we
        // need to check type arguments.
        var leftTypeArguments = promotedLeftType.typeArguments;
        var rightTypeArguments = promotedRightType.typeArguments;
        if (leftTypeArguments.length != rightTypeArguments.length) {
          // I cannot think of how we would enter this block, but it guards
          // against RangeError below.
          return false;
        }
        for (var i = 0; i < leftTypeArguments.length; i++) {
          // If any of the pair-wise type arguments are unrelated, then
          // [leftType] and [rightType] are unrelated.
          if (unrelatedTypes(
              typeSystem, leftTypeArguments[i], rightTypeArguments[i])) {
            return true;
          }
        }
        // Otherwise, they might be related.
        return false;
      } else {
        return (leftElement.supertype?.isDartCoreObject ?? false) ||
            leftElement.supertype != rightElement.supertype;
      }
    } else if (promotedLeftType is TypeParameterType &&
        promotedRightType is TypeParameterType) {
      return unrelatedTypes(typeSystem, promotedLeftType.element.bound,
          promotedRightType.element.bound);
    } else if (promotedLeftType is FunctionType) {
      if (_isFunctionTypeUnrelatedToType(promotedLeftType, promotedRightType)) {
        return true;
      }
    } else if (promotedRightType is FunctionType) {
      if (_isFunctionTypeUnrelatedToType(promotedRightType, promotedLeftType)) {
        return true;
      }
    }
    return false;
  }