Skip to content

Commit 739cc2a

Browse files
Merge pull request #64104 from sophiapoirier/type-parameter-pack-syntax-each-diagnostics
[Variadic Generics] fix diagnostics dangling reference and fixits for…
2 parents b021123 + cdde853 commit 739cc2a

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ if(SWIFT_ASM_AVAILABLE)
6868
enable_language(${SWIFT_ASM_DIALECT})
6969
endif()
7070

71-
# Use C++14.
71+
# Use C++17.
7272
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
7373
set(CMAKE_CXX_STANDARD_REQUIRED YES)
7474
set(CMAKE_CXX_EXTENSIONS NO)

lib/Parse/ParseDecl.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6391,6 +6391,14 @@ ParserResult<TypeDecl> Parser::parseDeclAssociatedType(Parser::ParseDeclOptions
63916391
AssociatedTypeLoc = consumeToken(tok::kw_associatedtype);
63926392
}
63936393

6394+
// Reject variadic associated types with a specific error.
6395+
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
6396+
Tok.isContextualKeyword("each")) {
6397+
const auto EachLoc = consumeToken();
6398+
diagnose(EachLoc, diag::associatedtype_cannot_be_variadic)
6399+
.fixItRemoveChars(EachLoc, Tok.getLoc());
6400+
}
6401+
63946402
Status = parseIdentifierDeclName(
63956403
*this, Id, IdLoc, "associatedtype",
63966404
[](const Token &next) { return next.isAny(tok::colon, tok::equal); });
@@ -6408,12 +6416,13 @@ ParserResult<TypeDecl> Parser::parseDeclAssociatedType(Parser::ParseDeclOptions
64086416
}
64096417
}
64106418

6411-
// Reject variadic associated types with a specific error.
6419+
// Reject (early syntax) variadic associated types with a specific error.
64126420
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
64136421
startsWithEllipsis(Tok)) {
6414-
auto Ellipsis = consumeStartingEllipsis();
6415-
diagnose(Ellipsis, diag::associatedtype_cannot_be_variadic)
6416-
.fixItRemoveChars(Ellipsis, Tok.getLoc());
6422+
const auto EllipsisLoc = consumeStartingEllipsis();
6423+
const auto EllipsisEnd = Lexer::getLocForEndOfToken(SourceMgr, EllipsisLoc);
6424+
diagnose(EllipsisLoc, diag::associatedtype_cannot_be_variadic)
6425+
.fixItRemoveChars(EllipsisLoc, EllipsisEnd);
64176426
}
64186427

64196428
// Parse optional inheritance clause.

lib/Parse/ParseGeneric.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,15 @@ Parser::parseGenericParametersBeforeWhere(SourceLoc LAngleLoc,
8080
// 'T...'.
8181
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
8282
startsWithEllipsis(Tok)) {
83+
const auto EllipsisLoc = consumeStartingEllipsis();
84+
// TODO: token length hardcoded because calculation for ellipsis
85+
// incorrectly includes '>' if one follows (as can occur in this parse).
8386
constexpr int EllipsisLength = 3;
84-
const SourceRange EllipsisRange(
85-
Tok.getLoc(), Tok.getLoc().getAdvancedLoc(EllipsisLength));
86-
auto &Diagnostic = diagnose(Tok, diag::type_parameter_pack_ellipsis)
87-
.fixItRemove(EllipsisRange);
87+
const auto EllipsisEnd = EllipsisLoc.getAdvancedLoc(EllipsisLength);
88+
auto Diag = diagnose(Tok, diag::type_parameter_pack_ellipsis);
89+
Diag.fixItRemoveChars(EllipsisLoc, EllipsisEnd);
8890
if (!EachLoc.isValid()) {
89-
Diagnostic.fixItInsert(NameLoc, "each");
91+
Diag.fixItInsert(NameLoc, "each ");
9092
}
9193
Result.setIsParseError();
9294
break;

test/Parse/type_parameter_packs.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
protocol P {}
66

77
protocol P1 {
8-
associatedtype A... // expected-error {{associated types cannot be variadic}}
9-
associatedtype B<U>...
10-
// expected-error@-1 {{associated types cannot be variadic}}
11-
// expected-error@-2 {{associated types must not have a generic parameter list}}
8+
associatedtype each A // expected-error {{associated types cannot be variadic}}{{18-23=}}
9+
associatedtype each B<U>
10+
// expected-error@-1 {{associated types cannot be variadic}}{{18-23=}}
11+
// expected-error@-2 {{associated types must not have a generic parameter list}}{{24-27=}}
12+
associatedtype C... // expected-error {{associated types cannot be variadic}}{{19-22=}}
13+
associatedtype D<U>...
14+
// expected-error@-1 {{associated types cannot be variadic}}{{22-25=}}
15+
// expected-error@-2 {{associated types must not have a generic parameter list}}{{19-22=}}
1216
}
1317

1418
typealias Alias<each T> = (repeat each T)
@@ -32,3 +36,10 @@ func quux<each T: P>(_ x: repeat each T) {}
3236
func foobar<T, U, each V>(x: T, y: U, z: repeat each V) { }
3337
func foobaz<T, each U, V>(x: T, y: repeat each U, z: V) { }
3438
func fooqux<each T, each U, each V>(x: repeat each T, y: repeat each U, z: repeat each V) { }
39+
40+
func ellipsis<T...>(_ x: repeat each T) {}
41+
// expected-error@-1 {{ellipsis operator cannot be used with a type parameter pack}}{{16-19=}}{{15-15=each }}
42+
// expected-error@-2 {{cannot find type 'T' in scope}}
43+
func eachEllipsis<each T...>(_ x: repeat each T) {}
44+
// expected-error@-1 {{ellipsis operator cannot be used with a type parameter pack}}{{25-28=}}
45+
// expected-error@-2 {{cannot find type 'T' in scope}}

0 commit comments

Comments
 (0)