Skip to content

Commit 08d88bc

Browse files
authored
Merge pull request #84994 from beccadax/mod-squad-arg-list
[SE-0491] Fix malformed arg label error with module selector
2 parents b662533 + 96e6b1d commit 08d88bc

File tree

3 files changed

+22
-30
lines changed

3 files changed

+22
-30
lines changed

include/swift/Parse/Parser.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1817,8 +1817,11 @@ class Parser {
18171817
/// \param loc The location of the label (empty if it doesn't exist)
18181818
/// \param isAttr True if this is an argument label for an attribute (allows, but deprecates, use of
18191819
/// \c '=' instead of \c ':').
1820+
/// \param splittingColonColon True if \c :: tokens should be treated as two
1821+
/// adjacent colons.
18201822
void parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
1821-
bool isAttr = false);
1823+
bool isAttr = false,
1824+
bool splittingColonColon = false);
18221825

18231826
/// If a \c module-selector is present, returns a true value (specifically,
18241827
/// 1 or 2 depending on how many tokens should be consumed to skip it).

lib/Parse/ParseExpr.cpp

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,29 +2154,15 @@ ParserResult<Expr> Parser::parseExprStringLiteral() {
21542154
AppendingExpr));
21552155
}
21562156

2157-
/// Equivalent to \c Tok.is(tok::colon), but pretends that \c tok::colon_colon
2158-
/// doesn't exist if \c EnableExperimentalModuleSelector is disabled.
2159-
static bool isColon(Parser &P, Token Tok, tok altColon = tok::NUM_TOKENS) {
2160-
// FIXME: Introducing tok::colon_colon broke diag::empty_arg_label_underscore.
2161-
// We only care about tok::colon_colon when module selectors are turned on, so
2162-
// when they are turned off, this function works around the bug by treating
2163-
// tok::colon_colon as a synonym for tok::colon. However, the bug still exists
2164-
// when Feature::ModuleSelector is enabled. We will need to address this
2165-
// before the feature can be released.
2166-
2167-
if (P.Context.LangOpts.hasFeature(Feature::ModuleSelector))
2168-
return Tok.isAny(tok::colon, altColon);
2169-
2170-
return Tok.isAny(tok::colon, tok::colon_colon, altColon);
2171-
}
2172-
21732157
void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
2174-
bool isAttr) {
2158+
bool isAttr, bool splittingColonColon) {
2159+
auto colonColon = splittingColonColon ? tok::colon_colon : tok::NUM_TOKENS;
21752160
/// A token that has the same meaning as colon, but is deprecated, if one exists for this call.
21762161
auto altColon = isAttr ? tok::equal : tok::NUM_TOKENS;
21772162

21782163
// Check to see if there is an argument label.
2179-
if (Tok.canBeArgumentLabel() && isColon(*this, peekToken(), altColon)) {
2164+
if (Tok.canBeArgumentLabel() && peekToken().isAny(tok::colon, colonColon,
2165+
altColon)) {
21802166
auto text = Tok.getText();
21812167

21822168
// If this was an escaped identifier that need not have been escaped, say
@@ -2195,7 +2181,7 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
21952181
}
21962182

21972183
loc = consumeArgumentLabel(name, /*diagnoseDollarPrefix=*/false);
2198-
} else if (isColon(*this, Tok, altColon)) {
2184+
} else if (Tok.isAny(tok::colon, colonColon, altColon)) {
21992185
// Found only the colon.
22002186
diagnose(Tok, diag::expected_label_before_colon)
22012187
.fixItInsert(Tok.getLoc(), "<#label#>");
@@ -2205,17 +2191,13 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
22052191
}
22062192

22072193
// If we get here, we ought to be on the colon.
2208-
ASSERT(Tok.isAny(tok::colon, tok::colon_colon, altColon));
2209-
2210-
if (Tok.is(tok::colon_colon)) {
2211-
consumeIfColonSplittingDoubles();
2194+
if (consumeIfColonSplittingDoubles())
22122195
return;
2213-
}
22142196

2215-
if (Tok.is(altColon))
2216-
diagnose(Tok, diag::replace_equal_with_colon_for_value)
2217-
.fixItReplace(Tok.getLoc(), ": ");
2197+
ASSERT(Tok.is(altColon));
22182198

2199+
diagnose(Tok, diag::replace_equal_with_colon_for_value)
2200+
.fixItReplace(Tok.getLoc(), ": ");
22192201
consumeToken();
22202202
}
22212203

@@ -2240,7 +2222,10 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
22402222
flags.contains(Parser::DeclNameFlag::AllowZeroArgCompoundNames) &&
22412223
next.is(tok::r_paren);
22422224
// An argument label.
2243-
bool nextIsArgLabel = next.canBeArgumentLabel() || isColon(P, next);
2225+
// We allow `tok::colon_colon` so that e.g. `fn(::)` gets diagnosed as a
2226+
// malformed version of `fn(_:_:)`.
2227+
bool nextIsArgLabel = next.canBeArgumentLabel()
2228+
|| next.isAny(tok::colon, tok::colon_colon);
22442229
// An editor placeholder.
22452230
bool nextIsPlaceholder = next.isEditorPlaceholder();
22462231

@@ -2262,7 +2247,8 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
22622247

22632248
Identifier argName;
22642249
SourceLoc argLoc;
2265-
P.parseOptionalArgumentLabel(argName, argLoc);
2250+
P.parseOptionalArgumentLabel(argName, argLoc, /*isAttr=*/false,
2251+
/*splittingColonColon=*/true);
22662252
if (argLoc.isValid()) {
22672253
argumentLabels.push_back(argName);
22682254
argumentLabelLocs.push_back(argLoc);

test/expr/primary/unqualified_name.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
// RUN: %target-typecheck-verify-swift -swift-version 4
22

3+
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-experimental-feature ModuleSelector
4+
// REQUIRES: swift_feature_ModuleSelector
5+
36
func f0(_ x: Int, y: Int, z: Int) { }
47
func f1(_ x: Int, while: Int) { }
58
func f2(_ x: Int, `let` _: Int) { }

0 commit comments

Comments
 (0)