Skip to content

Commit c8ed597

Browse files
Merge pull request swiftlang#40953 from AnthonyLatsis/any-aint-some
Parse: Fix accidental parsing of ExistentialTypeRepr as OpaqueReturnTypeRepr and vice versa
2 parents baf7ef1 + 52de904 commit c8ed597

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

lib/Parse/ParseType.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) {
796796
///
797797
/// type-composition:
798798
/// 'some'? type-simple
799+
/// 'any'? type-simple
799800
/// type-composition '&' type-simple
800801
ParserResult<TypeRepr>
801802
Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
@@ -818,8 +819,9 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
818819
SomeTypeContext.setTransparent();
819820
}
820821

821-
auto applyOpaque = [&](TypeRepr *type) -> TypeRepr* {
822-
if (opaqueLoc.isValid()) {
822+
auto applyOpaque = [&](TypeRepr *type) -> TypeRepr * {
823+
if (opaqueLoc.isValid() &&
824+
(anyLoc.isInvalid() || SourceMgr.isBeforeInBuffer(opaqueLoc, anyLoc))) {
823825
type = new (Context) OpaqueReturnTypeRepr(opaqueLoc, type);
824826
} else if (anyLoc.isValid()) {
825827
type = new (Context) ExistentialTypeRepr(anyLoc, type);
@@ -879,14 +881,18 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
879881
auto keyword = Tok.getText();
880882
auto badLoc = consumeToken();
881883

884+
const bool isAnyKeyword = keyword.equals("any");
885+
882886
diagnose(badLoc, diag::opaque_mid_composition, keyword)
883887
.fixItRemove(badLoc)
884888
.fixItInsert(FirstTypeLoc, keyword.str() + " ");
885889

886-
if (opaqueLoc.isInvalid()) {
890+
if (isAnyKeyword) {
891+
if (anyLoc.isInvalid()) {
892+
anyLoc = badLoc;
893+
}
894+
} else if (opaqueLoc.isInvalid()) {
887895
opaqueLoc = badLoc;
888-
} else if (anyLoc.isInvalid()) {
889-
anyLoc = badLoc;
890896
}
891897
}
892898

test/type/explicit_existential.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ func anyAny() {
156156

157157
protocol P1 {}
158158
protocol P2 {}
159+
do {
160+
// Test that we don't accidentally misparse an 'any' type as a 'some' type
161+
// and vice versa.
162+
let _: P1 & any P2 // expected-error {{'any' should appear at the beginning of a composition}}
163+
let _: any P1 & any P2 // expected-error {{'any' should appear at the beginning of a composition}}
164+
let _: any P1 & some P2 // expected-error {{'some' should appear at the beginning of a composition}}
165+
let _: some P1 & any P2
166+
// expected-error@-1 {{'some' type can only be declared on a single property declaration}}
167+
// expected-error@-2 {{'any' should appear at the beginning of a composition}}
168+
}
169+
159170
struct ConcreteComposition: P1, P2 {}
160171

161172
func testMetatypes() {

0 commit comments

Comments
 (0)