Skip to content

Commit cc780e3

Browse files
committed
[ConstraintSystem] Make sure that @autoclosure argument detection works for subscripts/members
Currently logic in `matchCallArguments` could only detect argument being an @autoclosure parameter for normal calls and operators. This patch extends it to support subscripts and unresolved member calls.
1 parent f9dae94 commit cc780e3

File tree

4 files changed

+37
-12
lines changed

4 files changed

+37
-12
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -848,18 +848,7 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
848848
auto isAutoClosureArg = [&](Expr *anchor, unsigned argIdx) -> bool {
849849
assert(anchor);
850850

851-
auto *call = dyn_cast<ApplyExpr>(anchor);
852-
if (!call)
853-
return false;
854-
855-
Expr *argExpr = nullptr;
856-
if (auto *PE = dyn_cast<ParenExpr>(call->getArg())) {
857-
assert(argsWithLabels.size() == 1);
858-
argExpr = PE->getSubExpr();
859-
} else if (auto *TE = dyn_cast<TupleExpr>(call->getArg())) {
860-
argExpr = TE->getElement(argIdx);
861-
}
862-
851+
auto *argExpr = getArgumentExpr(anchor, argIdx);
863852
if (!argExpr)
864853
return false;
865854

lib/Sema/ConstraintSystem.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,3 +2356,23 @@ Expr *constraints::simplifyLocatorToAnchor(ConstraintSystem &cs,
23562356

23572357
return locator->getAnchor();
23582358
}
2359+
2360+
Expr *constraints::getArgumentExpr(Expr *expr, unsigned index) {
2361+
Expr *argExpr = nullptr;
2362+
if (auto *AE = dyn_cast<ApplyExpr>(expr))
2363+
argExpr = AE->getArg();
2364+
else if (auto *UME = dyn_cast<UnresolvedMemberExpr>(expr))
2365+
argExpr = UME->getArgument();
2366+
else if (auto *SE = dyn_cast<SubscriptExpr>(expr))
2367+
argExpr = SE->getIndex();
2368+
else
2369+
return nullptr;
2370+
2371+
if (auto *PE = dyn_cast<ParenExpr>(argExpr)) {
2372+
assert(index == 0);
2373+
return PE->getSubExpr();
2374+
}
2375+
2376+
assert(isa<TupleExpr>(argExpr));
2377+
return cast<TupleExpr>(argExpr)->getElement(index);
2378+
}

lib/Sema/ConstraintSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3458,6 +3458,13 @@ void simplifyLocator(Expr *&anchor,
34583458
/// null otherwise.
34593459
Expr *simplifyLocatorToAnchor(ConstraintSystem &cs, ConstraintLocator *locator);
34603460

3461+
/// Retrieve argument at specified index from given expression.
3462+
/// The expression could be "application", "subscript" or "member" call.
3463+
///
3464+
/// \returns argument expression or `nullptr` if given "base" expression
3465+
/// wasn't of one of the kinds listed above.
3466+
Expr *getArgumentExpr(Expr *expr, unsigned index);
3467+
34613468
class DisjunctionChoice {
34623469
unsigned Index;
34633470
Constraint *Choice;

test/Compatibility/attr_autoclosure.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,12 @@ do {
3636
foo(c)
3737
}
3838
}
39+
40+
func passAutoClosureToSubscript(_ fn: @autoclosure () -> Int) {
41+
struct S {
42+
subscript(_ fn: @autoclosure () -> Int) -> Int { return fn() }
43+
}
44+
45+
let s = S()
46+
let _ = s[fn] // Ok
47+
}

0 commit comments

Comments
 (0)