@@ -2142,14 +2142,29 @@ ParserResult<Expr> Parser::parseExprStringLiteral() {
21422142 AppendingExpr));
21432143}
21442144
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+
21452161void Parser::parseOptionalArgumentLabel (Identifier &name, SourceLoc &loc,
21462162 bool isAttr) {
21472163 // / A token that has the same meaning as colon, but is deprecated, if one exists for this call.
21482164 auto altColon = isAttr ? tok::equal : tok::NUM_TOKENS;
21492165
21502166 // 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)) {
21532168 auto text = Tok.getText ();
21542169
21552170 // If this was an escaped identifier that need not have been escaped, say
@@ -2168,7 +2183,7 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
21682183 }
21692184
21702185 loc = consumeArgumentLabel (name, /* diagnoseDollarPrefix=*/ false );
2171- } else if (Tok. isAny (tok::colon , altColon)) {
2186+ } else if (isColon (* this , Tok , altColon)) {
21722187 // Found only the colon.
21732188 diagnose (Tok, diag::expected_label_before_colon)
21742189 .fixItInsert (Tok.getLoc (), " <#label#>" );
@@ -2178,7 +2193,12 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
21782193 }
21792194
21802195 // 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+ }
21822202
21832203 if (Tok.is (altColon))
21842204 diagnose (Tok, diag::replace_equal_with_colon_for_value)
@@ -2208,7 +2228,7 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
22082228 flags.contains (Parser::DeclNameFlag::AllowZeroArgCompoundNames) &&
22092229 next.is (tok::r_paren);
22102230 // An argument label.
2211- bool nextIsArgLabel = next.canBeArgumentLabel () || next. is (tok::colon );
2231+ bool nextIsArgLabel = next.canBeArgumentLabel () || isColon (P, next );
22122232 // An editor placeholder.
22132233 bool nextIsPlaceholder = next.isEditorPlaceholder ();
22142234
@@ -2221,11 +2241,11 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
22212241 lparenLoc = P.consumeToken (tok::l_paren);
22222242 while (P.Tok .isNot (tok::r_paren)) {
22232243 // 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 , " _" );
22272247 argumentLabels.push_back (Identifier ());
2228- argumentLabelLocs.push_back (P.consumeToken (tok::colon) );
2248+ argumentLabelLocs.push_back (P.PreviousLoc );
22292249 }
22302250
22312251 Identifier argName;
0 commit comments