Skip to content

Commit 3d846b2

Browse files
author
Joe Shajrawi
committed
Resolve an issue with indirect enum's match for opaque values
1 parent 667f4e6 commit 3d846b2

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

lib/SILGen/SILGenDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ emitEnumMatch(ManagedValue value, EnumElementDecl *ElementDecl,
814814
SILValue boxedValue = SGF.B.createProjectBox(loc, eltMV.getValue(), 0);
815815
auto &boxedTL = SGF.getTypeLowering(boxedValue->getType());
816816
// SEMANTIC ARC TODO: Revisit this when the verifier is enabled.
817-
if (boxedTL.isLoadable())
817+
if (boxedTL.isLoadable() || !SGF.silConv.useLoweredAddresses())
818818
boxedValue = boxedTL.emitLoad(SGF.B, loc, boxedValue,
819819
LoadOwnershipQualifier::Take);
820820

test/SILGen/opaque_values_silgen.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ struct AnyStruct {
3030
let a: Any
3131
}
3232

33+
indirect enum IndirectEnum<T> {
34+
case Nil
35+
case Node(T)
36+
}
37+
3338
func s010_hasVarArg(_ args: Any...) {}
3439

3540
// Tests Address only enums's construction
@@ -675,6 +680,36 @@ func s350_______addrOnlyIf(x: Bool) -> EmptyP {
675680
return x ? a : a
676681
}
677682

683+
// Tests support for guards and indirect enums for opaque values
684+
// ---
685+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s360________guardEnumyAA08IndirectF0OyxGlF : $@convention(thin) <T> (@owned IndirectEnum<T>) -> () {
686+
// CHECK: bb0([[ARG:%.*]] : $IndirectEnum<T>):
687+
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
688+
// CHECK: [[COPY__ARG:%.*]] = copy_value [[BORROWED_ARG]]
689+
// CHECK: switch_enum [[COPY__ARG]] : $IndirectEnum<T>, case #IndirectEnum.Node!enumelt.1: bb3, default bb1
690+
// CHECK: bb1:
691+
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]] : $IndirectEnum<T>, $IndirectEnum<T>
692+
// CHECK: br bb2
693+
// CHECK: bb2:
694+
// CHECK: br bb4
695+
// CHECK: bb3([[EARG:%.*]] : $<τ_0_0> { var τ_0_0 } <T>):
696+
// CHECK: [[PROJ_BOX:%.*]] = project_box [[EARG]]
697+
// CHECK: [[LOAD_BOX:%.*]] = load [take] [[PROJ_BOX]] : $*T
698+
// CHECK: [[COPY_BOX:%.*]] = copy_value [[LOAD_BOX]] : $T
699+
// CHECK: destroy_value [[EARG]]
700+
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]] : $IndirectEnum<T>, $IndirectEnum<T>
701+
// CHECK: destroy_value [[COPY_BOX]]
702+
// CHECK: br bb4
703+
// CHECK: bb4:
704+
// CHECK: destroy_value [[ARG]]
705+
// CHECK: return %{{.*}} : $()
706+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s360________guardEnumyAA08IndirectF0OyxGlF'
707+
func s360________guardEnum<T>(_ e: IndirectEnum<T>) {
708+
do {
709+
guard case .Node(let x) = e else { return }
710+
}
711+
}
712+
678713
// Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
679714
// ---
680715
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {

0 commit comments

Comments
 (0)