2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
5
- // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5
+ // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6
6
// Licensed under Apache License v2.0 with Runtime Library Exception
7
7
//
8
8
// See https://swift.org/LICENSE.txt for license information
31
31
32
32
using namespace swift ;
33
33
34
- // how does this code ever even get invoked? you can’t compare uninhabited enums...
35
34
static std::pair<BraceStmt *, bool >
36
35
deriveBodyComparable_enum_uninhabited_lt (AbstractFunctionDecl *ltDecl, void *) {
37
36
auto parentDC = ltDecl->getDeclContext ();
@@ -42,26 +41,9 @@ deriveBodyComparable_enum_uninhabited_lt(AbstractFunctionDecl *ltDecl, void *) {
42
41
auto bParam = args->get (1 );
43
42
44
43
assert (!cast<EnumDecl>(aParam->getType ()->getAnyNominal ())->hasCases ());
44
+ assert (!cast<EnumDecl>(bParam->getType ()->getAnyNominal ())->hasCases ());
45
45
46
- SmallVector<ASTNode, 1 > statements;
47
- SmallVector<ASTNode, 0 > cases;
48
-
49
- // switch (a, b) { }
50
- auto aRef = new (C) DeclRefExpr (aParam, DeclNameLoc (), /* implicit*/ true ,
51
- AccessSemantics::Ordinary,
52
- aParam->getType ());
53
- auto bRef = new (C) DeclRefExpr (bParam, DeclNameLoc (), /* implicit*/ true ,
54
- AccessSemantics::Ordinary,
55
- bParam->getType ());
56
- TupleTypeElt abTupleElts[2 ] = { aParam->getType (), bParam->getType () };
57
- auto abExpr = TupleExpr::create (C, SourceLoc (), {aRef, bRef}, {}, {},
58
- SourceLoc (), /* HasTrailingClosure*/ false ,
59
- /* implicit*/ true ,
60
- TupleType::get (abTupleElts, C));
61
- auto switchStmt = SwitchStmt::create (LabeledStmtInfo (), SourceLoc (), abExpr,
62
- SourceLoc (), cases, SourceLoc (), C);
63
- statements.push_back (switchStmt);
64
-
46
+ SmallVector<ASTNode, 0 > statements;
65
47
auto body = BraceStmt::create (C, SourceLoc (), statements, SourceLoc ());
66
48
return { body, /* isTypeChecked=*/ true };
67
49
}
@@ -143,7 +125,7 @@ deriveBodyComparable_enum_hasAssociatedValues_lt(AbstractFunctionDecl *ltDecl, v
143
125
144
126
SmallVector<ASTNode, 6 > statements;
145
127
SmallVector<ASTNode, 4 > cases;
146
- unsigned elementCount = 0 ;
128
+ unsigned elementCount = 0 ; // need this as `getAllElements` returns a generator
147
129
148
130
// For each enum element, generate a case statement matching a pair containing
149
131
// the same case, binding variables for the left- and right-hand associated
@@ -333,9 +315,10 @@ deriveComparable_lt(
333
315
return comparableDecl;
334
316
}
335
317
318
+ // for now, only enums can synthesize `Comparable`, so this function can take
319
+ // an `EnumDecl` instead of a `NominalTypeDecl`
336
320
bool
337
- DerivedConformance::canDeriveComparable (DeclContext *context, NominalTypeDecl *declaration) {
338
- auto enumeration = dyn_cast<EnumDecl>(declaration);
321
+ DerivedConformance::canDeriveComparable (DeclContext *context, EnumDecl *enumeration) {
339
322
// The type must be an enum.
340
323
if (!enumeration) {
341
324
return false ;
@@ -349,26 +332,27 @@ DerivedConformance::canDeriveComparable(DeclContext *context, NominalTypeDecl *d
349
332
}
350
333
351
334
ValueDecl *DerivedConformance::deriveComparable (ValueDecl *requirement) {
352
- if (checkAndDiagnoseDisallowedContext (requirement))
335
+ if (checkAndDiagnoseDisallowedContext (requirement)) {
353
336
return nullptr ;
337
+ }
338
+ if (requirement->getBaseName () != " <" ) {
339
+ requirement->diagnose (diag::broken_comparable_requirement);
340
+ return nullptr ;
341
+ }
342
+
354
343
// Build the necessary decl.
355
- if (requirement->getBaseName () == " <" ) {
356
- if (EnumDecl const *const enumeration = dyn_cast<EnumDecl>(this ->Nominal )) {
357
- std::pair<BraceStmt *, bool > (*synthesizer)(AbstractFunctionDecl *, void *);
358
- if (enumeration->hasCases ()) {
359
- if (enumeration->hasOnlyCasesWithoutAssociatedValues ()) {
360
- synthesizer = &deriveBodyComparable_enum_noAssociatedValues_lt;
361
- } else {
362
- synthesizer = &deriveBodyComparable_enum_hasAssociatedValues_lt;
363
- }
364
- } else {
365
- synthesizer = &deriveBodyComparable_enum_uninhabited_lt;
366
- }
367
- return deriveComparable_lt (*this , synthesizer);
344
+ auto enumeration = dyn_cast<EnumDecl>(this ->Nominal );
345
+ assert (enumeration);
346
+
347
+ std::pair<BraceStmt *, bool > (*synthesizer)(AbstractFunctionDecl *, void *);
348
+ if (enumeration->hasCases ()) {
349
+ if (enumeration->hasOnlyCasesWithoutAssociatedValues ()) {
350
+ synthesizer = &deriveBodyComparable_enum_noAssociatedValues_lt;
368
351
} else {
369
- llvm_unreachable ( " todo " ) ;
352
+ synthesizer = &deriveBodyComparable_enum_hasAssociatedValues_lt ;
370
353
}
354
+ } else {
355
+ synthesizer = &deriveBodyComparable_enum_uninhabited_lt;
371
356
}
372
- requirement->diagnose (diag::broken_comparable_requirement);
373
- return nullptr ;
357
+ return deriveComparable_lt (*this , synthesizer);
374
358
}
0 commit comments