Skip to content

Commit 4af501a

Browse files
authored
Merge pull request #67890 from tshortli/prevent-comparable-synthesis-for-enum-with-assoc-values-and-availability
AST: Fix EnumDecl's hasPotentiallyUnavailableCaseValue() cache
2 parents e13f72e + d438bac commit 4af501a

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

lib/AST/Decl.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5968,25 +5968,29 @@ bool EnumDecl::hasOnlyCasesWithoutAssociatedValues() const {
59685968
case AssociatedValueCheck::HasAssociatedValues:
59695969
return false;
59705970
}
5971+
5972+
bool hasAnyUnavailableValues = false;
5973+
bool hasAssociatedValues = false;
5974+
59715975
for (auto elt : getAllElements()) {
59725976
for (auto Attr : elt->getAttrs()) {
59735977
if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) {
5974-
if (!AvAttr->isInvalid()) {
5975-
const_cast<EnumDecl*>(this)->Bits.EnumDecl.HasAnyUnavailableValues
5976-
= true;
5977-
}
5978+
if (!AvAttr->isInvalid())
5979+
hasAnyUnavailableValues = true;
59785980
}
59795981
}
59805982

5981-
if (elt->hasAssociatedValues()) {
5982-
const_cast<EnumDecl*>(this)->Bits.EnumDecl.HasAssociatedValues
5983-
= static_cast<unsigned>(AssociatedValueCheck::HasAssociatedValues);
5984-
return false;
5985-
}
5983+
if (elt->hasAssociatedValues())
5984+
hasAssociatedValues = true;
59865985
}
5987-
const_cast<EnumDecl*>(this)->Bits.EnumDecl.HasAssociatedValues
5988-
= static_cast<unsigned>(AssociatedValueCheck::NoAssociatedValues);
5989-
return true;
5986+
5987+
EnumDecl *enumDecl = const_cast<EnumDecl *>(this);
5988+
5989+
enumDecl->Bits.EnumDecl.HasAnyUnavailableValues = hasAnyUnavailableValues;
5990+
enumDecl->Bits.EnumDecl.HasAssociatedValues = static_cast<unsigned>(
5991+
hasAssociatedValues ? AssociatedValueCheck::HasAssociatedValues
5992+
: AssociatedValueCheck::NoAssociatedValues);
5993+
return !hasAssociatedValues;
59905994
}
59915995

59925996
bool EnumDecl::isFormallyExhaustive(const DeclContext *useDC) const {

test/decl/protocol/special/comparable/comparable_unsupported.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ enum EnumWithUnavailableCaseAndAssociatedValue: Comparable {
4646
case some(SomeComparable)
4747
}
4848

49+
enum EnumWithUnavailableCaseAndAssociatedValue2: Comparable {
50+
// expected-error@-1 {{type 'EnumWithUnavailableCaseAndAssociatedValue2' does not conform to protocol 'Comparable'}}
51+
enum SomeComparable: Comparable {}
52+
53+
case this(SomeComparable)
54+
55+
@available(*, unavailable)
56+
case that(SomeComparable)
57+
}
58+
4959
// Automatic synthesis of Comparable requires associated values to be Comparable as well.
5060

5161
enum NotComparableEnumTwo: Comparable {

0 commit comments

Comments
 (0)