Skip to content

Commit 3d6c93f

Browse files
authored
Merge pull request #19909 from rudkx/extend-operator-designated-type
[ConstraintSystem] Extend solver support for designated types for ope…
2 parents b259271 + b158651 commit 3d6c93f

File tree

3 files changed

+58
-34
lines changed

3 files changed

+58
-34
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,13 +1672,12 @@ static bool isOperatorBindOverload(Constraint *bindOverload) {
16721672
// Given a bind overload constraint for an operator, return the
16731673
// protocol designated as the first place to look for overloads of the
16741674
// operator.
1675-
static NominalTypeDecl *
1676-
getOperatorDesignatedNominalType(Constraint *bindOverload) {
1675+
static ArrayRef<NominalTypeDecl *>
1676+
getOperatorDesignatedNominalTypes(Constraint *bindOverload) {
16771677
auto choice = bindOverload->getOverloadChoice();
16781678
auto *funcDecl = cast<FuncDecl>(choice.getDecl());
16791679
auto *operatorDecl = funcDecl->getOperatorDecl();
1680-
auto designatedTypes = operatorDecl->getDesignatedNominalTypes();
1681-
return !designatedTypes.empty() ? designatedTypes[0] : nullptr;
1680+
return operatorDecl->getDesignatedNominalTypes();
16821681
}
16831682

16841683
void ConstraintSystem::partitionDisjunction(
@@ -1703,8 +1702,8 @@ void ConstraintSystem::partitionDisjunction(
17031702
SmallVector<unsigned, 4> disabled;
17041703
SmallVector<unsigned, 4> unavailable;
17051704
SmallVector<unsigned, 4> globalScope;
1706-
SmallVector<unsigned, 4> definedInDesignatedType;
1707-
SmallVector<unsigned, 4> definedInExtensionOfDesignatedType;
1705+
SmallVector<SmallVector<unsigned, 4>, 4> definedInDesignatedType;
1706+
SmallVector<SmallVector<unsigned, 4>, 4> definedInExtensionOfDesignatedType;
17081707
SmallVector<unsigned, 4> everythingElse;
17091708
SmallSet<Constraint *, 16> taken;
17101709

@@ -1765,28 +1764,43 @@ void ConstraintSystem::partitionDisjunction(
17651764

17661765
// Now collect the overload choices that are defined within the type
17671766
// that was designated in the operator declaration.
1768-
auto *designatedNominal = getOperatorDesignatedNominalType(Choices[0]);
1769-
if (designatedNominal) {
1770-
forEachChoice(Choices, [&](unsigned index, Constraint *constraint) -> bool {
1771-
auto *decl = constraint->getOverloadChoice().getDecl();
1772-
auto *funcDecl = cast<FuncDecl>(decl);
1773-
1774-
auto *parentDecl = funcDecl->getParent()->getAsDecl();
1775-
if (parentDecl == designatedNominal) {
1776-
definedInDesignatedType.push_back(index);
1777-
return true;
1778-
}
1767+
auto designatedNominalTypes = getOperatorDesignatedNominalTypes(Choices[0]);
1768+
if (!designatedNominalTypes.empty()) {
1769+
forEachChoice(
1770+
Choices, [&](unsigned constraintIndex, Constraint *constraint) -> bool {
1771+
auto *decl = constraint->getOverloadChoice().getDecl();
1772+
auto *funcDecl = cast<FuncDecl>(decl);
1773+
1774+
auto *parentDecl = funcDecl->getParent()->getAsDecl();
1775+
for (auto designatedTypeIndex : indices(designatedNominalTypes)) {
1776+
auto *designatedNominal =
1777+
designatedNominalTypes[designatedTypeIndex];
1778+
if (parentDecl == designatedNominal) {
1779+
if (designatedTypeIndex >= definedInDesignatedType.size())
1780+
definedInDesignatedType.resize(designatedTypeIndex + 1);
1781+
auto &constraints = definedInDesignatedType[designatedTypeIndex];
1782+
constraints.push_back(constraintIndex);
1783+
return true;
1784+
}
17791785

1780-
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(parentDecl)) {
1781-
parentDecl = extensionDecl->getExtendedNominal();
1782-
if (parentDecl == designatedNominal) {
1783-
definedInExtensionOfDesignatedType.push_back(index);
1784-
return true;
1786+
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(parentDecl)) {
1787+
parentDecl = extensionDecl->getExtendedNominal();
1788+
if (parentDecl == designatedNominal) {
1789+
if (designatedTypeIndex >=
1790+
definedInExtensionOfDesignatedType.size())
1791+
definedInExtensionOfDesignatedType.resize(
1792+
designatedTypeIndex + 1);
1793+
1794+
auto &constraints =
1795+
definedInExtensionOfDesignatedType[designatedTypeIndex];
1796+
constraints.push_back(constraintIndex);
1797+
return true;
1798+
}
1799+
}
17851800
}
1786-
}
17871801

1788-
return false;
1789-
});
1802+
return false;
1803+
});
17901804
}
17911805

17921806
// Gather the remaining options.
@@ -1805,8 +1819,19 @@ void ConstraintSystem::partitionDisjunction(
18051819
};
18061820

18071821
// Now create the partitioning based on what was collected.
1808-
appendPartition(definedInDesignatedType);
1809-
appendPartition(definedInExtensionOfDesignatedType);
1822+
1823+
// First we'll add partitions for each of the overloads we found in
1824+
// types that were designated as part of the operator declaration.
1825+
for (auto designatedTypeIndex : indices(designatedNominalTypes)) {
1826+
if (designatedTypeIndex < definedInDesignatedType.size()) {
1827+
auto &primary = definedInDesignatedType[designatedTypeIndex];
1828+
appendPartition(primary);
1829+
}
1830+
if (designatedTypeIndex < definedInExtensionOfDesignatedType.size()) {
1831+
auto &secondary = definedInExtensionOfDesignatedType[designatedTypeIndex];
1832+
appendPartition(secondary);
1833+
}
1834+
}
18101835
appendPartition(everythingElse);
18111836
appendPartition(globalScope);
18121837
appendPartition(unavailable);

stdlib/public/core/Policy.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,15 +422,15 @@ infix operator &>> : BitwiseShiftPrecedence, FixedWidthInteger
422422

423423
infix operator * : MultiplicationPrecedence, Numeric
424424
infix operator &* : MultiplicationPrecedence, FixedWidthInteger
425-
infix operator / : MultiplicationPrecedence, BinaryInteger
425+
infix operator / : MultiplicationPrecedence, BinaryInteger, FloatingPoint
426426
infix operator % : MultiplicationPrecedence, BinaryInteger
427427
infix operator & : MultiplicationPrecedence, BinaryInteger
428428

429429
// "Additive"
430430

431-
infix operator + : AdditionPrecedence, Numeric
431+
infix operator + : AdditionPrecedence, Numeric, String, Strideable
432432
infix operator &+ : AdditionPrecedence, FixedWidthInteger
433-
infix operator - : AdditionPrecedence, Numeric
433+
infix operator - : AdditionPrecedence, Numeric, Strideable
434434
infix operator &- : AdditionPrecedence, FixedWidthInteger
435435
infix operator | : AdditionPrecedence, BinaryInteger
436436
infix operator ^ : AdditionPrecedence, BinaryInteger
@@ -482,9 +482,9 @@ infix operator *= : AssignmentPrecedence, Numeric
482482
infix operator &*= : AssignmentPrecedence, FixedWidthInteger
483483
infix operator /= : AssignmentPrecedence, BinaryInteger
484484
infix operator %= : AssignmentPrecedence, BinaryInteger
485-
infix operator += : AssignmentPrecedence, Numeric
485+
infix operator += : AssignmentPrecedence, Numeric, String, Strideable
486486
infix operator &+= : AssignmentPrecedence, FixedWidthInteger
487-
infix operator -= : AssignmentPrecedence, Numeric
487+
infix operator -= : AssignmentPrecedence, Numeric, Strideable
488488
infix operator &-= : AssignmentPrecedence, FixedWidthInteger
489489
infix operator <<= : AssignmentPrecedence, BinaryInteger
490490
infix operator &<<= : AssignmentPrecedence, FixedWidthInteger
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1
1+
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1 -swift-version 5 -solver-disable-shrink -disable-constraint-solver-performance-hacks -solver-enable-operator-designated-types
22
// REQUIRES: tools-release,no_asserts
33

44
let i: Int? = 1
55
let j: Int?
66
let k: Int? = 2
77

88
let _ = [i, j, k].reduce(0 as Int?) {
9-
// expected-error@-1 {{reasonable time}}
109
$0 != nil && $1 != nil ? $0! + $1! : ($0 != nil ? $0! : ($1 != nil ? $1! : nil))
1110
}

0 commit comments

Comments
 (0)