diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 0cd1fa94d7eb6..2d14c3f42b6f9 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -9188,13 +9188,6 @@ bool IsFunctionBodySkippedRequest::evaluate( // typecheck them. if (accessor->hasForcedStaticDispatch()) return false; - - if (auto *varDecl = dyn_cast(accessor->getStorage())) { - // FIXME: If we don't typecheck the synthesized accessors of lazy storage - // properties then SILGen crashes when emitting the initializer. - if (varDecl->getAttrs().hasAttribute() && accessor->isSynthesized()) - return false; - } } // Actor initializers need to be checked to determine delegation status. diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index 44de1a0138b2b..1b29af764d13f 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -994,7 +994,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { auto arg = param->getTypeCheckedDefaultExpr(); auto loc = RegularLocation::getAutoGeneratedLocation(arg); preEmitFunction(constant, f, loc); - PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f); + PrettyStackTraceSILFunction X("silgen default arg initializer", f); SILGenFunction SGF(*this, *f, initDC); SGF.emitGeneratorFunction(constant, arg); postEmitFunction(constant, f); @@ -1005,7 +1005,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { auto arg = param->getStoredProperty(); auto loc = RegularLocation::getAutoGeneratedLocation(arg); preEmitFunction(constant, f, loc); - PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f); + PrettyStackTraceSILFunction X("silgen stored property initializer", f); SILGenFunction SGF(*this, *f, initDC); SGF.emitGeneratorFunction(constant, arg); postEmitFunction(constant, f); diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index 841666e739bfc..e6ff99795edf7 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -1670,12 +1670,8 @@ synthesizeLazyGetterBody(AccessorDecl *Get, VarDecl *VD, VarDecl *Storage, Expr *InitValue; if (PBD->getInit(entryIndex)) { - PBD->setInitializerSubsumed(entryIndex); - - if (!PBD->isInitializerChecked(entryIndex)) - TypeChecker::typeCheckPatternBinding(PBD, entryIndex); - - InitValue = PBD->getInit(entryIndex); + assert(PBD->isInitializerSubsumed(entryIndex)); + InitValue = PBD->getCheckedAndContextualizedInit(entryIndex); } else { InitValue = new (Ctx) ErrorExpr(SourceRange(), Tmp2VD->getTypeInContext()); } @@ -2786,6 +2782,11 @@ LazyStoragePropertyRequest::evaluate(Evaluator &evaluator, addMemberToContextIfNeeded(PBD, VD->getDeclContext(), Storage); + // Make sure the original init is marked as subsumed. + auto *originalPBD = VD->getParentPatternBinding(); + auto originalIndex = originalPBD->getPatternEntryIndexForVarDecl(VD); + originalPBD->setInitializerSubsumed(originalIndex); + return Storage; } diff --git a/test/Frontend/skip-function-bodies.swift b/test/Frontend/skip-function-bodies.swift index 5ce29250c74ef..c4919b59c10d4 100644 --- a/test/Frontend/skip-function-bodies.swift +++ b/test/Frontend/skip-function-bodies.swift @@ -26,8 +26,7 @@ // RUN: %target-swift-emit-module-interface(%t/NoSkip.swiftinterface) %s -module-name Skip // RUN: %FileCheck %s --check-prefixes CHECK,CHECK-TEXTUAL --input-file %t/NoSkip.swiftinterface // RUN: diff -u %t/Skip.noninlinable.swiftinterface %t/NoSkip.swiftinterface -// FIXME: Skipping all function bodies causes the interfaces not to match. -// diff -u %t/Skip.all.swiftinterface %t/NoSkip.swiftinterface +// RUN: diff -u %t/Skip.all.swiftinterface %t/NoSkip.swiftinterface // Skipping all function bodies should skip *all* SIL. // CHECK-SIL-SKIP-ALL: sil_stage canonical @@ -480,6 +479,16 @@ public struct Struct { // CHECK-SIL-SKIP-NONINLINE: "Struct.varWithInlinableSetter.setter" // CHECK-SIL-SKIP-WITHOUTTYPES: "Struct.varWithInlinableSetter.setter" + public lazy var varWithLazyInitializer: Int = { + // We currently don't have a way to skip typechecking a pattern binding + // initializer expression + _blackHole("Struct.varWithLazyInitializer.init") + return 0 + }() + // CHECK-TEXTUAL-NOT: "Struct.varWithLazyInitializer.init" + // CHECK-SIL-NO-SKIP: "Struct.varWithLazyInitializer.init" + // CHECK-SIL-SKIP-NONINLINE-OR-WITHOUTTYPES-NOT: "Struct.varWithLazyInitializer.init" + public var varWithObserverDidSet: Int = 1 { didSet { // Body typechecked regardless diff --git a/test/Inputs/lazy_typecheck.swift b/test/Inputs/lazy_typecheck.swift index 9abb1863f343e..8d16662a40f1c 100644 --- a/test/Inputs/lazy_typecheck.swift +++ b/test/Inputs/lazy_typecheck.swift @@ -133,6 +133,8 @@ protocol InternalProtoConformingToPublicProto: PublicProto { public struct PublicStruct { public var publicProperty: Int = NoTypecheck.int public var publicPropertyInferredType = "" + public var publicLazyProperty: Int = NoTypecheck.int + public var publicLazyPropertyInferred = 1 @PublicWrapper public var publicWrappedProperty = 3.14 @_transparent public var publicTransparentProperty: Int { get { return 1 } @@ -192,6 +194,8 @@ struct InternalStruct: NoTypecheckProto { public class PublicClass { public var publicProperty: Int = NoTypecheck.int public var publicPropertyInferredType = "" + public var publicLazyProperty: Int = NoTypecheck.int + public var publicLazyPropertyInferred = 1 @PublicWrapper public final var publicFinalWrappedProperty: Bool = false public static let publicStaticProperty: Int = NoTypecheck.int public static let publicStaticPropertyInferred = 2 diff --git a/test/Inputs/lazy_typecheck_client.swift b/test/Inputs/lazy_typecheck_client.swift index 9c8216cb5c661..0d211b7b224d3 100644 --- a/test/Inputs/lazy_typecheck_client.swift +++ b/test/Inputs/lazy_typecheck_client.swift @@ -37,6 +37,8 @@ func testPublicStructs() { let _: Int = s.publicMethod() let _: Int = s.publicProperty let _: String = s.publicPropertyInferredType + let _: Int = s.publicLazyProperty + let _: Int = s.publicLazyPropertyInferred let _: Double = s.publicWrappedProperty let _: Double = s.$publicWrappedProperty.wrappedValue let _: Int = s.publicTransparentProperty @@ -59,6 +61,8 @@ func testPublicClasses() { let _: Int = c.publicMethod() let _: Int = c.publicProperty let _: String = c.publicPropertyInferredType + let _: Int = c.publicLazyProperty + let _: Int = c.publicLazyPropertyInferred c.publicFinalWrappedProperty = true PublicClass.publicClassMethod() let _: Int = PublicClass.publicStaticProperty diff --git a/test/SILGen/lazy_typecheck_var_init.swift b/test/SILGen/lazy_typecheck_var_init.swift index 5f40d09af16d6..f93ee934a580e 100644 --- a/test/SILGen/lazy_typecheck_var_init.swift +++ b/test/SILGen/lazy_typecheck_var_init.swift @@ -22,9 +22,7 @@ public struct S { // CHECK-LABEL: sil [transparent]{{.*}} @$s4Test1SV12instanceVar2Sivpfi : $@convention(thin) () -> Int { public var instanceVar2 = internalFunc(.b) - // FIXME: This initializer should be subsumed. - // CHECK-LAZY: sil [transparent] [ossa] @$s4Test1SV15lazyInstanceVarSivpfi : $@convention(thin) () -> Int { - // CHECK-NON-LAZY-NOT: sil [transparent] [ossa] @$s4Test1SV15lazyInstanceVarSivpfi : $@convention(thin) () -> Int { + // CHECK-NOT: s4Test1SV15lazyInstanceVarSivpfi // CHECK-LABEL: sil [transparent]{{.*}} @$s4Test1SV018$__lazy_storage_$_B11InstanceVar33_0E4F053AA3AB7D4CDE3A37DBA8EF0430LLSiSgvpfi : $@convention(thin) () -> Optional { public lazy var lazyInstanceVar = internalFunc() diff --git a/test/SILGen/skip-function-bodies-forced-static-dispatch-accessor.swift b/test/SILGen/skip-function-bodies-forced-static-dispatch-accessor.swift deleted file mode 100644 index 33761d726b3f3..0000000000000 --- a/test/SILGen/skip-function-bodies-forced-static-dispatch-accessor.swift +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -emit-silgen %s -experimental-skip-non-inlinable-function-bodies | %FileCheck %s -// RUN: %target-swift-frontend -emit-silgen %s -experimental-skip-non-inlinable-function-bodies-without-types | %FileCheck %s -// 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 - -public protocol P { - @_borrowed var x: Int { get } -} - -public struct S: P { - /// Since x implements a `@_borrowed` requirement of `P` the synthesized - /// `_read` accessor has forced static dispatch and is a serialized function - /// even though it is not `@_transparent`. - public var x: Int - - // CHECK-SKIP-ALL-NOT: s4main1SV1xSivr - // CHECK: sil shared [serialized]{{.*}} @$s4main1SV1xSivr : $@yield_once @convention(method) (S) -> @yields Int { - // CHECK: yield - // CHECK: } // end sil function '$s4main1SV1xSivr' -} diff --git a/test/SILGen/skip-function-bodies-lazy-property.swift b/test/SILGen/skip-function-bodies-lazy-property.swift deleted file mode 100644 index 124ab3cbddde2..0000000000000 --- a/test/SILGen/skip-function-bodies-lazy-property.swift +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -emit-silgen %s -experimental-skip-non-inlinable-function-bodies | %FileCheck %s -// RUN: %target-swift-frontend -emit-silgen %s -experimental-skip-non-inlinable-function-bodies-without-types | %FileCheck %s -// RUN: %target-swift-frontend -emit-silgen %s -experimental-skip-all-function-bodies | %FileCheck %s --check-prefix=CHECK-SKIP-ALL - -public struct S { - public lazy var x: Int = generateNumber() - - // CHECK-SKIP-ALL-NOT: s4main1SV1xSivg - // CHECK: sil [lazy_getter]{{.*}} @$s4main1SV1xSivg : $@convention(method) (@inout S) -> Int { - // CHECK: function_ref @$s4main1SV14generateNumberSiyF - // CHECK: } // end sil function '$s4main1SV1xSivg' - - func generateNumber() -> Int { return 1 } -} diff --git a/test/SILGen/skip-function-bodies-clang-enum-init-raw-value.swift b/test/SILGen/skip_function_bodies_clang_enum_init_raw_value.swift similarity index 56% rename from test/SILGen/skip-function-bodies-clang-enum-init-raw-value.swift rename to test/SILGen/skip_function_bodies_clang_enum_init_raw_value.swift index 881525e963310..465bf8338ff17 100644 --- a/test/SILGen/skip-function-bodies-clang-enum-init-raw-value.swift +++ b/test/SILGen/skip_function_bodies_clang_enum_init_raw_value.swift @@ -1,7 +1,7 @@ // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -emit-silgen %s -import-objc-header %S/Inputs/open_enum.h -experimental-skip-non-inlinable-function-bodies | %FileCheck %s -// 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 -// 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 +// 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 +// 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 +// 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 // CHECK-SKIP-ALL-NOT: s4main13inlinableFuncSo7YesOrNoVyF diff --git a/test/SILGen/skip_function_bodies_storage.swift b/test/SILGen/skip_function_bodies_storage.swift new file mode 100644 index 0000000000000..8287071c7243e --- /dev/null +++ b/test/SILGen/skip_function_bodies_storage.swift @@ -0,0 +1,41 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-silgen %s -module-name main -experimental-skip-non-inlinable-function-bodies | %FileCheck %s +// RUN: %target-swift-frontend -emit-silgen %s -module-name main -experimental-skip-non-inlinable-function-bodies-without-types | %FileCheck %s +// 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 + +// CHECK-SKIP-ALL: sil_stage raw +// CHECK-SKIP-ALL-NOT: sil + +public protocol P { + @_borrowed var borrowedVar: Int { get } +} + +func generateNumber() -> Int { return 1 } + +public struct S { + public var borrowedVar: Int + + public lazy var lazyVar: Int = generateNumber() + + // CHECK: sil [transparent] [serialized]{{.*}} @$s4main1SV7lazyVarSivM : $@yield_once @convention(method) (@inout S) -> @yields @inout Int + // CHECK: end sil function '$s4main1SV7lazyVarSivM' + + // CHECK: sil [lazy_getter]{{.*}} @$s4main1SV7lazyVarSivg : $@convention(method) (@inout S) -> Int + // CHECK-NOT: end sil function '$s4main1SV7lazyVarSivg' + + // CHECK: sil{{.*}} @$s4main1SV7lazyVarSivs : $@convention(method) (Int, @inout S) -> () + // CHECK-NOT: end sil function '$s4main1SV7lazyVarSivs' + + // CHECK: sil [transparent]{{.*}} @$s4main1SV018$__lazy_storage_$_B3Var33_39316373847D37F82BD23977A13DEF23LLSiSgvpfi : $@convention(thin) () -> Optional + // CHECK: end sil function '$s4main1SV018$__lazy_storage_$_B3Var33_39316373847D37F82BD23977A13DEF23LLSiSgvpfi' + +} + +/// Since `borrowedVar` implements a `@_borrowed` requirement of `P` the synthesized +/// `_read` accessor has forced static dispatch and is a serialized function +/// even though it is not `@_transparent`. +extension S: P {} + +// CHECK: sil shared [serialized]{{.*}} @$s4main1SV11borrowedVarSivr : $@yield_once @convention(method) (S) -> @yields Int { +// CHECK: yield +// CHECK: } // end sil function '$s4main1SV11borrowedVarSivr' diff --git a/test/SILGen/skip-non-exportable-decls.swift b/test/SILGen/skip_non_exportable_decls.swift similarity index 87% rename from test/SILGen/skip-non-exportable-decls.swift rename to test/SILGen/skip_non_exportable_decls.swift index 9cf5c6f4390b5..27b15898b86e5 100644 --- a/test/SILGen/skip-non-exportable-decls.swift +++ b/test/SILGen/skip_non_exportable_decls.swift @@ -15,8 +15,8 @@ import Swift // CHECK: sil_global @$s4Test15publicGlobalVarSivp : $Int -// CHECK-NO-SKIP: sil private{{.*}} @$s4Test11privateFunc33_E3F0E1C7B46D05C8067CB98677DE566CLLyyF : $@convention(thin) () -> () { -// CHECK-SKIP-NOT: s4Test11privateFunc33_E3F0E1C7B46D05C8067CB98677DE566CLLyyF +// CHECK-NO-SKIP: sil private{{.*}} @$s4Test11privateFunc33_CFB3F9DC47F5EF9E1D08B58758351A08LLyyF : $@convention(thin) () -> () { +// CHECK-SKIP-NOT: s4Test11privateFunc33_CFB3F9DC47F5EF9E1D08B58758351A08LLyyF private func privateFunc() {} // CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test12internalFuncyyF : $@convention(thin) () -> () { @@ -71,17 +71,17 @@ public var publicGlobalVar = 1 // CHECK: sil shared [serialized]{{.*}} @$s4Test023inlinableFuncWithNestedC0yyF6nestedL_yyF : $@convention(thin) () -> () { private class PrivateClass { - // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfd : $@convention(method) (@guaranteed PrivateClass) -> @owned Builtin.NativeObject { - // CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfd + // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfd : $@convention(method) (@guaranteed PrivateClass) -> @owned Builtin.NativeObject { + // CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfd - // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfD : $@convention(method) (@owned PrivateClass) -> () { - // CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfD + // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfD : $@convention(method) (@owned PrivateClass) -> () { + // CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCfD - // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfC : $@convention(method) (@thick PrivateClass.Type) -> @owned PrivateClass { - // CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfC + // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfC : $@convention(method) (@thick PrivateClass.Type) -> @owned PrivateClass { + // CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfC - // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfc : $@convention(method) (@owned PrivateClass) -> @owned PrivateClass { - // CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfc + // CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfc : $@convention(method) (@owned PrivateClass) -> @owned PrivateClass { + // CHECK-SKIP-NOT: s4Test12PrivateClass33_CFB3F9DC47F5EF9E1D08B58758351A08LLCADycfc } public class PublicClass {