@@ -31,7 +31,17 @@ using namespace swift;
31
31
// / This requires the getter's body to have a certain syntactic form. It should
32
32
// / be kept in sync with importEnumCaseAlias in the ClangImporter library.
33
33
static EnumElementDecl *
34
- extractEnumElement (const VarDecl *constant) {
34
+ extractEnumElement (TypeChecker &TC, SourceLoc UseLoc, const VarDecl *constant) {
35
+ if (auto Attr = AvailableAttr::isUnavailable (constant)) {
36
+ auto Kind = Attr->getUnconditionalAvailability ();
37
+ if (Kind == UnconditionalAvailabilityKind::UnavailableInCurrentSwift) {
38
+ auto diag = TC.diagnose (UseLoc, diag::availability_decl_unavailable_rename,
39
+ constant->getName (), /* "replaced"*/ false ,
40
+ /* special kind*/ 0 , Attr->Rename );
41
+ diag.fixItReplace (UseLoc, Attr->Rename );
42
+ }
43
+ }
44
+
35
45
const FuncDecl *getter = constant->getGetter ();
36
46
if (!getter)
37
47
return nullptr ;
@@ -61,7 +71,8 @@ extractEnumElement(const VarDecl *constant) {
61
71
// / If there are no enum elements but there are properties, attempts to map
62
72
// / an arbitrary property to an enum element using extractEnumElement.
63
73
static EnumElementDecl *
64
- filterForEnumElement (LookupResult foundElements) {
74
+ filterForEnumElement (TypeChecker &TC, SourceLoc UseLoc,
75
+ LookupResult foundElements) {
65
76
EnumElementDecl *foundElement = nullptr ;
66
77
VarDecl *foundConstant = nullptr ;
67
78
@@ -85,32 +96,32 @@ filterForEnumElement(LookupResult foundElements) {
85
96
}
86
97
87
98
if (!foundElement && foundConstant && foundConstant->hasClangNode ())
88
- foundElement = extractEnumElement (foundConstant);
99
+ foundElement = extractEnumElement (TC, UseLoc, foundConstant);
89
100
90
101
return foundElement;
91
102
}
92
103
93
104
// / Find an unqualified enum element.
94
105
static EnumElementDecl *
95
106
lookupUnqualifiedEnumMemberElement (TypeChecker &TC, DeclContext *DC,
96
- Identifier name) {
107
+ Identifier name, SourceLoc UseLoc ) {
97
108
auto lookupOptions = defaultUnqualifiedLookupOptions;
98
109
lookupOptions |= NameLookupFlags::KnownPrivate;
99
110
auto lookup = TC.lookupUnqualified (DC, name, SourceLoc (), lookupOptions);
100
- return filterForEnumElement (lookup);
111
+ return filterForEnumElement (TC, UseLoc, lookup);
101
112
}
102
113
103
114
// / Find an enum element in an enum type.
104
115
static EnumElementDecl *
105
116
lookupEnumMemberElement (TypeChecker &TC, DeclContext *DC, Type ty,
106
- Identifier name) {
117
+ Identifier name, SourceLoc UseLoc ) {
107
118
assert (ty->getAnyNominal ());
108
119
// Look up the case inside the enum.
109
120
// FIXME: We should be able to tell if this is a private lookup.
110
121
NameLookupOptions lookupOptions
111
122
= defaultMemberLookupOptions - NameLookupFlags::DynamicLookup;
112
123
LookupResult foundElements = TC.lookupMember (DC, ty, name, lookupOptions);
113
- return filterForEnumElement (foundElements);
124
+ return filterForEnumElement (TC, UseLoc, foundElements);
114
125
}
115
126
116
127
namespace {
@@ -435,7 +446,8 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
435
446
436
447
// FIXME: Argument labels?
437
448
EnumElementDecl *referencedElement
438
- = lookupEnumMemberElement (TC, DC, ty, ude->getName ().getBaseName ());
449
+ = lookupEnumMemberElement (TC, DC, ty, ude->getName ().getBaseName (),
450
+ ude->getLoc ());
439
451
440
452
// Build a TypeRepr from the head of the full path.
441
453
// FIXME: Compound names.
@@ -473,7 +485,8 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
473
485
// Try looking up an enum element in context.
474
486
if (EnumElementDecl *referencedElement
475
487
= lookupUnqualifiedEnumMemberElement (TC, DC,
476
- ude->getName ().getBaseName ())) {
488
+ ude->getName ().getBaseName (),
489
+ ude->getLoc ())) {
477
490
auto *enumDecl = referencedElement->getParentEnum ();
478
491
auto enumTy = enumDecl->getDeclaredTypeInContext ();
479
492
TypeLoc loc = TypeLoc::withoutLoc (enumTy);
@@ -557,7 +570,8 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
557
570
if (auto compId = dyn_cast<ComponentIdentTypeRepr>(repr)) {
558
571
// Try looking up an enum element in context.
559
572
EnumElementDecl *referencedElement
560
- = lookupUnqualifiedEnumMemberElement (TC, DC, compId->getIdentifier ());
573
+ = lookupUnqualifiedEnumMemberElement (TC, DC, compId->getIdentifier (),
574
+ repr->getLoc ());
561
575
562
576
if (!referencedElement)
563
577
return nullptr ;
@@ -595,7 +609,8 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
595
609
auto tailComponent = compoundR->Components .back ();
596
610
597
611
EnumElementDecl *referencedElement
598
- = lookupEnumMemberElement (TC, DC, enumTy, tailComponent->getIdentifier ());
612
+ = lookupEnumMemberElement (TC, DC, enumTy, tailComponent->getIdentifier (),
613
+ tailComponent->getLoc ());
599
614
if (!referencedElement)
600
615
return nullptr ;
601
616
@@ -1381,8 +1396,10 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
1381
1396
1382
1397
Type enumTy;
1383
1398
if (!elt) {
1384
- if (type->getAnyNominal ())
1385
- elt = lookupEnumMemberElement (*this , dc, type, EEP->getName ());
1399
+ if (type->getAnyNominal ()) {
1400
+ elt = lookupEnumMemberElement (*this , dc, type, EEP->getName (),
1401
+ EEP->getLoc ());
1402
+ }
1386
1403
if (!elt) {
1387
1404
if (!type->is <ErrorType>())
1388
1405
diagnose (EEP->getLoc (), diag::enum_element_pattern_member_not_found,
@@ -1492,7 +1509,8 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
1492
1509
// If the element decl was not resolved (because it was spelled without a
1493
1510
// type as `.Foo`), resolve it now that we have a type.
1494
1511
if (!OP->getElementDecl ()) {
1495
- auto *element = lookupEnumMemberElement (*this , dc, type, Context.Id_some );
1512
+ auto *element = lookupEnumMemberElement (*this , dc, type, Context.Id_some ,
1513
+ OP->getLoc ());
1496
1514
if (!element) {
1497
1515
diagnose (OP->getLoc (), diag::enum_element_pattern_member_not_found,
1498
1516
" Some" , type);
0 commit comments