Skip to content

Commit f182378

Browse files
committed
[CS] Re-order subscript constraint generation
Add the application constraint before the member constraint, which allows us to get rid of the special-cased delaying logic for dynamic member subscripts. The diagnostic change here is due to the fact that we no longer have a simplified type for the result in CSGen, which would also be the case if we had a disjunction for the member.
1 parent 4403625 commit f182378

File tree

4 files changed

+15
-34
lines changed

4 files changed

+15
-34
lines changed

lib/Sema/CSGen.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,18 @@ namespace {
11581158
if (addedTypeVars)
11591159
addedTypeVars->push_back(memberTy);
11601160

1161+
SmallVector<AnyFunctionType::Param, 8> params;
1162+
getMatchingParams(argList, params);
1163+
1164+
// Add the constraint that the index expression's type be convertible
1165+
// to the input type of the subscript operator.
1166+
// We add this as an unsolved constraint before adding the member
1167+
// constraint since some member constraints such as key-path dynamic
1168+
// member require the applicable function constraint to be available.
1169+
CS.addUnsolvedConstraint(Constraint::createApplicableFunction(
1170+
CS, FunctionType::get(params, outputTy), memberTy,
1171+
/*trailingClosureMatching=*/std::nullopt, CurDC, fnLocator));
1172+
11611173
// FIXME: synthesizeMaterializeForSet() wants to statically dispatch to
11621174
// a known subscript here. This might be cleaner if we split off a new
11631175
// UnresolvedSubscriptExpr from SubscriptExpr.
@@ -1173,15 +1185,6 @@ namespace {
11731185
/*outerAlternatives=*/{}, memberLocator);
11741186
}
11751187

1176-
SmallVector<AnyFunctionType::Param, 8> params;
1177-
getMatchingParams(argList, params);
1178-
1179-
// Add the constraint that the index expression's type be convertible
1180-
// to the input type of the subscript operator.
1181-
CS.addApplicationConstraint(FunctionType::get(params, outputTy), memberTy,
1182-
/*trailingClosureMatching=*/std::nullopt,
1183-
CurDC, fnLocator);
1184-
11851188
if (CS.performanceHacksEnabled()) {
11861189
Type fixedOutputType =
11871190
CS.getFixedTypeRecursive(outputTy, /*wantRValue=*/false);

lib/Sema/CSSimplify.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11465,22 +11465,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
1146511465
if (result.actualBaseType)
1146611466
baseTy = result.actualBaseType;
1146711467

11468-
// If only possible choice to refer to member is via keypath
11469-
// dynamic member dispatch, let's delay solving this constraint
11470-
// until constraint generation phase is complete, because
11471-
// subscript dispatch relies on presence of function application.
11472-
if (result.ViableCandidates.size() == 1) {
11473-
auto &choice = result.ViableCandidates.front();
11474-
if (Phase == ConstraintSystemPhase::ConstraintGeneration &&
11475-
choice.isKeyPathDynamicMemberLookup() &&
11476-
member.getBaseName().isSubscript()) {
11477-
// Let's move this constraint to the active
11478-
// list so it could be picked up right after
11479-
// constraint generation is done.
11480-
return formUnsolved(/*activate=*/true);
11481-
}
11482-
}
11483-
1148411468
generateOverloadConstraints(
1148511469
candidates, memberTy, result.ViableCandidates, useDC, locator,
1148611470
result.getFavoredIndex(), /*requiresFix=*/false,

lib/Sema/CSSolver.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,12 +1798,6 @@ ConstraintSystem::filterDisjunction(
17981798
// constraint, so instead let's keep the disjunction, but disable all
17991799
// unviable choices.
18001800
if (choice->getOverloadChoice().isKeyPathDynamicMemberLookup()) {
1801-
// Early simplification of the "keypath dynamic member lookup" choice
1802-
// is impossible because it requires constraints associated with
1803-
// subscript index expression to be present.
1804-
if (Phase == ConstraintSystemPhase::ConstraintGeneration)
1805-
return SolutionKind::Unsolved;
1806-
18071801
for (auto *currentChoice : disjunction->getNestedConstraints()) {
18081802
if (currentChoice->isDisabled())
18091803
continue;

test/Constraints/function.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ func f_45262(block: () -> (), other: () -> Int) {
115115

116116
struct S {
117117
init<T>(_ x: T, _ y: T) {} // expected-note {{generic parameters are always considered '@escaping'}}
118-
subscript<T>() -> (T, T) -> Void { { _, _ in } } // expected-note {{generic parameters are always considered '@escaping'}}
118+
subscript<T>() -> (T, T) -> Void { { _, _ in } }
119119

120-
init(fn: () -> Int) {
120+
init(fn: () -> Int) { // expected-note {{parameter 'fn' is implicitly non-escaping}}
121121
self.init({ 0 }, fn) // expected-error {{converting non-escaping parameter 'fn' to generic parameter 'T' may allow it to escape}}
122-
_ = self[]({ 0 }, fn) // expected-error {{converting non-escaping parameter 'fn' to generic parameter 'T' may allow it to escape}}
122+
_ = self[]({ 0 }, fn) // expected-error {{passing non-escaping parameter 'fn' to function expecting an '@escaping' closure}}
123123
}
124124
}
125125

0 commit comments

Comments
 (0)