Skip to content

Commit 323b9d9

Browse files
committed
Distinguish a function's result type in the interface vs. in the definition.
At present, this is a distinction without a difference. However, it's a step toward detangling archetypes from the interface of a polymorphic function. Swift SVN r7405
1 parent fe2d8d5 commit 323b9d9

File tree

5 files changed

+35
-10
lines changed

5 files changed

+35
-10
lines changed

include/swift/AST/Expr.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1688,6 +1688,11 @@ class FuncExpr : public CapturingExpr {
16881688

16891689
TypeLoc FnRetType;
16901690

1691+
/// The result type as seen from the body of the function.
1692+
///
1693+
/// \sa getBodyResultType()
1694+
Type BodyResultType;
1695+
16911696
Pattern **getParamsBuffer() {
16921697
return reinterpret_cast<Pattern**>(this+1);
16931698
}
@@ -1843,9 +1848,29 @@ class FuncExpr : public CapturingExpr {
18431848

18441849
TypeLoc &getBodyResultTypeLoc() { return FnRetType; }
18451850

1846-
/// \brief Retrieve the result type of this function.
1851+
/// Retrieve the result type of this function.
1852+
///
1853+
/// \sa getBodyResultType
18471854
Type getResultType(ASTContext &Ctx) const;
18481855

1856+
/// Retrieve the result type of this function for use within the function
1857+
/// definition.
1858+
///
1859+
/// FIXME: The statement below is a wish, not reality.
1860+
/// The "body" result type will only differ from the result type within the
1861+
/// interface to the function for a polymorphic function, where the interface
1862+
/// may contain generic parameters while the definition will contain
1863+
/// the corresponding archetypes.
1864+
Type getBodyResultType() const { return BodyResultType; }
1865+
1866+
/// Set the result type as viewed from the function body.
1867+
///
1868+
/// \sa getBodyResultType
1869+
void setBodyResultType(Type bodyResultType) {
1870+
assert(BodyResultType.isNull() && "Already set body result type");
1871+
BodyResultType = bodyResultType;
1872+
}
1873+
18491874
static bool classof(const Expr *E) { return E->getKind() == ExprKind::Func; }
18501875
static bool classof(const DeclContext *DC) {
18511876
return isa<CapturingExpr>(DC) && classof(cast<CapturingExpr>(DC));

lib/ClangImporter/ImportDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ namespace {
791791
argPatterns, bodyPatterns,
792792
TypeLoc::withoutLoc(resultTy), dc);
793793
funcExpr->setType(type);
794+
funcExpr->setBodyResultType(resultTy);
794795
auto nameLoc = Impl.importSourceLoc(decl->getLocation());
795796
auto result = new (Impl.SwiftContext) FuncDecl(SourceLoc(), loc,
796797
name, nameLoc,
@@ -961,7 +962,7 @@ namespace {
961962
argPatterns, bodyPatterns,
962963
TypeLoc::withoutLoc(resultTy), dc);
963964
funcExpr->setType(type);
964-
965+
funcExpr->setBodyResultType(resultTy);
965966
auto result = new (Impl.SwiftContext) FuncDecl(SourceLoc(), loc,
966967
name, nameLoc,
967968
/*GenericParams=*/0,
@@ -1438,6 +1439,7 @@ namespace {
14381439
TypeLoc::withoutLoc(elementTy),
14391440
getter->getDeclContext());
14401441
funcExpr->setType(getterType);
1442+
funcExpr->setBodyResultType(elementTy);
14411443
setVarDeclContexts(getterArgs, funcExpr);
14421444

14431445
// Create the getter thunk.
@@ -1562,6 +1564,7 @@ namespace {
15621564
TypeLoc::withoutLoc(TupleType::getEmpty(context)),
15631565
setter->getDeclContext());
15641566
funcExpr->setType(setterType);
1567+
funcExpr->setBodyResultType(TupleType::getEmpty(context));
15651568
setVarDeclContexts(setterArgs, funcExpr);
15661569

15671570
// Create the setter thunk.
@@ -2530,6 +2533,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
25302533
TypeLoc::withoutLoc(type),
25312534
dc);
25322535
funcExpr->setType(getterType);
2536+
funcExpr->setBodyResultType(type);
25332537
setVarDeclContexts(getterArgs, funcExpr);
25342538

25352539
// Create the getter function declaration.

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
10351035
if (!funcTy) {
10361036
funcTy = TupleType::getEmpty(TC.Context);
10371037
}
1038+
auto bodyResultType = funcTy;
10381039

10391040
// FIXME: it would be nice to have comments explaining what this is all about.
10401041
auto patterns = FE->getArgParamPatterns();
@@ -1069,6 +1070,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
10691070

10701071
}
10711072
FE->setType(funcTy);
1073+
FE->setBodyResultType(bodyResultType);
10721074
}
10731075

10741076
/// Bind the given function declaration, which declares an operator, to

lib/Sema/TypeCheckREPL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ static void generatePrintOfExpression(StringRef NameStr, Expr *E,
532532
Type FuncTy = FunctionType::get(ParamPat->getType(), TupleType::getEmpty(C),
533533
C);
534534
FE->setType(FuncTy);
535+
FE->setBodyResultType(TupleType::getEmpty(C));
535536
Arg->setDeclContext(FE);
536537

537538
// Convert the pattern to a string we can print.

lib/Sema/TypeCheckStmt.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
132132

133133
Type returnTypeOfFunc() {
134134
if (auto fe = TheFunc.dyn_cast<FuncExpr*>()) {
135-
Type resultTy = fe->getType();
136-
if (resultTy->is<ErrorType>())
137-
return resultTy;
138-
for (unsigned i = 0, e = fe->getNumParamPatterns();
139-
i != e;
140-
++i)
141-
resultTy = resultTy->castTo<AnyFunctionType>()->getResult();
142-
return resultTy;
135+
return fe->getBodyResultType();
143136
} else if (auto closure = TheFunc.dyn_cast<PipeClosureExpr *>()) {
144137
return closure->getResultType();
145138
} else

0 commit comments

Comments
 (0)