Merge pull request #15257 from rintaro/parse-eliminate-square_lit
[Parse] Eliminate {l,r}_square_lit tokens.
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 6ff2ef6..592481b 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -1190,14 +1190,15 @@
"expected ']' in container literal expression", ())
// Object literal expressions
-ERROR(expected_object_literal_identifier,none,
- "expected identifier after '#' in object literal expression", ())
-ERROR(expected_arg_list_in_object_literal,none,
+ERROR(expected_arg_list_in_object_literal,PointsToFirstBadToken,
"expected argument list in object literal", ())
-ERROR(object_literal_legacy_name,none,
- "'%0' has been renamed to '%1", (StringRef, StringRef))
-ERROR(legacy_object_literal_syntax,none,
- "object literal syntax no longer uses '[# ... #]'", ())
+ERROR(legacy_object_literal,none,
+ "'%select{|[}0#%1(...)%select{|#]}0' has been renamed to '#%2(...)'",
+ (bool, StringRef, StringRef))
+
+// Unknown pound expression.
+ERROR(unknown_pound_expr,none,
+ "use of unknown directive '#%0'", (StringRef))
// If expressions
ERROR(expected_expr_after_if_question,none,
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 19891ae..4dbfa12 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -1281,15 +1281,14 @@
/// Parse an object literal.
///
/// \param LK The literal kind as determined by the first token.
- /// \param NewName New name for a legacy literal.
ParserResult<Expr> parseExprObjectLiteral(ObjectLiteralExpr::LiteralKind LK,
- bool isExprBasic,
- StringRef NewName = StringRef());
+ bool isExprBasic);
ParserResult<Expr> parseExprCallSuffix(ParserResult<Expr> fn,
bool isExprBasic);
- ParserResult<Expr> parseExprCollection(SourceLoc LSquareLoc = SourceLoc());
+ ParserResult<Expr> parseExprCollection();
ParserResult<Expr> parseExprArray(SourceLoc LSquareLoc);
ParserResult<Expr> parseExprDictionary(SourceLoc LSquareLoc);
+ ParserResult<Expr> parseExprPoundUnknown(SourceLoc LSquareLoc);
UnresolvedDeclRefExpr *parseExprOperator();
diff --git a/include/swift/Syntax/TokenKinds.def b/include/swift/Syntax/TokenKinds.def
index 13238ad..eb33fac 100644
--- a/include/swift/Syntax/TokenKinds.def
+++ b/include/swift/Syntax/TokenKinds.def
@@ -22,7 +22,6 @@
/// SIL_KEYWORD(kw)
/// POUND_KEYWORD(kw)
/// POUND_OBJECT_LITERAL(kw, desc, proto)
-/// POUND_OLD_OBJECT_LITERAL(kw, new_kw, old_arg, new_arg)
/// POUND_CONFIG(kw)
/// POUND_DIRECTIVE_KEYWORD(kw)
/// POUND_COND_DIRECTIVE_KEYWORD(kw)
@@ -96,13 +95,6 @@
#define POUND_OBJECT_LITERAL(kw, desc, proto) POUND_KEYWORD(kw)
#endif
-/// POUND_OLD_OBJECT_LITERAL(kw, new_kw, old_arg, new_arg)
-/// Every keyword prefixed with a '#' representing the obsoleted form of an
-/// object literal.
-#ifndef POUND_OLD_OBJECT_LITERAL
-#define POUND_OLD_OBJECT_LITERAL(kw, new_kw, old_arg, new_arg) POUND_KEYWORD(kw)
-#endif
-
/// POUND_CONFIG(kw)
/// Every keyword prefixed with a '#' representing a configuration.
#ifndef POUND_CONFIG
@@ -261,11 +253,6 @@
PUNCTUATOR(string_quote, "\"")
PUNCTUATOR(multiline_string_quote, "\"\"\"")
-// Legacy punctuators used for migrating old object literal syntax.
-// NOTE: Remove in the future.
-PUNCTUATOR(l_square_lit, "[#")
-PUNCTUATOR(r_square_lit, "#]")
-
// Keywords prefixed with a '#'. "keyPath" becomes "tok::pound_keyPath".
POUND_KEYWORD(keyPath)
POUND_KEYWORD(line)
@@ -294,10 +281,6 @@
POUND_OBJECT_LITERAL(imageLiteral, "image", ExpressibleByImageLiteral)
POUND_OBJECT_LITERAL(colorLiteral, "color", ExpressibleByColorLiteral)
-POUND_OLD_OBJECT_LITERAL(FileReference, fileLiteral, fileReferenceLiteral, resourceName)
-POUND_OLD_OBJECT_LITERAL(Image, imageLiteral, imageLiteral, resourceName)
-POUND_OLD_OBJECT_LITERAL(Color, colorLiteral, colorLiteralRed, red)
-
// Single-token literals
LITERAL(integer_literal)
LITERAL(floating_literal)
@@ -330,7 +313,6 @@
#undef SIL_KEYWORD
#undef POUND_KEYWORD
#undef POUND_OBJECT_LITERAL
-#undef POUND_OLD_OBJECT_LITERAL
#undef POUND_CONFIG
#undef POUND_DIRECTIVE_KEYWORD
#undef POUND_COND_DIRECTIVE_KEYWORD
diff --git a/lib/IDE/SyntaxModel.cpp b/lib/IDE/SyntaxModel.cpp
index e79980a..56623da 100644
--- a/lib/IDE/SyntaxModel.cpp
+++ b/lib/IDE/SyntaxModel.cpp
@@ -100,8 +100,6 @@
Kind = SyntaxNodeKind::Keyword;
break;
-#define POUND_OLD_OBJECT_LITERAL(Name, NewName, OldArg, NewArg) \
- case tok::pound_##Name:
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) case tok::pound_##Name:
#include "swift/Syntax/TokenKinds.def"
LiteralStartLoc = Loc;
@@ -119,7 +117,6 @@
break;
#define POUND_OBJECT_LITERAL(Name, Desc, Proto)
-#define POUND_OLD_OBJECT_LITERAL(Name, NewName, OldArg, NewArg)
#define POUND_DIRECTIVE_KEYWORD(Name)
#define POUND_KEYWORD(Name) case tok::pound_##Name:
#include "swift/Syntax/TokenKinds.def"
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 816c6b4..3c504dc 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -637,12 +637,6 @@
void Lexer::lexHash() {
const char *TokStart = CurPtr-1;
- // NOTE: legacy punctuator. Remove in the future.
- if (*CurPtr == ']') { // #]
- ++CurPtr;
- return formToken(tok::r_square_lit, TokStart);
- }
-
// Scan for [a-zA-Z]+ to see what we match.
const char *tmpPtr = CurPtr;
if (clang::isIdentifierHead(*tmpPtr)) {
@@ -2224,29 +2218,16 @@
case '@': return formToken(tok::at_sign, TokStart);
case '{': return formToken(tok::l_brace, TokStart);
- case '[': {
- // NOTE: Legacy punctuator for old object literal syntax.
- // Remove in the future.
- if (*CurPtr == '#') { // [#
- // NOTE: Do NOT include the '#' in the token, unlike in earlier
- // versions of Swift that supported the old object literal syntax
- // directly. The '#' will be lexed as part of the object literal
- // keyword token itself.
- return formToken(tok::l_square_lit, TokStart);
- }
- return formToken(tok::l_square, TokStart);
- }
+ case '[': return formToken(tok::l_square, TokStart);
case '(': return formToken(tok::l_paren, TokStart);
case '}': return formToken(tok::r_brace, TokStart);
case ']': return formToken(tok::r_square, TokStart);
- case ')':
- return formToken(tok::r_paren, TokStart);
+ case ')': return formToken(tok::r_paren, TokStart);
case ',': return formToken(tok::comma, TokStart);
case ';': return formToken(tok::semi, TokStart);
case ':': return formToken(tok::colon, TokStart);
- case '\\':
- return formToken(tok::backslash, TokStart);
+ case '\\': return formToken(tok::backslash, TokStart);
case '#':
return lexHash();
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 66e0fdb..d933169 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -883,14 +883,6 @@
/*Implicit=*/false));
}
- // NOTE: l_square_lit is for migrating the old object literal syntax.
- // Eventually this block can be removed.
- if (Tok.is(tok::l_square_lit) && !Tok.isAtStartOfLine() &&
- isCollectionLiteralStartingWithLSquareLit()) {
- assert(Tok.getLength() == 1);
- Tok.setKind(tok::l_square);
- }
-
if (Tok.isFollowingLSquare()) {
// super[expr]
SourceLoc lSquareLoc, rSquareLoc;
@@ -1240,14 +1232,6 @@
continue;
}
- // NOTE: l_square_lit is for migrating the old object literal syntax.
- // Eventually this block can be removed.
- if (Tok.is(tok::l_square_lit) && !Tok.isAtStartOfLine() &&
- isCollectionLiteralStartingWithLSquareLit()) {
- assert(Tok.getLength() == 1);
- Tok.setKind(tok::l_square);
- }
-
// Check for a [expr] suffix.
// Note that this cannot be the start of a new line.
if (Tok.isFollowingLSquare()) {
@@ -1804,61 +1788,12 @@
break;
}
- // NOTE: This is for migrating the old object literal syntax.
- // Eventually this block can be removed.
- case tok::l_square_lit: {// [#Color(...)#], [#Image(...)#]
- // If this is actually a collection literal starting with '[#', handle it
- // as such.
- if (isCollectionLiteralStartingWithLSquareLit()) {
- // Split the token into two.
- SourceLoc LSquareLoc =
- consumeStartingCharacterOfCurrentToken(tok::l_square);
- // Consume the '[' token.
- Result = parseExprCollection(LSquareLoc);
- break;
- }
-
- auto LSquareLoc = Tok.getLoc();
- auto LSquareTokRange = Tok.getRange();
- (void)consumeToken(tok::l_square_lit);
-
- if (Tok.is(tok::pound)) {
- consumeToken();
- if (!Tok.is(tok::identifier))
- diagnose(LSquareLoc, diag::expected_object_literal_identifier);
- skipUntil(tok::r_square_lit);
- Result = makeParserError();
- }
- else {
- Result = parseExprPostfix(ID, isExprBasic);
- }
-
- // This should be an invariant based on the check in
- // isCollectionLiteralStartingWithLSquareLit().
- auto RSquareTokRange = Tok.getRange();
- (void)consumeToken(tok::r_square_lit);
-
- // Issue a diagnostic for the legacy syntax and provide a fixit
- // to strip away the '[#' and '#]'
- diagnose(LSquareLoc, diag::legacy_object_literal_syntax)
- .fixItRemoveChars(LSquareTokRange.getStart(), LSquareTokRange.getEnd())
- .fixItRemoveChars(RSquareTokRange.getStart(), RSquareTokRange.getEnd());
-
- break;
- }
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) case tok::pound_##Name: \
Result = parseExprObjectLiteral(ObjectLiteralExpr::Name, isExprBasic); \
break;
#include "swift/Syntax/TokenKinds.def"
-#define POUND_OLD_OBJECT_LITERAL(Name, NewName, NewArg, OldArg)\
- case tok::pound_##Name: \
- Result = parseExprObjectLiteral(ObjectLiteralExpr::NewName, isExprBasic, \
- "#" #NewName); \
- break;
-#include "swift/Syntax/TokenKinds.def"
-
case tok::code_complete:
Result = makeParserResult(new (Context) CodeCompletionExpr(Tok.getLoc()));
Result.setHasCodeCompletion();
@@ -1870,6 +1805,13 @@
consumeToken(tok::code_complete);
break;
+ case tok::pound:
+ if (peekToken().is(tok::identifier) && !peekToken().isEscapedIdentifier() &&
+ Tok.getLoc().getAdvancedLoc(1) == peekToken().getLoc()) {
+ return parseExprPoundUnknown(SourceLoc());
+ }
+ goto UnknownCharacter;
+
// Eat an invalid token in an expression context. Error tokens are diagnosed
// by the lexer, so there is no reason to emit another diagnostic.
case tok::unknown:
@@ -3052,7 +2994,7 @@
if (!exprLabels.empty()) {
exprLabels.push_back(FieldName);
exprLabelLocs.push_back(FieldNameLoc);
- } else if (FieldName.get()) {
+ } else if (FieldNameLoc.isValid()) {
exprLabels.resize(exprs.size());
exprLabels.push_back(FieldName);
@@ -3117,32 +3059,6 @@
return closure;
}
-
-// NOTE: this is to detect the old object literal syntax.
-// This will be removed in the future.
-bool Parser::isCollectionLiteralStartingWithLSquareLit() {
- BacktrackingScope backtracking(*this);
- (void)consumeToken(tok::l_square_lit);
- switch (Tok.getKind()) {
- // Handle both degenerate '#' and '# identifier'.
- case tok::pound:
- (void) consumeToken();
- if (Tok.is(tok::identifier)) skipSingle();
- break;
-#define POUND_OBJECT_LITERAL(kw, desc, proto)\
- case tok::pound_##kw: (void)consumeToken(); break;
-#define POUND_OLD_OBJECT_LITERAL(kw, new_kw, old_arg, new_arg)\
- case tok::pound_##kw: (void)consumeToken(); break;
-#include "swift/Syntax/TokenKinds.def"
- default:
- return true;
- }
-
- // Skip over a parenthesized argument, if present.
- if (Tok.is(tok::l_paren)) skipSingle();
-
- return Tok.isNot(tok::r_square_lit);
- }
/// \brief Parse an object literal expression.
///
@@ -3150,11 +3066,9 @@
/// '#' identifier expr-paren
ParserResult<Expr>
Parser::parseExprObjectLiteral(ObjectLiteralExpr::LiteralKind LitKind,
- bool isExprBasic,
- StringRef NewName) {
+ bool isExprBasic) {
SyntaxParsingContext ObjectLiteralContext(SyntaxContext,
SyntaxKind::ObjectLiteralExpr);
- auto PoundTok = Tok;
SourceLoc PoundLoc = consumeToken();
// Parse a tuple of args
if (!Tok.is(tok::l_paren)) {
@@ -3181,49 +3095,94 @@
if (status.isError())
return makeParserError();
- // If the legacy name was used (e.g., #Image instead of #imageLiteral)
- // prompt an error and a fixit.
- if (!NewName.empty()) {
- auto diag =
- diagnose(PoundTok, diag::object_literal_legacy_name,
- PoundTok.getText(), NewName);
- auto Range = PoundTok.getRange();
-
- // Create a FixIt for the keyword.
- diag.fixItReplaceChars(Range.getStart(), Range.getEnd(), NewName);
-
- // Try and construct a FixIt for the argument label.
- if (!argLabelLocs.empty() && !argLabels[0].empty()) {
- auto ArgLoc = argLabelLocs[0];
- auto FirstElementName = argLabels[0];
-
- if (ArgLoc.isValid() && !FirstElementName.empty()) {
- auto OldArg = FirstElementName.str();
- auto NewArg =
- llvm::StringSwitch<StringRef>(OldArg)
-#define POUND_OLD_OBJECT_LITERAL(kw, new_kw, old_arg, new_arg)\
- .Case(#old_arg, #new_arg)
-#include "swift/Syntax/TokenKinds.def"
- .Default("");
-
- if (!NewArg.empty()) {
- auto Loc = argLabelLocs[0];
- diag.fixItReplaceChars(Loc,
- Loc.getAdvancedLocOrInvalid(OldArg.size()),
- NewArg);
- }
- }
- }
-
- return makeParserError();
- }
-
return makeParserResult(
ObjectLiteralExpr::create(Context, PoundLoc, LitKind, lParenLoc, args,
argLabels, argLabelLocs, rParenLoc,
trailingClosure, /*implicit=*/false));
}
+/// \brief Parse and diagnose unknown pound expression
+///
+/// If it look like a legacy (Swift 2) object literal expression, suggest fix-it
+/// to use new object literal syntax.
+///
+/// expr-unknown-pound:
+/// '#' identifier expr-paren?
+/// '[' '#' identifier expr-paren? '#' ']' ; Legacy object literal
+ParserResult<Expr> Parser::parseExprPoundUnknown(SourceLoc LSquareLoc) {
+ SourceLoc PoundLoc = consumeToken(tok::pound);
+
+ assert(Tok.is(tok::identifier) && !Tok.isEscapedIdentifier() &&
+ PoundLoc.getAdvancedLoc(1) == Tok.getLoc());
+
+ Identifier Name;
+ SourceLoc NameLoc = consumeIdentifier(&Name);
+
+ // Parse arguments if exist.
+ SourceLoc LParenLoc, RParenLoc;
+ SmallVector<SourceLoc, 2> argLabelLocs;
+ SmallVector<Expr *, 2> args;
+ SmallVector<Identifier, 2> argLabels;
+ Expr *trailingClosure;
+ if (Tok.isFollowingLParen()) {
+ // Parse arguments.
+ ParserStatus status =
+ parseExprList(tok::l_paren, tok::r_paren,
+ /*isPostfix=*/false, /*isExprBasic*/ false, LParenLoc,
+ args, argLabels, argLabelLocs, RParenLoc, trailingClosure,
+ SyntaxKind::FunctionCallArgumentList);
+ if (status.hasCodeCompletion())
+ return makeParserCodeCompletionResult<Expr>();
+ if (status.isError())
+ return makeParserError();
+ }
+
+ std::pair<StringRef, StringRef> NewNameArgPair =
+ llvm::StringSwitch<std::pair<StringRef, StringRef>>(Name.str())
+ .Case("Color", {"colorLiteral", "red"})
+ .Case("Image", {"imageLiteral", "resourceName"})
+ .Case("FileReference", {"fileLiteral", "resourceName"})
+ .Default({});
+
+ // If it's not legacy object literal, we don't know how to handle this.
+ if (NewNameArgPair.first.empty()) {
+ diagnose(PoundLoc, diag::unknown_pound_expr, Name.str());
+ return makeParserError();
+ }
+
+ // Diagnose legacy object literal.
+
+ // Didn't have arguments.
+ if (LParenLoc.isInvalid()) {
+ diagnose(Tok.getLoc(), diag::expected_arg_list_in_object_literal);
+ return makeParserError();
+ }
+
+ // If it's started with '[', try to parse closing '#]'.
+ SourceLoc RPoundLoc, RSquareLoc;
+ if (LSquareLoc.isValid() && consumeIf(tok::pound, RPoundLoc))
+ consumeIf(tok::r_square, RSquareLoc);
+
+ auto diag = diagnose(LSquareLoc.isValid() ? LSquareLoc : PoundLoc,
+ diag::legacy_object_literal, LSquareLoc.isValid(),
+ Name.str(), NewNameArgPair.first);
+
+ // Remove '[' if exist.
+ if (LSquareLoc.isValid())
+ diag.fixItRemove(LSquareLoc);
+ // Replace the literal name.
+ diag.fixItReplace(NameLoc, NewNameArgPair.first);
+ // Replace the first argument.
+ if (!argLabelLocs.empty() && argLabelLocs[0].isValid())
+ diag.fixItReplace(argLabelLocs[0], NewNameArgPair.second);
+ // Remove '#]' if exist.
+ if (RPoundLoc.isValid())
+ diag.fixItRemove(
+ {RPoundLoc, RSquareLoc.isValid() ? RSquareLoc : RPoundLoc});
+
+ return makeParserError();
+}
+
/// \brief Parse an expression call suffix.
///
/// expr-call-suffix:
@@ -3293,12 +3252,9 @@
/// expr-array
/// expr-dictionary
// lsquare-starting ']'
-ParserResult<Expr> Parser::parseExprCollection(SourceLoc LSquareLoc) {
+ParserResult<Expr> Parser::parseExprCollection() {
SyntaxParsingContext ArrayOrDictContext(SyntaxContext);
-
- // If the caller didn't already consume the '[', do so now.
- if (LSquareLoc.isInvalid())
- LSquareLoc = consumeToken(tok::l_square);
+ SourceLoc LSquareLoc = consumeToken(tok::l_square);
Parser::StructureMarkerRAII ParsingCollection(
*this, LSquareLoc,
@@ -3324,6 +3280,15 @@
DictionaryExpr::create(Context, LSquareLoc, {}, {}, RSquareLoc));
}
+ // [#identifier is likely to be a legacy object literal.
+ if (Tok.is(tok::pound) && peekToken().is(tok::identifier) &&
+ !peekToken().isEscapedIdentifier() &&
+ LSquareLoc.getAdvancedLoc(1) == Tok.getLoc() &&
+ Tok.getLoc().getAdvancedLoc(1) == peekToken().getLoc()) {
+ ArrayOrDictContext.setCoerceKind(SyntaxContextKind::Expr);
+ return parseExprPoundUnknown(LSquareLoc);
+ }
+
bool ParseDict;
{
BacktrackingScope Scope(*this);
diff --git a/test/Parse/object_literals.swift b/test/Parse/object_literals.swift
index 9cb7e5a..ca00bd6 100644
--- a/test/Parse/object_literals.swift
+++ b/test/Parse/object_literals.swift
@@ -1,6 +1,19 @@
// RUN: %target-typecheck-verify-swift
-let _ = [##] // expected-error{{expected identifier after '#' in object literal expression}} expected-error{{object literal syntax no longer uses '[# ... #]'}} {{9-10=}} {{11-13=}}
-let _ = [#what#] // expected-error{{object literal syntax no longer uses '[# ... #]'}} {{9-10=}} {{15-17=}}
-let _ = [#what()#] // expected-error{{object literal syntax no longer uses '[# ... #]'}} {{9-10=}} {{17-19=}}
-let _ = [#colorLiteral( // expected-error@+1 {{expected expression in list of expressions}}
+let _ = [#Color(colorLiteralRed: red, green: green, blue: blue, alpha: alpha)#] // expected-error {{'[#Color(...)#]' has been renamed to '#colorLiteral(...)}} {{9-10=}} {{11-16=colorLiteral}} {{17-32=red}} {{78-80=}}
+let _ = [#Image(imageLiteral: localResourceNameAsString)#] // expected-error {{'[#Image(...)#]' has been renamed to '#imageLiteral(...)'}} {{9-10=}} {{11-16=imageLiteral}} {{17-29=resourceName}} {{57-59=}}
+let _ = [#FileReference(fileReferenceLiteral: localResourceNameAsString)#] // expected-error {{'[#FileReference(...)#]' has been renamed to '#fileLiteral(...)'}} {{9-10=}} {{11-24=fileLiteral}} {{25-45=resourceName}} {{73-75=}}
+
+let _ = #Color(colorLiteralRed: red, green: green, blue: blue, alpha: alpha) // expected-error {{'#Color(...)' has been renamed to '#colorLiteral(...)}} {{10-15=colorLiteral}} {{16-31=red}}
+let _ = #Image(imageLiteral: localResourceNameAsString) // expected-error {{'#Image(...)' has been renamed to '#imageLiteral(...)'}} {{10-15=imageLiteral}} {{16-28=resourceName}}
+let _ = #FileReference(fileReferenceLiteral: localResourceNameAsString) // expected-error {{'#FileReference(...)' has been renamed to '#fileLiteral(...)'}} {{10-23=fileLiteral}} {{24-44=resourceName}}
+
+let _ = #notAPound // expected-error {{use of unknown directive '#notAPound'}}
+let _ = #notAPound(1, 2) // expected-error {{use of unknown directive '#notAPound'}}
+let _ = #Color // expected-error {{expected argument list in object literal}} {{none}}
+
+let _ = [##] // expected-error {{expected expression in container literal}} {{none}}
+let _ = [#Color(_: 1, green: 1, 2) // expected-error {{'[#Color(...)#]' has been renamed to '#colorLiteral(...)'}} {{9-10=}} {{11-16=colorLiteral}} {{17-18=red}}
+let _ = [#Color(red: 1, green: 1, blue: 1)# // expected-error {{'[#Color(...)#]' has been renamed to '#colorLiteral(...)'}} {{9-10=}} {{11-16=colorLiteral}} {{17-20=red}} {{43-44=}}
+let _ = [#Color(withRed: 1, green: 1, whatever: 2)#] // expected-error {{'[#Color(...)#]' has been renamed to '#colorLiteral(...)'}} {{9-10=}} {{11-16=colorLiteral}} {{17-24=red}} {{51-53=}}
+let _ = #Color(_: 1, green: 1) // expected-error {{'#Color(...)' has been renamed to '#colorLiteral(...)'}} {{10-15=colorLiteral}} {{16-17=red}}
diff --git a/test/expr/postfix/keypath/keypath-objc.swift b/test/expr/postfix/keypath/keypath-objc.swift
index 24867a8..c130cfa 100644
--- a/test/expr/postfix/keypath/keypath-objc.swift
+++ b/test/expr/postfix/keypath/keypath-objc.swift
@@ -112,6 +112,7 @@
let dict: [String: Int] = [:]
let _: Int? = dict[#keyPath(A.propB)]
+ let _ = [#keyPath(A.propB)]
}
func testAsStaticString() {
diff --git a/test/expr/unary/selector/selector.swift b/test/expr/unary/selector/selector.swift
index 7b7a468..6f488c2 100644
--- a/test/expr/unary/selector/selector.swift
+++ b/test/expr/unary/selector/selector.swift
@@ -86,6 +86,7 @@
let dict: [Selector: Int] = [:]
let _: Int? = dict[#selector(c1.method1)]
+ let _ = [#selector(c1.method1)]
}
func testAmbiguity() {