Skip to content

Commit 07e53c2

Browse files
authored
Merge pull request #42158 from slavapestov/se-0346-revisions
Revise SE-0346 implementation for core team decision
2 parents 338af18 + cf76fcf commit 07e53c2

File tree

19 files changed

+168
-211
lines changed

19 files changed

+168
-211
lines changed

include/swift/AST/Decl.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -506,11 +506,6 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
506506
IsOpaqueType : 1
507507
);
508508

509-
SWIFT_INLINE_BITFIELD_FULL(AssociatedTypeDecl, AbstractTypeParamDecl, 1,
510-
/// Whether this is a primary associated type.
511-
IsPrimary : 1
512-
);
513-
514509
SWIFT_INLINE_BITFIELD_EMPTY(GenericTypeDecl, TypeDecl);
515510

516511
SWIFT_INLINE_BITFIELD(TypeAliasDecl, GenericTypeDecl, 1+1,
@@ -3272,14 +3267,6 @@ class AssociatedTypeDecl : public AbstractTypeParamDecl {
32723267
LazyMemberLoader *definitionResolver,
32733268
uint64_t resolverData);
32743269

3275-
bool isPrimary() const {
3276-
return Bits.AssociatedTypeDecl.IsPrimary;
3277-
}
3278-
3279-
void setPrimary() {
3280-
Bits.AssociatedTypeDecl.IsPrimary = true;
3281-
}
3282-
32833270
/// Get the protocol in which this associated type is declared.
32843271
ProtocolDecl *getProtocol() const {
32853272
return cast<ProtocolDecl>(getDeclContext());
@@ -4363,6 +4350,8 @@ enum class KnownDerivableProtocolKind : uint8_t {
43634350
DistributedActorSystem,
43644351
};
43654352

4353+
using PrimaryAssociatedTypeName = std::pair<Identifier, SourceLoc>;
4354+
43664355
/// ProtocolDecl - A declaration of a protocol, for example:
43674356
///
43684357
/// protocol Drawable {
@@ -4379,6 +4368,7 @@ enum class KnownDerivableProtocolKind : uint8_t {
43794368
class ProtocolDecl final : public NominalTypeDecl {
43804369
SourceLoc ProtocolLoc;
43814370

4371+
ArrayRef<PrimaryAssociatedTypeName> PrimaryAssociatedTypeNames;
43824372
ArrayRef<ProtocolDecl *> InheritedProtocols;
43834373
ArrayRef<AssociatedTypeDecl *> AssociatedTypes;
43844374

@@ -4460,7 +4450,9 @@ class ProtocolDecl final : public NominalTypeDecl {
44604450

44614451
public:
44624452
ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc, SourceLoc NameLoc,
4463-
Identifier Name, ArrayRef<InheritedEntry> Inherited,
4453+
Identifier Name,
4454+
ArrayRef<PrimaryAssociatedTypeName> PrimaryAssociatedTypeNames,
4455+
ArrayRef<InheritedEntry> Inherited,
44644456
TrailingWhereClause *TrailingWhere);
44654457

44664458
using Decl::getASTContext;
@@ -4486,6 +4478,13 @@ class ProtocolDecl final : public NominalTypeDecl {
44864478
/// a protocol having nested types (ObjC protocols).
44874479
ArrayRef<AssociatedTypeDecl *> getAssociatedTypeMembers() const;
44884480

4481+
/// Returns the list of primary associated type names. These are the associated
4482+
/// types that is parametrized with same-type requirements in a
4483+
/// parametrized protocol type of the form SomeProtocol<Arg1, Arg2...>.
4484+
ArrayRef<PrimaryAssociatedTypeName> getPrimaryAssociatedTypeNames() const {
4485+
return PrimaryAssociatedTypeNames;
4486+
}
4487+
44894488
/// Returns the list of primary associated types. These are the associated
44904489
/// types that is parametrized with same-type requirements in a
44914490
/// parametrized protocol type of the form SomeProtocol<Arg1, Arg2...>.

include/swift/AST/DiagnosticsSema.def

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3770,14 +3770,19 @@ ERROR(not_a_generic_definition,none,
37703770
"cannot specialize a non-generic definition", ())
37713771
ERROR(not_a_generic_type,none,
37723772
"cannot specialize non-generic type %0", (Type))
3773+
ERROR(protocol_declares_unknown_primary_assoc_type,none,
3774+
"an associated type named %0 must be declared in the protocol %1 or a protocol it inherits",
3775+
(Identifier, Type))
3776+
ERROR(protocol_declares_duplicate_primary_assoc_type,none,
3777+
"duplicate primary associated type name %0", (Identifier))
37733778
ERROR(parameterized_protocol_not_supported,none,
3774-
"protocol type with generic arguments can only be used as a generic constraint", ())
3779+
"protocol type with type arguments can only be used as a generic constraint", ())
37753780
ERROR(protocol_does_not_have_primary_assoc_type,none,
37763781
"cannot specialize protocol type %0", (Type))
3777-
ERROR(parameterized_protocol_too_many_type_arguments,none,
3778-
"protocol type %0 can specialized with too many type parameters "
3779-
"(got %1, but expected at most %2)",
3780-
(Type, unsigned, unsigned))
3782+
ERROR(parameterized_protocol_type_argument_count_mismatch,none,
3783+
"protocol type %0 specialized with %select{too many|too few}3 type arguments "
3784+
"(got %1, but expected %2)",
3785+
(Type, unsigned, unsigned, unsigned))
37813786
ERROR(cannot_specialize_self,none,
37823787
"cannot specialize 'Self'", ())
37833788
NOTE(specialize_explicit_type_instead,none,

include/swift/Parse/Parser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,9 +1213,9 @@ class Parser {
12131213
parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD);
12141214

12151215
ParserStatus parsePrimaryAssociatedTypes(
1216-
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes);
1216+
SmallVectorImpl<PrimaryAssociatedTypeName> &AssocTypeNames);
12171217
ParserStatus parsePrimaryAssociatedTypeList(
1218-
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes);
1218+
SmallVectorImpl<PrimaryAssociatedTypeName> &AssocTypeNames);
12191219
ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
12201220
DeclAttributes &Attributes);
12211221

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,8 +1381,7 @@ struct RequirementPrintLocation {
13811381
/// function does: asking "where should this requirement be printed?" and then
13821382
/// callers check if the location is the ATD.
13831383
static RequirementPrintLocation
1384-
bestRequirementPrintLocation(ProtocolDecl *proto, const Requirement &req,
1385-
PrintOptions opts, bool inheritanceClause) {
1384+
bestRequirementPrintLocation(ProtocolDecl *proto, const Requirement &req) {
13861385
auto protoSelf = proto->getProtocolSelfType();
13871386
// Returns the most relevant decl within proto connected to outerType (or null
13881387
// if one doesn't exist), and whether the type is an "direct use",
@@ -1415,16 +1414,6 @@ bestRequirementPrintLocation(ProtocolDecl *proto, const Requirement &req,
14151414
// desired.
14161415
auto directUse = foundType && outerType->isEqual(foundType);
14171416

1418-
// Prefer to attach requirements to associated type declarations,
1419-
// unless the associated type is a primary associated type and
1420-
// we're printing primary associated types using the new syntax.
1421-
if (!directUse &&
1422-
relevantDecl &&
1423-
opts.PrintPrimaryAssociatedTypes &&
1424-
isa<AssociatedTypeDecl>(relevantDecl) &&
1425-
cast<AssociatedTypeDecl>(relevantDecl)->isPrimary())
1426-
relevantDecl = proto;
1427-
14281417
return std::make_pair(relevantDecl, directUse);
14291418
};
14301419

@@ -1495,8 +1484,7 @@ void PrintAST::printInheritedFromRequirementSignature(ProtocolDecl *proto,
14951484
return false;
14961485
}
14971486

1498-
auto location = bestRequirementPrintLocation(proto, req, Options,
1499-
/*inheritanceClause=*/true);
1487+
auto location = bestRequirementPrintLocation(proto, req);
15001488
return location.AttachedTo == attachingTo && !location.InWhereClause;
15011489
});
15021490
}
@@ -1511,8 +1499,7 @@ void PrintAST::printWhereClauseFromRequirementSignature(ProtocolDecl *proto,
15111499
proto->getRequirementSignature().getRequirements()),
15121500
flags,
15131501
[&](const Requirement &req) {
1514-
auto location = bestRequirementPrintLocation(proto, req, Options,
1515-
/*inheritanceClause=*/false);
1502+
auto location = bestRequirementPrintLocation(proto, req);
15161503
return location.AttachedTo == attachingTo && location.InWhereClause;
15171504
});
15181505
}
@@ -3557,14 +3544,6 @@ void PrintAST::printPrimaryAssociatedTypes(ProtocolDecl *decl) {
35573544
assocType);
35583545
Printer.printName(assocType->getName(),
35593546
PrintNameContext::GenericParameter);
3560-
3561-
printInheritedFromRequirementSignature(decl, assocType);
3562-
3563-
if (assocType->hasDefaultDefinitionType()) {
3564-
Printer << " = ";
3565-
assocType->getDefaultDefinitionType().print(Printer, Options);
3566-
}
3567-
35683547
Printer.printStructurePost(PrintStructureKind::GenericParameter,
35693548
assocType);
35703549
},
@@ -5092,14 +5071,6 @@ bool Decl::shouldPrintInContext(const PrintOptions &PO) const {
50925071
return PO.PrintIfConfig;
50935072
}
50945073

5095-
if (auto *ATD = dyn_cast<AssociatedTypeDecl>(this)) {
5096-
// If PO.PrintPrimaryAssociatedTypes is on, primary associated
5097-
// types are printed as part of the protocol declaration itself,
5098-
// so skip them here.
5099-
if (ATD->isPrimary() && PO.PrintPrimaryAssociatedTypes)
5100-
return false;
5101-
}
5102-
51035074
// Print everything else.
51045075
return true;
51055076
}

lib/AST/Decl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4557,9 +4557,7 @@ AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
45574557
TrailingWhereClause *trailingWhere)
45584558
: AbstractTypeParamDecl(DeclKind::AssociatedType, dc, name, nameLoc),
45594559
KeywordLoc(keywordLoc), DefaultDefinition(defaultDefinition),
4560-
TrailingWhere(trailingWhere) {
4561-
Bits.AssociatedTypeDecl.IsPrimary = 0;
4562-
}
4560+
TrailingWhere(trailingWhere) {}
45634561

45644562
AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
45654563
Identifier name, SourceLoc nameLoc,
@@ -5305,11 +5303,13 @@ bool EnumDecl::hasCircularRawValue() const {
53055303

53065304
ProtocolDecl::ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc,
53075305
SourceLoc NameLoc, Identifier Name,
5306+
ArrayRef<PrimaryAssociatedTypeName> PrimaryAssociatedTypeNames,
53085307
ArrayRef<InheritedEntry> Inherited,
53095308
TrailingWhereClause *TrailingWhere)
53105309
: NominalTypeDecl(DeclKind::Protocol, DC, Name, NameLoc, Inherited,
53115310
nullptr),
5312-
ProtocolLoc(ProtocolLoc) {
5311+
ProtocolLoc(ProtocolLoc),
5312+
PrimaryAssociatedTypeNames(PrimaryAssociatedTypeNames) {
53135313
Bits.ProtocolDecl.RequiresClassValid = false;
53145314
Bits.ProtocolDecl.RequiresClass = false;
53155315
Bits.ProtocolDecl.ExistentialConformsToSelfValid = false;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5677,7 +5677,8 @@ namespace {
56775677
auto result = Impl.createDeclWithClangNode<ProtocolDecl>(
56785678
decl, AccessLevel::Public, dc,
56795679
Impl.importSourceLoc(decl->getBeginLoc()),
5680-
Impl.importSourceLoc(decl->getLocation()), name, None,
5680+
Impl.importSourceLoc(decl->getLocation()), name,
5681+
ArrayRef<PrimaryAssociatedTypeName>(), None,
56815682
/*TrailingWhere=*/nullptr);
56825683

56835684
addObjCAttribute(result, Impl.importIdentifier(decl->getIdentifier()));

lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7977,13 +7977,13 @@ ParserResult<ClassDecl> Parser::parseDeclClass(ParseDeclOptions Flags,
79777977
}
79787978

79797979
ParserStatus Parser::parsePrimaryAssociatedTypes(
7980-
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes) {
7980+
SmallVectorImpl<PrimaryAssociatedTypeName> &AssocTypeNames) {
79817981
SyntaxParsingContext GPSContext(SyntaxContext,
79827982
SyntaxKind::PrimaryAssociatedTypeClause);
79837983

79847984
SourceLoc LAngleLoc = consumeStartingLess();
79857985

7986-
auto Result = parsePrimaryAssociatedTypeList(AssocTypes);
7986+
auto Result = parsePrimaryAssociatedTypeList(AssocTypeNames);
79877987

79887988
// Parse the closing '>'.
79897989
SourceLoc RAngleLoc;
@@ -8001,7 +8001,7 @@ ParserStatus Parser::parsePrimaryAssociatedTypes(
80018001
}
80028002

80038003
ParserStatus Parser::parsePrimaryAssociatedTypeList(
8004-
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes) {
8004+
SmallVectorImpl<PrimaryAssociatedTypeName> &AssocTypeNames) {
80058005
ParserStatus Result;
80068006
SyntaxParsingContext PATContext(SyntaxContext,
80078007
SyntaxKind::PrimaryAssociatedTypeList);
@@ -8011,16 +8011,6 @@ ParserStatus Parser::parsePrimaryAssociatedTypeList(
80118011
SyntaxParsingContext ATContext(SyntaxContext,
80128012
SyntaxKind::PrimaryAssociatedType);
80138013

8014-
// Note that we're parsing a declaration.
8015-
StructureMarkerRAII ParsingDecl(*this, Tok.getLoc(),
8016-
StructureMarkerKind::Declaration);
8017-
8018-
// Parse attributes.
8019-
DeclAttributes Attrs;
8020-
if (Tok.hasComment())
8021-
Attrs.add(new (Context) RawDocCommentAttr(Tok.getCommentRange()));
8022-
parseDeclAttributeList(Attrs);
8023-
80248014
// Parse the name of the parameter.
80258015
Identifier Name;
80268016
SourceLoc NameLoc;
@@ -8030,54 +8020,7 @@ ParserStatus Parser::parsePrimaryAssociatedTypeList(
80308020
break;
80318021
}
80328022

8033-
// Parse the ':' followed by a type.
8034-
SmallVector<InheritedEntry, 1> Inherited;
8035-
if (Tok.is(tok::colon)) {
8036-
(void)consumeToken();
8037-
ParserResult<TypeRepr> Ty;
8038-
8039-
if (Tok.isAny(tok::identifier, tok::code_complete, tok::kw_protocol,
8040-
tok::kw_Any)) {
8041-
Ty = parseType();
8042-
} else if (Tok.is(tok::kw_class)) {
8043-
diagnose(Tok, diag::unexpected_class_constraint);
8044-
diagnose(Tok, diag::suggest_anyobject)
8045-
.fixItReplace(Tok.getLoc(), "AnyObject");
8046-
consumeToken();
8047-
Result.setIsParseError();
8048-
} else {
8049-
diagnose(Tok, diag::expected_generics_type_restriction, Name);
8050-
Result.setIsParseError();
8051-
}
8052-
8053-
if (Ty.hasCodeCompletion())
8054-
return makeParserCodeCompletionStatus();
8055-
8056-
if (Ty.isNonNull())
8057-
Inherited.push_back({Ty.get()});
8058-
}
8059-
8060-
ParserResult<TypeRepr> UnderlyingTy;
8061-
if (Tok.is(tok::equal)) {
8062-
SyntaxParsingContext InitContext(SyntaxContext,
8063-
SyntaxKind::TypeInitializerClause);
8064-
consumeToken(tok::equal);
8065-
UnderlyingTy = parseType(diag::expected_type_in_associatedtype);
8066-
Result |= UnderlyingTy;
8067-
if (UnderlyingTy.isNull())
8068-
return Result;
8069-
}
8070-
8071-
auto *AssocType = new (Context)
8072-
AssociatedTypeDecl(CurDeclContext, NameLoc, Name, NameLoc,
8073-
UnderlyingTy.getPtrOrNull(),
8074-
/*trailingWhere=*/nullptr);
8075-
AssocType->getAttrs() = Attrs;
8076-
if (!Inherited.empty())
8077-
AssocType->setInherited(Context.AllocateCopy(Inherited));
8078-
AssocType->setPrimary();
8079-
8080-
AssocTypes.push_back(AssocType);
8023+
AssocTypeNames.emplace_back(Name, NameLoc);
80818024

80828025
// Parse the comma, if the list continues.
80838026
HasNextParam = consumeIf(tok::comma);
@@ -8097,13 +8040,7 @@ ParserStatus Parser::parsePrimaryAssociatedTypeList(
80978040
/// inheritance?
80988041
///
80998042
/// primary-associated-type-list:
8100-
/// '<' primary-associated-type+ '>'
8101-
///
8102-
/// primary-associated-type:
8103-
/// identifier inheritance? default-associated-type
8104-
///
8105-
/// default-associated-type:
8106-
/// '=' type
8043+
/// '<' identifier+ '>'
81078044
///
81088045
/// protocol-member:
81098046
/// decl-func
@@ -8124,11 +8061,11 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
81248061
if (Status.isErrorOrHasCompletion())
81258062
return Status;
81268063

8127-
SmallVector<AssociatedTypeDecl *, 2> PrimaryAssociatedTypes;
8064+
SmallVector<PrimaryAssociatedTypeName, 2> PrimaryAssociatedTypeNames;
81288065

81298066
if (Context.LangOpts.EnableParameterizedProtocolTypes) {
81308067
if (startsWithLess(Tok)) {
8131-
Status |= parsePrimaryAssociatedTypes(PrimaryAssociatedTypes);
8068+
Status |= parsePrimaryAssociatedTypes(PrimaryAssociatedTypeNames);
81328069
}
81338070
} else {
81348071
// Protocols don't support generic parameters, but people often want them and
@@ -8167,6 +8104,7 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
81678104

81688105
ProtocolDecl *Proto = new (Context)
81698106
ProtocolDecl(CurDeclContext, ProtocolLoc, NameLoc, ProtocolName,
8107+
Context.AllocateCopy(PrimaryAssociatedTypeNames),
81708108
Context.AllocateCopy(InheritedProtocols), TrailingWhere);
81718109
// No need to setLocalDiscriminator: protocols can't appear in local contexts.
81728110

@@ -8176,12 +8114,6 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
81768114

81778115
ContextChange CC(*this, Proto);
81788116

8179-
// Re-parent the primary associated type declarations into the protocol.
8180-
for (auto *AssocType : PrimaryAssociatedTypes) {
8181-
AssocType->setDeclContext(Proto);
8182-
Proto->addMember(AssocType);
8183-
}
8184-
81858117
// Parse the body.
81868118
{
81878119
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);

0 commit comments

Comments
 (0)