// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:math' as math;

import '../ast.dart';
import '../class_hierarchy.dart';
import '../core_types.dart';
import '../type_algebra.dart';
import 'non_null.dart';

mixin StandardBounds {
  ClassHierarchyBase get hierarchy;

  bool isSubtypeOf(DartType subtype, DartType supertype);

  bool areMutualSubtypes(DartType s, DartType t);

  CoreTypes get coreTypes => hierarchy.coreTypes;

  /// Checks the value of the MORETOP predicate for [s] and [t].
  ///
  /// For the definition of MORETOP see the following:
  /// https://github.com/dart-lang/language/blob/master/resources/type-system/upper-lower-bounds.md#helper-predicates
  bool moretop(DartType s, DartType t) {
    assert(coreTypes.isTop(s) || coreTypes.isObject(s));
    assert(coreTypes.isTop(t) || coreTypes.isObject(t));

    switch ((s, t)) {
      // MORETOP(void, T) = true.
      case (VoidType(), _):
        return true;

      // MORETOP(S, void) = false.
      case (_, VoidType()):
        return false;

      // MORETOP(dynamic, T) = true.
      case (DynamicType(), _):
        return true;

      // MORETOP(S, dynamic) = false.
      case (_, DynamicType()):
        return false;

      // MORETOP(Object, T) = true.
      case (
            InterfaceType(
              classNode: Class sClassNode,
              declaredNullability: Nullability.nonNullable
            ),
            _
          )
          when sClassNode == coreTypes.objectClass:
        return true;

      // MORETOP(S, Object) = false.
      case (
            _,
            InterfaceType(
              classNode: Class tClassNode,
              declaredNullability: Nullability.nonNullable
            )
          )
          when tClassNode == coreTypes.objectClass:
        return false;

      // MORETOP(S?, T?) == MORETOP(S, T).
      case (
          DartType(declaredNullability: Nullability.nullable),
          DartType(declaredNullability: Nullability.nullable)
        ):
        DartType nonNullableS =
            s.withDeclaredNullability(Nullability.nonNullable);
        assert(!identical(s, nonNullableS));
        DartType nonNullableT =
            t.withDeclaredNullability(Nullability.nonNullable);
        assert(!identical(t, nonNullableT));
        return moretop(nonNullableS, nonNullableT);

      // MORETOP(S, T?) = true.
      case (
          DartType(declaredNullability: Nullability.nonNullable),
          DartType(declaredNullability: Nullability.nullable)
        ):
        return true;

      // MORETOP(S?, T) = false.
      case (
          DartType(declaredNullability: Nullability.nullable),
          DartType(declaredNullability: Nullability.nonNullable)
        ):
        return false;

      // MORETOP(FutureOr<S>, FutureOr<T>) = MORETOP(S, T).
      case (
          FutureOrType(
            typeArgument: DartType sTypeArgument,
            declaredNullability: Nullability.nonNullable
          ),
          FutureOrType(
            typeArgument: DartType tTypeArgument,
            declaredNullability: Nullability.nonNullable
          )
        ):
        return moretop(sTypeArgument, tTypeArgument);

      case (InterfaceType(), _):
      case (_, InterfaceType()):
      case (ExtensionType(), _):
      case (_, ExtensionType()):
      case (FunctionType(), _):
      case (_, FunctionType()):
      case (RecordType(), _):
      case (_, RecordType()):
      case (NeverType(), _):
      case (_, NeverType()):
      case (NullType(), _):
      case (_, NullType()):
      case (FutureOrType(), _):
      case (_, FutureOrType()):
      case (TypeParameterType(), _):
      case (_, TypeParameterType()):
      case (StructuralParameterType(), _):
      case (_, StructuralParameterType()):
      case (IntersectionType(), _):
      case (_, IntersectionType()):
      case (TypedefType(), _):
      case (_, TypedefType()):
      case (InvalidType(), _):
      case (_, InvalidType()):
      case (AuxiliaryType(), _):
        throw new UnsupportedError("moretop($s, $t)");
    }
  }

  /// Checks the value of the MOREBOTTOM predicate for [s] and [t].
  ///
  /// For the definition of MOREBOTTOM see the following:
  /// https://github.com/dart-lang/language/blob/master/resources/type-system/upper-lower-bounds.md#helper-predicates
  bool morebottom(DartType s, DartType t) {
    assert(coreTypes.isBottom(s) || coreTypes.isNull(s));
    assert(coreTypes.isBottom(t) || coreTypes.isNull(t));

    switch ((s, t)) {
      // MOREBOTTOM(Never, T) = true.
      case (NeverType(declaredNullability: Nullability.nonNullable), _):
        return true;

      // MOREBOTTOM(S, Never) = false.
      case (_, NeverType(declaredNullability: Nullability.nonNullable)):
        return false;

      // MOREBOTTOM(Null, T) = true.
      case (NullType(), _):
        return true;

      // MOREBOTTOM(S, Null) = false.
      case (_, NullType()):
        return false;

      // MOREBOTTOM(S?, T?) = MOREBOTTOM(S, T).
      case (
          DartType(declaredNullability: Nullability.nullable),
          DartType(declaredNullability: Nullability.nullable)
        ):
        DartType nonNullableS =
            s.withDeclaredNullability(Nullability.nonNullable);
        assert(s != nonNullableS);
        DartType nonNullableT =
            t.withDeclaredNullability(Nullability.nonNullable);
        assert(t != nonNullableT);
        return morebottom(nonNullableS, nonNullableT);

      // MOREBOTTOM(S, T?) = true.
      case (
          DartType(declaredNullability: Nullability.nonNullable),
          DartType(declaredNullability: Nullability.nullable)
        ):
        return true;

      // MOREBOTTOM(S?, T) = false.
      case (
          DartType(declaredNullability: Nullability.nullable),
          DartType(declaredNullability: Nullability.nonNullable)
        ):
        return false;

      // MOREBOTTOM(X&S, Y&T) = MOREBOTTOM(S, T).
      case (
          IntersectionType(right: DartType sRight),
          IntersectionType(right: DartType tRight)
        ):
        return morebottom(sRight, tRight);

      // MOREBOTTOM(X&S, T) = true.
      case (IntersectionType(), _):
        return true;

      // MOREBOTTOM(S, X&T) = false.
      case (_, IntersectionType()):
        return false;

      // MOREBOTTOM(X extends S, Y extends T) = MOREBOTTOM(S, T).
      case (
          TypeParameterType(parameter: TypeParameter sParameter),
          TypeParameterType(parameter: TypeParameter tParameter)
        ):
        return morebottom(sParameter.bound, tParameter.bound);

      case (DynamicType(), _):
      case (_, DynamicType()):
      case (VoidType(), _):
      case (_, VoidType()):
      case (NeverType(), _):
      case (_, NeverType()):
      case (FunctionType(), _):
      case (_, FunctionType()):
      case (TypedefType(), _):
      case (_, TypedefType()):
      case (FutureOrType(), _):
      case (_, FutureOrType()):
      case (TypeParameterType(), _):
      case (_, TypeParameterType()):
      case (StructuralParameterType(), _):
      case (_, StructuralParameterType()):
      case (RecordType(), _):
      case (_, RecordType()):
      case (InterfaceType(), _):
      case (_, InterfaceType()):
      case (ExtensionType(), _):
      case (_, ExtensionType()):
      case (InvalidType(), _):
      case (_, InvalidType()):
      case (AuxiliaryType(), _):
        throw new UnsupportedError("morebottom($s, $t)");
    }
  }

  /// Computes the standard lower bound of [type1] and [type2].
  ///
  /// Standard lower bound is a lower bound function that imposes an
  /// ordering on the top types `void`, `dynamic`, and `object`.  This function
  /// additionally handles the unknown type that appears during type inference.
  DartType getStandardLowerBound(DartType type1, DartType type2) {
    if (type1 is InvalidType || type2 is InvalidType) {
      return const InvalidType();
    }
    return _getStandardLowerBound(type1, type2);
  }

  DartType _getStandardLowerBound(DartType type1, DartType type2) {
    // DOWN(T, T) = T.
    if (type1 == type2) return type1;

    return getStandardLowerBoundInternal(type1, type2);
  }

  DartType getStandardLowerBoundInternal(DartType type1, DartType type2) {
    DartType type1WithoutNullabilityMarker =
        computeTypeWithoutNullabilityMarker(type1);
    DartType type2WithoutNullabilityMarker =
        computeTypeWithoutNullabilityMarker(type2);
    bool isType1WithoutNullabilityMarker =
        isTypeWithoutNullabilityMarker(type1);
    bool isType2WithoutNullabilityMarker =
        isTypeWithoutNullabilityMarker(type2);

    switch ((type1, type2)) {
      case (InvalidType(), _):
      case (_, InvalidType()):
        return const InvalidType();

      case (TypedefType typedefType1, _):
        return getStandardLowerBoundInternal(typedefType1.unalias, type2);
      case (_, TypedefType typedefType2):
        return getStandardLowerBoundInternal(type1, typedefType2.unalias);

      // DOWN(T1, T2) where TOP(T1) and TOP(T2) =
      //   T1 if MORETOP(T2, T1)
      //   T2 otherwise
      // DOWN(T1, T2) = T2 if TOP(T1)
      // DOWN(T1, T2) = T1 if TOP(T2)
      case (DynamicType(), DynamicType()):
      case (DynamicType(), VoidType()):
      case (VoidType(), DynamicType()):
      case (VoidType(), VoidType()):
      case (_, _) when coreTypes.isTop(type1) && coreTypes.isTop(type2):
        return moretop(type2, type1) ? type1 : type2;
      case (DynamicType(), _):
      case (VoidType(), _):
      case (_, _) when coreTypes.isTop(type1):
        return type2;
      case (_, DynamicType()):
      case (_, VoidType()):
      case (_, _) when coreTypes.isTop(type2):
        return type1;

      // DOWN(T1, T2) where BOTTOM(T1) and BOTTOM(T2) =
      //   T1 if MOREBOTTOM(T1, T2)
      //   T2 otherwise
      // DOWN(T1, T2) = T2 if BOTTOM(T2)
      // DOWN(T1, T2) = T1 if BOTTOM(T1)
      case (
          NeverType(nullability: Nullability.nonNullable),
          NeverType(nullability: Nullability.nonNullable)
        ):
      case (_, _) when coreTypes.isBottom(type1) && coreTypes.isBottom(type2):
        return morebottom(type1, type2) ? type1 : type2;
      case (NeverType(nullability: Nullability.nonNullable), _):
      case (_, _) when coreTypes.isBottom(type1):
        return type1;
      case (_, NeverType(nullability: Nullability.nonNullable)):
      case (_, _) when coreTypes.isBottom(type2):
        return type2;

      // DOWN(T1, T2) where NULL(T1) and NULL(T2) =
      //   T1 if MOREBOTTOM(T1, T2)
      //   T2 otherwise
      // DOWN(Null, T2) =
      //   Null if Null <: T2
      //   Never otherwise
      // DOWN(T1, Null) =
      //  Null if Null <: T1
      //  Never otherwise
      case (NullType(), NullType()):
      case (
          NeverType(nullability: Nullability.nullable),
          NeverType(nullability: Nullability.nullable)
        ):
      case (_, _) when coreTypes.isNull(type1) && coreTypes.isNull(type2):
        return morebottom(type1, type2) ? type1 : type2;
      case (NullType(), DartType(declaredNullability: Nullability.nullable)):
      case (
          NeverType(nullability: Nullability.nullable),
          DartType(declaredNullability: Nullability.nullable)
        ):
      case (_, DartType(declaredNullability: Nullability.nullable))
          when coreTypes.isNull(type1):
        return type1;
      case (NullType(), _):
      case (NeverType(nullability: Nullability.nullable), _):
      case (_, _) when coreTypes.isNull(type1):
        return const NeverType.nonNullable();
      case (DartType(declaredNullability: Nullability.nullable), NullType()):
      case (
          DartType(declaredNullability: Nullability.nullable),
          NeverType(nullability: Nullability.nullable)
        ):
      case (DartType(declaredNullability: Nullability.nullable), _)
          when coreTypes.isNull(type2):
        return type2;
      case (_, NullType()):
      case (_, NeverType(nullability: Nullability.nullable)):
      case (_, _) when coreTypes.isNull(type2):
        return const NeverType.nonNullable();

      // DOWN(T1, T2) where OBJECT(T1) and OBJECT(T2) =
      //   T1 if MORETOP(T2, T1)
      //   T2 otherwise
      // DOWN(T1, T2) where OBJECT(T1) =
      //   T2 if T2 is non-nullable
      //   NonNull(T2) if NonNull(T2) is non-nullable
      //   Never otherwise
      // DOWN(T1, T2) where OBJECT(T2) =
      //   T1 if T1 is non-nullable
      //   NonNull(T1) if NonNull(T1) is non-nullable
      //   Never otherwise
      case (_, _) when coreTypes.isObject(type1) && coreTypes.isObject(type2):
        return moretop(type2, type1) ? type1 : type2;
      case (_, DartType(nullability: Nullability.nonNullable))
          when coreTypes.isObject(type1):
        return type2;
      case (_, _) when coreTypes.isObject(type1):
        if (computeNonNull(type2) case DartType nonNullType2
            when nonNullType2.nullability == Nullability.nonNullable) {
          return nonNullType2;
        } else {
          return const NeverType.nonNullable();
        }
      case (DartType(nullability: Nullability.nonNullable), _)
          when coreTypes.isObject(type2):
        return type1;
      case (_, _) when coreTypes.isObject(type2):
        if (computeNonNull(type1) case DartType nonNullType1
            when nonNullType1.nullability == Nullability.nonNullable) {
          return nonNullType1;
        } else {
          return const NeverType.nonNullable();
        }

      // DOWN(T1*, T2*) = S* where S is DOWN(T1, T2)
      // DOWN(T1*, T2?) = S* where S is DOWN(T1, T2)
      // DOWN(T1?, T2*) = S* where S is DOWN(T1, T2)
      // DOWN(T1*, T2) = S where S is DOWN(T1, T2)
      // DOWN(T1, T2*) = S where S is DOWN(T1, T2)
      // DOWN(T1?, T2?) = S? where S is DOWN(T1, T2)
      // DOWN(T1?, T2) = S where S is DOWN(T1, T2)
      // DOWN(T1, T2?) = S where S is DOWN(T1, T2)
      case (_, _)
          when isType1WithoutNullabilityMarker &&
              !isType2WithoutNullabilityMarker:
        return _getStandardLowerBound(type1, type2WithoutNullabilityMarker);
      case (_, _)
          when !isType1WithoutNullabilityMarker &&
              isType2WithoutNullabilityMarker:
        return _getStandardLowerBound(type1WithoutNullabilityMarker, type2);
      case (_, _)
          when isNullableTypeConstructorApplication(type1) &&
              isNullableTypeConstructorApplication(type2):
        return _getStandardLowerBound(
                type1WithoutNullabilityMarker, type2WithoutNullabilityMarker)
            .withDeclaredNullability(Nullability.nullable);

      case (FunctionType functionType1, FunctionType functionType2):
        return _getFunctionStandardLowerBound(functionType1, functionType2);

      case (RecordType recordType1, RecordType recordType2):
        return _getRecordStandardLowerBound(recordType1, recordType2);

      // DOWN(T1, T2) = T1 if T1 <: T2.
      // DOWN(T1, T2) = T2 if T2 <: T1.
      //
      // We use the non-nullable variants of the two types to determine T1 <:
      // T2 without using the nullability of the outermost type. The result
      // uses [intersectNullabilities] to compute the resulting type if the
      // subtype relation is established.
      case (_, _)
          when isSubtypeOf(
              greatestClosureForLowerBound(type1WithoutNullabilityMarker),
              greatestClosureForLowerBound(type2WithoutNullabilityMarker)):
        return type1.withDeclaredNullability(intersectNullabilities(
            type1.declaredNullability, type2.declaredNullability));
      case (_, _)
          when isSubtypeOf(
              greatestClosureForLowerBound(type2WithoutNullabilityMarker),
              greatestClosureForLowerBound(type1WithoutNullabilityMarker)):
        return type2.withDeclaredNullability(intersectNullabilities(
            type2.declaredNullability, type1.declaredNullability));

      // See
      // https://github.com/dart-lang/sdk/issues/37439#issuecomment-519654959.
      //
      // GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)>
      case (
          FutureOrType(typeArgument: DartType t1),
          FutureOrType(typeArgument: DartType t2)
        ):
        DartType argument = getStandardLowerBound(t1, t2);
        return new FutureOrType(argument, argument.declaredNullability);
      // GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>
      case (
            FutureOrType(typeArgument: DartType t1),
            InterfaceType(
              classNode: Class classNode2,
              typeArguments: [DartType t2]
            )
          )
          when classNode2 == coreTypes.futureClass:
        return new InterfaceType(
            coreTypes.futureClass,
            intersectNullabilities(
                type1.declaredNullability, type2.declaredNullability),
            <DartType>[getStandardLowerBound(t1, t2)]);
      // GLB(FutureOr<A>, B) == GLB(A, B)
      case (FutureOrType(typeArgument: DartType t1), DartType t2):
        return getStandardLowerBound(t1, t2);

      // The if-statement below handles the following rule:
      //     GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)
      // It's broken down into sub-cases instead of making a recursive call
      // to avoid making the checks that were already made above.  Note that
      // at this point it's not possible for type1 to be a FutureOr.
      //
      // GLB(Future<A>, FutureOr<B>) == Future<GLB(B, A)>
      case (
            InterfaceType(
              classNode: Class classNode1,
              typeArguments: [DartType t1]
            ),
            FutureOrType(typeArgument: DartType t2)
          )
          when classNode1 == coreTypes.futureClass:
        return new InterfaceType(
            coreTypes.futureClass,
            intersectNullabilities(
                type1.declaredNullability, type2.declaredNullability),
            <DartType>[getStandardLowerBound(t2, t1)]);
      // GLB(A, FutureOr<B>) == GLB(B, A)
      case (DartType t1, FutureOrType(typeArgument: DartType t2)):
        return getStandardLowerBound(t2, t1);

      // DOWN(T1, T2) = Never otherwise.
      case (InterfaceType(), _):
      case (_, InterfaceType()):
      case (RecordType(), _):
      case (_, RecordType()):
      case (ExtensionType(), _):
      case (_, ExtensionType()):
      case (TypeParameterType(), _):
      case (_, TypeParameterType()):
      case (StructuralParameterType(), _):
      case (_, StructuralParameterType()):
      case (IntersectionType(), _):
      case (_, IntersectionType()):
        return NeverType.fromNullability(combineNullabilitiesForSubstitution(
            inner: Nullability.nonNullable,
            outer: intersectNullabilities(
                type1.declaredNullability, type2.declaredNullability)));

      case (NeverType(nullability: Nullability.undetermined), _):
      case (_, NeverType(nullability: Nullability.undetermined)):
        throw new StateError("Unsupported nullability for NeverType: "
            "'${Nullability.undetermined}'.");

      case (AuxiliaryType(), _):
      case (_, AuxiliaryType()):
        throw new StateError("Unsupported type combination: "
            "getStandardUpperBoundInternal("
            "${type1.runtimeType}, ${type2.runtimeType}"
            ")");
    }
  }

  /// Computes the standard upper bound of two types.
  ///
  /// Standard upper bound is an upper bound function that imposes an ordering
  /// on the top types 'void', 'dynamic', and `object`.  This function
  /// additionally handles the unknown type that appears during type inference.
  DartType getStandardUpperBound(DartType type1, DartType type2) {
    if (type1 is InvalidType || type2 is InvalidType) {
      return const InvalidType();
    }
    return _getStandardUpperBound(type1, type2);
  }

  DartType _getStandardUpperBound(DartType type1, DartType type2) {
    // UP(T, T) = T
    if (type1 == type2) return type1;

    return getStandardUpperBoundInternal(type1, type2);
  }

  DartType getStandardUpperBoundInternal(DartType type1, DartType type2) {
    DartType typeWithoutNullabilityMarker1 =
        computeTypeWithoutNullabilityMarker(type1);
    DartType typeWithoutNullabilityMarker2 =
        computeTypeWithoutNullabilityMarker(type2);

    switch ((type1, type2)) {
      case (InvalidType(), _):
      case (_, InvalidType()):
        return const InvalidType();

      case (TypedefType typedefType1, _):
        return getStandardUpperBoundInternal(typedefType1.unalias, type2);
      case (_, TypedefType typedefType2):
        return getStandardUpperBoundInternal(type1, typedefType2.unalias);

      // UP(T1, T2) where TOP(T1) and TOP(T2) =
      //   T1 if MORETOP(T1, T2)
      //   T2 otherwise
      // UP(T1, T2) = T1 if TOP(T1)
      // UP(T1, T2) = T2 if TOP(T2)
      case (DynamicType(), DynamicType()):
      case (DynamicType(), VoidType()):
      case (VoidType(), DynamicType()):
      case (VoidType(), VoidType()):
      case (_, _) when coreTypes.isTop(type1) && coreTypes.isTop(type2):
        return moretop(type1, type2) ? type1 : type2;
      case (DynamicType(), _):
      case (VoidType(), _):
      case (_, _) when coreTypes.isTop(type1):
        return type1;
      case (_, DynamicType()):
      case (_, VoidType()):
      case (_, _) when coreTypes.isTop(type2):
        return type2;

      // UP(T1, T2) where BOTTOM(T1) and BOTTOM(T2) =
      //   T2 if MOREBOTTOM(T1, T2)
      //   T1 otherwise
      // UP(T1, T2) = T2 if BOTTOM(T1)
      // UP(T1, T2) = T1 if BOTTOM(T2)
      case (
          NeverType(nullability: Nullability.nonNullable),
          NeverType(nullability: Nullability.nonNullable)
        ):
      case (_, _) when coreTypes.isBottom(type1) && coreTypes.isBottom(type2):
        return morebottom(type1, type2) ? type2 : type1;
      case (NeverType(nullability: Nullability.nonNullable), _):
      case (_, _) when coreTypes.isBottom(type1):
        return type2;
      case (_, NeverType(nullability: Nullability.nonNullable)):
      case (_, _) when coreTypes.isBottom(type2):
        return type1;

      case (IntersectionType intersectionType1, _):
        return _getIntersectionStandardUpperBound(intersectionType1, type2);
      case (_, IntersectionType intersectionType2):
        return _getIntersectionStandardUpperBound(intersectionType2, type1);

      // UP(T1, T2) where NULL(T1) and NULL(T2) =
      //   T2 if MOREBOTTOM(T1, T2)
      //   T1 otherwise
      // UP(T1, T2) where NULL(T1) =
      //   T2 if T2 is nullable
      //   T2? otherwise
      // UP(T1, T2) where NULL(T2) =
      //   T1 if T1 is nullable
      //   T1? otherwise
      case (NullType(), NullType()):
      case (
          NeverType(nullability: Nullability.nullable),
          NeverType(nullability: Nullability.nullable)
        ):
      case (_, _) when coreTypes.isNull(type1) && coreTypes.isNull(type2):
        return morebottom(type1, type2) ? type2 : type1;
      case (NullType(), _):
      case (NeverType(nullability: Nullability.nullable), _):
      case (_, _) when coreTypes.isNull(type1):
        return type2.withDeclaredNullability(Nullability.nullable);
      case (_, NullType()):
      case (_, NeverType(nullability: Nullability.nullable)):
      case (_, _) when coreTypes.isNull(type2):
        return type1.withDeclaredNullability(Nullability.nullable);

      // UP(T1, T2) where OBJECT(T1) and OBJECT(T2) =
      //   T1 if MORETOP(T1, T2)
      //   T2 otherwise
      // UP(T1, T2) where OBJECT(T1) =
      //   T1 if T2 is non-nullable
      //   T1? otherwise
      // UP(T1, T2) where OBJECT(T2) =
      //   T2 if T1 is non-nullable
      //   T2? otherwise
      case (_, _) when coreTypes.isObject(type1) && coreTypes.isObject(type2):
        return moretop(type1, type2) ? type1 : type2;
      case (_, _)
          when coreTypes.isObject(type1) &&
              type2.nullability == Nullability.nonNullable:
        return type1;
      case (_, _) when coreTypes.isObject(type1):
        return type1.withDeclaredNullability(Nullability.nullable);
      case (_, _)
          when coreTypes.isObject(type2) &&
              type1.nullability == Nullability.nonNullable:
        return type2;
      case (_, _) when coreTypes.isObject(type2):
        return type2.withDeclaredNullability(Nullability.nullable);

      // UP(T1*, T2*) = S* where S is UP(T1, T2)
      // UP(T1*, T2?) = S? where S is UP(T1, T2)
      // UP(T1?, T2*) = S? where S is UP(T1, T2)
      // UP(T1*, T2) = S* where S is UP(T1, T2)
      // UP(T1, T2*) = S* where S is UP(T1, T2)
      // UP(T1?, T2?) = S? where S is UP(T1, T2)
      // UP(T1?, T2) = S? where S is UP(T1, T2)
      // UP(T1, T2?) = S? where S is UP(T1, T2)
      case (_, _) when isNullableTypeConstructorApplication(type1):
      case (_, _) when isNullableTypeConstructorApplication(type2):
        return _getStandardUpperBound(
                computeTypeWithoutNullabilityMarker(type1),
                computeTypeWithoutNullabilityMarker(type2))
            .withDeclaredNullability(Nullability.nullable);

      case (TypeParameterType typeParameterType1, _):
        return _getTypeVariableStandardUpperBound(type1, type2,
            bound1: typeParameterType1.bound,
            nominalEliminationTarget: typeParameterType1.parameter);
      case (StructuralParameterType structuralParameterType1, _):
        return _getTypeVariableStandardUpperBound(type1, type2,
            bound1: structuralParameterType1.bound,
            structuralEliminationTarget: structuralParameterType1.parameter);
      case (_, TypeParameterType typeParameterType2):
        return _getTypeVariableStandardUpperBound(type2, type1,
            bound1: typeParameterType2.bound,
            nominalEliminationTarget: typeParameterType2.parameter);
      case (_, StructuralParameterType structuralParameterType2):
        return _getTypeVariableStandardUpperBound(type2, type1,
            bound1: structuralParameterType2.bound,
            structuralEliminationTarget: structuralParameterType2.parameter);

      case (FunctionType functionType1, FunctionType functionType2):
        return _getFunctionStandardUpperBound(functionType1, functionType2);
      case (FunctionType(), InterfaceType interfaceType2)
          when interfaceType2.classNode == coreTypes.functionClass:
        // UP(T Function<...>(...), Function) = Function
        return coreTypes.functionRawType(uniteNullabilities(
            type1.declaredNullability, type2.declaredNullability));
      case (FunctionType(), _):
        // UP(T Function<...>(...), T2) = UP(Object, T2)
        return _getStandardUpperBound(
            coreTypes.objectNonNullableRawType, type2);
      case (InterfaceType interfaceType1, FunctionType())
          when interfaceType1.classNode == coreTypes.functionClass:
        // UP(Function, T Function<...>(...)) = Function
        return coreTypes.functionRawType(uniteNullabilities(
            type1.declaredNullability, type2.declaredNullability));
      case (_, FunctionType()):
        // UP(T1, T Function<...>(...)) = UP(T1, Object)
        return _getStandardUpperBound(
            type1, coreTypes.objectNonNullableRawType);

      case (RecordType recordType1, RecordType recordType2):
        return _getRecordStandardUpperBound(recordType1, recordType2);
      case (RecordType(), InterfaceType interfaceType2)
          when interfaceType2.classNode == coreTypes.recordClass:
        // UP(Record(...), Record) = Record
        return coreTypes.recordRawType(uniteNullabilities(
            type1.declaredNullability, type2.declaredNullability));
      case (RecordType(), _):
        // UP(Record(...), T2) = UP(Object, T2)
        return _getStandardUpperBound(
            coreTypes.objectNonNullableRawType, type2);
      case (InterfaceType interfaceType1, RecordType())
          when interfaceType1.classNode == coreTypes.recordClass:
        // UP(Record, Record(...)) = Record
        return coreTypes.recordRawType(uniteNullabilities(
            type1.declaredNullability, type2.declaredNullability));
      case (_, RecordType()):
        // UP(T1, Record(...)) = UP(T1, Object)
        return _getStandardUpperBound(
            type1, coreTypes.objectNonNullableRawType);

      // UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
      // UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
      // UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
      // UP(T1, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
      // UP(FutureOr<T1>, T2) = FutureOr<T3> where T3 = UP(T1, T2)
      case (
          FutureOrType(typeArgument: DartType t1),
          FutureOrType(typeArgument: DartType t2)
        ):
      case (
            FutureOrType(typeArgument: DartType t1),
            InterfaceType(
              typeArguments: [DartType t2],
              classNode: Class classNode2
            )
          )
          when classNode2 == coreTypes.futureClass:
      case (FutureOrType(typeArgument: DartType t1), DartType t2):
      case (
            InterfaceType(
              typeArguments: [DartType t1],
              classNode: Class classNode1
            ),
            FutureOrType(typeArgument: DartType t2)
          )
          when classNode1 == coreTypes.futureClass:
      case (DartType t1, FutureOrType(typeArgument: DartType t2)):
        return new FutureOrType(
            getStandardUpperBound(t1, t2),
            uniteNullabilities(
                type1.declaredNullability, type2.declaredNullability));

      // We use the non-nullable variants of the two interfaces types to
      // determine T1 <: T2 without using the nullability of the outermost
      // type. The result uses [uniteNullabilities] to compute the resulting
      // type if the subtype relation is established.
      case (_, _)
          when isSubtypeOf(
              leastClosureForUpperBound(typeWithoutNullabilityMarker1),
              leastClosureForUpperBound(typeWithoutNullabilityMarker2)):
        // UP(T1, T2) = T2 if T1 <: T2
        //   Note that both types must be interface or extension types at this
        //   point.
        return type2.withDeclaredNullability(
            uniteNullabilities(type1.nullability, type2.nullability));
      case (_, _)
          when isSubtypeOf(
              leastClosureForUpperBound(typeWithoutNullabilityMarker2),
              leastClosureForUpperBound(typeWithoutNullabilityMarker1)):
        // UP(T1, T2) = T1 if T2 <: T1
        //   Note that both types must be interface or extension types at this
        //   point.
        return type1.withDeclaredNullability(uniteNullabilities(
            type1.declaredNullability, type2.declaredNullability));

      case (
          TypeDeclarationType typeDeclarationType1,
          TypeDeclarationType typeDeclarationType2
        ):
        if (typeDeclarationType1.typeDeclarationReference ==
            typeDeclarationType2.typeDeclarationReference) {
          // UP(C<T0, ..., Tn>, C<S0, ..., Sn>) = C<R0,..., Rn> where Ri is
          // UP(Ti, Si)

          TypeDeclaration typeDeclaration =
              typeDeclarationType1.typeDeclaration;
          List<TypeParameter> typeParameters = typeDeclaration.typeParameters;
          List<DartType> leftArguments = typeDeclarationType1.typeArguments;
          List<DartType> rightArguments = typeDeclarationType2.typeArguments;
          int n = typeParameters.length;
          List<DartType> typeArguments = new List<DartType>.of(leftArguments);
          for (int i = 0; i < n; ++i) {
            Variance variance = typeParameters[i].variance;
            if (variance == Variance.contravariant) {
              typeArguments[i] =
                  _getStandardLowerBound(leftArguments[i], rightArguments[i]);
            } else if (variance == Variance.invariant) {
              if (!areMutualSubtypes(leftArguments[i], rightArguments[i])) {
                return _getLegacyLeastUpperBound(
                    typeDeclarationType1, typeDeclarationType2);
              }
            } else {
              typeArguments[i] =
                  _getStandardUpperBound(leftArguments[i], rightArguments[i]);
            }
          }
          switch (typeDeclaration) {
            case Class():
              return new InterfaceType(
                  typeDeclaration,
                  uniteNullabilities(
                      type1.declaredNullability, type2.declaredNullability),
                  typeArguments);
            case ExtensionTypeDeclaration():
              return new ExtensionType(
                  typeDeclaration,
                  uniteNullabilities(
                      type1.declaredNullability, type2.declaredNullability),
                  typeArguments);
          }
        } else {
          // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
          //   = least upper bound of two interfaces as in Dart 1.
          return _getLegacyLeastUpperBound(
              typeDeclarationType1, typeDeclarationType2);
        }

      case (NeverType(nullability: Nullability.undetermined), _):
      case (_, NeverType(nullability: Nullability.undetermined)):
        throw new StateError("Unsupported nullability for NeverType: "
            "'${Nullability.undetermined}'.");

      case (AuxiliaryType(), _):
      case (_, AuxiliaryType()):
        throw new StateError("Unsupported type combination: "
            "getStandardUpperBoundInternal("
            "${type1.runtimeType}, ${type2.runtimeType}"
            ")");
    }
  }

  DartType _getLegacyLeastUpperBound(
      TypeDeclarationType type1, TypeDeclarationType type2) {
    if (type1 is InterfaceType && type2 is InterfaceType) {
      return hierarchy.getLegacyLeastUpperBound(type1, type2);
    } else if (type1 is ExtensionType || type2 is ExtensionType) {
      // This mimics the legacy least upper bound implementation for regular
      // classes, where the least upper bound is found as the single common
      // supertype with the highest class hierarchy depth.

      // TODO(johnniwinther): Move this computation to [ClassHierarchyBase] and
      // cache it there.
      // TODO(johnniwinther): Handle non-extension type supertypes.
      Map<ExtensionTypeDeclaration, int> extensionTypeDeclarationDepth = {};

      int computeExtensionTypeDeclarationDepth(
          ExtensionTypeDeclaration extensionTypeDeclaration,
          List<InterfaceType> superInterfaceType) {
        int? depth = extensionTypeDeclarationDepth[extensionTypeDeclaration];
        if (depth == null) {
          int maxDepth = 0;
          for (DartType implemented in extensionTypeDeclaration.implements) {
            if (implemented is ExtensionType) {
              int supertypeDepth = computeExtensionTypeDeclarationDepth(
                  implemented.extensionTypeDeclaration, superInterfaceType);
              if (supertypeDepth >= maxDepth) {
                maxDepth = supertypeDepth + 1;
              }
            } else if (implemented is InterfaceType) {
              superInterfaceType.add(implemented);
            }
          }
          depth = extensionTypeDeclarationDepth[extensionTypeDeclaration] =
              maxDepth;
        }
        return depth;
      }

      // TODO(johnniwinther): Handle non-extension type supertypes.
      void computeSuperTypes(ExtensionType type, List<ExtensionType> supertypes,
          List<InterfaceType> superInterfaceTypes) {
        computeExtensionTypeDeclarationDepth(
            type.extensionTypeDeclaration, superInterfaceTypes);
        supertypes.add(type);
        for (DartType implemented in type.extensionTypeDeclaration.implements) {
          if (implemented is ExtensionType) {
            ExtensionType supertype =
                hierarchy.getExtensionTypeAsInstanceOfExtensionTypeDeclaration(
                    type, implemented.extensionTypeDeclaration)!;
            computeSuperTypes(supertype, supertypes, superInterfaceTypes);
          }
        }
      }

      List<ExtensionType> supertypes1 = [];
      List<InterfaceType> superInterfaceTypes1 = [];
      if (type1 is ExtensionType) {
        computeSuperTypes(type1, supertypes1, superInterfaceTypes1);
      } else {
        type1 as InterfaceType;
        superInterfaceTypes1 = <InterfaceType>[type1];
      }
      List<ExtensionType> supertypes2 = [];
      List<InterfaceType> superInterfaceTypes2 = [];
      if (type2 is ExtensionType) {
        computeSuperTypes(type2, supertypes2, superInterfaceTypes2);
      } else {
        type2 as InterfaceType;
        superInterfaceTypes2 = <InterfaceType>[type2];
      }

      Set<ExtensionType> set = supertypes1.toSet()..retainAll(supertypes2);
      Map<int, List<ExtensionType>> commonSupertypesByDepth = {};
      for (ExtensionType type in set) {
        (commonSupertypesByDepth[extensionTypeDeclarationDepth[
                type.extensionTypeDeclaration]!] ??= [])
            .add(type);
      }
      int maxDepth = -1;
      ExtensionType? candidate;
      for (MapEntry<int, List<ExtensionType>> entry
          in commonSupertypesByDepth.entries) {
        if (entry.key > maxDepth && entry.value.length == 1) {
          maxDepth = entry.key;
          candidate = entry.value.single;
        }
      }
      if (candidate != null) {
        return candidate;
      }

      return hierarchy.getLegacyLeastUpperBoundFromSupertypeLists(
          type1, type2, superInterfaceTypes1, superInterfaceTypes2);
    }
    if (type1 is ExtensionType && type1.isPotentiallyNullable ||
        type2 is ExtensionType && type2.isPotentiallyNullable) {
      return coreTypes.objectNullableRawType;
    } else {
      return coreTypes.objectRawType(
          uniteNullabilities(type1.nullability, type2.nullability));
    }
  }

  /// Computes the nullability-aware lower bound of two function types.
  ///
  /// The algorithm is defined as follows:
  /// DOWN(
  ///   <X0 extends B00, ..., Xm extends B0m>(P00, ..., P0k) -> T0,
  ///   <X0 extends B10, ..., Xm extends B1m>(P10, ..., P1l) -> T1)
  /// =
  ///   <X0 extends B20, ..., Xm extends B2m>(P20, ..., P2q) -> R0
  /// if:
  ///   each B0i and B1i are equal types (syntactically),
  ///   q is max(k, l),
  ///   R0 is DOWN(T0, T1),
  ///   B2i is B0i,
  ///   P2i is UP(P0i, P1i) for i <= than min(k, l),
  ///   P2i is P0i for k < i <= q,
  ///   P2i is P1i for l < i <= q, and
  ///   P2i is optional if P0i or P1i is optional.
  ///
  /// DOWN(
  ///   <X0 extends B00, ..., Xm extends B0m>(P00, ..., P0k, Named0) -> T0,
  ///   <X0 extends B10, ..., Xm extends B1m>(P10, ..., P1k, Named1) -> T1)
  /// =
  ///   <X0 extends B20, ..., Xm extends B2m>(P20, ..., P2k, Named2) -> R0
  /// if:
  ///   each B0i and B1i are equal types (syntactically),
  ///   R0 is DOWN(T0, T1),
  ///   B2i is B0i,
  ///   P2i is UP(P0i, P1i),
  ///   Named2 contains R2i xi for each xi in both Named0 and Named1,
  ///     where R0i xi is in Named0,
  ///     where R1i xi is in Named1,
  ///     and R2i is UP(R0i, R1i),
  ///     and R2i xi is required if xi is required in both Named0 and Named1,
  ///   Named2 contains R0i xi for each xi in Named0 and not Named1,
  ///     where xi is optional in Named2,
  ///   Named2 contains R1i xi for each xi in Named1 and not Named0, and
  ///     where xi is optional in Named2.
  /// DOWN(T Function<...>(...), S Function<...>(...)) = Never otherwise.
  DartType _getFunctionStandardLowerBound(FunctionType f, FunctionType g) {
    bool haveNamed =
        f.namedParameters.isNotEmpty || g.namedParameters.isNotEmpty;
    bool haveOptionalPositional =
        f.requiredParameterCount < f.positionalParameters.length ||
            g.requiredParameterCount < g.positionalParameters.length;

    // The fallback result for whenever the following rule applies:
    //     DOWN(T Function<...>(...), S Function<...>(...)) = Never otherwise.
    final DartType fallbackResult = NeverType.fromNullability(
        intersectNullabilities(f.declaredNullability, g.declaredNullability));

    if (haveNamed && haveOptionalPositional) return fallbackResult;
    if (haveNamed &&
        f.positionalParameters.length != g.positionalParameters.length) {
      return fallbackResult;
    }

    int m = f.typeParameters.length;
    bool boundsMatch = false;
    if (g.typeParameters.length == m) {
      boundsMatch = true;
      if (m != 0) {
        List<DartType> fParametersAsArguments = [
          for (StructuralParameter parameter in f.typeParameters)
            new StructuralParameterType.withDefaultNullability(parameter)
        ];
        FunctionTypeInstantiator instantiator =
            FunctionTypeInstantiator.fromInstantiation(
                g, fParametersAsArguments);
        for (int i = 0; i < m && boundsMatch; ++i) {
          // TODO(cstefantsova): Figure out if a procedure for syntactic
          // equality should be used instead.
          if (!areMutualSubtypes(f.typeParameters[i].bound,
              instantiator.substitute(g.typeParameters[i].bound))) {
            boundsMatch = false;
          }
        }
        g = instantiator.substitute(g.withoutTypeParameters) as FunctionType;
      }
    }
    if (!boundsMatch) return fallbackResult;
    int maxPos =
        math.max(f.positionalParameters.length, g.positionalParameters.length);
    int minPos =
        math.min(f.positionalParameters.length, g.positionalParameters.length);

    List<StructuralParameter> typeParameters = f.typeParameters;

    List<DartType> positionalParameters =
        new List<DartType>.filled(maxPos, dummyDartType);
    for (int i = 0; i < minPos; ++i) {
      positionalParameters[i] = _getStandardUpperBound(
          f.positionalParameters[i], g.positionalParameters[i]);
    }
    for (int i = minPos; i < f.positionalParameters.length; ++i) {
      positionalParameters[i] = f.positionalParameters[i];
    }
    for (int i = minPos; i < g.positionalParameters.length; ++i) {
      positionalParameters[i] = g.positionalParameters[i];
    }

    List<NamedType> namedParameters = <NamedType>[];
    {
      // Assuming that the named parameters of both types are sorted
      // lexicographically.
      int i = 0;
      int j = 0;
      while (i < f.namedParameters.length && j < g.namedParameters.length) {
        NamedType named1 = f.namedParameters[i];
        NamedType named2 = g.namedParameters[j];
        int order = named1.name.compareTo(named2.name);
        NamedType named;
        if (order < 0) {
          named = new NamedType(named1.name, named1.type, isRequired: false);
          ++i;
        } else if (order > 0) {
          named = !named2.isRequired
              ? named2
              : new NamedType(named2.name, named2.type, isRequired: false);
          ++j;
        } else {
          named = new NamedType(
              named1.name, _getStandardUpperBound(named1.type, named2.type),
              isRequired: named1.isRequired && named2.isRequired);
          ++i;
          ++j;
        }
        namedParameters.add(named);
      }
      while (i < f.namedParameters.length) {
        NamedType named1 = f.namedParameters[i];
        namedParameters.add(!named1.isRequired
            ? named1
            : new NamedType(named1.name, named1.type, isRequired: false));
        ++i;
      }
      while (j < g.namedParameters.length) {
        NamedType named2 = g.namedParameters[j];
        namedParameters
            .add(new NamedType(named2.name, named2.type, isRequired: false));
        ++j;
      }
    }

    DartType returnType = _getStandardLowerBound(f.returnType, g.returnType);

    return new FunctionType(positionalParameters, returnType,
        intersectNullabilities(f.declaredNullability, g.declaredNullability),
        namedParameters: namedParameters,
        typeParameters: typeParameters,
        requiredParameterCount:
            math.min(f.requiredParameterCount, g.requiredParameterCount));
  }

  /// Computes the nullability-aware lower bound of two record types.
  ///
  /// The algorithm is defined as follows:
  /// DOWN((P00, ..., P0k, Named0), (P10, ..., P1k, Named1)) =
  ///   (P20, ..., P2k, Named2)
  /// if:
  ///   P2i is DOWN(P0i, P1i),
  ///   Named0 contains R0i xi
  ///       if Named1 contains R1i xi
  ///   Named1 contains R1i xi
  ///       if Named0 contains R0i xi
  ///   Named2 contains exactly R2i xi
  ///       for each xi in both Named0 and Named1
  ///     where R0i xi is in Named0
  ///     where R1i xi is in Named1
  ///     and R2i is UP(R0i, R1i)
  /// DOWN(Record(...), Record(...)) = Never otherwise.
  DartType _getRecordStandardLowerBound(RecordType r1, RecordType r2) {
    // The fallback result for whenever the following rule applies:
    //     DOWN(Record(...), Record(...)) = Never otherwise.
    late final DartType fallbackResult = NeverType.fromNullability(
        intersectNullabilities(r1.declaredNullability, r2.declaredNullability));

    if (r1.positional.length != r2.positional.length ||
        r1.named.length != r2.named.length) {
      return fallbackResult;
    }

    int positionalLength = r1.positional.length;
    int namedLength = r1.named.length;

    for (int i = 0; i < namedLength; i++) {
      if (r1.named[i].name != r2.named[i].name) {
        return fallbackResult;
      }
    }

    List<DartType> positional = new List<DartType>.generate(positionalLength,
        (i) => _getStandardLowerBound(r1.positional[i], r2.positional[i]));

    List<NamedType> named = new List<NamedType>.generate(
        namedLength,
        (i) => new NamedType(r1.named[i].name,
            _getStandardLowerBound(r1.named[i].type, r2.named[i].type)));

    return new RecordType(positional, named,
        intersectNullabilities(r1.declaredNullability, r2.declaredNullability));
  }

  /// Computes the nullability-aware lower bound of two function types.
  ///
  /// UP(
  ///   <X0 extends B00, ... Xm extends B0m>(P00, ... P0k) -> T0,
  ///   <X0 extends B10, ... Xm extends B1m>(P10, ... P1l) -> T1)
  /// =
  ///   <X0 extends B20, ..., Xm extends B2m>(P20, ..., P2q) -> R0
  /// if:
  ///   each B0i and B1i are equal types (syntactically)
  ///   Both have the same number of required positional parameters
  ///   q is min(k, l)
  ///   R0 is UP(T0, T1)
  ///   B2i is B0i
  ///   P2i is DOWN(P0i, P1i)
  /// UP(
  ///   <X0 extends B00, ... Xm extends B0m>(P00, ... P0k, Named0) -> T0,
  ///   <X0 extends B10, ... Xm extends B1m>(P10, ... P1k, Named1) -> T1)
  /// =
  ///   <X0 extends B20, ..., Xm extends B2m>(P20, ..., P2k, Named2) -> R0
  /// if:
  ///   each B0i and B1i are equal types (syntactically)
  ///   All positional parameters are required
  ///   R0 is UP(T0, T1)
  ///   B2i is B0i
  ///   P2i is DOWN(P0i, P1i)
  ///   Named0 contains R0i xi
  ///       if R1i xi is a required named parameter in Named1
  ///   Named1 contains R1i xi
  ///       if R0i xi is a required named parameter in Named0
  ///   Named2 contains exactly R2i xi
  ///       for each xi in both Named0 and Named1
  ///     where R0i xi is in Named0
  ///     where R1i xi is in Named1
  ///     and R2i is DOWN(R0i, R1i)
  ///     and R2i xi is required
  ///         if xi is required in either Named0 or Named1
  /// UP(T Function<...>(...), S Function<...>(...)) = Function otherwise
  DartType _getFunctionStandardUpperBound(FunctionType f, FunctionType g) {
    bool haveNamed =
        f.namedParameters.isNotEmpty || g.namedParameters.isNotEmpty;
    bool haveOptionalPositional =
        f.requiredParameterCount < f.positionalParameters.length ||
            g.requiredParameterCount < g.positionalParameters.length;

    // The return value for whenever the following applies:
    //     UP(T Function<...>(...), S Function<...>(...)) = Function otherwise
    final DartType fallbackResult = coreTypes.functionRawType(
        uniteNullabilities(f.declaredNullability, g.declaredNullability));

    if (haveNamed && haveOptionalPositional) return fallbackResult;
    if (!haveNamed && f.requiredParameterCount != g.requiredParameterCount) {
      return fallbackResult;
    }
    // Here we perform a quick check on the function types to figure out if we
    // can compute a non-trivial upper bound for them.  The check isn't merged
    // with the computation of the non-trivial upper bound itself to avoid
    // performing unnecessary computations.
    if (haveNamed) {
      if (f.positionalParameters.length != g.positionalParameters.length) {
        return fallbackResult;
      }
      // Assuming that the named parameters are sorted lexicographically in
      // both type1 and type2.
      int i = 0;
      int j = 0;
      while (i < f.namedParameters.length && j < g.namedParameters.length) {
        NamedType named1 = f.namedParameters[i];
        NamedType named2 = g.namedParameters[j];
        int order = named1.name.compareTo(named2.name);
        if (order < 0) {
          if (named1.isRequired) return fallbackResult;
          ++i;
        } else if (order > 0) {
          if (named2.isRequired) return fallbackResult;
          ++j;
        } else {
          ++i;
          ++j;
        }
      }
      while (i < f.namedParameters.length) {
        if (f.namedParameters[i].isRequired) return fallbackResult;
        ++i;
      }
      while (j < g.namedParameters.length) {
        if (g.namedParameters[j].isRequired) return fallbackResult;
        ++j;
      }
    }

    int m = f.typeParameters.length;
    bool boundsMatch = false;
    FunctionTypeInstantiator? instantiator;
    if (g.typeParameters.length == m) {
      boundsMatch = true;
      if (m != 0) {
        List<DartType> fTypeParametersAsTypes = [
          for (StructuralParameter parameter in f.typeParameters)
            new StructuralParameterType.withDefaultNullability(parameter)
        ];
        instantiator = FunctionTypeInstantiator.fromIterables(
            g.typeParameters, fTypeParametersAsTypes);
        for (int i = 0; i < m && boundsMatch; ++i) {
          // TODO(cstefantsova): Figure out if a procedure for syntactic
          // equality should be used instead.
          if (!areMutualSubtypes(f.typeParameters[i].bound,
              instantiator.substitute(g.typeParameters[i].bound))) {
            boundsMatch = false;
          }
        }
      }
    }
    if (!boundsMatch) return fallbackResult;
    int minPos =
        math.min(f.positionalParameters.length, g.positionalParameters.length);

    List<StructuralParameter> typeParameters = f.typeParameters;

    List<DartType> positionalParameters =
        new List<DartType>.filled(minPos, dummyDartType);
    for (int i = 0; i < minPos; ++i) {
      positionalParameters[i] = _getStandardLowerBound(
          f.positionalParameters[i],
          instantiator != null
              ? instantiator.substitute(g.positionalParameters[i])
              : g.positionalParameters[i]);
    }

    List<NamedType> namedParameters = <NamedType>[];
    {
      // Assuming that the named parameters of both types are sorted
      // lexicographically.
      int i = 0;
      int j = 0;
      while (i < f.namedParameters.length && j < g.namedParameters.length) {
        NamedType named1 = f.namedParameters[i];
        NamedType named2 = g.namedParameters[j];
        int order = named1.name.compareTo(named2.name);
        if (order < 0) {
          ++i;
        } else if (order > 0) {
          ++j;
        } else {
          namedParameters.add(new NamedType(
              named1.name,
              _getStandardLowerBound(
                  named1.type,
                  instantiator != null
                      ? instantiator.substitute(named2.type)
                      : named2.type),
              isRequired: named1.isRequired || named2.isRequired));
          ++i;
          ++j;
        }
      }
    }

    DartType returnType = _getStandardUpperBound(
        f.returnType,
        instantiator != null
            ? instantiator.substitute(g.returnType)
            : g.returnType);

    return new FunctionType(positionalParameters, returnType,
        uniteNullabilities(f.declaredNullability, g.declaredNullability),
        namedParameters: namedParameters,
        typeParameters: typeParameters,
        requiredParameterCount: f.requiredParameterCount);
  }

  /// Computes the nullability-aware lower bound of two record types.
  ///
  /// UP((P00, ... P0k, Named0), (P10, ... P1k, Named1)) =
  ///   (P20, ..., P2k, Named2)
  /// if:
  ///   P2i is UP(P0i, P1i)
  ///   Named0 contains R0i xi
  ///       if Named1 contains R1i xi
  ///   Named1 contains R1i xi
  ///       if Named0 contains R0i xi
  ///   Named2 contains exactly R2i xi
  ///       for each xi in both Named0 and Named1
  ///     where R0i xi is in Named0
  ///     where R1i xi is in Named1
  ///     and R2i is UP(R0i, R1i)
  /// UP(Record(...), Record(...)) = Record otherwise
  DartType _getRecordStandardUpperBound(RecordType r1, RecordType r2) {
    // The return value for whenever the following applies:
    //     UP(Record(...), Record(...)) = Record otherwise
    late final DartType fallbackResult = coreTypes.recordRawType(
        uniteNullabilities(r1.declaredNullability, r2.declaredNullability));

    // Here we perform a quick check on the function types to figure out if we
    // can compute a non-trivial upper bound for them.
    if (r1.positional.length != r2.positional.length ||
        r1.named.length != r2.named.length) {
      return fallbackResult;
    }

    int positionalLength = r1.positional.length;
    int namedLength = r1.named.length;

    for (int i = 0; i < namedLength; i++) {
      // The named parameters of record types are assumed to be sorted
      // lexicographically.
      if (r1.named[i].name != r2.named[i].name) {
        return fallbackResult;
      }
    }

    List<DartType> positional = new List<DartType>.generate(positionalLength,
        (i) => _getStandardUpperBound(r1.positional[i], r2.positional[i]));

    List<NamedType> named = new List<NamedType>.generate(
        namedLength,
        (i) => new NamedType(r1.named[i].name,
            _getStandardUpperBound(r1.named[i].type, r2.named[i].type)));

    return new RecordType(positional, named,
        uniteNullabilities(r1.declaredNullability, r2.declaredNullability));
  }

  DartType _getTypeVariableStandardUpperBound(DartType type1, DartType type2,
      {required DartType bound1,
      TypeParameter? nominalEliminationTarget,
      StructuralParameter? structuralEliminationTarget}) {
    assert(type1 is TypeParameterType || type1 is StructuralParameterType);
    assert(nominalEliminationTarget != null &&
            structuralEliminationTarget == null ||
        nominalEliminationTarget == null &&
            structuralEliminationTarget != null);

    // UP(X1 extends B1, T2) =
    //   T2 if X1 <: T2
    //   otherwise X1 if T2 <: X1
    //   otherwise UP(B1a, T2)
    //     where B1a is the greatest closure of B1 with respect to X1,
    //     as defined in [inference.md].

    if (isSubtypeOf(
        leastClosureForUpperBound(type1), leastClosureForUpperBound(type2))) {
      return type2.withDeclaredNullability(combineNullabilitiesForSubstitution(
          inner: type2.nullability,
          outer: uniteNullabilities(
              type1.declaredNullability, type2.nullability)));
    }
    if (isSubtypeOf(
        leastClosureForUpperBound(type2), leastClosureForUpperBound(type1))) {
      return type1.withDeclaredNullability(combineNullabilitiesForSubstitution(
          inner: type1.declaredNullability,
          outer: uniteNullabilities(
              type1.declaredNullability, type2.nullability)));
    }
    TypeParameterEliminator eliminator = new TypeParameterEliminator(
        structuralEliminationTargets: {
          if (structuralEliminationTarget != null) structuralEliminationTarget
        },
        nominalEliminationTargets: {
          if (nominalEliminationTarget != null) nominalEliminationTarget
        },
        coreTypes: coreTypes,
        unhandledTypeHandler: (type, recursor) => false);
    DartType result =
        _getStandardUpperBound(eliminator.eliminateToGreatest(bound1), type2);
    return result.withDeclaredNullability(combineNullabilitiesForSubstitution(
        inner: result.declaredNullability,
        outer:
            uniteNullabilities(bound1.declaredNullability, type2.nullability)));
  }

  DartType _getIntersectionStandardUpperBound(
      IntersectionType type1, DartType type2) {
    // UP(X1 & B1, T2) =
    //   T2 if X1 <: T2
    //   otherwise X1 if T2 <: X1
    //   otherwise UP(B1a, T2)
    //     where B1a is the greatest closure of B1 with respect to X1,
    //     as defined in [inference.md].
    DartType demoted = type1.left;
    if (isSubtypeOf(
        leastClosureForUpperBound(demoted), leastClosureForUpperBound(type2))) {
      return type2.withDeclaredNullability(uniteNullabilities(
          type1.declaredNullability, type2.declaredNullability));
    }
    if (isSubtypeOf(
        leastClosureForUpperBound(type2), leastClosureForUpperBound(demoted))) {
      return demoted.withDeclaredNullability(uniteNullabilities(
          demoted.declaredNullability, type2.declaredNullability));
    }
    TypeParameterEliminator eliminator = new TypeParameterEliminator(
        structuralEliminationTargets: {},
        nominalEliminationTargets: {type1.left.parameter},
        coreTypes: coreTypes,
        unhandledTypeHandler: (type, recursor) => false);
    Nullability resultingNullability =
        uniteNullabilities(type1.right.declaredNullability, type2.nullability);

    // If the resulting nullability is [Nullability.undetermined], one of the
    // types can be nullable at run time. The upper bound is supposed to be a
    // supertype to both of the types under all conditions, so we interpret the
    // undetermined case as [Nullability.nullable].
    resultingNullability = resultingNullability == Nullability.undetermined
        ? Nullability.nullable
        : resultingNullability;

    return _getStandardUpperBound(
            eliminator.eliminateToGreatest(type1.right), type2)
        .withDeclaredNullability(resultingNullability);
  }

  /// Compute the greatest closure of [typeSchema] for subtyping in DOWN.
  ///
  /// > We add the axiom that DOWN(T, _) == T and the symmetric version.
  /// > We replace all uses of T1 <: T2 in the DOWN algorithm by S1 <: S2 where
  /// >   Si is the greatest closure of Ti with respect to _.
  ///
  /// The specification of using the greatest closure in DOWN can be found at
  /// https://github.com/dart-lang/language/blob/main/resources/type-system/inference.md#upper-bound
  DartType greatestClosureForLowerBound(DartType typeSchema) => typeSchema;

  /// Compute the least closure of [typeSchema] for subtyping in UP.
  ///
  /// Taking closures of type schemas in UP is specified as follows:
  ///
  /// > We add the axiom that UP(T, _) == T and the symmetric version.
  /// > We replace all uses of T1 <: T2 in the UP algorithm by S1 <: S2 where Si
  /// >   is the least closure of Ti with respect to _.
  ///
  /// The specification of using the least closure in UP can be found at
  /// https://github.com/dart-lang/language/blob/main/resources/type-system/inference.md#upper-bound
  DartType leastClosureForUpperBound(DartType typeSchema) => typeSchema;
}
