Repository: apple/swift
File: lib/Sema/CSOptimizer.cpp (C++)

Code before:
    if (auto *disjunction = selectDisjunctionWithHacks())
      return std::make_pair(disjunction, llvm::TinyPtrVector<Constraint *>());
    return std::nullopt;
  }

  SmallVector<Constraint *, 4> disjunctions;

  collectDisjunctions(disjunctions);
  if (disjunctions.empty())
    return std::nullopt;

  llvm::DenseMap<Constraint *, DisjunctionInfo> favorings;
  determineBestChoicesInContext(*this, disjunctions, favorings);

  // Pick the disjunction with the smallest number of favored, then active
  // choices.
  auto bestDisjunction = std::min_element(
      disjunctions.begin(), disjunctions.end(),
      [&](Constraint *first, Constraint *second) -> bool {
        unsigned firstActive = first->countActiveNestedConstraints();
        unsigned secondActive = second->countActiveNestedConstraints();

        if (firstActive == 1 || secondActive == 1)
          return secondActive != 1;

        if (auto preference = isPreferable(*this, first, second))
          return preference.value();

        auto &[firstScore, firstFavoredChoices, isFirstSpeculative] =
            favorings[first];
        auto &[secondScore, secondFavoredChoices, isSecondSpeculative] =
            favorings[second];

        bool isFirstOperator = isOperatorDisjunction(first);
        bool isSecondOperator = isOperatorDisjunction(second);

        // Infix logical operators are usually not overloaded and don't
        // form disjunctions, but when they do, let's prefer them over
        // other operators when they have fewer choices because it helps
        // to split operator chains.
        if (isFirstOperator && isSecondOperator) {
          if (isStandardInfixLogicalOperator(first) !=
              isStandardInfixLogicalOperator(second))
            return firstActive < secondActive;
        }

        // Not all of the non-operator disjunctions are supported by the
        // ranking algorithm, so to prevent eager selection of operators
        // when nothing concrete is known about them, let's reset the score
        // and compare purely based on number of choices.
        if (isFirstOperator != isSecondOperator) {

Review comment (suggestion):
@slavapestov out of curiosity: i thought there was some frontend/driver setting to try and catch nondeterminism that would like compile twice and compare the outputs – would that have caught this? (assuming i'm not hallucinating...)

Code after:
    if (auto *disjunction = selectDisjunctionWithHacks())
      return std::make_pair(disjunction, llvm::TinyPtrVector<Constraint *>());
    return std::nullopt;
  }

  SmallVector<Constraint *, 4> disjunctions;

  collectDisjunctions(disjunctions);
  if (disjunctions.empty())
    return std::nullopt;

  llvm::DenseMap<Constraint *, DisjunctionInfo> favorings;
  determineBestChoicesInContext(*this, disjunctions, favorings);

  // Pick the disjunction with the smallest number of favored, then active
  // choices.
  auto bestDisjunction = std::min_element(
      disjunctions.begin(), disjunctions.end(),
      [&](Constraint *first, Constraint *second) -> bool {
        unsigned firstActive = first->countActiveNestedConstraints();
        unsigned secondActive = second->countActiveNestedConstraints();

        if (firstActive == 1 || secondActive == 1)
          return secondActive != 1;

        if (auto preference = isPreferable(*this, first, second))
          return preference.value();

        const auto &firstFavorings = favorings[first];
        const auto &secondFavorings = favorings[second];

        auto firstScore = firstFavorings.Score;
        auto secondScore = secondFavorings.Score;

        bool isFirstOperator = isOperatorDisjunction(first);
        bool isSecondOperator = isOperatorDisjunction(second);

        // Infix logical operators are usually not overloaded and don't
        // form disjunctions, but when they do, let's prefer them over
        // other operators when they have fewer choices because it helps
        // to split operator chains.
        if (isFirstOperator && isSecondOperator) {
          if (isStandardInfixLogicalOperator(first) !=
              isStandardInfixLogicalOperator(second))
            return firstActive < secondActive;
        }

        // Not all of the non-operator disjunctions are supported by the
        // ranking algorithm, so to prevent eager selection of operators
        // when nothing concrete is known about them, let's reset the score
        // and compare purely based on number of choices.