Skip to content

Commit 93a70a0

Browse files
authored
Merge pull request #67349 from drexin/wip-resilient-metadata-inst
[IRGen] Fix enum metadata instantiation for resilient payload
2 parents 5956cc3 + 937d172 commit 93a70a0

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

lib/IRGen/GenMeta.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,16 +2581,18 @@ void irgen::emitLazyTypeContextDescriptor(IRGenModule &IGM,
25812581
auto genericSig =
25822582
lowered.getNominalOrBoundGenericNominal()->getGenericSignature();
25832583
hasLayoutString = !!typeLayoutEntry->layoutString(IGM, genericSig);
2584-
}
25852584

2586-
if (auto sd = dyn_cast<StructDecl>(type)) {
2587-
if (IGM.Context.LangOpts.hasFeature(Feature::LayoutStringValueWitnessesInstantiation) &&
2585+
if (!hasLayoutString &&
2586+
IGM.Context.LangOpts.hasFeature(
2587+
Feature::LayoutStringValueWitnessesInstantiation) &&
25882588
IGM.getOptions().EnableLayoutStringValueWitnessesInstantiation) {
25892589
hasLayoutString |= requiresForeignTypeMetadata(type) ||
2590-
needsSingletonMetadataInitialization(IGM, type) ||
2591-
(type->isGenericContext() && !isa<FixedTypeInfo>(ti));
2590+
needsSingletonMetadataInitialization(IGM, type) ||
2591+
(type->isGenericContext() && !isa<FixedTypeInfo>(ti));
25922592
}
2593+
}
25932594

2595+
if (auto sd = dyn_cast<StructDecl>(type)) {
25942596
StructContextDescriptorBuilder(IGM, sd, requireMetadata,
25952597
hasLayoutString).emit();
25962598
} else if (auto ed = dyn_cast<EnumDecl>(type)) {
@@ -5487,6 +5489,26 @@ namespace {
54875489
return emitValueWitnessTable(relativeReference);
54885490
}
54895491

5492+
bool hasInstantiatedLayoutString() {
5493+
if (IGM.Context.LangOpts.hasFeature(
5494+
Feature::LayoutStringValueWitnessesInstantiation) &&
5495+
IGM.getOptions().EnableLayoutStringValueWitnessesInstantiation) {
5496+
return needsSingletonMetadataInitialization(IGM, Target);
5497+
}
5498+
5499+
return false;
5500+
}
5501+
5502+
bool hasLayoutString() {
5503+
if (!IGM.Context.LangOpts.hasFeature(
5504+
Feature::LayoutStringValueWitnesses) ||
5505+
!IGM.getOptions().EnableLayoutStringValueWitnesses) {
5506+
return false;
5507+
}
5508+
5509+
return hasInstantiatedLayoutString() || !!getLayoutString();
5510+
}
5511+
54905512
llvm::Constant *emitLayoutString() {
54915513
if (!IGM.Context.LangOpts.hasFeature(Feature::LayoutStringValueWitnesses) ||
54925514
!IGM.getOptions().EnableLayoutStringValueWitnesses)
@@ -5521,7 +5543,7 @@ namespace {
55215543

55225544
llvm::Constant *emitNominalTypeDescriptor() {
55235545
auto descriptor = EnumContextDescriptorBuilder(
5524-
IGM, Target, RequireMetadata, !!getLayoutString())
5546+
IGM, Target, RequireMetadata, hasLayoutString())
55255547
.emit();
55265548
return descriptor;
55275549
}
@@ -5570,7 +5592,7 @@ namespace {
55705592
}
55715593

55725594
bool canBeConstant() {
5573-
return !HasUnfilledPayloadSize;
5595+
return !HasUnfilledPayloadSize && !hasInstantiatedLayoutString();
55745596
}
55755597
};
55765598

stdlib/public/runtime/Enum.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ XIElement findXIElement(const Metadata *type) {
222222
void swift::swift_initEnumMetadataSinglePayloadWithLayoutString(
223223
EnumMetadata *self, EnumLayoutFlags layoutFlags,
224224
const Metadata *payloadType, unsigned emptyCases) {
225+
assert(self->hasLayoutString());
226+
225227
auto *payloadLayout = payloadType->getTypeLayout();
226228
size_t payloadSize = payloadLayout->size;
227229
unsigned payloadNumExtraInhabitants = payloadLayout->getNumExtraInhabitants();

test/Interpreter/Inputs/layout_string_witnesses_types_resilient.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,9 @@ public func getResilientSinglePayloadEnumSimpleEmpty0() -> ResilientSinglePayloa
7878
public func getResilientSingletonEnumNonEmpty(_ x: AnyObject) -> ResilientSingletonEnum {
7979
return .nonEmpty(x)
8080
}
81+
82+
public enum ResilientSinglePayloadEnum {
83+
case empty0
84+
case empty1
85+
case nonEmpty(AnyObject, Int)
86+
}

test/Interpreter/layout_string_witnesses_dynamic.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,22 @@ func testResilientSingletonEnumGenericInjectTag() {
923923

924924
testResilientSingletonEnumGenericInjectTag()
925925

926+
enum ResilientPayloadSinglePayloadEnum {
927+
case empty0
928+
case empty1
929+
case empty2
930+
case nonEmpty(ResilientSinglePayloadEnum, Int)
931+
}
932+
933+
func testResilientPayloadSinglePayloadEnum() {
934+
let xxx = ResilientPayloadSinglePayloadEnum.nonEmpty(.empty0, 1)
935+
936+
// CHECK: nonEmpty(layout_string_witnesses_types_resilient.ResilientSinglePayloadEnum.empty0, 1)
937+
print(xxx)
938+
}
939+
940+
testResilientPayloadSinglePayloadEnum()
941+
926942
#if os(macOS)
927943

928944
import Foundation

0 commit comments

Comments
 (0)