Skip to content

Commit fa4e814

Browse files
authored
Merge pull request #34421 from slavapestov/enum-protocol-witness-vs-resilience
SILGen: Fix crash in emitEnumConstructor() if type lowering depends on resilience
2 parents 246fe46 + 5413488 commit fa4e814

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@ IsSerialized_t SILDeclRef::isSerialized() const {
531531
if (d->getEffectiveAccess() < AccessLevel::Public)
532532
return IsNotSerialized;
533533

534+
// Enum element constructors are serializable if the enum is
535+
// @usableFromInline or public.
536+
if (isEnumElement())
537+
return IsSerializable;
538+
534539
// 'read' and 'modify' accessors synthesized on-demand are serialized if
535540
// visible outside the module.
536541
if (auto fn = dyn_cast<FuncDecl>(d))

lib/SILGen/SILGenConstructor.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,11 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
544544
// Return the enum.
545545
auto ReturnLoc = ImplicitReturnLocation::getImplicitReturnLoc(Loc);
546546

547-
if (mv.isInContext()) {
548-
assert(enumTI.isAddressOnly());
547+
if (dest) {
548+
if (!mv.isInContext()) {
549+
dest->copyOrInitValueInto(*this, Loc, mv, /*isInit*/ true);
550+
dest->finishInitialization(*this);
551+
}
549552
scope.pop();
550553
B.createReturn(ReturnLoc, emitEmptyTuple(Loc));
551554
} else {
Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
// RUN: %target-swift-emit-silgen %s -enable-library-evolution
23

3-
protocol Foo {
4+
public protocol Foo {
45
static var button: Self { get }
56
}
67

7-
enum Bar: Foo {
8+
public enum Bar: Foo {
89
case button
910
}
1011

11-
protocol AnotherFoo {
12+
public protocol AnotherFoo {
1213
static func bar(arg: Int) -> Self
1314
}
1415

15-
enum AnotherBar: AnotherFoo {
16+
public enum AnotherBar: AnotherFoo {
1617
case bar(arg: Int)
1718
}
1819

19-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21protocol_enum_witness3BarOAA3FooA2aDP6buttonxvgZTW : $@convention(witness_method: Foo) (@thick Bar.Type) -> @out Bar {
20+
public struct PublicStruct {}
21+
22+
enum InternalEnumWithPublicStruct : Foo {
23+
case button
24+
case other(PublicStruct)
25+
}
26+
27+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s21protocol_enum_witness3BarOAA3FooA2aDP6buttonxvgZTW : $@convention(witness_method: Foo) (@thick Bar.Type) -> @out Bar {
2028
// CHECK: bb0([[BAR:%.*]] : $*Bar, [[BAR_TYPE:%.*]] : $@thick Bar.Type):
2129
// CHECK-NEXT: [[META_TYPE:%.*]] = metatype $@thin Bar.Type
2230
// CHECK: [[REF:%.*]] = function_ref @$s21protocol_enum_witness3BarO6buttonyA2CmF : $@convention(method) (@thin Bar.Type) -> Bar
@@ -26,13 +34,13 @@ enum AnotherBar: AnotherFoo {
2634
// CHECK-NEXT: return [[TUPLE]] : $()
2735
// CHECK-END: }
2836

29-
// CHECK-LABEL: sil shared [transparent] [ossa] @$s21protocol_enum_witness3BarO6buttonyA2CmF : $@convention(method) (@thin Bar.Type) -> Bar {
37+
// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$s21protocol_enum_witness3BarO6buttonyA2CmF : $@convention(method) (@thin Bar.Type) -> Bar {
3038
// CHECK: bb0({{%.*}} : $@thin Bar.Type):
3139
// CHECK-NEXT: [[CASE:%.*]] = enum $Bar, #Bar.button!enumelt
3240
// CHECK-NEXT: return [[CASE]] : $Bar
3341
// CHECK-END: }
3442

35-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21protocol_enum_witness10AnotherBarOAA0D3FooA2aDP3bar3argxSi_tFZTW : $@convention(witness_method: AnotherFoo) (Int, @thick AnotherBar.Type) -> @out AnotherBar {
43+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s21protocol_enum_witness10AnotherBarOAA0D3FooA2aDP3bar3argxSi_tFZTW : $@convention(witness_method: AnotherFoo) (Int, @thick AnotherBar.Type) -> @out AnotherBar {
3644
// CHECK: bb0([[ANOTHER_BAR:%.*]] : $*AnotherBar, [[INT_ARG:%.*]] : $Int, [[ANOTHER_BAR_TYPE:%.*]] : $@thick AnotherBar.Type):
3745
// CHECK-NEXT: [[META_TYPE:%.*]] = metatype $@thin AnotherBar.Type
3846
// CHECK: [[REF:%.*]] = function_ref @$s21protocol_enum_witness10AnotherBarO3baryACSi_tcACmF : $@convention(method) (Int, @thin AnotherBar.Type) -> AnotherBar
@@ -42,8 +50,8 @@ enum AnotherBar: AnotherFoo {
4250
// CHECK-NEXT: return [[TUPLE]] : $()
4351
// CHECK-END: }
4452

45-
// CHECK-LABEL: sil_witness_table hidden Bar: Foo module protocol_enum_witness {
53+
// CHECK-LABEL: sil_witness_table [serialized] Bar: Foo module protocol_enum_witness {
4654
// CHECK: method #Foo.button!getter: <Self where Self : Foo> (Self.Type) -> () -> Self : @$s21protocol_enum_witness3BarOAA3FooA2aDP6buttonxvgZTW
4755

48-
// CHECK-LABEL: sil_witness_table hidden AnotherBar: AnotherFoo module protocol_enum_witness {
56+
// CHECK-LABEL: sil_witness_table [serialized] AnotherBar: AnotherFoo module protocol_enum_witness {
4957
// CHECK: method #AnotherFoo.bar: <Self where Self : AnotherFoo> (Self.Type) -> (Int) -> Self : @$s21protocol_enum_witness10AnotherBarOAA0D3FooA2aDP3bar3argxSi_tFZTW

0 commit comments

Comments
 (0)