Skip to content

Commit f357116

Browse files
committed
[Type System] Use the constraint type of an existential type in
various places that expect ProtocolType or ProtocoolCompositionType.
1 parent c7ddea4 commit f357116

File tree

13 files changed

+70
-15
lines changed

13 files changed

+70
-15
lines changed

include/swift/AST/ProtocolConformance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ class SelfProtocolConformance : public RootProtocolConformance {
660660
public:
661661
/// Get the protocol being conformed to.
662662
ProtocolDecl *getProtocol() const {
663-
return getType()->castTo<ProtocolType>()->getDecl();
663+
return dyn_cast<ProtocolDecl>(getType()->getAnyNominal());
664664
}
665665

666666
/// Get the declaration context in which this conformance was declared.

include/swift/AST/Types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6301,6 +6301,8 @@ inline NominalTypeDecl *TypeBase::getNominalOrBoundGenericNominal() {
63016301
inline NominalTypeDecl *CanType::getNominalOrBoundGenericNominal() const {
63026302
if (auto Ty = dyn_cast<NominalOrBoundGenericNominalType>(*this))
63036303
return Ty->getDecl();
6304+
if (auto Ty = dyn_cast<ExistentialType>(*this))
6305+
return Ty->getConstraintType()->getNominalOrBoundGenericNominal();
63046306
return nullptr;
63056307
}
63066308

@@ -6309,6 +6311,9 @@ inline NominalTypeDecl *TypeBase::getAnyNominal() {
63096311
}
63106312

63116313
inline Type TypeBase::getNominalParent() {
6314+
if (auto existential = getAs<ExistentialType>())
6315+
return existential->getConstraintType()->getNominalParent();
6316+
63126317
return castTo<AnyGenericType>()->getParent();
63136318
}
63146319

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,12 @@ static StringRef getTypeName(SDKContext &Ctx, Type Ty,
10171017
if (auto *NAT = dyn_cast<TypeAliasType>(Ty.getPointer())) {
10181018
return NAT->getDecl()->getNameStr();
10191019
}
1020+
1021+
if (auto existential = Ty->getAs<ExistentialType>()) {
1022+
return getTypeName(Ctx, existential->getConstraintType(),
1023+
IsImplicitlyUnwrappedOptional);
1024+
}
1025+
10201026
if (Ty->getAnyNominal()) {
10211027
if (IsImplicitlyUnwrappedOptional) {
10221028
assert(Ty->getOptionalObjectType());

lib/AST/Decl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5151,7 +5151,10 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
51515151
return SelfReferenceInfo::forSelfRef(SelfReferencePosition::Invariant);
51525152

51535153
// Protocol compositions preserve variance.
5154-
if (auto *comp = type->getAs<ProtocolCompositionType>()) {
5154+
auto constraint = type;
5155+
if (auto existential = constraint->getAs<ExistentialType>())
5156+
constraint = existential->getConstraintType();
5157+
if (auto *comp = constraint->getAs<ProtocolCompositionType>()) {
51555158
// 'Self' may be referenced only in a superclass component.
51565159
if (const auto superclass = comp->getSuperclass()) {
51575160
return findProtocolSelfReferences(proto, superclass, position);

lib/AST/Type.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ NominalTypeDecl *CanType::getAnyNominal() const {
104104
}
105105

106106
GenericTypeDecl *CanType::getAnyGeneric() const {
107+
if (auto existential = dyn_cast<ExistentialType>(*this))
108+
return existential->getConstraintType()->getAnyGeneric();
107109
if (auto Ty = dyn_cast<AnyGenericType>(*this))
108110
return Ty->getDecl();
109111
return nullptr;
@@ -2604,14 +2606,17 @@ getForeignRepresentable(Type type, ForeignLanguage language,
26042606
// If type has an error let's fail early.
26052607
if (type->hasError())
26062608
return failure();
2607-
2609+
26082610
// Look through one level of optional type, but remember that we did.
26092611
bool wasOptional = false;
26102612
if (auto valueType = type->getOptionalObjectType()) {
26112613
type = valueType;
26122614
wasOptional = true;
26132615
}
26142616

2617+
if (auto existential = type->getAs<ExistentialType>())
2618+
type = existential->getConstraintType();
2619+
26152620
// Objective-C object types, including metatypes.
26162621
if (language == ForeignLanguage::ObjectiveC) {
26172622
auto representable = getObjCObjectRepresentable(type, dc);
@@ -3199,9 +3204,14 @@ Type ArchetypeType::getExistentialType() const {
31993204
for (auto proto : getConformsTo()) {
32003205
constraintTypes.push_back(proto->getDeclaredInterfaceType());
32013206
}
3202-
return ProtocolCompositionType::get(
3203-
const_cast<ArchetypeType*>(this)->getASTContext(), constraintTypes,
3204-
requiresClass());
3207+
auto &ctx = const_cast<ArchetypeType*>(this)->getASTContext();
3208+
auto constraint = ProtocolCompositionType::get(
3209+
ctx, constraintTypes, requiresClass());
3210+
3211+
if (ctx.LangOpts.EnableExplicitExistentialTypes)
3212+
return ExistentialType::get(constraint);
3213+
3214+
return constraint;
32053215
}
32063216

32073217
PrimaryArchetypeType::PrimaryArchetypeType(const ASTContext &Ctx,
@@ -5356,6 +5366,10 @@ bool Type::isPrivateStdlibType(bool treatNonBuiltinProtocolsAsPublic) const {
53565366
if (!Ty)
53575367
return false;
53585368

5369+
if (auto existential = dyn_cast<ExistentialType>(Ty.getPointer()))
5370+
return existential->getConstraintType()
5371+
.isPrivateStdlibType(treatNonBuiltinProtocolsAsPublic);
5372+
53595373
// A 'public' typealias can have an 'internal' type.
53605374
if (auto *NAT = dyn_cast<TypeAliasType>(Ty.getPointer())) {
53615375
auto *AliasDecl = NAT->getDecl();
@@ -5542,7 +5556,7 @@ SILBoxType::SILBoxType(ASTContext &C,
55425556
Type TypeBase::openAnyExistentialType(OpenedArchetypeType *&opened) {
55435557
assert(isAnyExistentialType());
55445558
if (auto metaty = getAs<ExistentialMetatypeType>()) {
5545-
opened = OpenedArchetypeType::get(metaty->getInstanceType());
5559+
opened = OpenedArchetypeType::get(metaty->getExistentialInstanceType());
55465560
if (metaty->hasRepresentation())
55475561
return MetatypeType::get(opened, metaty->getRepresentation());
55485562
else

lib/IRGen/DebugTypeInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ TypeDecl *DebugTypeInfo::getDecl() const {
158158
return UBG->getDecl();
159159
if (auto *BG = dyn_cast<BoundGenericType>(Type))
160160
return BG->getDecl();
161+
if (auto *E = dyn_cast<ExistentialType>(Type))
162+
return E->getConstraintType()->getAnyNominal();
161163
return nullptr;
162164
}
163165

lib/IRGen/IRGenMangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ std::string IRGenMangler::mangleTypeForLLVMTypeName(CanType Ty) {
215215
// To make LLVM IR more readable we always add a 'T' prefix so that type names
216216
// don't start with a digit and don't need to be quoted.
217217
Buffer << 'T';
218+
if (auto existential = Ty->getAs<ExistentialType>())
219+
Ty = existential->getConstraintType()->getCanonicalType();
218220
if (auto P = dyn_cast<ProtocolType>(Ty)) {
219221
appendProtocolName(P->getDecl(), /*allowStandardSubstitution=*/false);
220222
appendOperator("P");

lib/SIL/Utils/DynamicCasts.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
468468
: DynamicCastFeasibility::WillFail;
469469
}
470470

471-
if (targetMetatype.isAnyExistentialType() &&
472-
(isa<ProtocolType>(target) || isa<ProtocolCompositionType>(target))) {
471+
if (targetMetatype.isAnyExistentialType() && target->isExistentialType()) {
473472
auto Feasibility =
474473
classifyDynamicCastToProtocol(M, source, target, isWholeModuleOpts);
475474
// Cast from existential metatype to existential metatype may still

lib/SILGen/SILGenConvert.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -913,8 +913,11 @@ ManagedValue SILGenFunction::emitExistentialMetatypeToObject(SILLocation loc,
913913
ManagedValue SILGenFunction::emitProtocolMetatypeToObject(SILLocation loc,
914914
CanType inputTy,
915915
SILType resultTy) {
916-
ProtocolDecl *protocol = inputTy->castTo<MetatypeType>()
917-
->getInstanceType()->castTo<ProtocolType>()->getDecl();
916+
auto protocolType = inputTy->castTo<MetatypeType>()->getInstanceType();
917+
if (auto existential = protocolType->getAs<ExistentialType>())
918+
protocolType = existential->getConstraintType();
919+
920+
ProtocolDecl *protocol = protocolType->castTo<ProtocolType>()->getDecl();
918921

919922
SILValue value = B.createObjCProtocol(loc, protocol, resultTy);
920923

lib/SILGen/SILGenType.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,10 @@ static SILFunction *emitSelfConformanceWitness(SILGenModule &SGM,
831831
ProtocolConformanceRef(conformance));
832832

833833
// Open the protocol type.
834-
auto openedType = OpenedArchetypeType::get(protocolType);
834+
Type existential = protocolType;
835+
if (SGM.getASTContext().LangOpts.EnableExplicitExistentialTypes)
836+
existential = ExistentialType::get(protocolType);
837+
auto openedType = OpenedArchetypeType::get(existential);
835838

836839
// Form the substitutions for calling the witness.
837840
auto witnessSubs = SubstitutionMap::getProtocolSubstitutions(protocol,

0 commit comments

Comments
 (0)