Skip to content

Commit ea365d5

Browse files
committed
[TypeChecker] Do not attempt to skip typechecking for didSet
15f8eb4 (see PR#26632) introduced refined didSet semantics where the `oldValue` parameter is skipped if it isn't used. This would perform typechecking, but later try to set the body to skipped and thus fire an assert. For now, do not attempt to skip typechecking of didSet accessors. Still skip outputting their SIL though.
1 parent b57aa8f commit ea365d5

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

lib/SILOptimizer/UtilityPasses/NonInlinableFunctionSkippingChecker.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ static bool shouldHaveSkippedFunction(const SILFunction &F) {
6565
if (isa<DestructorDecl>(func) || isa<ConstructorDecl>(func))
6666
return false;
6767

68+
// See DeclChecker::shouldSkipBodyTypechecking. Can't skip didSet for now.
69+
if (auto *AD = dyn_cast<AccessorDecl>(func)) {
70+
if (AD->getAccessorKind() == AccessorKind::DidSet)
71+
return false;
72+
}
73+
6874
// If none of those conditions trip, then this is something that _should_
6975
// be serialized in the module even when we're skipping non-inlinable
7076
// function bodies.

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,6 +2332,13 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23322332
if (!AFD->getBodySourceRange().isValid())
23332333
return false;
23342334

2335+
// didSet runs typechecking to determine whether to keep its parameter,
2336+
// so never try to skip.
2337+
if (auto *AD = dyn_cast<AccessorDecl>(AFD)) {
2338+
if (AD->getAccessorKind() == AccessorKind::DidSet)
2339+
return false;
2340+
}
2341+
23352342
// If we're gonna serialize the body, we can't skip it.
23362343
if (AFD->getResilienceExpansion() == ResilienceExpansion::Minimal)
23372344
return false;

test/Frontend/skip-non-inlinable-function-bodies.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,18 @@ public struct Struct {
157157
}
158158
}
159159

160+
public var willSetVar: Int = 1 {
161+
willSet {
162+
_blackHole("willSet body") // CHECK-NOT: "willSet body"
163+
}
164+
}
165+
166+
public var didSetVar: Int = 1 {
167+
didSet {
168+
_blackHole("didSet body") // CHECK-NOT: "didSet body"
169+
}
170+
}
171+
160172
@_transparent
161173
public func transparentFunc() {
162174
_blackHole("@_transparent method body") // CHECK: "@_transparent method body"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend -emit-module %s -experimental-skip-non-inlinable-function-bodies
2+
3+
struct Foo {
4+
var fieldWithDidSet : Int {
5+
didSet {
6+
let local = oldValue
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)