@@ -682,7 +682,8 @@ bool Parser::parseSpecializeAttributeArguments(
682682 DeclNameFlag::AllowZeroArgCompoundNames |
683683 DeclNameFlag::AllowKeywordsUsingSpecialNames |
684684 DeclNameFlag::AllowOperators |
685- DeclNameFlag::AllowLowercaseAndUppercaseSelf);
685+ DeclNameFlag::AllowLowercaseAndUppercaseSelf |
686+ DeclNameFlag::ModuleSelectorUnsupported);
686687 }
687688 }
688689 if (ParamLabel == " spiModule" ) {
@@ -1136,7 +1137,8 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
11361137 MemberNameLoc, diag::attr_implements_expected_member_name,
11371138 DeclNameFlag::AllowZeroArgCompoundNames |
11381139 DeclNameFlag::AllowOperators |
1139- DeclNameFlag::AllowLowercaseAndUppercaseSelf);
1140+ DeclNameFlag::AllowLowercaseAndUppercaseSelf |
1141+ DeclNameFlag::ModuleSelectorUnsupported);
11401142 if (!MemberName) {
11411143 Status.setIsParseError ();
11421144 }
@@ -1159,7 +1161,7 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
11591161 return Status;
11601162 }
11611163
1162- // FIXME(ModQual): Reject module qualification on MemberName.
1164+ assert ( MemberName.getModuleSelector (). empty ());
11631165 return ParserResult<ImplementsAttr>(
11641166 ImplementsAttr::create (Context, AtLoc, SourceRange (Loc, rParenLoc),
11651167 ProtocolType.get (), MemberName.getFullName (),
@@ -2440,7 +2442,8 @@ Parser::parseMacroRoleAttribute(
24402442 (DeclNameFlag::AllowOperators | DeclNameFlag::AllowKeywords |
24412443 DeclNameFlag::AllowKeywordsUsingSpecialNames |
24422444 DeclNameFlag::AllowCompoundNames |
2443- DeclNameFlag::AllowZeroArgCompoundNames));
2445+ DeclNameFlag::AllowZeroArgCompoundNames |
2446+ DeclNameFlag::ModuleSelectorUnsupported));
24442447 if (!name) {
24452448 status.setIsParseError ();
24462449 return status;
@@ -4256,11 +4259,15 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
42564259 .warnUntilSwiftVersion (6 );
42574260 }
42584261
4262+ bool hasModuleSelector = Context.LangOpts .hasFeature (Feature::ModuleSelector)
4263+ && peekToken ().is (tok::colon_colon);
4264+
42594265 // If this not an identifier, the attribute is malformed.
42604266 if (Tok.isNot (tok::identifier) &&
42614267 Tok.isNot (tok::kw_in) &&
42624268 Tok.isNot (tok::kw_inout) &&
4263- Tok.isNot (tok::kw_rethrows)) {
4269+ Tok.isNot (tok::kw_rethrows) &&
4270+ !hasModuleSelector) {
42644271
42654272 if (Tok.is (tok::code_complete)) {
42664273 if (CodeCompletionCallbacks) {
@@ -4281,7 +4288,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
42814288
42824289 // If the attribute follows the new representation, switch
42834290 // over to the alternate parsing path.
4284- std::optional<DeclAttrKind> DK =
4291+ std::optional<DeclAttrKind> DK = hasModuleSelector ? std:: nullopt :
42854292 DeclAttribute::getAttrKindFromString (Tok.getText ());
42864293 if (DK == DeclAttrKind::Rethrows) {
42874294 DK = DeclAttrKind::AtRethrows;
@@ -4293,7 +4300,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
42934300 auto checkInvalidAttrName =
42944301 [&](StringRef invalidName, StringRef correctName, DeclAttrKind kind,
42954302 std::optional<Diag<StringRef, StringRef>> diag = std::nullopt ) {
4296- if (!DK && Tok.getText () == invalidName) {
4303+ if (!DK && !hasModuleSelector && Tok.getText () == invalidName) {
42974304 DK = kind;
42984305
42994306 if (diag) {
@@ -4357,7 +4364,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
43574364 DeclAttrKind::Preconcurrency,
43584365 diag::attr_renamed_warning);
43594366
4360- if (!DK && Tok.getText () == " warn_unused_result" ) {
4367+ if (!DK && !hasModuleSelector && Tok.getText () == " warn_unused_result" ) {
43614368 // The behavior created by @warn_unused_result is now the default. Emit a
43624369 // Fix-It to remove.
43634370 SourceLoc attrLoc = consumeToken ();
@@ -4432,9 +4439,10 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
44324439 return parseNewDeclAttribute (Attributes, AtLoc, *DK, isFromClangAttribute);
44334440 }
44344441
4435- if (TypeAttribute::getAttrKindFromString (Tok.getText ()).has_value ())
4442+ if (!hasModuleSelector &&
4443+ TypeAttribute::getAttrKindFromString (Tok.getText ()).has_value ())
44364444 diagnose (Tok, diag::type_attribute_applied_to_decl);
4437- else if (Tok.isContextualKeyword (" unknown" )) {
4445+ else if (!hasModuleSelector && Tok.isContextualKeyword (" unknown" )) {
44384446 diagnose (Tok, diag::unknown_attr_name, " unknown" );
44394447 } else {
44404448 // Change the context to create a custom attribute syntax.
@@ -5761,6 +5769,8 @@ static void skipAttribute(Parser &P) {
57615769 // Parse the attribute name, which can be qualified, have
57625770 // generic arguments, and so on.
57635771 do {
5772+ P.parseModuleSelector ();
5773+
57645774 if (!(P.consumeIf (tok::identifier) || P.consumeIf (tok::kw_rethrows)) &&
57655775 !P.consumeIf (tok::code_complete))
57665776 return ;
@@ -10343,9 +10353,11 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1034310353 return makeParserCodeCompletionResult<OperatorDecl>();
1034410354 }
1034510355
10356+ // TODO: We could support module selectors for precedence groups if we
10357+ // implemented the lookup for it.
1034610358 groupName = parseDeclNameRef (groupLoc,
1034710359 diag::operator_decl_expected_precedencegroup,
10348- {} );
10360+ DeclNameFlag::ModuleSelectorUnsupported );
1034910361
1035010362 if (Context.TypeCheckerOpts .EnableOperatorDesignatedTypes ) {
1035110363 // Designated types have been removed; consume the list (mainly for source
@@ -10643,7 +10655,7 @@ Parser::parseDeclPrecedenceGroup(ParseDeclOptions flags,
1064310655 auto name = parseDeclNameRef (nameLoc,
1064410656 { diag::expected_precedencegroup_relation,
1064510657 attrName },
10646- {} );
10658+ DeclNameFlag::ModuleSelectorUnsupported );
1064710659 if (!name) {
1064810660 return abortBody ();
1064910661 }
0 commit comments