Skip to content

Commit b489450

Browse files
committed
[Parse] Parse 'any' as a contextual keyword.
1 parent 4fafee7 commit b489450

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,8 @@ ERROR(sil_function_subs_without_generics,none,
873873

874874
// Opaque types
875875
ERROR(opaque_mid_composition,none,
876-
"'some' should appear at the beginning of a composition", ())
876+
"'%0' should appear at the beginning of a composition",
877+
(StringRef))
877878

878879
//------------------------------------------------------------------------------
879880
// MARK: Layout constraint diagnostics

lib/Parse/ParsePattern.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ bool Parser::startsParameterName(bool isClosure) {
165165
if (nextTok.canBeArgumentLabel()) {
166166
// If the first name wasn't "isolated", we're done.
167167
if (!Tok.isContextualKeyword("isolated") &&
168-
!Tok.isContextualKeyword("some"))
168+
!Tok.isContextualKeyword("some") &&
169+
!Tok.isContextualKeyword("any"))
169170
return true;
170171

171172
// "isolated" can be an argument label, but it's also a contextual keyword,

lib/Parse/ParseType.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -804,10 +804,15 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
804804
// This is only semantically allowed in certain contexts, but we parse it
805805
// generally for diagnostics and recovery.
806806
SourceLoc opaqueLoc;
807+
SourceLoc anyLoc;
807808
if (Tok.isContextualKeyword("some")) {
808809
// Treat some as a keyword.
809810
TokReceiver->registerTokenKindChange(Tok.getLoc(), tok::contextual_keyword);
810811
opaqueLoc = consumeToken();
812+
} else if (Tok.isContextualKeyword("any")) {
813+
// Treat any as a keyword.
814+
TokReceiver->registerTokenKindChange(Tok.getLoc(), tok::contextual_keyword);
815+
anyLoc = consumeToken();
811816
} else {
812817
// This isn't a some type.
813818
SomeTypeContext.setTransparent();
@@ -816,6 +821,8 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
816821
auto applyOpaque = [&](TypeRepr *type) -> TypeRepr* {
817822
if (opaqueLoc.isValid()) {
818823
type = new (Context) OpaqueReturnTypeRepr(opaqueLoc, type);
824+
} else if (anyLoc.isValid()) {
825+
type = new (Context) ExistentialTypeRepr(anyLoc, type);
819826
}
820827
return type;
821828
};
@@ -866,16 +873,21 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
866873
consumeToken(); // consume '&'
867874
}
868875

869-
// Diagnose invalid `some` after an ampersand.
870-
if (Tok.isContextualKeyword("some")) {
876+
// Diagnose invalid `some` or `any` after an ampersand.
877+
if (Tok.isContextualKeyword("some") ||
878+
Tok.isContextualKeyword("any")) {
879+
auto keyword = Tok.getText();
871880
auto badLoc = consumeToken();
872881

873-
diagnose(badLoc, diag::opaque_mid_composition)
882+
diagnose(badLoc, diag::opaque_mid_composition, keyword)
874883
.fixItRemove(badLoc)
875-
.fixItInsert(FirstTypeLoc, "some ");
884+
.fixItInsert(FirstTypeLoc, keyword.str() + " ");
876885

877-
if (opaqueLoc.isInvalid())
886+
if (opaqueLoc.isInvalid()) {
878887
opaqueLoc = badLoc;
888+
} else if (anyLoc.isInvalid()) {
889+
anyLoc = badLoc;
890+
}
879891
}
880892

881893
// Parse next type.
@@ -1441,8 +1453,11 @@ bool Parser::canParseType() {
14411453
// Accept 'inout' at for better recovery.
14421454
consumeIf(tok::kw_inout);
14431455

1444-
if (Tok.isContextualKeyword("some"))
1456+
if (Tok.isContextualKeyword("some")) {
14451457
consumeToken();
1458+
} else if (Tok.isContextualKeyword("any")) {
1459+
consumeToken();
1460+
}
14461461

14471462
switch (Tok.getKind()) {
14481463
case tok::kw_Self:

0 commit comments

Comments
 (0)