Skip to content

Commit 98e65d0

Browse files
authored
Merge pull request #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

lib/AST/Decl.cpp

Lines changed: 0 additions & 7 deletions
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.

lib/SILGen/SILGen.cpp

Lines changed: 2 additions & 2 deletions
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);

lib/Sema/TypeCheckStorage.cpp

Lines changed: 7 additions & 6 deletions
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

test/Frontend/skip-function-bodies.swift

Lines changed: 11 additions & 2 deletions
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

test/Inputs/lazy_typecheck.swift

Lines changed: 4 additions & 0 deletions
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

test/Inputs/lazy_typecheck_client.swift

Lines changed: 4 additions & 0 deletions
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

test/SILGen/lazy_typecheck_var_init.swift

Lines changed: 1 addition & 3 deletions
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

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

Lines changed: 0 additions & 20 deletions
This file was deleted.

test/SILGen/skip-function-bodies-lazy-property.swift

Lines changed: 0 additions & 15 deletions
This file was deleted.

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

Lines changed: 3 additions & 3 deletions
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

0 commit comments

Comments
 (0)