@@ -2142,14 +2142,29 @@ ParserResult<Expr> Parser::parseExprStringLiteral() {
2142
2142
AppendingExpr));
2143
2143
}
2144
2144
2145
+ // / Equivalent to \c Tok.is(tok::colon), but pretends that \c tok::colon_colon
2146
+ // / doesn't exist if \c EnableExperimentalModuleSelector is disabled.
2147
+ static bool isColon (Parser &P, Token Tok, tok altColon = tok::NUM_TOKENS) {
2148
+ // FIXME: Introducing tok::colon_colon broke diag::empty_arg_label_underscore.
2149
+ // We only care about tok::colon_colon when module selectors are turned on, so
2150
+ // when they are turned off, this function works around the bug by treating
2151
+ // tok::colon_colon as a synonym for tok::colon. However, the bug still exists
2152
+ // when Feature::ModuleSelector is enabled. We will need to address this
2153
+ // before the feature can be released.
2154
+
2155
+ if (P.Context .LangOpts .hasFeature (Feature::ModuleSelector))
2156
+ return Tok.isAny (tok::colon, altColon);
2157
+
2158
+ return Tok.isAny (tok::colon, tok::colon_colon, altColon);
2159
+ }
2160
+
2145
2161
void Parser::parseOptionalArgumentLabel (Identifier &name, SourceLoc &loc,
2146
2162
bool isAttr) {
2147
2163
// / A token that has the same meaning as colon, but is deprecated, if one exists for this call.
2148
2164
auto altColon = isAttr ? tok::equal : tok::NUM_TOKENS;
2149
2165
2150
2166
// Check to see if there is an argument label.
2151
- if (Tok.canBeArgumentLabel () && peekToken ().isAny (tok::colon, altColon)) {
2152
- // Label found, including colon.
2167
+ if (Tok.canBeArgumentLabel () && isColon (*this , peekToken (), altColon)) {
2153
2168
auto text = Tok.getText ();
2154
2169
2155
2170
// If this was an escaped identifier that need not have been escaped, say
@@ -2168,7 +2183,7 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
2168
2183
}
2169
2184
2170
2185
loc = consumeArgumentLabel (name, /* diagnoseDollarPrefix=*/ false );
2171
- } else if (Tok. isAny (tok::colon , altColon)) {
2186
+ } else if (isColon (* this , Tok , altColon)) {
2172
2187
// Found only the colon.
2173
2188
diagnose (Tok, diag::expected_label_before_colon)
2174
2189
.fixItInsert (Tok.getLoc (), " <#label#>" );
@@ -2178,7 +2193,12 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
2178
2193
}
2179
2194
2180
2195
// If we get here, we ought to be on the colon.
2181
- assert (Tok.isAny (tok::colon, altColon));
2196
+ ASSERT (Tok.isAny (tok::colon, tok::colon_colon, altColon));
2197
+
2198
+ if (Tok.is (tok::colon_colon)) {
2199
+ consumeIfColonSplittingDoubles ();
2200
+ return ;
2201
+ }
2182
2202
2183
2203
if (Tok.is (altColon))
2184
2204
diagnose (Tok, diag::replace_equal_with_colon_for_value)
@@ -2208,7 +2228,7 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
2208
2228
flags.contains (Parser::DeclNameFlag::AllowZeroArgCompoundNames) &&
2209
2229
next.is (tok::r_paren);
2210
2230
// An argument label.
2211
- bool nextIsArgLabel = next.canBeArgumentLabel () || next. is (tok::colon );
2231
+ bool nextIsArgLabel = next.canBeArgumentLabel () || isColon (P, next );
2212
2232
// An editor placeholder.
2213
2233
bool nextIsPlaceholder = next.isEditorPlaceholder ();
2214
2234
@@ -2221,11 +2241,11 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
2221
2241
lparenLoc = P.consumeToken (tok::l_paren);
2222
2242
while (P.Tok .isNot (tok::r_paren)) {
2223
2243
// If we see a ':', the user forgot the '_';
2224
- if (P.Tok . is (tok::colon )) {
2225
- P.diagnose (P.Tok , diag::empty_arg_label_underscore)
2226
- .fixItInsert (P.Tok . getLoc () , " _" );
2244
+ if (P.consumeIfColonSplittingDoubles ( )) {
2245
+ P.diagnose (P.PreviousLoc , diag::empty_arg_label_underscore)
2246
+ .fixItInsert (P.PreviousLoc , " _" );
2227
2247
argumentLabels.push_back (Identifier ());
2228
- argumentLabelLocs.push_back (P.consumeToken (tok::colon) );
2248
+ argumentLabelLocs.push_back (P.PreviousLoc );
2229
2249
}
2230
2250
2231
2251
Identifier argName;
0 commit comments