@@ -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;
@@ -4269,11 +4272,15 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
42694272 .warnUntilSwiftVersion (6 );
42704273 }
42714274
4275+ bool hasModuleSelector = Context.LangOpts .hasFeature (Feature::ModuleSelector)
4276+ && peekToken ().is (tok::colon_colon);
4277+
42724278 // If this not an identifier, the attribute is malformed.
42734279 if (Tok.isNot (tok::identifier) &&
42744280 Tok.isNot (tok::kw_in) &&
42754281 Tok.isNot (tok::kw_inout) &&
4276- Tok.isNot (tok::kw_rethrows)) {
4282+ Tok.isNot (tok::kw_rethrows) &&
4283+ !hasModuleSelector) {
42774284
42784285 if (Tok.is (tok::code_complete)) {
42794286 if (CodeCompletionCallbacks) {
@@ -4294,7 +4301,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
42944301
42954302 // If the attribute follows the new representation, switch
42964303 // over to the alternate parsing path.
4297- std::optional<DeclAttrKind> DK =
4304+ std::optional<DeclAttrKind> DK = hasModuleSelector ? std:: nullopt :
42984305 DeclAttribute::getAttrKindFromString (Tok.getText ());
42994306 if (DK == DeclAttrKind::Rethrows) {
43004307 DK = DeclAttrKind::AtRethrows;
@@ -4306,7 +4313,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
43064313 auto checkInvalidAttrName =
43074314 [&](StringRef invalidName, StringRef correctName, DeclAttrKind kind,
43084315 std::optional<Diag<StringRef, StringRef>> diag = std::nullopt ) {
4309- if (!DK && Tok.getText () == invalidName) {
4316+ if (!DK && !hasModuleSelector && Tok.getText () == invalidName) {
43104317 DK = kind;
43114318
43124319 if (diag) {
@@ -4370,7 +4377,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
43704377 DeclAttrKind::Preconcurrency,
43714378 diag::attr_renamed_warning);
43724379
4373- if (!DK && Tok.getText () == " warn_unused_result" ) {
4380+ if (!DK && !hasModuleSelector && Tok.getText () == " warn_unused_result" ) {
43744381 // The behavior created by @warn_unused_result is now the default. Emit a
43754382 // Fix-It to remove.
43764383 SourceLoc attrLoc = consumeToken ();
@@ -4445,9 +4452,10 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
44454452 return parseNewDeclAttribute (Attributes, AtLoc, *DK, isFromClangAttribute);
44464453 }
44474454
4448- if (TypeAttribute::getAttrKindFromString (Tok.getText ()).has_value ())
4455+ if (!hasModuleSelector &&
4456+ TypeAttribute::getAttrKindFromString (Tok.getText ()).has_value ())
44494457 diagnose (Tok, diag::type_attribute_applied_to_decl);
4450- else if (Tok.isContextualKeyword (" unknown" )) {
4458+ else if (!hasModuleSelector && Tok.isContextualKeyword (" unknown" )) {
44514459 diagnose (Tok, diag::unknown_attr_name, " unknown" );
44524460 } else {
44534461 // Change the context to create a custom attribute syntax.
@@ -5780,6 +5788,8 @@ static void skipAttribute(Parser &P) {
57805788 // Parse the attribute name, which can be qualified, have
57815789 // generic arguments, and so on.
57825790 do {
5791+ P.parseModuleSelector ();
5792+
57835793 if (!(P.consumeIf (tok::identifier) || P.consumeIf (tok::kw_rethrows)) &&
57845794 !P.consumeIf (tok::code_complete))
57855795 return ;
@@ -10330,9 +10340,11 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1033010340 return makeParserCodeCompletionResult<OperatorDecl>();
1033110341 }
1033210342
10343+ // TODO: We could support module selectors for precedence groups if we
10344+ // implemented the lookup for it.
1033310345 groupName = parseDeclNameRef (groupLoc,
1033410346 diag::operator_decl_expected_precedencegroup,
10335- {} );
10347+ DeclNameFlag::ModuleSelectorUnsupported );
1033610348
1033710349 if (Context.TypeCheckerOpts .EnableOperatorDesignatedTypes ) {
1033810350 // Designated types have been removed; consume the list (mainly for source
@@ -10630,7 +10642,7 @@ Parser::parseDeclPrecedenceGroup(ParseDeclOptions flags,
1063010642 auto name = parseDeclNameRef (nameLoc,
1063110643 { diag::expected_precedencegroup_relation,
1063210644 attrName },
10633- {} );
10645+ DeclNameFlag::ModuleSelectorUnsupported );
1063410646 if (!name) {
1063510647 return abortBody ();
1063610648 }
0 commit comments