Skip to content

Commit d7f8f20

Browse files
committed
Sema: Generalize ProtocolDecl::getPrimaryAssociatedType() to ProtocolDecl::getPrimaryAssociatedTypes()
1 parent 7e5d6f4 commit d7f8f20

13 files changed

+94
-53
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4402,10 +4402,10 @@ class ProtocolDecl final : public NominalTypeDecl {
44024402
/// a protocol having nested types (ObjC protocols).
44034403
ArrayRef<AssociatedTypeDecl *> getAssociatedTypeMembers() const;
44044404

4405-
/// Returns the primary associated type, or nullptr if there isn't one. This is
4406-
/// the associated type that is parametrized with a same-type requirement in a
4407-
/// parametrized protocol type of the form SomeProtocol<SomeArgType>.
4408-
AssociatedTypeDecl *getPrimaryAssociatedType() const;
4405+
/// Returns the list of primary associated types. These are the associated
4406+
/// types that is parametrized with same-type requirements in a
4407+
/// parametrized protocol type of the form SomeProtocol<Arg1, Arg2...>.
4408+
ArrayRef<AssociatedTypeDecl *> getPrimaryAssociatedTypes() const;
44094409

44104410
/// Returns a protocol requirement with the given name, or nullptr if the
44114411
/// name has multiple overloads, or no overloads at all.

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,11 +3734,13 @@ ERROR(not_a_generic_definition,none,
37343734
ERROR(not_a_generic_type,none,
37353735
"cannot specialize non-generic type %0", (Type))
37363736
ERROR(parameterized_protocol_not_supported,none,
3737-
"protocol type with generic argument can only be used as a generic constraint", ())
3737+
"protocol type with generic arguments can only be used as a generic constraint", ())
37383738
ERROR(protocol_does_not_have_primary_assoc_type,none,
37393739
"cannot specialize protocol type %0", (Type))
3740-
ERROR(protocol_cannot_have_multiple_generic_arguments,none,
3741-
"protocol type %0 can only be specialized with exactly one argument", (Type))
3740+
ERROR(parameterized_protocol_too_many_type_arguments,none,
3741+
"protocol type %0 can specialized with too many type parameters "
3742+
"(got %1, but expected at most %2)",
3743+
(Type, unsigned, unsigned))
37423744
ERROR(cannot_specialize_self,none,
37433745
"cannot specialize 'Self'", ())
37443746
NOTE(specialize_explicit_type_instead,none,

include/swift/AST/TypeCheckRequests.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,10 @@ class ExistentialRequiresAnyRequest :
313313
void cacheResult(bool value) const;
314314
};
315315

316-
/// Find the primary associated type of the given protocol.
317-
class PrimaryAssociatedTypeRequest :
318-
public SimpleRequest<PrimaryAssociatedTypeRequest,
319-
AssociatedTypeDecl *(ProtocolDecl *),
316+
/// Find the list of primary associated types of the given protocol.
317+
class PrimaryAssociatedTypesRequest :
318+
public SimpleRequest<PrimaryAssociatedTypesRequest,
319+
ArrayRef<AssociatedTypeDecl *>(ProtocolDecl *),
320320
RequestFlags::Cached> {
321321
public:
322322
using SimpleRequest::SimpleRequest;
@@ -325,7 +325,7 @@ class PrimaryAssociatedTypeRequest :
325325
friend SimpleRequest;
326326

327327
// Evaluation.
328-
AssociatedTypeDecl *
328+
ArrayRef<AssociatedTypeDecl *>
329329
evaluate(Evaluator &evaluator, ProtocolDecl *decl) const;
330330

331331
public:

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ SWIFT_REQUEST(TypeChecker, PropertyWrapperTypeInfoRequest,
262262
NoLocationInfo)
263263
SWIFT_REQUEST(TypeChecker, ProtocolRequiresClassRequest, bool(ProtocolDecl *),
264264
SeparatelyCached, NoLocationInfo)
265-
SWIFT_REQUEST(TypeChecker, PrimaryAssociatedTypeRequest,
266-
AssociatedTypeDecl *(ProtocolDecl *),
265+
SWIFT_REQUEST(TypeChecker, PrimaryAssociatedTypesRequest,
266+
ArrayRef<AssociatedTypeDecl *>(ProtocolDecl *),
267267
Cached, NoLocationInfo)
268268
SWIFT_REQUEST(TypeChecker, RequirementRequest,
269269
Requirement(WhereClauseOwner, unsigned, TypeResolutionStage),

include/swift/AST/Types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5289,6 +5289,8 @@ class ParameterizedProtocolType final : public TypeBase,
52895289
Bits.ParameterizedProtocolType.ArgCount};
52905290
}
52915291

5292+
void getRequirements(Type baseType, SmallVectorImpl<Requirement> &reqs) const;
5293+
52925294
void Profile(llvm::FoldingSetNodeID &ID) {
52935295
Profile(ID, Base, getArgs());
52945296
}

lib/AST/Decl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5398,9 +5398,10 @@ bool ProtocolDecl::existentialRequiresAny() const {
53985398
ExistentialRequiresAnyRequest{const_cast<ProtocolDecl *>(this)}, true);
53995399
}
54005400

5401-
AssociatedTypeDecl *ProtocolDecl::getPrimaryAssociatedType() const {
5401+
ArrayRef<AssociatedTypeDecl *>
5402+
ProtocolDecl::getPrimaryAssociatedTypes() const {
54025403
return evaluateOrDefault(getASTContext().evaluator,
5403-
PrimaryAssociatedTypeRequest{const_cast<ProtocolDecl *>(this)},
5404+
PrimaryAssociatedTypesRequest{const_cast<ProtocolDecl *>(this)},
54045405
nullptr);
54055406
}
54065407

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4523,14 +4523,13 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
45234523
source)))
45244524
anyErrors = true;
45254525

4526-
auto *assocType = protoDecl->getPrimaryAssociatedType();
4527-
auto depType = DependentMemberType::get(
4528-
resolvedSubject.getDependentType(*this), assocType);
4529-
if (isErrorResult(addSameTypeRequirement(Type(depType),
4530-
paramProtoType->getArgs()[0],
4531-
source,
4532-
UnresolvedHandlingKind::GenerateConstraints)))
4533-
anyErrors = true;
4526+
SmallVector<Requirement, 2> reqs;
4527+
auto baseType = resolvedSubject.getDependentType(*this);
4528+
paramProtoType->getRequirements(baseType, reqs);
4529+
for (auto req : reqs) {
4530+
if (isErrorResult(addRequirement(req, source, inferForModule)))
4531+
anyErrors = true;
4532+
}
45344533

45354534
return anyErrors ? ConstraintResult::Conflicting
45364535
: ConstraintResult::Resolved;

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,16 +217,15 @@ static void desugarConformanceRequirement(Type subjectType, Type constraintType,
217217
}
218218

219219
if (auto *paramType = constraintType->getAs<ParameterizedProtocolType>()) {
220-
auto *protoDecl = paramType->getBaseType()->getDecl();
221-
222220
desugarConformanceRequirement(subjectType, paramType->getBaseType(),
223221
loc, result, errors);
224222

225-
auto *assocType = protoDecl->getPrimaryAssociatedType();
223+
SmallVector<Requirement, 2> reqs;
224+
paramType->getRequirements(subjectType, reqs);
225+
226+
for (const auto &req : reqs)
227+
desugarRequirement(req, result, errors);
226228

227-
auto memberType = lookupMemberType(subjectType, protoDecl, assocType);
228-
desugarSameTypeRequirement(memberType, paramType->getArgs()[0],
229-
loc, result, errors);
230229
return;
231230
}
232231

lib/AST/Type.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3894,6 +3894,24 @@ void ParameterizedProtocolType::Profile(llvm::FoldingSetNodeID &ID,
38943894
ID.AddPointer(arg.getPointer());
38953895
}
38963896

3897+
void ParameterizedProtocolType::getRequirements(
3898+
Type baseType, SmallVectorImpl<Requirement> &reqs) const {
3899+
auto *protoDecl = getBaseType()->getDecl();
3900+
3901+
auto assocTypes = protoDecl->getPrimaryAssociatedTypes();
3902+
auto argTypes = getArgs();
3903+
assert(argTypes.size() <= assocTypes.size());
3904+
3905+
for (unsigned i : indices(argTypes)) {
3906+
auto argType = argTypes[i];
3907+
auto *assocType = assocTypes[i];
3908+
auto subjectType = assocType->getDeclaredInterfaceType()
3909+
->castTo<DependentMemberType>()
3910+
->substBaseType(protoDecl->getParentModule(), baseType);
3911+
reqs.emplace_back(RequirementKind::SameType, subjectType, argType);
3912+
}
3913+
}
3914+
38973915
bool ProtocolType::requiresClass() {
38983916
return getDecl()->requiresClass();
38993917
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -698,15 +698,17 @@ ExistentialRequiresAnyRequest::evaluate(Evaluator &evaluator,
698698
return false;
699699
}
700700

701-
AssociatedTypeDecl *
702-
PrimaryAssociatedTypeRequest::evaluate(Evaluator &evaluator,
703-
ProtocolDecl *decl) const {
701+
ArrayRef<AssociatedTypeDecl *>
702+
PrimaryAssociatedTypesRequest::evaluate(Evaluator &evaluator,
703+
ProtocolDecl *decl) const {
704+
SmallVector<AssociatedTypeDecl *, 2> assocTypes;
705+
704706
for (auto *assocType : decl->getAssociatedTypeMembers()) {
705707
if (assocType->getAttrs().hasAttribute<PrimaryAssociatedTypeAttr>())
706-
return assocType;
708+
assocTypes.push_back(assocType);
707709
}
708710

709-
return nullptr;
711+
return decl->getASTContext().AllocateCopy(assocTypes);
710712
}
711713

712714
bool

0 commit comments

Comments
 (0)