Skip to content

Commit ab09048

Browse files
authored
Merge pull request #33544 from CodaFi/coordination-in-name-only
Partially Revert #33371
2 parents 18af945 + e42037a commit ab09048

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

lib/Sema/DerivedConformanceCaseIterable.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ static ArraySliceType *computeAllCasesType(NominalTypeDecl *enumDecl) {
6969
return ArraySliceType::get(enumType);
7070
}
7171

72+
static Type deriveCaseIterable_AllCases(DerivedConformance &derived) {
73+
// enum SomeEnum : CaseIterable {
74+
// @derived
75+
// typealias AllCases = [SomeEnum]
76+
// }
77+
auto *rawInterfaceType = computeAllCasesType(cast<EnumDecl>(derived.Nominal));
78+
return derived.getConformanceContext()->mapTypeIntoContext(rawInterfaceType);
79+
}
80+
7281
ValueDecl *DerivedConformance::deriveCaseIterable(ValueDecl *requirement) {
7382
// Conformance can't be synthesized in an extension.
7483
if (checkAndDiagnoseDisallowedContext(requirement))
@@ -102,3 +111,18 @@ ValueDecl *DerivedConformance::deriveCaseIterable(ValueDecl *requirement) {
102111

103112
return propDecl;
104113
}
114+
115+
Type DerivedConformance::deriveCaseIterable(AssociatedTypeDecl *assocType) {
116+
// Check that we can actually derive CaseIterable for this type.
117+
if (!canDeriveConformance(Nominal))
118+
return nullptr;
119+
120+
if (assocType->getName() == Context.Id_AllCases) {
121+
return deriveCaseIterable_AllCases(*this);
122+
}
123+
124+
Context.Diags.diagnose(assocType->getLoc(),
125+
diag::broken_case_iterable_requirement);
126+
return nullptr;
127+
}
128+

lib/Sema/DerivedConformances.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ class DerivedConformance {
163163
/// \returns the derived member, which will also be added to the type.
164164
ValueDecl *deriveCaseIterable(ValueDecl *requirement);
165165

166+
/// Derive a CaseIterable type witness for an enum if it has no associated
167+
/// values for any of its cases.
168+
///
169+
/// \returns the derived member, which will also be added to the type.
170+
Type deriveCaseIterable(AssociatedTypeDecl *assocType);
171+
166172
/// Determine if a RawRepresentable requirement can be derived for a type.
167173
///
168174
/// This is implemented for non-empty enums without associated values,

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5771,6 +5771,8 @@ TypeChecker::deriveTypeWitness(DeclContext *DC,
57715771
switch (*knownKind) {
57725772
case KnownProtocolKind::RawRepresentable:
57735773
return std::make_pair(derived.deriveRawRepresentable(AssocType), nullptr);
5774+
case KnownProtocolKind::CaseIterable:
5775+
return std::make_pair(derived.deriveCaseIterable(AssocType), nullptr);
57745776
case KnownProtocolKind::Differentiable:
57755777
return derived.deriveDifferentiable(AssocType);
57765778
default:

0 commit comments

Comments
 (0)