@@ -682,7 +682,8 @@ bool Parser::parseSpecializeAttributeArguments(
682
682
DeclNameFlag::AllowZeroArgCompoundNames |
683
683
DeclNameFlag::AllowKeywordsUsingSpecialNames |
684
684
DeclNameFlag::AllowOperators |
685
- DeclNameFlag::AllowLowercaseAndUppercaseSelf);
685
+ DeclNameFlag::AllowLowercaseAndUppercaseSelf |
686
+ DeclNameFlag::ModuleSelectorUnsupported);
686
687
}
687
688
}
688
689
if (ParamLabel == " spiModule" ) {
@@ -1136,7 +1137,8 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
1136
1137
MemberNameLoc, diag::attr_implements_expected_member_name,
1137
1138
DeclNameFlag::AllowZeroArgCompoundNames |
1138
1139
DeclNameFlag::AllowOperators |
1139
- DeclNameFlag::AllowLowercaseAndUppercaseSelf);
1140
+ DeclNameFlag::AllowLowercaseAndUppercaseSelf |
1141
+ DeclNameFlag::ModuleSelectorUnsupported);
1140
1142
if (!MemberName) {
1141
1143
Status.setIsParseError ();
1142
1144
}
@@ -1159,7 +1161,7 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
1159
1161
return Status;
1160
1162
}
1161
1163
1162
- // FIXME(ModQual): Reject module qualification on MemberName.
1164
+ assert ( MemberName.getModuleSelector (). empty ());
1163
1165
return ParserResult<ImplementsAttr>(
1164
1166
ImplementsAttr::create (Context, AtLoc, SourceRange (Loc, rParenLoc),
1165
1167
ProtocolType.get (), MemberName.getFullName (),
@@ -2440,7 +2442,8 @@ Parser::parseMacroRoleAttribute(
2440
2442
(DeclNameFlag::AllowOperators | DeclNameFlag::AllowKeywords |
2441
2443
DeclNameFlag::AllowKeywordsUsingSpecialNames |
2442
2444
DeclNameFlag::AllowCompoundNames |
2443
- DeclNameFlag::AllowZeroArgCompoundNames));
2445
+ DeclNameFlag::AllowZeroArgCompoundNames |
2446
+ DeclNameFlag::ModuleSelectorUnsupported));
2444
2447
if (!name) {
2445
2448
status.setIsParseError ();
2446
2449
return status;
@@ -4245,11 +4248,15 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
4245
4248
.warnUntilSwiftVersion (6 );
4246
4249
}
4247
4250
4251
+ bool hasModuleSelector = Context.LangOpts .hasFeature (Feature::ModuleSelector)
4252
+ && peekToken ().is (tok::colon_colon);
4253
+
4248
4254
// If this not an identifier, the attribute is malformed.
4249
4255
if (Tok.isNot (tok::identifier) &&
4250
4256
Tok.isNot (tok::kw_in) &&
4251
4257
Tok.isNot (tok::kw_inout) &&
4252
- Tok.isNot (tok::kw_rethrows)) {
4258
+ Tok.isNot (tok::kw_rethrows) &&
4259
+ !hasModuleSelector) {
4253
4260
4254
4261
if (Tok.is (tok::code_complete)) {
4255
4262
if (CodeCompletionCallbacks) {
@@ -4270,7 +4277,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
4270
4277
4271
4278
// If the attribute follows the new representation, switch
4272
4279
// over to the alternate parsing path.
4273
- std::optional<DeclAttrKind> DK =
4280
+ std::optional<DeclAttrKind> DK = hasModuleSelector ? std::nullopt :
4274
4281
DeclAttribute::getAttrKindFromString (Tok.getText ());
4275
4282
if (DK == DeclAttrKind::Rethrows) {
4276
4283
DK = DeclAttrKind::AtRethrows;
@@ -4282,7 +4289,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
4282
4289
auto checkInvalidAttrName =
4283
4290
[&](StringRef invalidName, StringRef correctName, DeclAttrKind kind,
4284
4291
std::optional<Diag<StringRef, StringRef>> diag = std::nullopt) {
4285
- if (!DK && Tok.getText () == invalidName) {
4292
+ if (!DK && !hasModuleSelector && Tok.getText () == invalidName) {
4286
4293
DK = kind;
4287
4294
4288
4295
if (diag) {
@@ -4346,7 +4353,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
4346
4353
DeclAttrKind::Preconcurrency,
4347
4354
diag::attr_renamed_warning);
4348
4355
4349
- if (!DK && Tok.getText () == " warn_unused_result" ) {
4356
+ if (!DK && !hasModuleSelector && Tok.getText () == " warn_unused_result" ) {
4350
4357
// The behavior created by @warn_unused_result is now the default. Emit a
4351
4358
// Fix-It to remove.
4352
4359
SourceLoc attrLoc = consumeToken ();
@@ -4421,9 +4428,10 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
4421
4428
return parseNewDeclAttribute (Attributes, AtLoc, *DK, isFromClangAttribute);
4422
4429
}
4423
4430
4424
- if (TypeAttribute::getAttrKindFromString (Tok.getText ()).has_value ())
4431
+ if (!hasModuleSelector &&
4432
+ TypeAttribute::getAttrKindFromString (Tok.getText ()).has_value ())
4425
4433
diagnose (Tok, diag::type_attribute_applied_to_decl);
4426
- else if (Tok.isContextualKeyword (" unknown" )) {
4434
+ else if (!hasModuleSelector && Tok.isContextualKeyword (" unknown" )) {
4427
4435
diagnose (Tok, diag::unknown_attr_name, " unknown" );
4428
4436
} else {
4429
4437
// Change the context to create a custom attribute syntax.
@@ -5756,6 +5764,8 @@ static void skipAttribute(Parser &P) {
5756
5764
// Parse the attribute name, which can be qualified, have
5757
5765
// generic arguments, and so on.
5758
5766
do {
5767
+ P.parseModuleSelector ();
5768
+
5759
5769
if (!(P.consumeIf (tok::identifier) || P.consumeIf (tok::kw_rethrows)) &&
5760
5770
!P.consumeIf (tok::code_complete))
5761
5771
return ;
@@ -10300,9 +10310,11 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
10300
10310
return makeParserCodeCompletionResult<OperatorDecl>();
10301
10311
}
10302
10312
10313
+ // TODO: We could support module selectors for precedence groups if we
10314
+ // implemented the lookup for it.
10303
10315
groupName = parseDeclNameRef (groupLoc,
10304
10316
diag::operator_decl_expected_precedencegroup,
10305
- {} );
10317
+ DeclNameFlag::ModuleSelectorUnsupported );
10306
10318
10307
10319
if (Context.TypeCheckerOpts .EnableOperatorDesignatedTypes ) {
10308
10320
// Designated types have been removed; consume the list (mainly for source
@@ -10600,7 +10612,7 @@ Parser::parseDeclPrecedenceGroup(ParseDeclOptions flags,
10600
10612
auto name = parseDeclNameRef (nameLoc,
10601
10613
{ diag::expected_precedencegroup_relation,
10602
10614
attrName },
10603
- {} );
10615
+ DeclNameFlag::ModuleSelectorUnsupported );
10604
10616
if (!name) {
10605
10617
return abortBody ();
10606
10618
}
0 commit comments