@@ -4598,22 +4598,17 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC,
4598
4598
std::vector<Element> elementsWithPayload;
4599
4599
std::vector<Element> elementsWithNoPayload;
4600
4600
4601
- // Resilient enums are manipulated as opaque values, except we still
4602
- // make the following assumptions:
4603
- // 1) Physical case indices won't change
4604
- // 2) The indirect-ness of cases won't change
4605
- // 3) Payload types won't change in a non-resilient way
4606
- bool isResilient = TC.IGM .isResilient (theEnum, ResilienceScope::Component);
4607
-
4608
- // The most general resilience scope where the enum type is visible.
4609
- // Case numbering must not depend on any information that is not static
4610
- // in this resilience scope.
4611
- ResilienceScope accessScope = TC.IGM .getResilienceScopeForAccess (theEnum);
4612
-
4613
- // The most general resilience scope where the enum's layout is known.
4614
- // Fixed-size optimizations can be applied if all payload types are
4615
- // fixed-size from this resilience scope.
4616
- ResilienceScope layoutScope = TC.IGM .getResilienceScopeForLayout (theEnum);
4601
+ // The most general resilience scope that can have knowledge of this
4602
+ // enum's layout. If all payload types have a fixed size in this
4603
+ // resilience scope, we can make further assumptions to optimize
4604
+ // layout.
4605
+ ResilienceScope scope = ResilienceScope::Universal;
4606
+
4607
+ // TODO: Replace this with 'public or internal with @availability' check
4608
+ // once that is in place
4609
+ if (theEnum->getFormalAccess () != Accessibility::Public ||
4610
+ TC.IGM .isResilient (theEnum, ResilienceScope::Universal))
4611
+ scope = ResilienceScope::Component;
4617
4612
4618
4613
for (auto elt : theEnum->getAllElements ()) {
4619
4614
numElements++;
@@ -4643,20 +4638,14 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC,
4643
4638
= TC.tryGetCompleteTypeInfo (origArgLoweredTy.getSwiftRValueType ());
4644
4639
assert (origArgTI && " didn't complete type info?!" );
4645
4640
4646
- // If the unsubstituted argument contains a generic parameter type, or
4647
- // is not fixed-size in all resilience domains that have knowledge of
4648
- // this enum's layout, we need to constrain our layout optimizations to
4649
- // what the runtime can reproduce.
4650
- if (!isResilient &&
4651
- !origArgTI->isFixedSize (layoutScope))
4641
+ // If the unsubstituted argument contains a generic parameter type, or if
4642
+ // the substituted argument is not universally fixed-size, we need to
4643
+ // constrain our layout optimizations to what the runtime can reproduce.
4644
+ if (!origArgTI->isFixedSize (scope))
4652
4645
alwaysFixedSize = IsNotFixedSize;
4653
4646
4654
- // If the payload is empty, turn the case into a no-payload case, but
4655
- // only if case numbering remains unchanged from all resilience domains
4656
- // that can see the enum.
4657
- if (origArgTI->isFixedSize (accessScope) &&
4658
- isa<LoadableTypeInfo>(origArgTI) &&
4659
- cast<LoadableTypeInfo>(origArgTI)->isKnownEmpty ()) {
4647
+ auto loadableOrigArgTI = dyn_cast<LoadableTypeInfo>(origArgTI);
4648
+ if (loadableOrigArgTI && loadableOrigArgTI->isKnownEmpty ()) {
4660
4649
elementsWithNoPayload.push_back ({elt, nullptr , nullptr });
4661
4650
} else {
4662
4651
// *Now* apply the substitutions and get the type info for the instance's
@@ -4666,20 +4655,16 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC,
4666
4655
auto *substArgTI = &TC.IGM .getTypeInfo (fieldTy);
4667
4656
4668
4657
elementsWithPayload.push_back ({elt, substArgTI, origArgTI});
4658
+ if (!substArgTI->isFixedSize ())
4659
+ tik = Opaque;
4660
+ else if (!substArgTI->isLoadable () && tik > Fixed)
4661
+ tik = Fixed;
4669
4662
4670
- if (!isResilient) {
4671
- if (!substArgTI->isFixedSize (ResilienceScope::Component))
4672
- tik = Opaque;
4673
- else if (!substArgTI->isLoadable () && tik > Fixed)
4674
- tik = Fixed;
4675
-
4676
- // If the substituted argument contains a type that is not fixed-size
4677
- // in all resilience domains that have knowledge of this enum's layout,
4678
- // we need to constrain our layout optimizations to what the runtime
4679
- // can reproduce.
4680
- if (!substArgTI->isFixedSize (layoutScope))
4681
- alwaysFixedSize = IsNotFixedSize;
4682
- }
4663
+ // If the substituted argument contains a type that is not universally
4664
+ // fixed-size, we need to constrain our layout optimizations to what
4665
+ // the runtime can reproduce.
4666
+ if (!substArgTI->isFixedSize (scope))
4667
+ alwaysFixedSize = IsNotFixedSize;
4683
4668
}
4684
4669
}
4685
4670
@@ -4688,7 +4673,12 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC,
4688
4673
+ elementsWithNoPayload.size ()
4689
4674
&& " not all elements accounted for" );
4690
4675
4691
- if (isResilient) {
4676
+ // Resilient enums are manipulated as opaque values, except we still
4677
+ // make the following assumptions:
4678
+ // 1) Physical case indices won't change
4679
+ // 2) The indirect-ness of cases won't change
4680
+ // 3) Payload types won't change in a non-resilient way
4681
+ if (TC.IGM .isResilient (theEnum, ResilienceScope::Component)) {
4692
4682
return new ResilientEnumImplStrategy (TC.IGM ,
4693
4683
numElements,
4694
4684
std::move (elementsWithPayload),
0 commit comments