Skip to content

Commit 3524945

Browse files
authored
[IRGen+Runtime] Implement getEnumTag for singleton enums in layout strings (#66985)
1 parent 4bb51a2 commit 3524945

File tree

6 files changed

+38
-1
lines changed

6 files changed

+38
-1
lines changed

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,6 +2326,16 @@ FUNCTION(GenericInitializeBufferWithCopyOfBuffer,
23262326
ATTRS(NoUnwind),
23272327
EFFECT(Refcounting))
23282328

2329+
// unsigned swift_singletonEnum_getEnumTag(swift::OpaqueValue *address,
2330+
// const Metadata *metadata);
2331+
FUNCTION(SingletonEnumGetEnumTag,
2332+
swift_singletonEnum_getEnumTag,
2333+
C_CC, AlwaysAvailable,
2334+
RETURNS(Int32Ty),
2335+
ARGS(Int8PtrTy, TypeMetadataPtrTy),
2336+
ATTRS(NoUnwind),
2337+
EFFECT(NoEffect))
2338+
23292339
// unsigned swift_enumSimple_getEnumTag(swift::OpaqueValue *address,
23302340
// const Metadata *metadata);
23312341
FUNCTION(EnumSimpleGetEnumTag,

lib/IRGen/GenValueWitness.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ static llvm::Constant *getEnumTagFunction(IRGenModule &IGM,
905905
if ((!typeLayoutEntry->layoutString(IGM, genericSig) &&
906906
!isRuntimeInstatiatedLayoutString(IGM, typeLayoutEntry)) ||
907907
typeLayoutEntry->isSingleton()) {
908-
return nullptr;
908+
return IGM.getSingletonEnumGetEnumTagFn();
909909
} else if (!typeLayoutEntry->isFixedSize(IGM)) {
910910
if (typeLayoutEntry->isMultiPayloadEnum()) {
911911
return IGM.getMultiPayloadEnumGenericGetEnumTagFn();

stdlib/public/runtime/BytecodeLayouts.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,11 @@ swift_generic_assignWithTake(swift::OpaqueValue *dest, swift::OpaqueValue *src,
652652
return swift_generic_initWithTake(dest, src, metadata);
653653
}
654654

655+
extern "C" unsigned swift_singletonEnum_getEnumTag(swift::OpaqueValue *address,
656+
const Metadata *metadata) {
657+
return 0;
658+
}
659+
655660
extern "C"
656661
unsigned swift_enumSimple_getEnumTag(swift::OpaqueValue *address,
657662
const Metadata *metadata) {

stdlib/public/runtime/BytecodeLayouts.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ swift_generic_initializeBufferWithCopyOfBuffer(swift::ValueBuffer *dest,
118118
swift::ValueBuffer *src,
119119
const Metadata *metadata);
120120
SWIFT_RUNTIME_EXPORT
121+
unsigned swift_singletonEnum_getEnumTag(swift::OpaqueValue *address,
122+
const Metadata *metadata);
123+
SWIFT_RUNTIME_EXPORT
121124
unsigned swift_enumSimple_getEnumTag(swift::OpaqueValue *address,
122125
const Metadata *metadata);
123126
SWIFT_RUNTIME_EXPORT

test/Interpreter/Inputs/layout_string_witnesses_types_resilient.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public enum ResilientSinglePayloadEnumSimple {
5151
case nonEmpty(AnyObject)
5252
}
5353

54+
public enum ResilientSingletonEnum {
55+
case nonEmpty(AnyObject)
56+
}
57+
5458
public func getResilientSinglePayloadEnumGenericEmpty0<T>(_ t: T.Type) -> ResilientSinglePayloadEnumGeneric<T> {
5559
return .empty0
5660
}
@@ -70,3 +74,7 @@ public func getResilientSinglePayloadEnumComplexEmpty0() -> ResilientSinglePaylo
7074
public func getResilientSinglePayloadEnumSimpleEmpty0() -> ResilientSinglePayloadEnumSimple {
7175
return .empty0
7276
}
77+
78+
public func getResilientSingletonEnumNonEmpty(_ x: AnyObject) -> ResilientSingletonEnum {
79+
return .nonEmpty(x)
80+
}

test/Interpreter/layout_string_witnesses_dynamic.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,17 @@ func testGenericSinglePayloadEnumManyXI() {
516516

517517
testGenericSinglePayloadEnumManyXI()
518518

519+
func testResilientSingletonEnumTag() {
520+
let x = switch getResilientSingletonEnumNonEmpty(SimpleClass(x: 23)) {
521+
case .nonEmpty: 0
522+
}
523+
524+
// CHECK: Enum case: 0
525+
print("Enum case: \(x)")
526+
}
527+
528+
testResilientSingletonEnumTag()
529+
519530
func testResilientSinglePayloadEnumSimpleTag() {
520531
let x = switch getResilientSinglePayloadEnumSimpleEmpty0() {
521532
case .nonEmpty: 0

0 commit comments

Comments
 (0)