Skip to content

Commit 41adfec

Browse files
committed
[NFC] AST, Sema: Move TypeChecker::findReturnStatements into AnyFunctionRef
Also rename it to `getExplicitReturnStmts` for clarity and have it take a `SmallVector` out parameter instead as a small optimization and to discourage use of this new method as an alternative to `AnyFunctionRef::bodyHasExplicitReturnStmt`.
1 parent e31e877 commit 41adfec

File tree

9 files changed

+42
-14
lines changed

9 files changed

+42
-14
lines changed

include/swift/AST/AnyFunctionRef.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ class AnyFunctionRef {
160160
/// `false` otherwise.
161161
bool bodyHasExplicitReturnStmt() const;
162162

163+
/// Finds occurrences of explicit `return` statements within the body, if any.
164+
///
165+
/// \param results An out container to which the results are added.
166+
void getExplicitReturnStmts(SmallVectorImpl<ReturnStmt *> &results) const;
167+
163168
DeclContext *getAsDeclContext() const {
164169
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>())
165170
return AFD;

include/swift/AST/Decl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ namespace swift {
109109
class ProtocolType;
110110
struct RawComment;
111111
enum class ResilienceExpansion : unsigned;
112+
class ReturnStmt;
112113
enum class EffectKind : uint8_t;
113114
enum class PolymorphicEffectKind : uint8_t;
114115
class TrailingWhereClause;
@@ -7682,6 +7683,11 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
76827683
/// `false` otherwise.
76837684
bool bodyHasExplicitReturnStmt() const;
76847685

7686+
/// Finds occurrences of explicit `return` statements within the body, if any.
7687+
///
7688+
/// \param results An out container to which the results are added.
7689+
void getExplicitReturnStmts(SmallVectorImpl<ReturnStmt *> &results) const;
7690+
76857691
/// Returns true if the text of this function's body can be retrieved either
76867692
/// by extracting the text from the source buffer or reading the inlinable
76877693
/// body from a deserialized swiftmodule.

include/swift/AST/Expr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ namespace swift {
7171
class KeyPathExpr;
7272
class CaptureListExpr;
7373
class ThenStmt;
74+
class ReturnStmt;
7475

7576
enum class ExprKind : uint8_t {
7677
#define EXPR(Id, Parent) Id,
@@ -4058,6 +4059,11 @@ class AbstractClosureExpr : public DeclContext, public Expr {
40584059
/// `false` otherwise.
40594060
bool bodyHasExplicitReturnStmt() const;
40604061

4062+
/// Finds occurrences of explicit `return` statements within the body, if any.
4063+
///
4064+
/// \param results An out container to which the results are added.
4065+
void getExplicitReturnStmts(SmallVectorImpl<ReturnStmt *> &results) const;
4066+
40614067
ActorIsolation getActorIsolation() const {
40624068
return actorIsolation;
40634069
}

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9361,6 +9361,12 @@ bool AbstractFunctionDecl::bodyHasExplicitReturnStmt() const {
93619361
.bodyHasExplicitReturnStmt();
93629362
}
93639363

9364+
void AbstractFunctionDecl::getExplicitReturnStmts(
9365+
SmallVectorImpl<ReturnStmt *> &results) const {
9366+
AnyFunctionRef(const_cast<AbstractFunctionDecl *>(this))
9367+
.getExplicitReturnStmts(results);
9368+
}
9369+
93649370
/// Expand all preamble macros attached to the given function declaration.
93659371
static std::vector<ASTNode> expandPreamble(AbstractFunctionDecl *func) {
93669372
std::vector<ASTNode> preamble;

lib/AST/Expr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,12 @@ bool AbstractClosureExpr::bodyHasExplicitReturnStmt() const {
19671967
.bodyHasExplicitReturnStmt();
19681968
}
19691969

1970+
void AbstractClosureExpr::getExplicitReturnStmts(
1971+
SmallVectorImpl<ReturnStmt *> &results) const {
1972+
AnyFunctionRef(const_cast<AbstractClosureExpr *>(this))
1973+
.getExplicitReturnStmts(results);
1974+
}
1975+
19701976
Type AbstractClosureExpr::getResultType(
19711977
llvm::function_ref<Type(Expr *)> getType) const {
19721978
auto *E = const_cast<AbstractClosureExpr *>(this);

lib/Sema/BuilderTransform.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,11 @@ std::optional<BraceStmt *>
918918
TypeChecker::applyResultBuilderBodyTransform(FuncDecl *func, Type builderType) {
919919
// First look for any return statements, and bail if we have any.
920920
auto &ctx = func->getASTContext();
921-
if (auto returnStmts = findReturnStatements(func); !returnStmts.empty()) {
921+
922+
SmallVector<ReturnStmt *> returnStmts;
923+
func->getExplicitReturnStmts(returnStmts);
924+
925+
if (!returnStmts.empty()) {
922926
// One or more explicit 'return' statements were encountered, which
923927
// disables the result builder transform. Warn when we do this.
924928
ctx.Diags.diagnose(
@@ -1298,19 +1302,16 @@ bool AnyFunctionRef::bodyHasExplicitReturnStmt() const {
12981302
BraceHasExplicitReturnStmtRequest{body}, false);
12991303
}
13001304

1301-
std::vector<ReturnStmt *> TypeChecker::findReturnStatements(AnyFunctionRef fn) {
1302-
if (!fn.bodyHasExplicitReturnStmt()) {
1303-
return std::vector<ReturnStmt *>();
1305+
void AnyFunctionRef::getExplicitReturnStmts(
1306+
SmallVectorImpl<ReturnStmt *> &results) const {
1307+
if (!bodyHasExplicitReturnStmt()) {
1308+
return;
13041309
}
13051310

1306-
std::vector<ReturnStmt *> results;
1307-
1308-
walkExplicitReturnStmts(fn.getBody(), [&results](ReturnStmt *RS) {
1311+
walkExplicitReturnStmts(getBody(), [&results](ReturnStmt *RS) {
13091312
results.push_back(RS);
13101313
return false;
13111314
});
1312-
1313-
return results;
13141315
}
13151316

13161317
ResultBuilderOpSupport TypeChecker::checkBuilderOpSupport(

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8862,7 +8862,8 @@ bool ReferenceToInvalidDeclaration::diagnoseAsError() {
88628862
bool InvalidReturnInResultBuilderBody::diagnoseAsError() {
88638863
auto *closure = castToExpr<ClosureExpr>(getAnchor());
88648864

8865-
auto returnStmts = TypeChecker::findReturnStatements(closure);
8865+
SmallVector<ReturnStmt *> returnStmts;
8866+
closure->getExplicitReturnStmts(returnStmts);
88668867
assert(!returnStmts.empty());
88678868

88688869
auto loc = returnStmts.front()->getReturnLoc();

lib/Sema/TypeCheckRequestFunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static Type inferResultBuilderType(ValueDecl *decl) {
263263
// the result of inferring for 'x' will be considered when inferring for 'y'
264264
// either way.
265265
if (!funcDecl->hasBody() || !dc->getParentSourceFile() ||
266-
!TypeChecker::findReturnStatements(funcDecl).empty()) {
266+
funcDecl->bodyHasExplicitReturnStmt()) {
267267
return Type();
268268
}
269269

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,6 @@ void typeCheckASTNode(ASTNode &node, DeclContext *DC,
468468
std::optional<BraceStmt *> applyResultBuilderBodyTransform(FuncDecl *func,
469469
Type builderType);
470470

471-
/// Find the return statements within the body of the given function.
472-
std::vector<ReturnStmt *> findReturnStatements(AnyFunctionRef fn);
473-
474471
bool typeCheckTapBody(TapExpr *expr, DeclContext *DC);
475472

476473
Type typeCheckParameterDefault(Expr *&defaultValue, DeclContext *DC,

0 commit comments

Comments
 (0)