Skip to content

Commit 5b30603

Browse files
committed
[NFC] Strip ClosureExpr of its TypeLoc
1 parent fe89fca commit 5b30603

File tree

13 files changed

+75
-40
lines changed

13 files changed

+75
-40
lines changed

include/swift/AST/Expr.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,15 +3706,15 @@ class ClosureExpr : public AbstractClosureExpr {
37063706
SourceLoc InLoc;
37073707

37083708
/// The explicitly-specified result type.
3709-
TypeLoc ExplicitResultType;
3709+
TypeExpr *ExplicitResultType;
37103710

37113711
/// The body of the closure, along with a bit indicating whether it
37123712
/// was originally just a single expression.
37133713
llvm::PointerIntPair<BraceStmt *, 1, bool> Body;
37143714
public:
37153715
ClosureExpr(SourceRange bracketRange, VarDecl *capturedSelfDecl,
37163716
ParameterList *params, SourceLoc throwsLoc, SourceLoc arrowLoc,
3717-
SourceLoc inLoc, TypeLoc explicitResultType,
3717+
SourceLoc inLoc, TypeExpr *explicitResultType,
37183718
unsigned discriminator, DeclContext *parent)
37193719
: AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
37203720
discriminator, parent),
@@ -3774,11 +3774,17 @@ class ClosureExpr : public AbstractClosureExpr {
37743774
}
37753775

37763776
/// Retrieve the explicit result type location information.
3777-
TypeLoc &getExplicitResultTypeLoc() {
3777+
TypeExpr *getExplicitResultTypeExpr() const {
37783778
assert(hasExplicitResultType() && "No explicit result type");
37793779
return ExplicitResultType;
37803780
}
37813781

3782+
void setExplicitResultTypeExpr(TypeExpr *NewResultType) {
3783+
assert(hasExplicitResultType() && "No explicit result type");
3784+
ExplicitResultType = NewResultType;
3785+
assert(hasExplicitResultType() && "No explicit result type");
3786+
}
3787+
37823788
TypeRepr *getExplicitResultTypeRepr() const {
37833789
assert(hasExplicitResultType() && "No explicit result type");
37843790
return ExplicitResultType->getTypeRepr();

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1551,7 +1551,7 @@ class Parser {
15511551
ParameterList *&params,
15521552
SourceLoc &throwsLoc,
15531553
SourceLoc &arrowLoc,
1554-
TypeRepr *&explicitResultType,
1554+
TypeExpr *&explicitResultType,
15551555
SourceLoc &inLoc);
15561556

15571557
Expr *parseExprAnonClosureArg();

lib/AST/ASTWalker.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -810,9 +810,11 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
810810
Expr *visitClosureExpr(ClosureExpr *expr) {
811811
visit(expr->getParameters());
812812

813-
if (expr->hasExplicitResultType())
814-
if (doIt(expr->getExplicitResultTypeLoc()))
815-
return nullptr;
813+
if (expr->hasExplicitResultType()) {
814+
Expr *result = doIt(expr->getExplicitResultTypeExpr());
815+
if (!result) return nullptr;
816+
expr->setExplicitResultTypeExpr(cast<TypeExpr>(result));
817+
}
816818

817819
// Handle single-expression closures.
818820
if (expr->hasSingleExpressionBody()) {

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/Basic/SourceManager.h"
3030
#include "swift/IDE/CodeCompletion.h"
3131
#include "swift/Sema/IDETypeChecking.h"
32+
#include "swift/Subsystems.h"
3233
#include "clang/AST/Attr.h"
3334
#include "clang/AST/Decl.h"
3435

@@ -209,10 +210,23 @@ Type swift::ide::getReturnTypeFromContext(const DeclContext *DC) {
209210
if (ACE->getType() && !ACE->getType()->hasError())
210211
return ACE->getResultType();
211212
if (auto CE = dyn_cast<ClosureExpr>(ACE)) {
212-
if (CE->hasExplicitResultType())
213-
return const_cast<ClosureExpr *>(CE)
214-
->getExplicitResultTypeLoc()
215-
.getType();
213+
if (CE->hasExplicitResultType()) {
214+
if (auto ty = CE->getExplicitResultTypeExpr()->getInstanceType()) {
215+
return ty;
216+
}
217+
218+
auto typeLoc = TypeLoc{CE->getExplicitResultTypeRepr()};
219+
if (swift::performTypeLocChecking(DC->getASTContext(),
220+
typeLoc,
221+
/*isSILMode*/ false,
222+
/*isSILType*/ false,
223+
DC->getGenericEnvironmentOfContext(),
224+
const_cast<DeclContext *>(DC),
225+
/*diagnostics*/ false)) {
226+
return Type();
227+
}
228+
return typeLoc.getType();
229+
}
216230
}
217231
}
218232
return Type();

lib/IDE/SyntaxModel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ std::pair<bool, Expr *> ModelASTWalker::walkToExprPre(Expr *E) {
663663
SN.BodyRange = innerCharSourceRangeFromSourceRange(SM, E->getSourceRange());
664664
if (Closure->hasExplicitResultType())
665665
SN.TypeRange = charSourceRangeFromSourceRange(SM,
666-
Closure->getExplicitResultTypeLoc().getSourceRange());
666+
Closure->getExplicitResultTypeExpr()->getSourceRange());
667667

668668
pushStructureNode(SN, Closure);
669669

lib/Parse/ParseExpr.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2422,7 +2422,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
24222422
VarDecl *&capturedSelfDecl,
24232423
ParameterList *&params, SourceLoc &throwsLoc,
24242424
SourceLoc &arrowLoc,
2425-
TypeRepr *&explicitResultType, SourceLoc &inLoc){
2425+
TypeExpr *&explicitResultType, SourceLoc &inLoc){
24262426
// Clear out result parameters.
24272427
bracketRange = SourceRange();
24282428
capturedSelfDecl = nullptr;
@@ -2686,12 +2686,14 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26862686
arrowLoc = consumeToken();
26872687

26882688
// Parse the type.
2689-
explicitResultType =
2689+
auto *explicitResultTypeRepr =
26902690
parseType(diag::expected_closure_result_type).getPtrOrNull();
2691-
if (!explicitResultType) {
2691+
if (!explicitResultTypeRepr) {
26922692
// If we couldn't parse the result type, clear out the arrow location.
26932693
arrowLoc = SourceLoc();
26942694
invalid = true;
2695+
} else {
2696+
explicitResultType = new (Context) TypeExpr(explicitResultTypeRepr);
26952697
}
26962698
}
26972699
}
@@ -2791,7 +2793,7 @@ ParserResult<Expr> Parser::parseExprClosure() {
27912793
ParameterList *params = nullptr;
27922794
SourceLoc throwsLoc;
27932795
SourceLoc arrowLoc;
2794-
TypeRepr *explicitResultType;
2796+
TypeExpr *explicitResultType;
27952797
SourceLoc inLoc;
27962798
parseClosureSignatureIfPresent(bracketRange, captureList,
27972799
capturedSelfDecl, params, throwsLoc,

lib/Sema/CSGen.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,14 +2177,25 @@ namespace {
21772177
// parameter or return type is omitted, a fresh type variable is used to
21782178
// stand in for that parameter or return type, allowing it to be inferred
21792179
// from context.
2180+
auto getExplicitResultType = [&]() -> Type {
2181+
if (!closure->hasExplicitResultType()) {
2182+
return Type();
2183+
}
2184+
2185+
auto *resultExpr = closure->getExplicitResultTypeExpr();
2186+
if (auto declaredTy = resultExpr->getInstanceType()) {
2187+
return declaredTy;
2188+
}
2189+
2190+
return resolveTypeReferenceInExpression(closure->getExplicitResultTypeRepr());
2191+
};
2192+
21802193
Type resultTy;
2181-
if (closure->hasExplicitResultType() &&
2182-
closure->getExplicitResultTypeLoc().getType()) {
2183-
resultTy = closure->getExplicitResultTypeLoc().getType();
2184-
} else {
2185-
auto *resultLoc =
2194+
auto *resultLoc =
21862195
CS.getConstraintLocator(closure, ConstraintLocator::ClosureResult);
2187-
2196+
if (auto explicityTy = getExplicitResultType()) {
2197+
resultTy = explicityTy;
2198+
} else {
21882199
auto getContextualResultType = [&]() -> Type {
21892200
if (auto contextualType = CS.getContextualType(closure)) {
21902201
if (auto fnType = contextualType->getAs<FunctionType>())
@@ -2207,6 +2218,11 @@ namespace {
22072218
}
22082219
}
22092220

2221+
if (closure->hasExplicitResultType()) {
2222+
CS.setType(closure->getExplicitResultTypeExpr(),
2223+
MetatypeType::get(resultTy));
2224+
}
2225+
22102226
return FunctionType::get(closureParams, resultTy, extInfo);
22112227
}
22122228

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7078,14 +7078,11 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
70787078
closureType->getResult(),
70797079
getConstraintLocator(closure, LocatorPathElt::ClosureBody(hasReturn)));
70807080
} else if (!hasReturn) {
7081-
bool hasExplicitResult = closure->hasExplicitResultType() &&
7082-
closure->getExplicitResultTypeLoc().getType();
7083-
70847081
// If this closure has an empty body and no explicit result type
70857082
// let's bind result type to `Void` since that's the only type empty body
70867083
// can produce. Otherwise, if (multi-statement) closure doesn't have
70877084
// an explicit result (no `return` statements) let's default it to `Void`.
7088-
auto constraintKind = (closure->hasEmptyBody() && !hasExplicitResult)
7085+
auto constraintKind = (closure->hasEmptyBody() && !closure->hasExplicitResultType())
70897086
? ConstraintKind::Bind
70907087
: ConstraintKind::Defaultable;
70917088
addConstraint(

lib/Sema/DebuggerTestingTransform.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class DebuggerTestingTransform : public ASTWalker {
226226
auto *Params = ParameterList::createEmpty(Ctx);
227227
auto *Closure = new (Ctx)
228228
ClosureExpr(SourceRange(), nullptr, Params, SourceLoc(), SourceLoc(),
229-
SourceLoc(), TypeLoc(), DF.getNextDiscriminator(),
229+
SourceLoc(), nullptr, DF.getNextDiscriminator(),
230230
getCurrentDeclContext());
231231
Closure->setImplicit(true);
232232

lib/Sema/MiscDiagnostics.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,13 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
537537
isa<SubscriptExpr>(ParentExpr)) {
538538
return;
539539
}
540+
541+
if (auto *CE = dyn_cast<ClosureExpr>(ParentExpr)) {
542+
if (CE->hasExplicitResultType() &&
543+
CE->getExplicitResultTypeExpr() == E) {
544+
return;
545+
}
546+
}
540547
}
541548

542549
// Is this a protocol metatype?

0 commit comments

Comments
 (0)