Skip to content

Commit c12e31f

Browse files
authored
Merge pull request #40804 from hborla/5.6-enable-existential-any
[5.6][SE-0335] Enable explicit existential types.
2 parents fa43d48 + 8fe5396 commit c12e31f

File tree

85 files changed

+678
-297
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+678
-297
lines changed

include/swift/AST/ASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ class ASTContext final {
526526

527527
/// Retrieve the declaration of Swift.Error.
528528
ProtocolDecl *getErrorDecl() const;
529-
CanType getExceptionType() const;
529+
CanType getErrorExistentialType() const;
530530

531531
#define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \
532532
/** Retrieve the declaration of Swift.NAME. */ \

include/swift/AST/ASTDemangler.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class ASTBuilder {
6666

6767
Demangle::NodeFactory &getNodeFactory() { return Factory; }
6868

69-
Type decodeMangledType(NodePointer node);
69+
Type decodeMangledType(NodePointer node, bool forRequirement = true);
7070
Type createBuiltinType(StringRef builtinName, StringRef mangledName);
7171

7272
TypeDecl *createTypeDecl(NodePointer node);
@@ -109,7 +109,8 @@ class ASTBuilder {
109109

110110
Type createProtocolCompositionType(ArrayRef<ProtocolDecl *> protocols,
111111
Type superclass,
112-
bool isClassBound);
112+
bool isClassBound,
113+
bool forRequirement = true);
113114

114115
Type createExistentialMetatypeType(Type instance,
115116
Optional<Demangle::ImplMetatypeRepresentation> repr=None);

include/swift/AST/ASTSynthesis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ inline Type synthesizeType(SynthesisContext &SC,
5656
switch (kind) {
5757
case _any: return SC.Context.TheAnyType;
5858
case _bridgeObject: return SC.Context.TheBridgeObjectType;
59-
case _error: return SC.Context.getExceptionType();
59+
case _error: return SC.Context.getErrorExistentialType();
6060
case _executor: return SC.Context.TheExecutorType;
6161
case _job: return SC.Context.TheJobType;
6262
case _nativeObject: return SC.Context.TheNativeObjectType;

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4297,6 +4297,11 @@ class ProtocolDecl final : public NominalTypeDecl {
42974297
/// not exist.
42984298
AssociatedTypeDecl *getAssociatedType(Identifier name) const;
42994299

4300+
/// Returns the existential type for this protocol.
4301+
Type getExistentialType() const {
4302+
return ExistentialType::get(getDeclaredInterfaceType());
4303+
}
4304+
43004305
/// Walk this protocol and all of the protocols inherited by this protocol,
43014306
/// transitively, invoking the callback function for each protocol.
43024307
///

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2441,8 +2441,8 @@ ERROR(protocol_composition_one_class,none,
24412441
"contains class %1", (Type, Type))
24422442

24432443
ERROR(requires_conformance_nonprotocol,none,
2444-
"type %0 constrained to non-protocol, non-class type %1",
2445-
(Type, Type))
2444+
"type %0 constrained to non-protocol, non-class type '%1'",
2445+
(Type, StringRef))
24462446
NOTE(requires_conformance_nonprotocol_fixit,none,
24472447
"use '%0 == %1' to require '%0' to be '%1'",
24482448
(StringRef, StringRef))
@@ -4643,8 +4643,6 @@ ERROR(unchecked_not_inheritance_clause,none,
46434643
ERROR(unchecked_not_existential,none,
46444644
"'unchecked' attribute cannot apply to non-protocol type %0", (Type))
46454645

4646-
WARNING(unnecessary_any,none,
4647-
"'any' is redundant on type %0", (Type))
46484646
ERROR(any_not_existential,none,
46494647
"'any' has no effect on %select{concrete type|type parameter}0 %1",
46504648
(bool, Type))

include/swift/AST/PrintOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ struct PrintOptions {
276276

277277
bool PrintImplicitAttrs = true;
278278

279+
/// Whether to print the \c any keyword for existential
280+
/// types.
281+
bool PrintExplicitAny = false;
282+
279283
/// Whether to skip keywords with a prefix of underscore such as __consuming.
280284
bool SkipUnderscoredKeywords = false;
281285

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/Type.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ class CanType : public Type {
385385

386386
static bool isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig,
387387
bool functionsCount);
388+
static bool isConstraintTypeImpl(CanType type);
388389
static bool isExistentialTypeImpl(CanType type);
389390
static bool isAnyExistentialTypeImpl(CanType type);
390391
static bool isObjCExistentialTypeImpl(CanType type);
@@ -457,6 +458,10 @@ class CanType : public Type {
457458
/*functions count*/ false);
458459
}
459460

461+
bool isConstraintType() const {
462+
return isConstraintTypeImpl(*this);
463+
}
464+
460465
/// Is this type existential?
461466
bool isExistentialType() const {
462467
return isExistentialTypeImpl(*this);

include/swift/AST/Types.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,9 @@ class alignas(1 << TypeAlignInBits) TypeBase
703703
return getRecursiveProperties().hasDependentMember();
704704
}
705705

706+
/// Whether this type represents a generic constraint.
707+
bool isConstraintType() const;
708+
706709
/// isExistentialType - Determines whether this type is an existential type,
707710
/// whose real (runtime) type is unknown but which is known to conform to
708711
/// some set of protocols. Protocol and protocol-conformance types are
@@ -2704,6 +2707,8 @@ class ExistentialMetatypeType : public AnyMetatypeType {
27042707
static bool classof(const TypeBase *T) {
27052708
return T->getKind() == TypeKind::ExistentialMetatype;
27062709
}
2710+
2711+
Type getExistentialInstanceType();
27072712

27082713
private:
27092714
ExistentialMetatypeType(Type T, const ASTContext *C,
@@ -5213,7 +5218,7 @@ class ExistentialType final : public TypeBase {
52135218
ConstraintType(constraintType) {}
52145219

52155220
public:
5216-
static ExistentialType *get(Type constraint);
5221+
static Type get(Type constraint);
52175222

52185223
Type getConstraintType() const { return ConstraintType; }
52195224

@@ -6181,6 +6186,15 @@ inline GenericTypeParamType *TypeBase::getRootGenericParam() {
61816186
return t->castTo<GenericTypeParamType>();
61826187
}
61836188

6189+
inline bool TypeBase::isConstraintType() const {
6190+
return getCanonicalType().isConstraintType();
6191+
}
6192+
6193+
inline bool CanType::isConstraintTypeImpl(CanType type) {
6194+
return (isa<ProtocolType>(type) ||
6195+
isa<ProtocolCompositionType>(type));
6196+
}
6197+
61846198
inline bool TypeBase::isExistentialType() {
61856199
return getCanonicalType().isExistentialType();
61866200
}
@@ -6287,6 +6301,8 @@ inline NominalTypeDecl *TypeBase::getNominalOrBoundGenericNominal() {
62876301
inline NominalTypeDecl *CanType::getNominalOrBoundGenericNominal() const {
62886302
if (auto Ty = dyn_cast<NominalOrBoundGenericNominalType>(*this))
62896303
return Ty->getDecl();
6304+
if (auto Ty = dyn_cast<ExistentialType>(*this))
6305+
return Ty->getConstraintType()->getNominalOrBoundGenericNominal();
62906306
return nullptr;
62916307
}
62926308

@@ -6295,6 +6311,9 @@ inline NominalTypeDecl *TypeBase::getAnyNominal() {
62956311
}
62966312

62976313
inline Type TypeBase::getNominalParent() {
6314+
if (auto existential = getAs<ExistentialType>())
6315+
return existential->getConstraintType()->getNominalParent();
6316+
62986317
return castTo<AnyGenericType>()->getParent();
62996318
}
63006319

include/swift/Basic/LangOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ namespace swift {
315315

316316
/// Enable support for explicit existential types via the \c any
317317
/// keyword.
318-
bool EnableExplicitExistentialTypes = false;
318+
bool EnableExplicitExistentialTypes = true;
319319

320320
/// Enable experimental flow-sensitive concurrent captures.
321321
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;

include/swift/Demangling/TypeDecoder.h

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,16 @@ void decodeRequirement(NodePointer node,
372372

373373
BuiltType constraintType;
374374
if (child->getKind() ==
375-
Demangle::Node::Kind::DependentGenericConformanceRequirement ||
376-
child->getKind() ==
377-
Demangle::Node::Kind::DependentGenericSameTypeRequirement) {
375+
Demangle::Node::Kind::DependentGenericConformanceRequirement) {
378376
constraintType = Builder.decodeMangledType(child->getChild(1));
379377
if (!constraintType)
380378
return;
379+
} else if (child->getKind() ==
380+
Demangle::Node::Kind::DependentGenericSameTypeRequirement) {
381+
constraintType = Builder.decodeMangledType(
382+
child->getChild(1), /*forRequirement=*/false);
383+
if (!constraintType)
384+
return;
381385
}
382386

383387
switch (child->getKind()) {
@@ -468,15 +472,17 @@ class TypeDecoder {
468472
explicit TypeDecoder(BuilderType &Builder) : Builder(Builder) {}
469473

470474
/// Given a demangle tree, attempt to turn it into a type.
471-
TypeLookupErrorOr<BuiltType> decodeMangledType(NodePointer Node) {
472-
return decodeMangledType(Node, 0);
475+
TypeLookupErrorOr<BuiltType> decodeMangledType(NodePointer Node,
476+
bool forRequirement = true) {
477+
return decodeMangledType(Node, 0, forRequirement);
473478
}
474479

475480
protected:
476481
static const unsigned MaxDepth = 1024;
477482

478483
TypeLookupErrorOr<BuiltType> decodeMangledType(NodePointer Node,
479-
unsigned depth) {
484+
unsigned depth,
485+
bool forRequirement = true) {
480486
if (depth > TypeDecoder::MaxDepth)
481487
return TypeLookupError("Mangled type is too complex");
482488

@@ -499,7 +505,8 @@ class TypeDecoder {
499505
if (Node->getNumChildren() < 1)
500506
return MAKE_NODE_TYPE_ERROR0(Node, "no children.");
501507

502-
return decodeMangledType(Node->getChild(0), depth + 1);
508+
return decodeMangledType(Node->getChild(0), depth + 1,
509+
forRequirement);
503510
case NodeKind::Class:
504511
{
505512
#if SWIFT_OBJC_INTEROP
@@ -543,7 +550,8 @@ class TypeDecoder {
543550
return MAKE_NODE_TYPE_ERROR0(genericArgs, "is not TypeList");
544551

545552
for (auto genericArg : *genericArgs) {
546-
auto paramType = decodeMangledType(genericArg, depth + 1);
553+
auto paramType = decodeMangledType(genericArg, depth + 1,
554+
/*forRequirement=*/false);
547555
if (paramType.isError())
548556
return paramType;
549557
args.push_back(paramType.getType());
@@ -698,14 +706,16 @@ class TypeDecoder {
698706
}
699707

700708
return Builder.createProtocolCompositionType(Protocols, Superclass,
701-
IsClassBound);
709+
IsClassBound,
710+
forRequirement);
702711
}
703712

704713
case NodeKind::Protocol:
705714
case NodeKind::ProtocolSymbolicReference: {
706715
if (auto Proto = decodeMangledProtocolType(Node, depth + 1)) {
707716
return Builder.createProtocolCompositionType(Proto, BuiltType(),
708-
/*IsClassBound=*/false);
717+
/*IsClassBound=*/false,
718+
forRequirement);
709719
}
710720

711721
return MAKE_NODE_TYPE_ERROR0(Node, "failed to decode protocol type");
@@ -845,7 +855,8 @@ class TypeDecoder {
845855
Node->getKind() == NodeKind::EscapingObjCBlock);
846856

847857
auto result =
848-
decodeMangledType(Node->getChild(firstChildIdx + 1), depth + 1);
858+
decodeMangledType(Node->getChild(firstChildIdx + 1), depth + 1,
859+
/*forRequirement=*/false);
849860
if (result.isError())
850861
return result;
851862
return Builder.createFunctionType(
@@ -962,7 +973,8 @@ class TypeDecoder {
962973
if (Node->getNumChildren() < 1)
963974
return MAKE_NODE_TYPE_ERROR0(Node, "no children");
964975

965-
return decodeMangledType(Node->getChild(0), depth + 1);
976+
return decodeMangledType(Node->getChild(0), depth + 1,
977+
/*forRequirement=*/false);
966978

967979
case NodeKind::Tuple: {
968980
llvm::SmallVector<BuiltType, 8> elements;
@@ -994,7 +1006,8 @@ class TypeDecoder {
9941006

9951007
// Decode the element type.
9961008
auto elementType =
997-
decodeMangledType(element->getChild(typeChildIndex), depth + 1);
1009+
decodeMangledType(element->getChild(typeChildIndex), depth + 1,
1010+
/*forRequirement=*/false);
9981011
if (elementType.isError())
9991012
return elementType;
10001013

@@ -1012,9 +1025,11 @@ class TypeDecoder {
10121025
"fewer children (%zu) than required (2)",
10131026
Node->getNumChildren());
10141027

1015-
return decodeMangledType(Node->getChild(1), depth + 1);
1028+
return decodeMangledType(Node->getChild(1), depth + 1,
1029+
/*forRequirement=*/false);
10161030
}
1017-
return decodeMangledType(Node->getChild(0), depth + 1);
1031+
return decodeMangledType(Node->getChild(0), depth + 1,
1032+
/*forRequirement=*/false);
10181033

10191034
case NodeKind::DependentGenericType: {
10201035
if (Node->getNumChildren() < 2)
@@ -1161,7 +1176,8 @@ return {}; // Not Implemented!
11611176
"more substitutions than generic params");
11621177
while (index >= genericParamsAtDepth[paramDepth])
11631178
++paramDepth, index = 0;
1164-
auto substTy = decodeMangledType(subst, depth + 1);
1179+
auto substTy = decodeMangledType(subst, depth + 1,
1180+
/*forRequirement=*/false);
11651181
if (substTy.isError())
11661182
return substTy;
11671183
substitutions.emplace_back(
@@ -1243,7 +1259,8 @@ return {}; // Not Implemented!
12431259
if (genericsNode->getKind() != NodeKind::TypeList)
12441260
break;
12451261
for (auto argNode : *genericsNode) {
1246-
auto arg = decodeMangledType(argNode, depth + 1);
1262+
auto arg = decodeMangledType(argNode, depth + 1,
1263+
/*forRequirement=*/false);
12471264
if (arg.isError())
12481265
return arg;
12491266
genericArgsBuf.push_back(arg.getType());
@@ -1479,7 +1496,8 @@ return {}; // Not Implemented!
14791496
}
14801497
}
14811498

1482-
auto paramType = decodeMangledType(node, depth + 1);
1499+
auto paramType = decodeMangledType(node, depth + 1,
1500+
/*forRequirement=*/false);
14831501
if (paramType.isError())
14841502
return false;
14851503

@@ -1543,8 +1561,10 @@ return {}; // Not Implemented!
15431561

15441562
template <typename BuilderType>
15451563
inline TypeLookupErrorOr<typename BuilderType::BuiltType>
1546-
decodeMangledType(BuilderType &Builder, NodePointer Node) {
1547-
return TypeDecoder<BuilderType>(Builder).decodeMangledType(Node);
1564+
decodeMangledType(BuilderType &Builder, NodePointer Node,
1565+
bool forRequirement = false) {
1566+
return TypeDecoder<BuilderType>(Builder)
1567+
.decodeMangledType(Node, forRequirement);
15481568
}
15491569

15501570
SWIFT_END_INLINE_NAMESPACE

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class TypeRefBuilder {
288288

289289
void clearNodeFactory() { Dem.clear(); }
290290

291-
BuiltType decodeMangledType(Node *node);
291+
BuiltType decodeMangledType(Node *node, bool forRequirement = true);
292292

293293
///
294294
/// Factory methods for all TypeRef kinds
@@ -491,7 +491,8 @@ class TypeRefBuilder {
491491

492492
const ProtocolCompositionTypeRef *
493493
createProtocolCompositionType(llvm::ArrayRef<BuiltProtocolDecl> protocols,
494-
BuiltType superclass, bool isClassBound) {
494+
BuiltType superclass, bool isClassBound,
495+
bool forRequirement = true) {
495496
std::vector<const TypeRef *> protocolRefs;
496497
for (const auto &protocol : protocols) {
497498
if (!protocol)

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ visitOpenExistentialMetatypeInst(OpenExistentialMetatypeInst *Inst) {
21892189
auto openedType = Inst->getType().getASTType();
21902190
auto exType = Inst->getOperand()->getType().getASTType();
21912191
while (auto exMetatype = dyn_cast<ExistentialMetatypeType>(exType)) {
2192-
exType = exMetatype.getInstanceType();
2192+
exType = exMetatype->getExistentialInstanceType()->getCanonicalType();
21932193
openedType = cast<MetatypeType>(openedType).getInstanceType();
21942194
}
21952195
remapOpenedType(cast<OpenedArchetypeType>(openedType));

include/swift/SIL/SILInstruction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7056,7 +7056,7 @@ class InitExistentialMetatypeInst final
70567056
auto exType = getType().getASTType();
70577057
auto concreteType = getOperand()->getType().getASTType();
70587058
while (auto exMetatype = dyn_cast<ExistentialMetatypeType>(exType)) {
7059-
exType = exMetatype.getInstanceType();
7059+
exType = exMetatype->getExistentialInstanceType()->getCanonicalType();
70607060
concreteType = cast<MetatypeType>(concreteType).getInstanceType();
70617061
}
70627062
assert(exType.isExistentialType());

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());

0 commit comments

Comments
 (0)