Skip to content

Commit 41cc3f3

Browse files
authored
Merge pull request #30772 from mikeash/fix-mirror-enum-payload-extraction
[Mirror] Don't destroy and reconstitute enums when reflecting them.
2 parents 5f17f5b + f4e6353 commit 41cc3f3

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

stdlib/public/runtime/ReflectionMirror.mm

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -488,14 +488,21 @@ AnyReturn subscript(intptr_t i, const char **outName,
488488

489489
auto *caseName = getInfo(&tag, &payloadType, &indirect);
490490

491+
// Copy the enum itself so that we can project the data without destroying
492+
// the original.
493+
Any enumCopy;
494+
auto *enumCopyContainer
495+
= type->allocateBoxForExistentialIn(&enumCopy.Buffer);
496+
type->vw_initializeWithCopy(enumCopyContainer,
497+
const_cast<OpaqueValue *>(value));
498+
491499
// Copy the enum payload into a box
492500
const Metadata *boxType = (indirect ? &METADATA_SYM(Bo).base : payloadType);
493501
BoxPair pair = swift_allocBox(boxType);
494-
495-
type->vw_destructiveProjectEnumData(const_cast<OpaqueValue *>(value));
496-
boxType->vw_initializeWithCopy(pair.buffer, const_cast<OpaqueValue *>(value));
497-
type->vw_destructiveInjectEnumTag(const_cast<OpaqueValue *>(value), tag);
498-
502+
type->vw_destructiveProjectEnumData(enumCopyContainer);
503+
boxType->vw_initializeWithTake(pair.buffer, enumCopyContainer);
504+
type->deallocateBoxForExistentialIn(&enumCopy.Buffer);
505+
499506
value = pair.buffer;
500507

501508
// If the payload is indirect, we need to jump through the box to get it.

0 commit comments

Comments
 (0)