@@ -1929,30 +1929,6 @@ Constraint *ConstraintSystem::getUnboundBindOverloadDisjunction(
19291929 return result->first ;
19301930}
19311931
1932- // Find a disjunction associated with an ApplicableFunction constraint
1933- // where we have some information about all of the types of in the
1934- // function application (even if we only know something about what the
1935- // types conform to and not actually a concrete type).
1936- Constraint *ConstraintSystem::selectApplyDisjunction () {
1937- for (auto &constraint : InactiveConstraints) {
1938- if (constraint.getKind () != ConstraintKind::ApplicableFunction)
1939- continue ;
1940-
1941- auto *applicable = &constraint;
1942- if (haveTypeInformationForAllArguments (
1943- applicable->getFirstType ()->castTo <FunctionType>())) {
1944- auto *tyvar = applicable->getSecondType ()->castTo <TypeVariableType>();
1945-
1946- // If we have created the disjunction for this apply, find it.
1947- auto *disjunction = getUnboundBindOverloadDisjunction (tyvar);
1948- if (disjunction)
1949- return disjunction;
1950- }
1951- }
1952-
1953- return nullptr ;
1954- }
1955-
19561932static bool isOperatorBindOverload (Constraint *bindOverload) {
19571933 if (bindOverload->getKind () != ConstraintKind::BindOverload)
19581934 return false ;
@@ -1965,165 +1941,6 @@ static bool isOperatorBindOverload(Constraint *bindOverload) {
19651941 return funcDecl && funcDecl->getOperatorDecl ();
19661942}
19671943
1968- // Given a bind overload constraint for an operator, return the
1969- // protocol designated as the first place to look for overloads of the
1970- // operator.
1971- static ArrayRef<NominalTypeDecl *>
1972- getOperatorDesignatedNominalTypes (Constraint *bindOverload) {
1973- auto choice = bindOverload->getOverloadChoice ();
1974- auto *funcDecl = cast<FuncDecl>(choice.getDecl ());
1975- auto *operatorDecl = funcDecl->getOperatorDecl ();
1976- return operatorDecl->getDesignatedNominalTypes ();
1977- }
1978-
1979- void ConstraintSystem::sortDesignatedTypes (
1980- SmallVectorImpl<NominalTypeDecl *> &nominalTypes,
1981- Constraint *bindOverload) {
1982- auto *tyvar = bindOverload->getFirstType ()->castTo <TypeVariableType>();
1983- auto applicableFns = getConstraintGraph ().gatherConstraints (
1984- tyvar, ConstraintGraph::GatheringKind::EquivalenceClass,
1985- [](Constraint *match) {
1986- return match->getKind () == ConstraintKind::ApplicableFunction;
1987- });
1988-
1989- // FIXME: This is not true when we run the constraint optimizer.
1990- // assert(applicableFns.size() <= 1);
1991-
1992- // We have a disjunction for an operator but no application of it,
1993- // so it's being passed as an argument.
1994- if (applicableFns.size () == 0 )
1995- return ;
1996-
1997- // FIXME: We have more than one applicable per disjunction as a
1998- // result of merging disjunction type variables. We may want
1999- // to rip that out at some point.
2000- Constraint *foundApplicable = nullptr ;
2001- SmallVector<Optional<Type>, 2 > argumentTypes;
2002- for (auto *applicableFn : applicableFns) {
2003- argumentTypes.clear ();
2004- auto *fnTy = applicableFn->getFirstType ()->castTo <FunctionType>();
2005- ArgumentInfoCollector argInfo (*this , fnTy);
2006- // Stop if we hit anything with concrete types or conformances to
2007- // literals.
2008- if (!argInfo.getTypes ().empty () || !argInfo.getLiteralProtocols ().empty ()) {
2009- foundApplicable = applicableFn;
2010- break ;
2011- }
2012- }
2013-
2014- if (!foundApplicable)
2015- return ;
2016-
2017- // FIXME: It would be good to avoid this redundancy.
2018- auto *fnTy = foundApplicable->getFirstType ()->castTo <FunctionType>();
2019- ArgumentInfoCollector argInfo (*this , fnTy);
2020-
2021- size_t nextType = 0 ;
2022- for (auto argType : argInfo.getTypes ()) {
2023- auto *nominal = argType->getAnyNominal ();
2024- for (size_t i = nextType; i < nominalTypes.size (); ++i) {
2025- if (nominal == nominalTypes[i]) {
2026- std::swap (nominalTypes[nextType], nominalTypes[i]);
2027- ++nextType;
2028- break ;
2029- } else if (auto *protoDecl = dyn_cast<ProtocolDecl>(nominalTypes[i])) {
2030- if (TypeChecker::conformsToProtocol (argType, protoDecl, DC)) {
2031- std::swap (nominalTypes[nextType], nominalTypes[i]);
2032- ++nextType;
2033- break ;
2034- }
2035- }
2036- }
2037- }
2038-
2039- if (nextType + 1 >= nominalTypes.size ())
2040- return ;
2041-
2042- for (auto *protocol : argInfo.getLiteralProtocols ()) {
2043- auto defaultType = TypeChecker::getDefaultType (protocol, DC);
2044- // ExpressibleByNilLiteral does not have a default type.
2045- if (!defaultType)
2046- continue ;
2047- auto *nominal = defaultType->getAnyNominal ();
2048- for (size_t i = nextType + 1 ; i < nominalTypes.size (); ++i) {
2049- if (nominal == nominalTypes[i]) {
2050- std::swap (nominalTypes[nextType], nominalTypes[i]);
2051- ++nextType;
2052- break ;
2053- }
2054- }
2055- }
2056- }
2057-
2058- void ConstraintSystem::partitionForDesignatedTypes (
2059- ArrayRef<Constraint *> Choices, ConstraintMatchLoop forEachChoice,
2060- PartitionAppendCallback appendPartition) {
2061-
2062- auto types = getOperatorDesignatedNominalTypes (Choices[0 ]);
2063- if (types.empty ())
2064- return ;
2065-
2066- SmallVector<NominalTypeDecl *, 4 > designatedNominalTypes (types.begin (),
2067- types.end ());
2068-
2069- if (designatedNominalTypes.size () > 1 )
2070- sortDesignatedTypes (designatedNominalTypes, Choices[0 ]);
2071-
2072- SmallVector<SmallVector<unsigned , 4 >, 4 > definedInDesignatedType;
2073- SmallVector<SmallVector<unsigned , 4 >, 4 > definedInExtensionOfDesignatedType;
2074-
2075- auto examineConstraint =
2076- [&](unsigned constraintIndex, Constraint *constraint) -> bool {
2077- auto *decl = constraint->getOverloadChoice ().getDecl ();
2078- auto *funcDecl = cast<FuncDecl>(decl);
2079-
2080- auto *parentDC = funcDecl->getParent ();
2081- auto *parentDecl = parentDC->getSelfNominalTypeDecl ();
2082-
2083- // Skip anything not defined in a nominal type.
2084- if (!parentDecl)
2085- return false ;
2086-
2087- for (auto designatedTypeIndex : indices (designatedNominalTypes)) {
2088- auto *designatedNominal =
2089- designatedNominalTypes[designatedTypeIndex];
2090-
2091- if (parentDecl != designatedNominal)
2092- continue ;
2093-
2094- auto &constraints =
2095- isa<ExtensionDecl>(parentDC)
2096- ? definedInExtensionOfDesignatedType[designatedTypeIndex]
2097- : definedInDesignatedType[designatedTypeIndex];
2098-
2099- constraints.push_back (constraintIndex);
2100- return true ;
2101- }
2102-
2103- return false ;
2104- };
2105-
2106- definedInDesignatedType.resize (designatedNominalTypes.size ());
2107- definedInExtensionOfDesignatedType.resize (designatedNominalTypes.size ());
2108-
2109- forEachChoice (Choices, examineConstraint);
2110-
2111- // Now collect the overload choices that are defined within the type
2112- // that was designated in the operator declaration.
2113- // Add partitions for each of the overloads we found in types that
2114- // were designated as part of the operator declaration.
2115- for (auto designatedTypeIndex : indices (designatedNominalTypes)) {
2116- if (designatedTypeIndex < definedInDesignatedType.size ()) {
2117- auto &primary = definedInDesignatedType[designatedTypeIndex];
2118- appendPartition (primary);
2119- }
2120- if (designatedTypeIndex < definedInExtensionOfDesignatedType.size ()) {
2121- auto &secondary = definedInExtensionOfDesignatedType[designatedTypeIndex];
2122- appendPartition (secondary);
2123- }
2124- }
2125- }
2126-
21271944// Performance hack: if there are two generic overloads, and one is
21281945// more specialized than the other, prefer the more-specialized one.
21291946static Constraint *tryOptimizeGenericDisjunction (
@@ -2266,8 +2083,7 @@ void ConstraintSystem::partitionDisjunction(
22662083 }
22672084
22682085 // Partition SIMD operators.
2269- if (!getASTContext ().TypeCheckerOpts .SolverEnableOperatorDesignatedTypes &&
2270- isOperatorBindOverload (Choices[0 ])) {
2086+ if (isOperatorBindOverload (Choices[0 ])) {
22712087 forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
22722088 if (!isOperatorBindOverload (constraint))
22732089 return false ;
@@ -2291,11 +2107,6 @@ void ConstraintSystem::partitionDisjunction(
22912107 }
22922108 };
22932109
2294- if (getASTContext ().TypeCheckerOpts .SolverEnableOperatorDesignatedTypes &&
2295- isOperatorBindOverload (Choices[0 ])) {
2296- partitionForDesignatedTypes (Choices, forEachChoice, appendPartition);
2297- }
2298-
22992110 SmallVector<unsigned , 4 > everythingElse;
23002111 // Gather the remaining options.
23012112 forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
@@ -2320,17 +2131,6 @@ Constraint *ConstraintSystem::selectDisjunction() {
23202131 if (disjunctions.empty ())
23212132 return nullptr ;
23222133
2323- // Attempt apply disjunctions first. When we have operators with
2324- // designated types, this is important, because it allows us to
2325- // select all the preferred operator overloads prior to other
2326- // disjunctions that we may not be able to short-circuit, allowing
2327- // us to eliminate behavior that is exponential in the number of
2328- // operators in the expression.
2329- if (getASTContext ().TypeCheckerOpts .SolverEnableOperatorDesignatedTypes ) {
2330- if (auto *disjunction = selectApplyDisjunction ())
2331- return disjunction;
2332- }
2333-
23342134 if (auto *disjunction = selectBestBindingDisjunction (*this , disjunctions))
23352135 return disjunction;
23362136
0 commit comments