diff --git a/lib/IRGen/GenArchetype.cpp b/lib/IRGen/GenArchetype.cpp index a74471d787b2a..9b04b4e87dfad 100644 --- a/lib/IRGen/GenArchetype.cpp +++ b/lib/IRGen/GenArchetype.cpp @@ -99,7 +99,7 @@ class OpaqueArchetypeTypeInfo void collectMetadataForOutlining(OutliningMetadataCollector &collector, SILType T) const override { // We'll need formal type metadata for this archetype. - collector.collectFormalTypeMetadata(T.getSwiftRValueType()); + collector.collectTypeMetadataForLayout(T); } }; diff --git a/lib/IRGen/Outlining.cpp b/lib/IRGen/Outlining.cpp index cae28be03c47a..c4c60dc6ed573 100644 --- a/lib/IRGen/Outlining.cpp +++ b/lib/IRGen/Outlining.cpp @@ -35,10 +35,14 @@ void OutliningMetadataCollector::collectTypeMetadataForLayout(SILType type) { return; } + CanType formalType = type.getSwiftRValueType(); + if (isa(IGF.IGM.getTypeInfoForLowered(formalType))) { + return; + } + // If the type is a legal formal type, add it as a formal type. // FIXME: does this force us to emit a more expensive metadata than we need // to? - CanType formalType = type.getSwiftRValueType(); if (formalType->isLegalFormalType()) { return collectFormalTypeMetadata(formalType); } @@ -53,9 +57,7 @@ void OutliningMetadataCollector::collectTypeMetadataForLayout(SILType type) { void OutliningMetadataCollector::collectFormalTypeMetadata(CanType type) { // If the type has no archetypes, we can emit it from scratch in the callee. - if (!type->hasArchetype()) { - return; - } + assert(type->hasArchetype()); auto key = LocalTypeDataKey(type, LocalTypeDataKind::forFormalTypeMetadata()); if (Values.count(key)) return; diff --git a/test/IRGen/outlined_copy_addr.swift b/test/IRGen/outlined_copy_addr.swift index a4973b40cc1a4..b68a57b5bab25 100644 --- a/test/IRGen/outlined_copy_addr.swift +++ b/test/IRGen/outlined_copy_addr.swift @@ -18,9 +18,33 @@ public struct StructWithBaseStruct { var elem2: BaseStruct } -// CHECK-LABEL: define hidden swiftcc void @"$S11outcopyaddr010StructWithbc4BaseB0V4elemAA0bcdB0VyxGvg"(%T11outcopyaddr014StructWithBaseB0V.0* noalias nocapture sret, %swift.type* %"StructWithStructWithBaseStruct", %T11outcopyaddr010StructWithbc4BaseB0V* noalias nocapture swiftself) -// CHECK: call %T11outcopyaddr014StructWithBaseB0V.0* @"$S11outcopyaddr014StructWithBaseB0VyxGAA9ChildProtRzlWOc" +// CHECK-LABEL: define hidden swiftcc void @"$S11outcopyaddr010StructWithbc4BaseB0V4elemAA0bcdB0VyxGvg"(%T11outcopyaddr014StructWithBaseB0V.4* noalias nocapture sret, %swift.type* %"StructWithStructWithBaseStruct", %T11outcopyaddr010StructWithbc4BaseB0V* noalias nocapture swiftself) +// CHECK: call %T11outcopyaddr014StructWithBaseB0V.4* @"$S11outcopyaddr014StructWithBaseB0VyxGAA9ChildProtRzlWOc" public struct StructWithStructWithBaseStruct { public typealias Element = T let elem: StructWithBaseStruct } + +protocol P { } + +class OtherPrivate { } + +struct OtherInternal { + var myPrivate: OtherPrivate? = nil +} + +struct MyPrivate { + var otherHelper: OtherInternal? = nil + + // CHECK-LABEL: define hidden swiftcc {{i32|i64}} @"$S11outcopyaddr9MyPrivateVyACyxGxcfC"(%swift.opaque* noalias nocapture, %swift.type* %T, i8** %T.P) {{.*}} { + // CHECK: call %T11outcopyaddr9MyPrivateV* @"$S11outcopyaddr9MyPrivateVyxGAA1PRzlWOh"(%T11outcopyaddr9MyPrivateV* %self) + // CHECK: ret + init(_: T) { } +} + +extension P { + func foo(data: Any) { + _ = MyPrivate(data as! Self) + } +} + diff --git a/test/multifile/Inputs/outlined-thunks-other.swift b/test/multifile/Inputs/outlined-thunks-other.swift new file mode 100644 index 0000000000000..95da4035497e4 --- /dev/null +++ b/test/multifile/Inputs/outlined-thunks-other.swift @@ -0,0 +1,5 @@ +private class OtherPrivate { } + +struct OtherInternal { + fileprivate var myPrivate: OtherPrivate? = nil +} diff --git a/test/multifile/outlined-thunks.swift b/test/multifile/outlined-thunks.swift new file mode 100644 index 0000000000000..b24a959ca7b81 --- /dev/null +++ b/test/multifile/outlined-thunks.swift @@ -0,0 +1,18 @@ +// RUN: %empty-directory(%t) +// RUN: %target-build-swift -emit-library -module-name outlined_thunks %S/Inputs/outlined-thunks-other.swift %s +// RUN: %target-build-swift -emit-library -module-name outlined_thunks -whole-module-optimization %S/Inputs/outlined-thunks-other.swift %s + +// rdar://problem/39470607 + +protocol P { } + +private struct MyPrivate { + private var otherHelper: OtherInternal? = nil + init(_: T) { } +} + +extension P { + func foo(data: Any) { + _ = MyPrivate(data as! Self) + } +}