Skip to content

Commit acab50b

Browse files
committed
AST: Update callers of ProtocolCompositionType::get() to handle inverses
And remove the old overload.
1 parent 9bf51a9 commit acab50b

File tree

8 files changed

+58
-41
lines changed

8 files changed

+58
-41
lines changed

include/swift/AST/Types.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5943,24 +5943,21 @@ class ProtocolCompositionType final : public TypeBase,
59435943

59445944
public:
59455945
/// Retrieve an instance of a protocol composition type with the
5946-
/// given set of members. A "hidden member" is an implicit constraint that
5947-
/// is present for all protocol compositions.
5948-
///
5949-
/// \param Members the regular members of this composition.
5950-
/// \param Inverses the set of inverses that are a member of the composition,
5951-
/// i.e., if \c IP is in this set, then \c ~IP is a member of
5952-
/// this composition.
5953-
/// \param HasExplicitAnyObject indicates whether this composition should be
5954-
/// treated as if \c AnyObject was a member.
5946+
/// given set of members.
5947+
///
5948+
/// This presents a syntactic view of the world, where an empty composition
5949+
/// has implicit Copyable and Escapable members, unless they are supressed
5950+
/// with the Inverses field.
5951+
///
5952+
/// The list of members consists of zero or more ProtocolType,
5953+
/// ProtocolCompositionType, ParameterizedProtocolType, together with at
5954+
/// most one ClassType or BoundGenericClassType.
5955+
///
5956+
/// HasExplicitAnyObject is the 'AnyObject' member.
59555957
static Type get(const ASTContext &C, ArrayRef<Type> Members,
59565958
InvertibleProtocolSet Inverses,
59575959
bool HasExplicitAnyObject);
59585960

5959-
/// Retrieve an instance of a protocol composition type with the
5960-
/// given set of members. Assumes no inverses are present in \c Members.
5961-
static Type get(const ASTContext &C, ArrayRef<Type> Members,
5962-
bool HasExplicitAnyObject);
5963-
59645961
/// Constructs a protocol composition corresponding to the `Any` type.
59655962
static Type theAnyType(const ASTContext &C);
59665963

lib/AST/ASTContext.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3837,6 +3837,15 @@ ProtocolCompositionType::build(const ASTContext &C, ArrayRef<Type> Members,
38373837
bool HasExplicitAnyObject) {
38383838
assert(Members.size() != 1 || HasExplicitAnyObject || !Inverses.empty());
38393839

3840+
#ifndef NDEBUG
3841+
for (auto member : Members) {
3842+
if (auto *proto = member->getAs<ProtocolType>()) {
3843+
assert(!proto->getDecl()->getInvertibleProtocolKind() &&
3844+
"Should have been folded away");
3845+
}
3846+
}
3847+
#endif
3848+
38403849
// Check to see if we've already seen this protocol composition before.
38413850
void *InsertPos = nullptr;
38423851
llvm::FoldingSetNodeID ID;

lib/AST/ASTDemangler.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,10 @@ Type ASTBuilder::createProtocolCompositionType(
673673
if (superclass && superclass->getClassOrBoundGenericClass())
674674
members.push_back(superclass);
675675

676-
Type composition = ProtocolCompositionType::get(Ctx, members, isClassBound);
676+
// FIXME: move-only generics
677+
InvertibleProtocolSet inverses;
678+
Type composition = ProtocolCompositionType::get(Ctx, members, inverses,
679+
isClassBound);
677680
if (forRequirement)
678681
return composition;
679682

lib/AST/ExistentialGeneralization.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class Generalizer : public CanTypeVisitor<Generalizer, Type> {
107107
newMembers.push_back(generalizeStructure(origMember));
108108
}
109109
return ProtocolCompositionType::get(ctx, newMembers,
110+
origType->getInverses(),
110111
origType->hasExplicitAnyObject());
111112
}
112113

lib/AST/Type.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,7 @@ Type TypeBase::stripConcurrency(bool recurse, bool dropGlobalActor) {
11411141
if (!newMembers.empty()) {
11421142
return ProtocolCompositionType::get(
11431143
getASTContext(), newMembers,
1144+
protocolCompositionType->getInverses(),
11441145
protocolCompositionType->hasExplicitAnyObject());
11451146
}
11461147

@@ -1606,18 +1607,20 @@ static void addProtocols(Type T,
16061607
SmallVectorImpl<ProtocolDecl *> &Protocols,
16071608
ParameterizedProtocolMap &Parameterized,
16081609
Type &Superclass,
1610+
InvertibleProtocolSet &Inverses,
16091611
bool &HasExplicitAnyObject) {
16101612
if (auto Proto = T->getAs<ProtocolType>()) {
16111613
Protocols.push_back(Proto->getDecl());
16121614
return;
16131615
}
16141616

16151617
if (auto PC = T->getAs<ProtocolCompositionType>()) {
1616-
if (PC->hasExplicitAnyObject())
1617-
HasExplicitAnyObject = true;
1618-
for (auto P : PC->getMembers())
1619-
addProtocols(P, Protocols, Parameterized, Superclass,
1618+
Inverses.insertAll(PC->getInverses());
1619+
HasExplicitAnyObject |= PC->hasExplicitAnyObject();
1620+
for (auto P : PC->getMembers()) {
1621+
addProtocols(P, Protocols, Parameterized, Superclass, Inverses,
16201622
HasExplicitAnyObject);
1623+
}
16211624
return;
16221625
}
16231626

@@ -1918,6 +1921,7 @@ CanType TypeBase::computeCanonicalType() {
19181921
assert(!CanProtos.empty() && "Non-canonical empty composition?");
19191922
const ASTContext &C = CanProtos[0]->getASTContext();
19201923
Type Composition = ProtocolCompositionType::get(C, CanProtos,
1924+
PCT->getInverses(),
19211925
PCT->hasExplicitAnyObject());
19221926
Result = Composition.getPointer();
19231927
break;
@@ -4009,27 +4013,22 @@ bool ProtocolCompositionType::requiresClass() {
40094013

40104014
/// Constructs a protocol composition corresponding to the `Any` type.
40114015
Type ProtocolCompositionType::theAnyType(const ASTContext &C) {
4012-
return ProtocolCompositionType::get(C, {}, /*HasExplicitAnyObject=*/false);
4016+
return ProtocolCompositionType::get(C, {}, /*Inverses=*/{},
4017+
/*HasExplicitAnyObject=*/false);
40134018
}
40144019

40154020
/// Constructs a protocol composition containing the `AnyObject` constraint.
40164021
Type ProtocolCompositionType::theAnyObjectType(const ASTContext &C) {
4017-
return ProtocolCompositionType::get(C, {}, /*HasExplicitAnyObject=*/true);
4022+
return ProtocolCompositionType::get(C, {}, /*Inverses=*/{},
4023+
/*HasExplicitAnyObject=*/true);
40184024
}
40194025

40204026
Type ProtocolCompositionType::getInverseOf(const ASTContext &C,
40214027
InvertibleProtocolKind IP) {
4022-
return ProtocolCompositionType::get(C, {}, {IP},
4028+
return ProtocolCompositionType::get(C, {}, /*Inverses=*/{IP},
40234029
/*HasExplicitAnyObject=*/false);
40244030
}
40254031

4026-
Type ProtocolCompositionType::get(const ASTContext &C, ArrayRef<Type> Members,
4027-
bool HasExplicitAnyObject) {
4028-
return ProtocolCompositionType::get(C, Members,
4029-
/*Inverses=*/{},
4030-
HasExplicitAnyObject);
4031-
}
4032-
40334032
Type ProtocolCompositionType::get(const ASTContext &C,
40344033
ArrayRef<Type> Members,
40354034
InvertibleProtocolSet Inverses,
@@ -4055,29 +4054,29 @@ Type ProtocolCompositionType::get(const ASTContext &C,
40554054
if (!t->isCanonical())
40564055
return build(C, Members, Inverses, HasExplicitAnyObject);
40574056
}
4058-
4057+
40594058
Type Superclass;
40604059
SmallVector<ProtocolDecl *, 4> Protocols;
40614060
ParameterizedProtocolMap Parameterized;
40624061
for (Type t : Members) {
4063-
addProtocols(t, Protocols, Parameterized, Superclass, HasExplicitAnyObject);
4062+
addProtocols(t, Protocols, Parameterized, Superclass,
4063+
Inverses, HasExplicitAnyObject);
40644064
}
40654065

4066+
// Form the set of canonical component types.
4067+
SmallVector<Type, 4> CanTypes;
4068+
40664069
// The presence of a superclass constraint makes AnyObject redundant.
4067-
if (Superclass)
4070+
if (Superclass) {
40684071
HasExplicitAnyObject = false;
4072+
CanTypes.push_back(Superclass->getCanonicalType());
4073+
}
40694074

40704075
// If there are any parameterized protocols, the canonicalization
40714076
// algorithm gets more complex.
4072-
4073-
// Form the set of canonical component types.
4074-
SmallVector<Type, 4> CanTypes;
4075-
if (Superclass)
4076-
CanTypes.push_back(Superclass->getCanonicalType());
4077-
40784077
canonicalizeProtocols(Protocols, &Parameterized);
40794078

4080-
for (auto proto: Protocols) {
4079+
for (auto proto : Protocols) {
40814080
// If we have a parameterized type for this protocol, use the
40824081
// canonical type of that. Sema should prevent us from building
40834082
// compositions with the same protocol and conflicting constraints.
@@ -5346,6 +5345,7 @@ case TypeKind::Id:
53465345

53475346
return ProtocolCompositionType::get(Ptr->getASTContext(),
53485347
substMembers,
5348+
pc->getInverses(),
53495349
pc->hasExplicitAnyObject());
53505350
}
53515351

lib/AST/TypeJoinMeet.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,8 @@ CanType TypeJoin::computeProtocolCompositionJoin(ArrayRef<Type> firstMembers,
404404
return TheAnyType;
405405

406406
auto &ctx = result[0]->getASTContext();
407-
return ProtocolCompositionType::get(ctx, result, false)->getCanonicalType();
407+
return ProtocolCompositionType::get(ctx, result, /*inverses=*/{},
408+
false)->getCanonicalType();
408409
}
409410

410411
CanType TypeJoin::visitProtocolCompositionType(CanType second) {
@@ -431,8 +432,12 @@ CanType TypeJoin::visitProtocolCompositionType(CanType second) {
431432
protocolType.push_back(First);
432433
firstMembers = protocolType;
433434
} else {
435+
assert(cast<ProtocolCompositionType>(First)->getInverses().empty() &&
436+
"FIXME: move-only generics");
434437
firstMembers = cast<ProtocolCompositionType>(First)->getMembers();
435438
}
439+
assert(cast<ProtocolCompositionType>(second)->getInverses().empty() &&
440+
"FIXME: move-only generics");
436441
auto secondMembers = cast<ProtocolCompositionType>(second)->getMembers();
437442

438443
return computeProtocolCompositionJoin(firstMembers, secondMembers);

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,7 @@ namespace {
12431243

12441244
importedType = ExistentialType::get(
12451245
ProtocolCompositionType::get(Impl.SwiftContext, members,
1246+
/*Inverses=*/{},
12461247
/*HasExplicitAnyObject=*/false));
12471248
}
12481249

lib/Sema/CSBindings.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ static Type getKeyPathType(ASTContext &ctx, KeyPathCapability capability,
593593
auto *sendable = ctx.getProtocol(KnownProtocolKind::Sendable);
594594
keyPathTy = ProtocolCompositionType::get(
595595
ctx, {keyPathTy, sendable->getDeclaredInterfaceType()},
596-
/*hasExplicitAnyObject=*/false);
596+
/*inverses=*/{}, /*hasExplicitAnyObject=*/false);
597597
return ExistentialType::get(keyPathTy);
598598
}
599599

@@ -2203,6 +2203,7 @@ static Type getOptionalSuperclass(Type type) {
22032203

22042204
superclass = ExistentialType::get(
22052205
ProtocolCompositionType::get(type->getASTContext(), members,
2206+
compositionTy->getInverses(),
22062207
compositionTy->hasExplicitAnyObject()));
22072208
} else {
22082209
// Avoid producing superclass for situations like `any P` where `P` is

0 commit comments

Comments
 (0)