Skip to content

Commit aeb36ab

Browse files
authored
Merge pull request #38712 from apple/missing-roles
[IDE] Skip synthesized curry thunks and walk their unwrapped expression
2 parents 1dd8a0e + 15c7ddd commit aeb36ab

File tree

5 files changed

+43
-25
lines changed

5 files changed

+43
-25
lines changed

include/swift/IDE/Utils.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,10 @@ ClangNode extensionGetClangNode(const ExtensionDecl *ext);
588588

589589
/// Utility for finding the referenced declaration from a call, which might
590590
/// include a second level of function application for a 'self.' expression,
591-
/// or a curry thunk, etc.
592-
std::pair<Type, ConcreteDeclRef> getReferencedDecl(Expr *expr);
591+
/// or a curry thunk, etc. If \p semantic is true then the underlying semantic
592+
/// expression of \p expr is used.
593+
std::pair<Type, ConcreteDeclRef> getReferencedDecl(Expr *expr,
594+
bool semantic = true);
593595

594596
/// Whether the last expression in \p ExprStack is being called.
595597
bool isBeingCalled(ArrayRef<Expr*> ExprStack);

lib/IDE/SourceEntityWalker.cpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,21 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
275275
return { false, E };
276276
}
277277

278+
auto doStopTraversal = [&]() -> std::pair<bool, Expr *> {
279+
Cancelled = true;
280+
return { false, nullptr };
281+
};
282+
283+
// Skip the synthesized curry thunks and just walk over the unwrapped
284+
// expression
285+
if (auto *ACE = dyn_cast<AutoClosureExpr>(E)) {
286+
if (auto *SubExpr = ACE->getUnwrappedCurryThunkExpr()) {
287+
if (!SubExpr->walk(*this))
288+
return doStopTraversal();
289+
return { false, E };
290+
}
291+
}
292+
278293
if (!SEWalker.walkToExprPre(E)) {
279294
return { false, E };
280295
}
@@ -291,30 +306,9 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
291306
return { false, E };
292307
};
293308

294-
auto doStopTraversal = [&]() -> std::pair<bool, Expr *> {
295-
Cancelled = true;
296-
return { false, nullptr };
297-
};
298-
299309
if (auto *CtorRefE = dyn_cast<ConstructorRefCallExpr>(E))
300310
CtorRefs.push_back(CtorRefE);
301311

302-
if (auto *ACE = dyn_cast<AutoClosureExpr>(E)) {
303-
if (auto *SubExpr = ACE->getUnwrappedCurryThunkExpr()) {
304-
if (auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
305-
if (!passReference(DRE->getDecl(), DRE->getType(),
306-
DRE->getNameLoc(),
307-
ReferenceMetaData(getReferenceKind(Parent.getAsExpr(), DRE),
308-
OpAccess)))
309-
return doStopTraversal();
310-
311-
return doSkipChildren();
312-
}
313-
}
314-
315-
return { true, E };
316-
}
317-
318312
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
319313
auto *FD = dyn_cast<FuncDecl>(DRE->getDecl());
320314
// Handle implicit callAsFunction reference. An explicit reference will be

lib/IDE/Utils.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,11 @@ ClangNode swift::ide::extensionGetClangNode(const ExtensionDecl *ext) {
11531153
return ClangNode();
11541154
}
11551155

1156-
std::pair<Type, ConcreteDeclRef> swift::ide::getReferencedDecl(Expr *expr) {
1156+
std::pair<Type, ConcreteDeclRef> swift::ide::getReferencedDecl(Expr *expr,
1157+
bool semantic) {
1158+
if (semantic)
1159+
expr = expr->getSemanticsProvidingExpr();
1160+
11571161
auto exprTy = expr->getType();
11581162

11591163
// Look through unbound instance member accesses.
@@ -1219,13 +1223,19 @@ Expr *swift::ide::getBase(ArrayRef<Expr *> ExprStack) {
12191223
Expr *CurrentE = ExprStack.back();
12201224
Expr *ParentE = getContainingExpr(ExprStack, 1);
12211225
Expr *Base = nullptr;
1226+
12221227
if (auto DSE = dyn_cast_or_null<DotSyntaxCallExpr>(ParentE))
12231228
Base = DSE->getBase();
12241229
else if (auto MRE = dyn_cast<MemberRefExpr>(CurrentE))
12251230
Base = MRE->getBase();
12261231
else if (auto SE = dyn_cast<SubscriptExpr>(CurrentE))
12271232
Base = SE->getBase();
12281233

1234+
// Look through curry thunks
1235+
if (auto ACE = dyn_cast_or_null<AutoClosureExpr>(Base))
1236+
if (auto *Unwrapped = ACE->getUnwrappedCurryThunkExpr())
1237+
Base = Unwrapped;
1238+
12291239
if (Base) {
12301240
while (auto ICE = dyn_cast<ImplicitConversionExpr>(Base))
12311241
Base = ICE->getSubExpr();

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
572572
}
573573
return false;
574574
};
575-
if (auto *VD = getReferencedDecl(Call).second.getDecl())
575+
if (auto *VD = getReferencedDecl(Call, /*semantic=*/false).second.getDecl())
576576
if (handleDecl(VD, Call->getSourceRange()))
577577
return true;
578578

test/Index/index_curry_thunk.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
2+
3+
struct SomeStruct {
4+
func simple(_ someClosure: () -> Void) { }
5+
}
6+
7+
func test(s: SomeStruct) {
8+
s.simple { }
9+
// CHECK: [[@LINE-1]]:5 | instance-method/Swift | simple(_:) | s:14swift_ide_test10SomeStructV6simpleyyyyXEF | Ref,Call,RelRec,RelCall,RelCont | rel: 2
10+
(((s).simple)) { }
11+
// CHECK: [[@LINE-1]]:9 | instance-method/Swift | simple(_:) | s:14swift_ide_test10SomeStructV6simpleyyyyXEF | Ref,Call,RelRec,RelCall,RelCont | rel: 2
12+
}

0 commit comments

Comments
 (0)