Skip to content

Commit 98e65d0

Browse files
authored
Merge pull request swiftlang#69946 from tshortli/silgen-lazy-typecheck-lazy-var
Sema: Always mark initializers of lazy vars as subsumed
2 parents e395df3 + 84098f9 commit 98e65d0

12 files changed

+83
-68
lines changed

Diff for: lib/AST/Decl.cpp

-7
Original file line numberDiff line numberDiff line change
@@ -9188,13 +9188,6 @@ bool IsFunctionBodySkippedRequest::evaluate(
91889188
// typecheck them.
91899189
if (accessor->hasForcedStaticDispatch())
91909190
return false;
9191-
9192-
if (auto *varDecl = dyn_cast<VarDecl>(accessor->getStorage())) {
9193-
// FIXME: If we don't typecheck the synthesized accessors of lazy storage
9194-
// properties then SILGen crashes when emitting the initializer.
9195-
if (varDecl->getAttrs().hasAttribute<LazyAttr>() && accessor->isSynthesized())
9196-
return false;
9197-
}
91989191
}
91999192

92009193
// Actor initializers need to be checked to determine delegation status.

Diff for: lib/SILGen/SILGen.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
994994
auto arg = param->getTypeCheckedDefaultExpr();
995995
auto loc = RegularLocation::getAutoGeneratedLocation(arg);
996996
preEmitFunction(constant, f, loc);
997-
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
997+
PrettyStackTraceSILFunction X("silgen default arg initializer", f);
998998
SILGenFunction SGF(*this, *f, initDC);
999999
SGF.emitGeneratorFunction(constant, arg);
10001000
postEmitFunction(constant, f);
@@ -1005,7 +1005,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
10051005
auto arg = param->getStoredProperty();
10061006
auto loc = RegularLocation::getAutoGeneratedLocation(arg);
10071007
preEmitFunction(constant, f, loc);
1008-
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
1008+
PrettyStackTraceSILFunction X("silgen stored property initializer", f);
10091009
SILGenFunction SGF(*this, *f, initDC);
10101010
SGF.emitGeneratorFunction(constant, arg);
10111011
postEmitFunction(constant, f);

Diff for: lib/Sema/TypeCheckStorage.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -1670,12 +1670,8 @@ synthesizeLazyGetterBody(AccessorDecl *Get, VarDecl *VD, VarDecl *Storage,
16701670

16711671
Expr *InitValue;
16721672
if (PBD->getInit(entryIndex)) {
1673-
PBD->setInitializerSubsumed(entryIndex);
1674-
1675-
if (!PBD->isInitializerChecked(entryIndex))
1676-
TypeChecker::typeCheckPatternBinding(PBD, entryIndex);
1677-
1678-
InitValue = PBD->getInit(entryIndex);
1673+
assert(PBD->isInitializerSubsumed(entryIndex));
1674+
InitValue = PBD->getCheckedAndContextualizedInit(entryIndex);
16791675
} else {
16801676
InitValue = new (Ctx) ErrorExpr(SourceRange(), Tmp2VD->getTypeInContext());
16811677
}
@@ -2786,6 +2782,11 @@ LazyStoragePropertyRequest::evaluate(Evaluator &evaluator,
27862782

27872783
addMemberToContextIfNeeded(PBD, VD->getDeclContext(), Storage);
27882784

2785+
// Make sure the original init is marked as subsumed.
2786+
auto *originalPBD = VD->getParentPatternBinding();
2787+
auto originalIndex = originalPBD->getPatternEntryIndexForVarDecl(VD);
2788+
originalPBD->setInitializerSubsumed(originalIndex);
2789+
27892790
return Storage;
27902791
}
27912792

Diff for: test/Frontend/skip-function-bodies.swift

+11-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
// RUN: %target-swift-emit-module-interface(%t/NoSkip.swiftinterface) %s -module-name Skip
2727
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-TEXTUAL --input-file %t/NoSkip.swiftinterface
2828
// RUN: diff -u %t/Skip.noninlinable.swiftinterface %t/NoSkip.swiftinterface
29-
// FIXME: Skipping all function bodies causes the interfaces not to match.
30-
// diff -u %t/Skip.all.swiftinterface %t/NoSkip.swiftinterface
29+
// RUN: diff -u %t/Skip.all.swiftinterface %t/NoSkip.swiftinterface
3130

3231
// Skipping all function bodies should skip *all* SIL.
3332
// CHECK-SIL-SKIP-ALL: sil_stage canonical
@@ -480,6 +479,16 @@ public struct Struct {
480479
// CHECK-SIL-SKIP-NONINLINE: "Struct.varWithInlinableSetter.setter"
481480
// CHECK-SIL-SKIP-WITHOUTTYPES: "Struct.varWithInlinableSetter.setter"
482481

482+
public lazy var varWithLazyInitializer: Int = {
483+
// We currently don't have a way to skip typechecking a pattern binding
484+
// initializer expression
485+
_blackHole("Struct.varWithLazyInitializer.init")
486+
return 0
487+
}()
488+
// CHECK-TEXTUAL-NOT: "Struct.varWithLazyInitializer.init"
489+
// CHECK-SIL-NO-SKIP: "Struct.varWithLazyInitializer.init"
490+
// CHECK-SIL-SKIP-NONINLINE-OR-WITHOUTTYPES-NOT: "Struct.varWithLazyInitializer.init"
491+
483492
public var varWithObserverDidSet: Int = 1 {
484493
didSet {
485494
// Body typechecked regardless

Diff for: test/Inputs/lazy_typecheck.swift

+4
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ protocol InternalProtoConformingToPublicProto: PublicProto {
133133
public struct PublicStruct {
134134
public var publicProperty: Int = NoTypecheck.int
135135
public var publicPropertyInferredType = ""
136+
public var publicLazyProperty: Int = NoTypecheck.int
137+
public var publicLazyPropertyInferred = 1
136138
@PublicWrapper public var publicWrappedProperty = 3.14
137139
@_transparent public var publicTransparentProperty: Int {
138140
get { return 1 }
@@ -192,6 +194,8 @@ struct InternalStruct: NoTypecheckProto {
192194
public class PublicClass {
193195
public var publicProperty: Int = NoTypecheck.int
194196
public var publicPropertyInferredType = ""
197+
public var publicLazyProperty: Int = NoTypecheck.int
198+
public var publicLazyPropertyInferred = 1
195199
@PublicWrapper public final var publicFinalWrappedProperty: Bool = false
196200
public static let publicStaticProperty: Int = NoTypecheck.int
197201
public static let publicStaticPropertyInferred = 2

Diff for: test/Inputs/lazy_typecheck_client.swift

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ func testPublicStructs() {
3737
let _: Int = s.publicMethod()
3838
let _: Int = s.publicProperty
3939
let _: String = s.publicPropertyInferredType
40+
let _: Int = s.publicLazyProperty
41+
let _: Int = s.publicLazyPropertyInferred
4042
let _: Double = s.publicWrappedProperty
4143
let _: Double = s.$publicWrappedProperty.wrappedValue
4244
let _: Int = s.publicTransparentProperty
@@ -59,6 +61,8 @@ func testPublicClasses() {
5961
let _: Int = c.publicMethod()
6062
let _: Int = c.publicProperty
6163
let _: String = c.publicPropertyInferredType
64+
let _: Int = c.publicLazyProperty
65+
let _: Int = c.publicLazyPropertyInferred
6266
c.publicFinalWrappedProperty = true
6367
PublicClass.publicClassMethod()
6468
let _: Int = PublicClass.publicStaticProperty

Diff for: test/SILGen/lazy_typecheck_var_init.swift

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ public struct S {
2222
// CHECK-LABEL: sil [transparent]{{.*}} @$s4Test1SV12instanceVar2Sivpfi : $@convention(thin) () -> Int {
2323
public var instanceVar2 = internalFunc(.b)
2424

25-
// FIXME: This initializer should be subsumed.
26-
// CHECK-LAZY: sil [transparent] [ossa] @$s4Test1SV15lazyInstanceVarSivpfi : $@convention(thin) () -> Int {
27-
// CHECK-NON-LAZY-NOT: sil [transparent] [ossa] @$s4Test1SV15lazyInstanceVarSivpfi : $@convention(thin) () -> Int {
25+
// CHECK-NOT: s4Test1SV15lazyInstanceVarSivpfi
2826
// CHECK-LABEL: sil [transparent]{{.*}} @$s4Test1SV018$__lazy_storage_$_B11InstanceVar33_0E4F053AA3AB7D4CDE3A37DBA8EF0430LLSiSgvpfi : $@convention(thin) () -> Optional<Int> {
2927
public lazy var lazyInstanceVar = internalFunc()
3028

Diff for: test/SILGen/skip-function-bodies-forced-static-dispatch-accessor.swift

-20
This file was deleted.

Diff for: test/SILGen/skip-function-bodies-lazy-property.swift

-15
This file was deleted.

Diff for: test/SILGen/skip-function-bodies-clang-enum-init-raw-value.swift renamed to test/SILGen/skip_function_bodies_clang_enum_init_raw_value.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend -emit-silgen %s -import-objc-header %S/Inputs/open_enum.h -experimental-skip-non-inlinable-function-bodies | %FileCheck %s
3-
// RUN: %target-swift-frontend -emit-silgen %s -import-objc-header %S/Inputs/open_enum.h -experimental-skip-non-inlinable-function-bodies-without-types | %FileCheck %s
4-
// RUN: %target-swift-frontend -emit-silgen %s -import-objc-header %S/Inputs/open_enum.h -debug-forbid-typecheck-prefix SKIP_ALL_NO_TYPECHECK -experimental-skip-all-function-bodies | %FileCheck %s --check-prefix=CHECK-SKIP-ALL
2+
// RUN: %target-swift-frontend -emit-silgen %s -module-name main -import-objc-header %S/Inputs/open_enum.h -experimental-skip-non-inlinable-function-bodies | %FileCheck %s
3+
// RUN: %target-swift-frontend -emit-silgen %s -module-name main -import-objc-header %S/Inputs/open_enum.h -experimental-skip-non-inlinable-function-bodies-without-types | %FileCheck %s
4+
// RUN: %target-swift-frontend -emit-silgen %s -module-name main -import-objc-header %S/Inputs/open_enum.h -debug-forbid-typecheck-prefix SKIP_ALL_NO_TYPECHECK -experimental-skip-all-function-bodies | %FileCheck %s --check-prefix=CHECK-SKIP-ALL
55

66
// CHECK-SKIP-ALL-NOT: s4main13inlinableFuncSo7YesOrNoVyF
77

Diff for: test/SILGen/skip_function_bodies_storage.swift

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-silgen %s -module-name main -experimental-skip-non-inlinable-function-bodies | %FileCheck %s
3+
// RUN: %target-swift-frontend -emit-silgen %s -module-name main -experimental-skip-non-inlinable-function-bodies-without-types | %FileCheck %s
4+
// RUN: %target-swift-frontend -emit-silgen %s -module-name main -import-objc-header %S/Inputs/open_enum.h -debug-forbid-typecheck-prefix SKIP_ALL_NO_TYPECHECK -experimental-skip-all-function-bodies | %FileCheck %s --check-prefix=CHECK-SKIP-ALL
5+
6+
// CHECK-SKIP-ALL: sil_stage raw
7+
// CHECK-SKIP-ALL-NOT: sil
8+
9+
public protocol P {
10+
@_borrowed var borrowedVar: Int { get }
11+
}
12+
13+
func generateNumber() -> Int { return 1 }
14+
15+
public struct S {
16+
public var borrowedVar: Int
17+
18+
public lazy var lazyVar: Int = generateNumber()
19+
20+
// CHECK: sil [transparent] [serialized]{{.*}} @$s4main1SV7lazyVarSivM : $@yield_once @convention(method) (@inout S) -> @yields @inout Int
21+
// CHECK: end sil function '$s4main1SV7lazyVarSivM'
22+
23+
// CHECK: sil [lazy_getter]{{.*}} @$s4main1SV7lazyVarSivg : $@convention(method) (@inout S) -> Int
24+
// CHECK-NOT: end sil function '$s4main1SV7lazyVarSivg'
25+
26+
// CHECK: sil{{.*}} @$s4main1SV7lazyVarSivs : $@convention(method) (Int, @inout S) -> ()
27+
// CHECK-NOT: end sil function '$s4main1SV7lazyVarSivs'
28+
29+
// CHECK: sil [transparent]{{.*}} @$s4main1SV018$__lazy_storage_$_B3Var33_39316373847D37F82BD23977A13DEF23LLSiSgvpfi : $@convention(thin) () -> Optional<Int>
30+
// CHECK: end sil function '$s4main1SV018$__lazy_storage_$_B3Var33_39316373847D37F82BD23977A13DEF23LLSiSgvpfi'
31+
32+
}
33+
34+
/// Since `borrowedVar` implements a `@_borrowed` requirement of `P` the synthesized
35+
/// `_read` accessor has forced static dispatch and is a serialized function
36+
/// even though it is not `@_transparent`.
37+
extension S: P {}
38+
39+
// CHECK: sil shared [serialized]{{.*}} @$s4main1SV11borrowedVarSivr : $@yield_once @convention(method) (S) -> @yields Int {
40+
// CHECK: yield
41+
// CHECK: } // end sil function '$s4main1SV11borrowedVarSivr'

Diff for: test/SILGen/skip-non-exportable-decls.swift renamed to test/SILGen/skip_non_exportable_decls.swift

+10-10
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import Swift
1515

1616
// CHECK: sil_global @$s4Test15publicGlobalVarSivp : $Int
1717

18-
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test11privateFunc33_E3F0E1C7B46D05C8067CB98677DE566CLLyyF : $@convention(thin) () -> () {
19-
// CHECK-SKIP-NOT: s4Test11privateFunc33_E3F0E1C7B46D05C8067CB98677DE566CLLyyF
18+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test11privateFunc33_CFB3F9DC47F5EF9E1D08B58758351A08LLyyF : $@convention(thin) () -> () {
19+
// CHECK-SKIP-NOT: s4Test11privateFunc33_CFB3F9DC47F5EF9E1D08B58758351A08LLyyF
2020
private func privateFunc() {}
2121

2222
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test12internalFuncyyF : $@convention(thin) () -> () {
@@ -71,17 +71,17 @@ public var publicGlobalVar = 1
7171
// CHECK: sil shared [serialized]{{.*}} @$s4Test023inlinableFuncWithNestedC0yyF6nestedL_yyF : $@convention(thin) () -> () {
7272

7373
private class PrivateClass {
74-
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfd : $@convention(method) (@guaranteed PrivateClass) -> @owned Builtin.NativeObject {
75-
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfd
74+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfd : $@convention(method) (@guaranteed PrivateClass) -> @owned Builtin.NativeObject {
75+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfd
7676

77-
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfD : $@convention(method) (@owned PrivateClass) -> () {
78-
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfD
77+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfD : $@convention(method) (@owned PrivateClass) -> () {
78+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfD
7979

80-
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfC : $@convention(method) (@thick PrivateClass.Type) -> @owned PrivateClass {
81-
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfC
80+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfC : $@convention(method) (@thick PrivateClass.Type) -> @owned PrivateClass {
81+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfC
8282

83-
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfc : $@convention(method) (@owned PrivateClass) -> @owned PrivateClass {
84-
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfc
83+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfc : $@convention(method) (@owned PrivateClass) -> @owned PrivateClass {
84+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfc
8585
}
8686

8787
public class PublicClass {

0 commit comments

Comments
 (0)