Skip to content

Commit a99f24f

Browse files
authored
Merge pull request #28895 from slavapestov/prep-for-sr-75
Preparations for building curry thunks in Sema
2 parents 0514248 + 3604b21 commit a99f24f

File tree

17 files changed

+138
-123
lines changed

17 files changed

+138
-123
lines changed

include/swift/AST/Expr.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,12 @@ class alignas(8) Expr {
284284
Discriminator : 16
285285
);
286286

287+
SWIFT_INLINE_BITFIELD(AutoClosureExpr, AbstractClosureExpr, 1,
288+
/// True if this autoclosure was built for a function conversion, and
289+
/// not an actual @autoclosure parameter.
290+
IsThunk : 1
291+
);
292+
287293
SWIFT_INLINE_BITFIELD(ClosureExpr, AbstractClosureExpr, 1,
288294
/// True if closure parameters were synthesized from anonymous closure
289295
/// variables.
@@ -3762,6 +3768,16 @@ class AutoClosureExpr : public AbstractClosureExpr {
37623768
Discriminator, Parent) {
37633769
if (Body != nullptr)
37643770
setBody(Body);
3771+
3772+
Bits.AutoClosureExpr.IsThunk = false;
3773+
}
3774+
3775+
bool isThunk() const {
3776+
return Bits.AutoClosureExpr.IsThunk;
3777+
}
3778+
3779+
void setIsThunk(bool isThunk) {
3780+
Bits.AutoClosureExpr.IsThunk = isThunk;
37653781
}
37663782

37673783
SourceRange getSourceRange() const;

include/swift/IDE/Utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,11 @@ ClangNode getEffectiveClangNode(const Decl *decl);
584584
/// Retrieve the Clang node for the given extension, if it has one.
585585
ClangNode extensionGetClangNode(const ExtensionDecl *ext);
586586

587+
/// Utility for finding the referenced declaration from a call, which might
588+
/// include a second level of function application for a 'self.' expression,
589+
/// or a curry thunk, etc.
590+
std::pair<Type, ConcreteDeclRef> getReferencedDecl(Expr *expr);
591+
587592
} // namespace ide
588593
} // namespace swift
589594

lib/AST/Expr.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,7 @@ ConcreteDeclRef Expr::getReferencedDecl() const {
254254
SIMPLE_REFERENCE(DeclRef, getDeclRef);
255255
SIMPLE_REFERENCE(SuperRef, getSelf);
256256

257-
case ExprKind::Type: {
258-
auto typeRepr = cast<TypeExpr>(this)->getTypeRepr();
259-
if (!typeRepr) return ConcreteDeclRef();
260-
auto ident = dyn_cast<IdentTypeRepr>(typeRepr);
261-
if (!ident) return ConcreteDeclRef();
262-
return ident->getComponentRange().back()->getBoundDecl();
263-
}
257+
NO_REFERENCE(Type);
264258

265259
SIMPLE_REFERENCE(OtherConstructorDeclRef, getDeclRef);
266260

@@ -324,8 +318,8 @@ ConcreteDeclRef Expr::getReferencedDecl() const {
324318
NO_REFERENCE(Binary);
325319
NO_REFERENCE(DotSyntaxCall);
326320
NO_REFERENCE(MakeTemporarilyEscapable);
321+
NO_REFERENCE(ConstructorRefCall);
327322

328-
PASS_THROUGH_REFERENCE(ConstructorRefCall, getFn);
329323
PASS_THROUGH_REFERENCE(Load, getSubExpr);
330324
NO_REFERENCE(DestructureTuple);
331325
NO_REFERENCE(UnresolvedTypeConversion);

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,6 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
12641264
/// to the \c Consumer.
12651265
bool DeliveredResults = false;
12661266

1267-
12681267
Optional<std::pair<Type, ConcreteDeclRef>> typeCheckParsedExpr() {
12691268
assert(ParsedExpr && "should have an expression");
12701269

@@ -1279,24 +1278,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
12791278
// typecheck again. rdar://21466394
12801279
if (CheckKind == CompletionTypeCheckKind::Normal &&
12811280
ParsedExpr->getType() && !ParsedExpr->getType()->is<ErrorType>()) {
1282-
auto refDecl = ParsedExpr->getReferencedDecl();
1283-
auto exprTy = ParsedExpr->getType();
1284-
if (!refDecl) {
1285-
// FIXME: do this in the not-already-type-checked branch too?
1286-
if (auto *apply = dyn_cast<SelfApplyExpr>(ParsedExpr)) {
1287-
refDecl = apply->getFn()->getReferencedDecl();
1288-
} else if (auto *apply = dyn_cast<ApplyExpr>(ParsedExpr)) {
1289-
// If this is an IUO, use the underlying non-optional type instead
1290-
auto fnDecl = apply->getFn()->getReferencedDecl();
1291-
if (auto FD = fnDecl.getDecl()) {
1292-
if (FD->isImplicitlyUnwrappedOptional()) {
1293-
if (auto OT = exprTy->getOptionalObjectType())
1294-
exprTy = OT;
1295-
}
1296-
}
1297-
}
1298-
}
1299-
return std::make_pair(exprTy, refDecl);
1281+
return getReferencedDecl(ParsedExpr);
13001282
}
13011283

13021284
ConcreteDeclRef ReferencedDecl = nullptr;

lib/IDE/Utils.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,3 +976,55 @@ ClangNode swift::ide::extensionGetClangNode(const ExtensionDecl *ext) {
976976

977977
return ClangNode();
978978
}
979+
980+
std::pair<Type, ConcreteDeclRef> swift::ide::getReferencedDecl(Expr *expr) {
981+
auto exprTy = expr->getType();
982+
983+
// Look through unbound instance member accesses.
984+
if (auto *dotSyntaxExpr = dyn_cast<DotSyntaxBaseIgnoredExpr>(expr))
985+
expr = dotSyntaxExpr->getRHS();
986+
987+
// Look through the 'self' application.
988+
if (auto *selfApplyExpr = dyn_cast<SelfApplyExpr>(expr))
989+
expr = selfApplyExpr->getFn();
990+
991+
// Look through curry thunks.
992+
if (auto *closure = dyn_cast<AutoClosureExpr>(expr)) {
993+
if (closure->isThunk()) {
994+
auto *body = closure->getSingleExpressionBody();
995+
if (isa<AutoClosureExpr>(body) &&
996+
closure->getParameters()->size() == 1)
997+
expr = closure->getSingleExpressionBody();
998+
}
999+
}
1000+
1001+
if (auto *closure = dyn_cast<AutoClosureExpr>(expr)) {
1002+
if (closure->isThunk()) {
1003+
auto *body = closure->getSingleExpressionBody();
1004+
body = body->getSemanticsProvidingExpr();
1005+
if (auto *outerCall = dyn_cast<ApplyExpr>(body)) {
1006+
if (auto *innerCall = dyn_cast<ApplyExpr>(outerCall->getFn())) {
1007+
if (auto *declRef = dyn_cast<DeclRefExpr>(innerCall->getFn())) {
1008+
expr = declRef;
1009+
}
1010+
}
1011+
}
1012+
}
1013+
}
1014+
1015+
// If this is an IUO result, unwrap the optional type.
1016+
auto refDecl = expr->getReferencedDecl();
1017+
if (!refDecl) {
1018+
if (auto *applyExpr = dyn_cast<ApplyExpr>(expr)) {
1019+
auto fnDecl = applyExpr->getFn()->getReferencedDecl();
1020+
if (auto *func = fnDecl.getDecl()) {
1021+
if (func->isImplicitlyUnwrappedOptional()) {
1022+
if (auto objectTy = exprTy->getOptionalObjectType())
1023+
exprTy = objectTy;
1024+
}
1025+
}
1026+
}
1027+
}
1028+
1029+
return std::make_pair(exprTy, refDecl);
1030+
}

lib/Index/Index.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,10 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
362362
}
363363

364364
void handleMemberwiseInitRefs(Expr *E) {
365-
if (!isa<ConstructorRefCallExpr>(E))
365+
if (!isa<ApplyExpr>(E))
366366
return;
367367

368-
auto *DeclRef = dyn_cast<DeclRefExpr>(cast<ConstructorRefCallExpr>(E)->getFn());
368+
auto *DeclRef = dyn_cast<DeclRefExpr>(cast<ApplyExpr>(E)->getFn());
369369
if (!DeclRef || !isMemberwiseInit(DeclRef->getDecl()))
370370
return;
371371

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 36 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -231,21 +231,6 @@ class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
231231
}
232232
};
233233

234-
static ValueDecl* getReferencedDecl(Expr *E) {
235-
// Get the syntactic expression out of an implicit expression.
236-
if (auto *ICE = dyn_cast<ImplicitConversionExpr>(E))
237-
E = ICE->getSyntacticSubExpr();
238-
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
239-
return DRE->getDecl();
240-
} else if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
241-
return MRE->getMember().getDecl();
242-
} else if (auto OtherCtorE = dyn_cast<OtherConstructorDeclRefExpr>(E)) {
243-
return OtherCtorE->getDecl();
244-
} else {
245-
return nullptr;
246-
}
247-
}
248-
249234
struct ConversionFunctionInfo {
250235
Expr *ExpressionToWrap;
251236
SmallString<256> Buffer;
@@ -582,15 +567,10 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
582567
}
583568
return false;
584569
};
585-
if (auto *DSC = dyn_cast<DotSyntaxCallExpr>(Call)) {
586-
if (auto FD = DSC->getFn()->getReferencedDecl().getDecl()) {
587-
if (handleDecl(FD, Call->getSourceRange()))
588-
return true;
589-
}
590-
} else if (auto MRE = dyn_cast<MemberRefExpr>(Call)) {
591-
if (handleDecl(MRE->getReferencedDecl().getDecl(), MRE->getSourceRange()))
570+
if (auto *VD = getReferencedDecl(Call).second.getDecl())
571+
if (handleDecl(VD, Call->getSourceRange()))
592572
return true;
593-
}
573+
594574
return false;
595575
}
596576

@@ -858,11 +838,12 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
858838
Lexer::getLocForEndOfToken(SM, E->getEndLoc())), Text);
859839
}
860840

861-
bool wrapAttributeReference(Expr* Reference, Expr* WrapperTarget,
841+
bool wrapAttributeReference(Expr *Reference, Expr *WrapperTarget,
862842
bool FromString) {
863-
auto *RD = getReferencedDecl(Reference);
843+
auto *RD = Reference->getReferencedDecl().getDecl();
864844
if (!RD)
865845
return false;
846+
866847
std::string Rename;
867848
Optional<NodeAnnotation> Kind;
868849
StringRef LeftComment;
@@ -1110,7 +1091,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
11101091
// reference of the property.
11111092
bool handlePropertyTypeChange(Expr *E) {
11121093
if (auto MRE = dyn_cast<MemberRefExpr>(E)) {
1113-
if (auto *VD = MRE->getReferencedDecl().getDecl()) {
1094+
if (auto *VD = MRE->getMember().getDecl()) {
11141095
for (auto *I: getRelatedDiffItems(VD)) {
11151096
if (auto *Item = dyn_cast<CommonDiffItem>(I)) {
11161097
if (Item->DiffKind == NodeAnnotation::WrapOptional &&
@@ -1143,46 +1124,36 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
11431124
if (auto *CE = dyn_cast<CallExpr>(E)) {
11441125
auto Fn = CE->getFn();
11451126
auto Args = CE->getArg();
1146-
switch (Fn->getKind()) {
1147-
case ExprKind::DeclRef: {
1148-
if (auto FD = Fn->getReferencedDecl().getDecl()) {
1149-
handleFuncRename(FD, Fn, Args);
1150-
handleTypeHoist(FD, CE, Args);
1151-
handleSpecialCases(FD, CE, Args);
1152-
handleStringRepresentableArg(FD, Args, CE);
1153-
handleResultTypeChange(FD, CE);
1154-
}
1155-
break;
1156-
}
1157-
case ExprKind::DotSyntaxCall: {
1158-
auto DSC = cast<DotSyntaxCallExpr>(Fn);
1159-
if (auto FD = DSC->getFn()->getReferencedDecl().getDecl()) {
1160-
handleFuncRename(FD, DSC->getFn(), Args);
1161-
handleFunctionCallToPropertyChange(FD, DSC->getFn(), Args);
1162-
handleSpecialCases(FD, CE, Args);
1163-
handleStringRepresentableArg(FD, Args, CE);
1164-
handleResultTypeChange(FD, CE);
1127+
1128+
if (auto *DRE = dyn_cast<DeclRefExpr>(Fn)) {
1129+
if (auto *VD = DRE->getDecl()) {
1130+
if (VD->getNumCurryLevels() == 1) {
1131+
handleFuncRename(VD, Fn, Args);
1132+
handleTypeHoist(VD, CE, Args);
1133+
handleSpecialCases(VD, CE, Args);
1134+
handleStringRepresentableArg(VD, Args, CE);
1135+
handleResultTypeChange(VD, CE);
1136+
}
11651137
}
1166-
break;
11671138
}
1168-
case ExprKind::ConstructorRefCall: {
1169-
auto CCE = cast<ConstructorRefCallExpr>(Fn);
1170-
if (auto FD = CCE->getFn()->getReferencedDecl().getDecl()) {
1171-
handleFuncRename(FD, CE, Args);
1172-
handleStringRepresentableArg(FD, Args, CE);
1173-
handleResultTypeChange(FD, CE);
1139+
1140+
if (auto *SelfApply = dyn_cast<ApplyExpr>(Fn)) {
1141+
if (auto VD = SelfApply->getFn()->getReferencedDecl().getDecl()) {
1142+
if (VD->getNumCurryLevels() == 2) {
1143+
handleFuncRename(VD, SelfApply->getFn(), Args);
1144+
handleFunctionCallToPropertyChange(VD, SelfApply->getFn(), Args);
1145+
handleSpecialCases(VD, CE, Args);
1146+
handleStringRepresentableArg(VD, Args, CE);
1147+
handleResultTypeChange(VD, CE);
1148+
}
11741149
}
1175-
break;
1176-
}
1177-
default:
1178-
break;
11791150
}
11801151
}
11811152
return true;
11821153
}
11831154

1184-
static void collectParamters(AbstractFunctionDecl *AFD,
1185-
SmallVectorImpl<ParamDecl*> &Results) {
1155+
static void collectParameters(AbstractFunctionDecl *AFD,
1156+
SmallVectorImpl<ParamDecl*> &Results) {
11861157
for (auto PD : *AFD->getParameters()) {
11871158
Results.push_back(PD);
11881159
}
@@ -1197,7 +1168,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
11971168
Editor.replace(NameRange, View.base());
11981169
unsigned Index = 0;
11991170
SmallVector<ParamDecl*, 4> Params;
1200-
collectParamters(AFD, Params);
1171+
collectParameters(AFD, Params);
12011172
for (auto *PD: Params) {
12021173
if (Index == View.argSize())
12031174
break;
@@ -1322,7 +1293,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
13221293
return;
13231294
Idx --;
13241295
SmallVector<ParamDecl*, 4> Params;
1325-
collectParamters(AFD, Params);
1296+
collectParameters(AFD, Params);
13261297
if (Params.size() <= Idx)
13271298
return;
13281299

@@ -1397,11 +1368,11 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
13971368
Editor(Editor), USRs(USRs) {}
13981369
bool isSuperExpr(Expr *E) {
13991370
if (E->isImplicit())
1400-
return false;
1371+
return false;
14011372
// Check if the expression is super.foo().
14021373
if (auto *CE = dyn_cast<CallExpr>(E)) {
14031374
if (auto *DSC = dyn_cast<DotSyntaxCallExpr>(CE->getFn())) {
1404-
if (DSC->getBase()->getKind() != ExprKind::SuperRef)
1375+
if (!isa<SuperRefExpr>(DSC->getBase()))
14051376
return false;
14061377
llvm::SmallString<64> Buffer;
14071378
llvm::raw_svector_ostream OS(Buffer);
@@ -1419,9 +1390,9 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
14191390
}
14201391
std::pair<bool, Stmt*> walkToStmtPre(Stmt *S) override {
14211392
if (auto *BS = dyn_cast<BraceStmt>(S)) {
1422-
for(auto Ele: BS->getElements()) {
1423-
if (Ele.is<Expr*>() && isSuperExpr(Ele.get<Expr*>())) {
1424-
Editor.remove(Ele.getSourceRange());
1393+
for(auto Ele: BS->getElements()) {
1394+
if (Ele.is<Expr*>() && isSuperExpr(Ele.get<Expr*>())) {
1395+
Editor.remove(Ele.getSourceRange());
14251396
}
14261397
}
14271398
}

lib/SILGen/SILGenFunction.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,12 @@ void SILGenFunction::emitClosure(AbstractClosureExpr *ace) {
513513
emitStmt(ce->getBody());
514514
} else {
515515
auto *autoclosure = cast<AutoClosureExpr>(ace);
516-
emitStmt(autoclosure->getBody());
516+
// Closure expressions implicitly return the result of their body
517+
// expression.
518+
if (B.hasValidInsertionPoint()) {
519+
emitReturnExpr(ImplicitReturnLocation(ace),
520+
autoclosure->getSingleExpressionBody());
521+
}
517522
}
518523
emitEpilog(ace);
519524
}

lib/SILGen/SILGenStmt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ void SILGenFunction::emitReturnExpr(SILLocation branchLoc,
482482
RValue RV = emitRValue(ret).ensurePlusOne(*this, CleanupLocation(ret));
483483
std::move(RV).forwardAll(*this, directResults);
484484
}
485+
485486
Cleanups.emitBranchAndCleanups(ReturnDest, branchLoc, directResults);
486487
}
487488

lib/SILOptimizer/Transforms/AllocBoxToStack.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ SILFunction *PromotedParamCloner::initCloned(SILOptFunctionBuilder &FuncBuilder,
634634
assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned");
635635
auto *Fn = FuncBuilder.createFunction(
636636
SILLinkage::Shared, ClonedName, ClonedTy, Orig->getGenericEnvironment(),
637-
Orig->getLocation(), Orig->isBare(), IsNotTransparent, Serialized,
637+
Orig->getLocation(), Orig->isBare(), Orig->isTransparent(), Serialized,
638638
IsNotDynamic, Orig->getEntryCount(), Orig->isThunk(),
639639
Orig->getClassSubclassScope(), Orig->getInlineStrategy(),
640640
Orig->getEffectsKind(), Orig, Orig->getDebugScope());

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7208,7 +7208,7 @@ bool ConstraintSystem::applySolutionFixes(const Solution &solution) {
72087208
Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr,
72097209
Type convertType,
72107210
bool discardedExpr,
7211-
bool skipClosures) {
7211+
bool performingDiagnostics) {
72127212
// If any fixes needed to be applied to arrive at this solution, resolve
72137213
// them to specific expressions.
72147214
if (!solution.Fixes.empty()) {
@@ -7242,7 +7242,7 @@ Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr,
72427242

72437243
// If we're re-typechecking an expression for diagnostics, don't
72447244
// visit closures that have non-single expression bodies.
7245-
if (!skipClosures) {
7245+
if (!performingDiagnostics) {
72467246
bool hadError = false;
72477247
for (auto *closure : walker.getClosuresToTypeCheck())
72487248
hadError |= TypeChecker::typeCheckClosureBody(closure);

0 commit comments

Comments
 (0)