Skip to content

Commit 7e5d6f4

Browse files
committed
AST: Rework ParameterizedProtocolTypes to store multiple argument types
For now, this is NFC since we still assume one argument elsewhere.
1 parent b0c2dbe commit 7e5d6f4

15 files changed

+113
-85
lines changed

include/swift/AST/ExistentialLayout.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ namespace swift {
2626
class ProtocolType;
2727
class ProtocolCompositionType;
2828

29-
struct PrimaryAssociatedTypeRequirement {
30-
AssociatedTypeDecl *AssocType;
31-
Type Argument;
32-
};
33-
3429
struct ExistentialLayout {
3530
enum Kind { Class, Error, Opaque };
3631

@@ -117,7 +112,7 @@ struct ExistentialLayout {
117112

118113
/// Zero or more primary associated type requirements from a
119114
/// ParameterizedProtocolType
120-
ArrayRef<PrimaryAssociatedTypeRequirement> sameTypeRequirements;
115+
ArrayRef<Type> sameTypeRequirements;
121116
};
122117

123118
}

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
344344
if (asImpl().visit(type1.getBaseType(), type2.getBaseType()))
345345
return true;
346346

347-
return asImpl().visit(type1.getArgumentType(),
348-
type2.getArgumentType());
347+
return visitComponentArray(type1, type2,
348+
type1->getArgs(), type2->getArgs());
349349
}
350350

351351
bool visitExistentialType(CanExistentialType type1,

include/swift/AST/TypeMatcher.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,19 @@ class TypeMatcher {
342342
return false;
343343
}
344344

345-
return this->visit(firstParametrizedProto.getArgumentType(),
346-
secondParametrizedProto->getArgumentType(),
347-
sugaredFirstType->castTo<ParameterizedProtocolType>()
348-
->getArgumentType());
345+
auto firstArgs = firstParametrizedProto->getArgs();
346+
auto secondArgs = secondParametrizedProto->getArgs();
347+
348+
if (firstArgs.size() == secondArgs.size()) {
349+
for (unsigned i : indices(firstArgs)) {
350+
return this->visit(CanType(firstArgs[i]),
351+
secondArgs[i],
352+
sugaredFirstType->castTo<ParameterizedProtocolType>()
353+
->getArgs()[i]);
354+
}
355+
356+
return true;
357+
}
349358
}
350359

351360
return mismatch(firstParametrizedProto.getPointer(), secondType,

include/swift/AST/Types.h

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,11 @@ class alignas(1 << TypeAlignInBits) TypeBase
413413
Count : 32
414414
);
415415

416+
SWIFT_INLINE_BITFIELD_FULL(ParameterizedProtocolType, TypeBase, 32,
417+
/// The number of type arguments.
418+
ArgCount : 32
419+
);
420+
416421
SWIFT_INLINE_BITFIELD_FULL(TupleType, TypeBase, 1+32,
417422
/// Whether an element of the tuple is inout, __shared or __owned.
418423
/// Values cannot have such tuple types in the language.
@@ -5243,15 +5248,16 @@ class ProtocolCompositionType final : public TypeBase,
52435248
BEGIN_CAN_TYPE_WRAPPER(ProtocolCompositionType, Type)
52445249
END_CAN_TYPE_WRAPPER(ProtocolCompositionType, Type)
52455250

5246-
/// ParameterizedProtocolType - A type that constrains the primary associated
5247-
/// type of a protocol to an argument type.
5251+
/// ParameterizedProtocolType - A type that constrains one or more primary
5252+
/// associated type of a protocol to a list of argument types.
52485253
///
52495254
/// Written like a bound generic type, eg Sequence<Int>.
52505255
///
52515256
/// For now, these are only supported in generic requirement-like contexts:
52525257
/// - Inheritance clauses of protocols, generic parameters, associated types
52535258
/// - Conformance requirements in where clauses
52545259
/// - Extensions
5260+
/// - Opaque result types
52555261
///
52565262
/// Assuming that the primary associated type of Sequence is Element, the
52575263
/// desugaring is that T : Sequence<Int> is equivalent to
@@ -5260,51 +5266,52 @@ END_CAN_TYPE_WRAPPER(ProtocolCompositionType, Type)
52605266
/// T : Sequence where T.Element == Int.
52615267
/// \endcode
52625268
class ParameterizedProtocolType final : public TypeBase,
5263-
public llvm::FoldingSetNode {
5269+
public llvm::FoldingSetNode,
5270+
private llvm::TrailingObjects<ParameterizedProtocolType, Type> {
52645271
friend struct ExistentialLayout;
5272+
friend TrailingObjects;
52655273

52665274
ProtocolType *Base;
5267-
AssociatedTypeDecl *AssocType;
52685275
Type Arg;
52695276

52705277
public:
52715278
/// Retrieve an instance of a protocol composition type with the
52725279
/// given set of members.
52735280
static Type get(const ASTContext &C, ProtocolType *base,
5274-
Type arg);
5281+
ArrayRef<Type> args);
52755282

52765283
ProtocolType *getBaseType() const {
52775284
return Base;
52785285
}
52795286

5280-
AssociatedTypeDecl *getAssocType() const {
5281-
return AssocType;
5282-
}
5283-
5284-
Type getArgumentType() const {
5285-
return Arg;
5287+
ArrayRef<Type> getArgs() const {
5288+
return {getTrailingObjects<Type>(),
5289+
Bits.ParameterizedProtocolType.ArgCount};
52865290
}
52875291

52885292
void Profile(llvm::FoldingSetNodeID &ID) {
5289-
Profile(ID, Base, Arg);
5293+
Profile(ID, Base, getArgs());
52905294
}
52915295
static void Profile(llvm::FoldingSetNodeID &ID,
52925296
ProtocolType *base,
5293-
Type arg);
5297+
ArrayRef<Type> args);
52945298

52955299
// Implement isa/cast/dyncast/etc.
52965300
static bool classof(const TypeBase *T) {
52975301
return T->getKind() == TypeKind::ParameterizedProtocol;
52985302
}
5299-
5303+
53005304
private:
53015305
ParameterizedProtocolType(const ASTContext *ctx,
5302-
ProtocolType *base, Type arg,
5306+
ProtocolType *base,
5307+
ArrayRef<Type> args,
53035308
RecursiveTypeProperties properties);
53045309
};
53055310
BEGIN_CAN_TYPE_WRAPPER(ParameterizedProtocolType, Type)
53065311
PROXY_CAN_TYPE_SIMPLE_GETTER(getBaseType)
5307-
PROXY_CAN_TYPE_SIMPLE_GETTER(getArgumentType)
5312+
CanTypeArrayRef getArgs() const {
5313+
return CanTypeArrayRef(getPointer()->getArgs());
5314+
}
53085315
END_CAN_TYPE_WRAPPER(ParameterizedProtocolType, Type)
53095316

53105317
/// An existential type, spelled with \c any .

lib/AST/ASTContext.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,25 +3360,31 @@ ProtocolCompositionType::build(const ASTContext &C, ArrayRef<Type> Members,
33603360

33613361
Type ParameterizedProtocolType::get(const ASTContext &C,
33623362
ProtocolType *baseTy,
3363-
Type argTy) {
3363+
ArrayRef<Type> args) {
3364+
assert(args.size() > 0);
3365+
33643366
bool isCanonical = baseTy->isCanonical();
33653367
RecursiveTypeProperties properties = baseTy->getRecursiveProperties();
3366-
properties |= argTy->getRecursiveProperties();
3367-
isCanonical &= argTy->isCanonical();
3368+
for (auto arg : args) {
3369+
properties |= arg->getRecursiveProperties();
3370+
isCanonical &= arg->isCanonical();
3371+
}
33683372

33693373
auto arena = getArena(properties);
33703374

33713375
void *InsertPos = nullptr;
33723376
llvm::FoldingSetNodeID ID;
3373-
ParameterizedProtocolType::Profile(ID, baseTy, argTy);
3377+
ParameterizedProtocolType::Profile(ID, baseTy, args);
33743378

33753379
if (auto paramTy
33763380
= C.getImpl().getArena(arena).ParameterizedProtocolTypes
33773381
.FindNodeOrInsertPos(ID, InsertPos))
33783382
return paramTy;
33793383

3380-
auto paramTy = new (C, arena) ParameterizedProtocolType(
3381-
isCanonical ? &C : nullptr, baseTy, argTy, properties);
3384+
auto size = totalSizeToAlloc<Type>(args.size());
3385+
auto mem = C.Allocate(size, alignof(ParameterizedProtocolType), arena);
3386+
auto paramTy = new (mem) ParameterizedProtocolType(
3387+
isCanonical ? &C : nullptr, baseTy, args, properties);
33823388
C.getImpl().getArena(arena).ParameterizedProtocolTypes.InsertNode(
33833389
paramTy, InsertPos);
33843390
return paramTy;

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3947,7 +3947,9 @@ namespace {
39473947
StringRef label) {
39483948
printCommon(label, "parameterized_protocol_type");
39493949
printRec("base", T->getBaseType());
3950-
printRec("arg", T->getArgumentType());
3950+
for (auto arg : T->getArgs()) {
3951+
printRec(arg);
3952+
}
39513953
PrintWithColorRAII(OS, ParenthesisColor) << ')';
39523954
}
39533955

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6105,7 +6105,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
61056105
void visitParameterizedProtocolType(ParameterizedProtocolType *T) {
61066106
visit(T->getBaseType());
61076107
Printer << "<";
6108-
visit(T->getArgumentType());
6108+
interleave(T->getArgs(), [&](Type Ty) { visit(Ty); },
6109+
[&] { Printer << ", "; });
61096110
Printer << ">";
61106111
}
61116112

lib/AST/GenericSignatureBuilder.cpp

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

4526-
auto *assocType = paramProtoType->getAssocType();
4526+
auto *assocType = protoDecl->getPrimaryAssociatedType();
45274527
auto depType = DependentMemberType::get(
45284528
resolvedSubject.getDependentType(*this), assocType);
45294529
if (isErrorResult(addSameTypeRequirement(Type(depType),
4530-
paramProtoType->getArgumentType(),
4530+
paramProtoType->getArgs()[0],
45314531
source,
45324532
UnresolvedHandlingKind::GenerateConstraints)))
45334533
anyErrors = true;

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static void desugarConformanceRequirement(Type subjectType, Type constraintType,
225225
auto *assocType = protoDecl->getPrimaryAssociatedType();
226226

227227
auto memberType = lookupMemberType(subjectType, protoDecl, assocType);
228-
desugarSameTypeRequirement(memberType, paramType->getArgumentType(),
228+
desugarSameTypeRequirement(memberType, paramType->getArgs()[0],
229229
loc, result, errors);
230230
return;
231231
}

lib/AST/Type.cpp

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,7 @@ ExistentialLayout::ExistentialLayout(ParameterizedProtocolType *type) {
299299
assert(type->isCanonical());
300300

301301
*this = ExistentialLayout(type->getBaseType());
302-
sameTypeRequirements = {
303-
reinterpret_cast<PrimaryAssociatedTypeRequirement *>(&type->AssocType),
304-
1
305-
};
302+
sameTypeRequirements = type->getArgs();
306303
}
307304

308305
ExistentialLayout TypeBase::getExistentialLayout() {
@@ -1555,9 +1552,11 @@ CanType TypeBase::computeCanonicalType() {
15551552
case TypeKind::ParameterizedProtocol: {
15561553
auto *PPT = cast<ParameterizedProtocolType>(this);
15571554
auto Base = cast<ProtocolType>(PPT->getBaseType()->getCanonicalType());
1558-
auto Arg = PPT->getArgumentType()->getCanonicalType();
1555+
SmallVector<Type, 1> CanArgs;
1556+
for (Type t : PPT->getArgs())
1557+
CanArgs.push_back(t->getCanonicalType());
15591558
auto &C = Base->getASTContext();
1560-
Result = ParameterizedProtocolType::get(C, Base, Arg).getPointer();
1559+
Result = ParameterizedProtocolType::get(C, Base, CanArgs).getPointer();
15611560
break;
15621561
}
15631562
case TypeKind::Existential: {
@@ -3877,20 +3876,22 @@ void ProtocolCompositionType::Profile(llvm::FoldingSetNodeID &ID,
38773876

38783877
ParameterizedProtocolType::ParameterizedProtocolType(
38793878
const ASTContext *ctx,
3880-
ProtocolType *base, Type arg,
3879+
ProtocolType *base, ArrayRef<Type> args,
38813880
RecursiveTypeProperties properties)
38823881
: TypeBase(TypeKind::ParameterizedProtocol, /*Context=*/ctx, properties),
3883-
Base(base), AssocType(base->getDecl()->getPrimaryAssociatedType()),
3884-
Arg(arg) {
3885-
assert(AssocType != nullptr &&
3886-
"Protocol doesn't have a primary associated type");
3882+
Base(base) {
3883+
assert(args.size() > 0);
3884+
Bits.ParameterizedProtocolType.ArgCount = args.size();
3885+
for (unsigned i : indices(args))
3886+
getTrailingObjects<Type>()[i] = args[i];
38873887
}
38883888

38893889
void ParameterizedProtocolType::Profile(llvm::FoldingSetNodeID &ID,
38903890
ProtocolType *baseTy,
3891-
Type argTy) {
3891+
ArrayRef<Type> args) {
38923892
ID.AddPointer(baseTy);
3893-
ID.AddPointer(argTy.getPointer());
3893+
for (auto arg : args)
3894+
ID.AddPointer(arg.getPointer());
38943895
}
38953896

38963897
bool ProtocolType::requiresClass() {
@@ -5649,25 +5650,15 @@ case TypeKind::Id:
56495650
SmallVector<Type, 4> substMembers;
56505651
auto members = pc->getMembers();
56515652
bool anyChanged = false;
5652-
unsigned index = 0;
56535653
for (auto member : members) {
56545654
auto substMember = member.transformWithPosition(pos, fn);
56555655
if (!substMember)
56565656
return Type();
5657-
5658-
if (anyChanged) {
5659-
substMembers.push_back(substMember);
5660-
++index;
5661-
continue;
5662-
}
5663-
5664-
if (substMember.getPointer() != member.getPointer()) {
5657+
5658+
substMembers.push_back(substMember);
5659+
5660+
if (substMember.getPointer() != member.getPointer())
56655661
anyChanged = true;
5666-
substMembers.append(members.begin(), members.begin() + index);
5667-
substMembers.push_back(substMember);
5668-
}
5669-
5670-
++index;
56715662
}
56725663

56735664
if (!anyChanged)
@@ -5681,7 +5672,6 @@ case TypeKind::Id:
56815672
case TypeKind::ParameterizedProtocol: {
56825673
auto *ppt = cast<ParameterizedProtocolType>(base);
56835674
Type base = ppt->getBaseType();
5684-
Type arg = ppt->getArgumentType();
56855675

56865676
bool anyChanged = false;
56875677

@@ -5692,20 +5682,25 @@ case TypeKind::Id:
56925682
if (substBase.getPointer() != base.getPointer())
56935683
anyChanged = true;
56945684

5695-
auto substArg = arg.transformWithPosition(TypePosition::Invariant, fn);
5696-
if (!substArg)
5697-
return Type();
5685+
SmallVector<Type, 2> substArgs;
5686+
for (auto arg : ppt->getArgs()) {
5687+
auto substArg = arg.transformWithPosition(TypePosition::Invariant, fn);
5688+
if (!substArg)
5689+
return Type();
56985690

5699-
if (substArg.getPointer() != arg.getPointer())
5700-
anyChanged = true;
5691+
substArgs.push_back(substArg);
5692+
5693+
if (substArg.getPointer() != arg.getPointer())
5694+
anyChanged = true;
5695+
}
57015696

57025697
if (!anyChanged)
57035698
return *this;
57045699

57055700
return ParameterizedProtocolType::get(
57065701
Ptr->getASTContext(),
57075702
substBase->castTo<ProtocolType>(),
5708-
substArg);
5703+
substArgs);
57095704
}
57105705
}
57115706

0 commit comments

Comments
 (0)