Skip to content

Commit 73b184d

Browse files
authored
Merge pull request #78564 from swiftlang/eng/chrismiles/playground-transform-crash-parsing-nested-generic-func
Fixes crash instrumenting generic func body nested in another func. The crash was caused by attempting to add logging expressions that capture generic variables while using the outer func decl context that was not the generic decl context of the inner (generic) func. The fix "pushes" the current func decl context while instrumenting the body. Rather than always using the top-level func decl context for all nested func bodies.
2 parents 44a4a67 + f2846ce commit 73b184d

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

lib/Sema/PCMacro.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,12 @@ class Instrumenter : InstrumenterBase {
339339
if (auto *FD = dyn_cast<FuncDecl>(D)) {
340340
if (BraceStmt *B = FD->getTypecheckedBody()) {
341341
const ParameterList *PL = FD->getParameters();
342+
343+
// Use FD's DeclContext as TypeCheckDC for transforms in func body
344+
// then swap back TypeCheckDC at end of scope.
345+
llvm::SaveAndRestore<DeclContext *> localDC(TypeCheckDC, FD);
342346
BraceStmt *NB = transformBraceStmt(B, PL);
347+
343348
// Since it would look strange going straight to the first line in a
344349
// function body, we throw in a before/after pointing at the function
345350
// decl at the start of the transformed body

lib/Sema/PlaygroundTransform.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ class Instrumenter : InstrumenterBase {
312312
if (BraceStmt *B = FD->getTypecheckedBody()) {
313313
const ParameterList *PL = FD->getParameters();
314314
TargetKindSetter TKS(BracePairs, BracePair::TargetKinds::Return);
315+
316+
// Use FD's DeclContext as TypeCheckDC for transforms in func body
317+
// then swap back TypeCheckDC at end of scope.
318+
llvm::SaveAndRestore<DeclContext *> localDC(TypeCheckDC, FD);
319+
315320
BraceStmt *NB = transformBraceStmt(B, PL);
316321
if (NB != B) {
317322
FD->setBody(NB, AbstractFunctionDecl::BodyKind::TypeChecked);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// Build PlaygroundSupport module
4+
// RUN: %target-build-swift -whole-module-optimization -module-name PlaygroundSupport -emit-module-path %t/PlaygroundSupport.swiftmodule -parse-as-library -c -o %t/PlaygroundSupport.o %S/Inputs/SilentPCMacroRuntime.swift %S/Inputs/PlaygroundsRuntime.swift
5+
6+
// RUN: %target-build-swift -swift-version 5 -emit-module -Xfrontend -playground -I=%t %s
7+
// RUN: %target-build-swift -swift-version 6 -emit-module -Xfrontend -playground -I=%t %s
8+
9+
// RUN: %target-build-swift -swift-version 5 -emit-module -Xfrontend -playground -Xfrontend -pc-macro -I=%t %s
10+
// RUN: %target-build-swift -swift-version 6 -emit-module -Xfrontend -playground -Xfrontend -pc-macro -I=%t %s
11+
12+
// REQUIRES: executable_test
13+
14+
import PlaygroundSupport
15+
16+
func test1() {
17+
func buildBlock<Content>(content: Content) {
18+
content
19+
}
20+
}
21+
22+
func test2() {
23+
func buildBlock<Content>(content: Content) -> Content {
24+
content
25+
return content
26+
}
27+
}
28+
29+
func test3<Content>(_ content: Content) {
30+
func buildBlock<Content2>(_ content2: Content2) -> Content2 {
31+
return content2
32+
}
33+
}

0 commit comments

Comments
 (0)