Skip to content

Commit e0d416c

Browse files
Ungate accepted parts of SE439
1 parent e1f5371 commit e0d416c

File tree

6 files changed

+515
-512
lines changed

6 files changed

+515
-512
lines changed

include/swift/Basic/Features.def

+1-1
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ EXPERIMENTAL_FEATURE(ReinitializeConsumeInMultiBlockDefer, false)
398398
EXPERIMENTAL_FEATURE(SE427NoInferenceOnExtension, false)
399399

400400
// Enable trailing comma for comma-separated lists.
401-
EXPERIMENTAL_FEATURE(TrailingComma, true)
401+
EXPERIMENTAL_FEATURE(TrailingComma, false)
402402

403403
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
404404
#undef EXPERIMENTAL_FEATURE

lib/Parse/ParseDecl.cpp

+167-169
Original file line numberDiff line numberDiff line change
@@ -2549,195 +2549,190 @@ Parser::parseMacroRoleAttribute(
25492549
bool sawNames = false;
25502550
SmallVector<MacroIntroducedDeclName, 2> names;
25512551
SmallVector<TypeExpr *, 2> conformances;
2552-
auto argumentsStatus = parseList(tok::r_paren, lParenLoc, rParenLoc,
2553-
/*AllowSepAfterLast=*/Context.LangOpts.hasFeature(Feature::TrailingComma),
2554-
diag::expected_rparen_expr_list,
2555-
[&] {
2556-
ParserStatus status;
2557-
2558-
if (consumeIf(tok::code_complete)) {
2559-
status.setHasCodeCompletionAndIsError();
2560-
if (!sawRole) {
2561-
sawRole = true;
2562-
if (this->CodeCompletionCallbacks) {
2563-
this->CodeCompletionCallbacks->completeDeclAttrParam(
2564-
getCustomSyntaxAttributeKind(isAttached), 0, /*HasLabel=*/false);
2565-
}
2566-
} else if (!sawNames) {
2567-
if (this->CodeCompletionCallbacks) {
2568-
this->CodeCompletionCallbacks->completeDeclAttrParam(
2569-
getCustomSyntaxAttributeKind(isAttached), 1, /*HasLabel=*/false);
2552+
auto argumentsStatus = parseList(
2553+
tok::r_paren, lParenLoc, rParenLoc,
2554+
/*AllowSepAfterLast=*/true, diag::expected_rparen_expr_list, [&] {
2555+
ParserStatus status;
2556+
2557+
if (consumeIf(tok::code_complete)) {
2558+
status.setHasCodeCompletionAndIsError();
2559+
if (!sawRole) {
2560+
sawRole = true;
2561+
if (this->CodeCompletionCallbacks) {
2562+
this->CodeCompletionCallbacks->completeDeclAttrParam(
2563+
getCustomSyntaxAttributeKind(isAttached), 0,
2564+
/*HasLabel=*/false);
2565+
}
2566+
} else if (!sawNames) {
2567+
if (this->CodeCompletionCallbacks) {
2568+
this->CodeCompletionCallbacks->completeDeclAttrParam(
2569+
getCustomSyntaxAttributeKind(isAttached), 1,
2570+
/*HasLabel=*/false);
2571+
}
2572+
}
25702573
}
2571-
}
2572-
}
2573-
2574-
// Parse the argment label, if there is one.
2575-
Identifier fieldName;
2576-
SourceLoc fieldNameLoc;
2577-
parseOptionalArgumentLabel(fieldName, fieldNameLoc);
25782574

2579-
// If there is a field name, it better be 'names'.
2580-
if (!(fieldName.empty() || fieldName.is("names") ||
2581-
fieldName.is("conformances"))) {
2582-
diagnose(
2583-
fieldNameLoc, diag::macro_attribute_unknown_label, isAttached,
2584-
fieldName);
2585-
status.setIsParseError();
2586-
return status;
2587-
}
2575+
// Parse the argment label, if there is one.
2576+
Identifier fieldName;
2577+
SourceLoc fieldNameLoc;
2578+
parseOptionalArgumentLabel(fieldName, fieldNameLoc);
2579+
2580+
// If there is a field name, it better be 'names'.
2581+
if (!(fieldName.empty() || fieldName.is("names") ||
2582+
fieldName.is("conformances"))) {
2583+
diagnose(fieldNameLoc, diag::macro_attribute_unknown_label,
2584+
isAttached, fieldName);
2585+
status.setIsParseError();
2586+
return status;
2587+
}
25882588

2589-
// If there is no field name and we haven't seen either names or the role,
2590-
// this is the role.
2591-
if (fieldName.empty() && !sawConformances && !sawNames && !sawRole) {
2592-
// Whether we saw anything we tried to treat as a role.
2593-
sawRole = true;
2594-
2595-
auto diagKind = isAttached
2596-
? diag::macro_role_attr_expected_attached_kind
2597-
: diag::macro_role_attr_expected_freestanding_kind;
2598-
Identifier roleName;
2599-
SourceLoc roleNameLoc;
2600-
if (Tok.is(tok::kw_extension)) {
2601-
roleNameLoc = consumeToken();
2602-
role = MacroRole::Extension;
2603-
} else if (parseIdentifier(roleName, roleNameLoc, diagKind,
2604-
/*diagnoseDollarPrefix=*/true)) {
2605-
status.setIsParseError();
2606-
return status;
2607-
}
2589+
// If there is no field name and we haven't seen either names or the
2590+
// role, this is the role.
2591+
if (fieldName.empty() && !sawConformances && !sawNames && !sawRole) {
2592+
// Whether we saw anything we tried to treat as a role.
2593+
sawRole = true;
2594+
2595+
auto diagKind =
2596+
isAttached ? diag::macro_role_attr_expected_attached_kind
2597+
: diag::macro_role_attr_expected_freestanding_kind;
2598+
Identifier roleName;
2599+
SourceLoc roleNameLoc;
2600+
if (Tok.is(tok::kw_extension)) {
2601+
roleNameLoc = consumeToken();
2602+
role = MacroRole::Extension;
2603+
} else if (parseIdentifier(roleName, roleNameLoc, diagKind,
2604+
/*diagnoseDollarPrefix=*/true)) {
2605+
status.setIsParseError();
2606+
return status;
2607+
}
26082608

2609-
if (!role)
2610-
role = getMacroRole(roleName.str());
2609+
if (!role)
2610+
role = getMacroRole(roleName.str());
26112611

2612-
if (!role) {
2613-
diagnose(roleNameLoc, diag::macro_role_attr_expected_kind, isAttached);
2614-
status.setIsParseError();
2615-
return status;
2616-
}
2617-
if (!isMacroSupported(*role, Context)) {
2618-
diagnose(roleNameLoc, diag::macro_experimental, roleName.str(), "");
2619-
status.setIsParseError();
2620-
return status;
2621-
}
2612+
if (!role) {
2613+
diagnose(roleNameLoc, diag::macro_role_attr_expected_kind,
2614+
isAttached);
2615+
status.setIsParseError();
2616+
return status;
2617+
}
2618+
if (!isMacroSupported(*role, Context)) {
2619+
diagnose(roleNameLoc, diag::macro_experimental, roleName.str(), "");
2620+
status.setIsParseError();
2621+
return status;
2622+
}
26222623

2623-
// Check that the role makes sense.
2624-
if (isAttached == !isAttachedMacro(*role)) {
2625-
diagnose(
2626-
roleNameLoc, diag::macro_role_syntax_mismatch, isAttached, roleName
2627-
);
2624+
// Check that the role makes sense.
2625+
if (isAttached == !isAttachedMacro(*role)) {
2626+
diagnose(roleNameLoc, diag::macro_role_syntax_mismatch, isAttached,
2627+
roleName);
26282628

2629-
status.setIsParseError();
2630-
return status;
2631-
}
2629+
status.setIsParseError();
2630+
return status;
2631+
}
26322632

2633-
return status;
2634-
}
2633+
return status;
2634+
}
26352635

2636-
if (fieldName.is("conformances") ||
2637-
(fieldName.empty() && sawConformances && !sawNames)) {
2638-
if (fieldName.is("conformances") && sawConformances) {
2639-
diagnose(fieldNameLoc.isValid() ? fieldNameLoc : Tok.getLoc(),
2640-
diag::macro_attribute_duplicate_label,
2641-
isAttached,
2642-
"conformances");
2643-
}
2636+
if (fieldName.is("conformances") ||
2637+
(fieldName.empty() && sawConformances && !sawNames)) {
2638+
if (fieldName.is("conformances") && sawConformances) {
2639+
diagnose(fieldNameLoc.isValid() ? fieldNameLoc : Tok.getLoc(),
2640+
diag::macro_attribute_duplicate_label, isAttached,
2641+
"conformances");
2642+
}
26442643

2645-
sawConformances = true;
2644+
sawConformances = true;
26462645

2647-
// Parse the introduced conformances
2648-
auto type = parseType();
2649-
auto *typeExpr = new (Context) TypeExpr(type.get());
2650-
conformances.push_back(typeExpr);
2646+
// Parse the introduced conformances
2647+
auto type = parseType();
2648+
auto *typeExpr = new (Context) TypeExpr(type.get());
2649+
conformances.push_back(typeExpr);
26512650

2652-
return status;
2653-
}
2651+
return status;
2652+
}
26542653

2655-
// If the field name is empty and we haved seen "names", or the field name
2656-
// is "names" but we've already seen the argument label, complain.
2657-
if (fieldName.empty() != sawNames) {
2658-
diagnose(fieldNameLoc.isValid() ? fieldNameLoc : Tok.getLoc(),
2659-
sawNames ? diag::macro_attribute_duplicate_label
2660-
: diag::macro_attribute_missing_label,
2661-
isAttached,
2662-
"names");
2663-
}
2664-
sawNames = true;
2665-
2666-
// Parse the introduced name kind.
2667-
Identifier introducedNameKind;
2668-
SourceLoc introducedNameKindLoc;
2669-
if (consumeIf(tok::code_complete)) {
2670-
status.setHasCodeCompletionAndIsError();
2671-
if (this->CodeCompletionCallbacks) {
2672-
this->CodeCompletionCallbacks->completeDeclAttrParam(
2673-
getCustomSyntaxAttributeKind(isAttached), 1, /*HasLabel=*/true);
2674-
}
2675-
} else if (parseIdentifier(introducedNameKind, introducedNameKindLoc,
2676-
diag::macro_attribute_unknown_argument_form,
2677-
/*diagnoseDollarPrefix=*/true)) {
2678-
status.setIsParseError();
2679-
return status;
2680-
}
2654+
// If the field name is empty and we haved seen "names", or the field
2655+
// name is "names" but we've already seen the argument label, complain.
2656+
if (fieldName.empty() != sawNames) {
2657+
diagnose(fieldNameLoc.isValid() ? fieldNameLoc : Tok.getLoc(),
2658+
sawNames ? diag::macro_attribute_duplicate_label
2659+
: diag::macro_attribute_missing_label,
2660+
isAttached, "names");
2661+
}
2662+
sawNames = true;
2663+
2664+
// Parse the introduced name kind.
2665+
Identifier introducedNameKind;
2666+
SourceLoc introducedNameKindLoc;
2667+
if (consumeIf(tok::code_complete)) {
2668+
status.setHasCodeCompletionAndIsError();
2669+
if (this->CodeCompletionCallbacks) {
2670+
this->CodeCompletionCallbacks->completeDeclAttrParam(
2671+
getCustomSyntaxAttributeKind(isAttached), 1, /*HasLabel=*/true);
2672+
}
2673+
} else if (parseIdentifier(introducedNameKind, introducedNameKindLoc,
2674+
diag::macro_attribute_unknown_argument_form,
2675+
/*diagnoseDollarPrefix=*/true)) {
2676+
status.setIsParseError();
2677+
return status;
2678+
}
26812679

2682-
auto introducedKind = getMacroIntroducedDeclNameKind(introducedNameKind);
2683-
if (!introducedKind) {
2684-
diagnose(
2685-
introducedNameKindLoc, diag::macro_attribute_unknown_name_kind,
2686-
introducedNameKind
2687-
);
2688-
status.setIsParseError();
2689-
return status;
2690-
}
2680+
auto introducedKind =
2681+
getMacroIntroducedDeclNameKind(introducedNameKind);
2682+
if (!introducedKind) {
2683+
diagnose(introducedNameKindLoc,
2684+
diag::macro_attribute_unknown_name_kind, introducedNameKind);
2685+
status.setIsParseError();
2686+
return status;
2687+
}
26912688

2692-
// If we don't need an argument, we're done.
2693-
if (!macroIntroducedNameRequiresArgument(*introducedKind)) {
2694-
// If there is an argument, complain about it.
2695-
if (Tok.is(tok::l_paren)) {
2696-
diagnose(
2697-
Tok, diag::macro_attribute_introduced_name_requires_no_argument,
2698-
introducedNameKind);
2699-
skipSingle();
2700-
}
2689+
// If we don't need an argument, we're done.
2690+
if (!macroIntroducedNameRequiresArgument(*introducedKind)) {
2691+
// If there is an argument, complain about it.
2692+
if (Tok.is(tok::l_paren)) {
2693+
diagnose(Tok,
2694+
diag::macro_attribute_introduced_name_requires_no_argument,
2695+
introducedNameKind);
2696+
skipSingle();
2697+
}
27012698

2702-
names.push_back(MacroIntroducedDeclName(*introducedKind));
2703-
return status;
2704-
}
2699+
names.push_back(MacroIntroducedDeclName(*introducedKind));
2700+
return status;
2701+
}
27052702

2706-
if (!Tok.is(tok::l_paren)) {
2707-
diagnose(
2708-
Tok, diag::macro_attribute_introduced_name_requires_argument,
2709-
introducedNameKind);
2710-
status.setIsParseError();
2711-
return status;
2712-
}
2703+
if (!Tok.is(tok::l_paren)) {
2704+
diagnose(Tok, diag::macro_attribute_introduced_name_requires_argument,
2705+
introducedNameKind);
2706+
status.setIsParseError();
2707+
return status;
2708+
}
27132709

2714-
// Parse the name.
2715-
(void)consumeToken(tok::l_paren);
2716-
DeclNameLoc nameLoc;
2717-
DeclNameRef name = parseDeclNameRef(
2718-
nameLoc, diag::macro_attribute_unknown_argument_form,
2719-
(DeclNameFlag::AllowOperators |
2720-
DeclNameFlag::AllowKeywords |
2721-
DeclNameFlag::AllowKeywordsUsingSpecialNames |
2722-
DeclNameFlag::AllowCompoundNames |
2723-
DeclNameFlag::AllowZeroArgCompoundNames));
2724-
if (!name) {
2725-
status.setIsParseError();
2726-
return status;
2727-
}
2710+
// Parse the name.
2711+
(void)consumeToken(tok::l_paren);
2712+
DeclNameLoc nameLoc;
2713+
DeclNameRef name = parseDeclNameRef(
2714+
nameLoc, diag::macro_attribute_unknown_argument_form,
2715+
(DeclNameFlag::AllowOperators | DeclNameFlag::AllowKeywords |
2716+
DeclNameFlag::AllowKeywordsUsingSpecialNames |
2717+
DeclNameFlag::AllowCompoundNames |
2718+
DeclNameFlag::AllowZeroArgCompoundNames));
2719+
if (!name) {
2720+
status.setIsParseError();
2721+
return status;
2722+
}
27282723

2729-
SourceLoc rParenLoc;
2730-
if (!consumeIf(tok::r_paren, rParenLoc)) {
2731-
diagnose(Tok, diag::attr_expected_rparen, attrName, false);
2732-
rParenLoc = Tok.getLoc();
2733-
}
2724+
SourceLoc rParenLoc;
2725+
if (!consumeIf(tok::r_paren, rParenLoc)) {
2726+
diagnose(Tok, diag::attr_expected_rparen, attrName, false);
2727+
rParenLoc = Tok.getLoc();
2728+
}
27342729

2735-
// Add the name we introduced.
2736-
names.push_back(
2737-
MacroIntroducedDeclName(*introducedKind, name.getFullName()));
2730+
// Add the name we introduced.
2731+
names.push_back(
2732+
MacroIntroducedDeclName(*introducedKind, name.getFullName()));
27382733

2739-
return status;
2740-
});
2734+
return status;
2735+
});
27412736

27422737
if (argumentsStatus.isErrorOrHasCompletion())
27432738
return argumentsStatus;
@@ -6804,10 +6799,13 @@ ParserStatus Parser::parseInheritance(
68046799
ParserStatus Status;
68056800
SourceLoc prevComma;
68066801
bool HasNextType;
6802+
bool IsEndOfList;
68076803
do {
68086804
SWIFT_DEFER {
68096805
// Check for a ',', which indicates that there are more protocols coming.
68106806
HasNextType = consumeIf(tok::comma, prevComma);
6807+
IsEndOfList = (Context.LangOpts.hasFeature(Feature::TrailingComma) &&
6808+
(Tok.is(tok::l_brace) || Tok.is(tok::kw_where)));
68116809
};
68126810
// Parse the 'class' keyword for a class requirement.
68136811
if (Tok.is(tok::kw_class)) {
@@ -6859,7 +6857,7 @@ ParserStatus Parser::parseInheritance(
68596857
// Record the type if its a single type.
68606858
if (ParsedTypeResult.isNonNull())
68616859
Inherited.push_back(InheritedEntry(ParsedTypeResult.get()));
6862-
} while (HasNextType);
6860+
} while (HasNextType && !IsEndOfList);
68636861

68646862
return Status;
68656863
}

0 commit comments

Comments
 (0)