Skip to content

Commit 8055e6e

Browse files
committed
Ensures top-level functions after guard statements are typechecked
unless skipping all function bodies Changes in this commit ensure that all top-level functions appearing after a `guard` statement are always typechecked, unless `-experimental-skip-all-function-bodies` has been specified. This means that such functions should be typechecked and SILGen-ed in the presence of `-experimental-skip-non-inlinable-function-bodies` and `-experimental-skip-non-inlinable-function-bodies-without-types` flags. Fixes #57646
1 parent ecca144 commit 8055e6e

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

lib/AST/Decl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9384,6 +9384,17 @@ bool IsFunctionBodySkippedRequest::evaluate(
93849384
skippingMode == FunctionBodySkipping::NonInlinableWithoutTypes)
93859385
return false;
93869386

9387+
// If we have a top-level function with local captures, we can't skip it.
9388+
// A top-level function can have local captures if it appears after a `guard`
9389+
// statement.
9390+
if (auto *fd = dyn_cast<FuncDecl>(afd)) {
9391+
if (fd->hasTopLevelLocalContextCaptures() &&
9392+
(skippingMode == FunctionBodySkipping::NonInlinable ||
9393+
skippingMode == FunctionBodySkipping::NonInlinableWithoutTypes)) {
9394+
return false;
9395+
}
9396+
}
9397+
93879398
// Skip functions that don't need to be serialized.
93889399
return afd->getResilienceExpansion() != ResilienceExpansion::Minimal;
93899400
}

lib/SILOptimizer/UtilityPasses/SILSkippingChecker.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ static bool shouldHaveSkippedFunction(const SILFunction &F) {
7575
return false;
7676
}
7777

78+
// Top-level functions with local captures, should not be skipped.
79+
// A top-level function can have local captures if it appears after a
80+
// `guard` statement.
81+
if (auto *FD = dyn_cast<FuncDecl>(func)) {
82+
if (FD->hasTopLevelLocalContextCaptures()) {
83+
return false;
84+
}
85+
}
86+
7887
// Functions with @backDeployed may be copied into the client, so they
7988
// shouldn't be skipped. The SILFunction that may be copied into the client
8089
// should be serialized and therefore is already handled above. However, a

test/SILGen/top_level_captures.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
22
// RUN: %target-swift-frontend -enable-experimental-async-top-level -emit-silgen %s | %FileCheck %s
3+
// RUN: %target-swift-frontend -experimental-skip-non-inlinable-function-bodies -experimental-skip-non-inlinable-function-bodies-without-types -emit-silgen %s | %FileCheck %s
34

45
guard let x: Int = nil else { while true { } }
56

0 commit comments

Comments
 (0)