Skip to content

Commit de8726e

Browse files
committed
[Type Reconstruction] Re-construct existential types with ExistentialType
by propagating whether the decoded type is for a requirement through TypeDecoder.
1 parent 2c48da8 commit de8726e

File tree

7 files changed

+83
-47
lines changed

7 files changed

+83
-47
lines changed

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/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)

lib/AST/ASTDemangler.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ TypeDecl *swift::Demangle::getTypeDeclForUSR(ASTContext &ctx,
7070
return getTypeDeclForMangling(ctx, mangling);
7171
}
7272

73-
Type ASTBuilder::decodeMangledType(NodePointer node) {
74-
return swift::Demangle::decodeMangledType(*this, node).getType();
73+
Type ASTBuilder::decodeMangledType(NodePointer node, bool forRequirement) {
74+
return swift::Demangle::decodeMangledType(*this, node, forRequirement)
75+
.getType();
7576
}
7677

7778
TypeDecl *ASTBuilder::createTypeDecl(NodePointer node) {
@@ -583,22 +584,19 @@ Type ASTBuilder::createImplFunctionType(
583584
Type ASTBuilder::createProtocolCompositionType(
584585
ArrayRef<ProtocolDecl *> protocols,
585586
Type superclass,
586-
bool isClassBound) {
587+
bool isClassBound,
588+
bool forRequirement) {
587589
std::vector<Type> members;
588590
for (auto protocol : protocols)
589591
members.push_back(protocol->getDeclaredInterfaceType());
590592
if (superclass && superclass->getClassOrBoundGenericClass())
591593
members.push_back(superclass);
592594

593-
// FIXME: When explicit existential types are enabled, protocol
594-
// compositions should be wrapped in ExistentialType based on
595-
// context, similar to how protocol compositions are resolved
596-
// during type resolution. For example, protocol compositions
597-
// in parameter types should be wrapped in ExistentialType, but
598-
// protocol compositions on the right side of a conformance
599-
// requirement should not.
600595
Type composition = ProtocolCompositionType::get(Ctx, members, isClassBound);
601-
return composition;
596+
if (forRequirement)
597+
return composition;
598+
599+
return ExistentialType::get(composition);
602600
}
603601

604602
static MetatypeRepresentation

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ class EqualUpToClangTypes
9797
};
9898
};
9999

100+
static bool equalWithoutExistentialTypes(Type t1, Type t2) {
101+
if (!t1->getASTContext().LangOpts.EnableExplicitExistentialTypes)
102+
return false;
103+
104+
auto withoutExistentialTypes = [](Type type) -> Type {
105+
return type.transform([](Type type) -> Type {
106+
if (auto existential = type->getAs<ExistentialType>())
107+
return existential->getConstraintType();
108+
return type;
109+
});
110+
};
111+
112+
return withoutExistentialTypes(t1)
113+
->isEqual(withoutExistentialTypes(t2));
114+
}
115+
100116
class IRGenDebugInfoImpl : public IRGenDebugInfo {
101117
friend class IRGenDebugInfoImpl;
102118
const IRGenOptions &Opts;
@@ -902,14 +918,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
902918
Ty->dump(llvm::errs());
903919
abort();
904920
} else if (!Reconstructed->isEqual(Ty) &&
905-
// FIXME: Existential types are reconstructed without
921+
// FIXME: Some existential types are reconstructed without
906922
// an explicit ExistentialType wrapping the constraint.
907-
!(Ty->getASTContext().LangOpts.EnableExplicitExistentialTypes &&
908-
Ty.transform([](Type type) -> Type {
909-
if (auto existential = type->getAs<ExistentialType>())
910-
return existential->getConstraintType();
911-
return type;
912-
})->isEqual(Reconstructed)) &&
923+
!equalWithoutExistentialTypes(Reconstructed, Ty) &&
913924
!EqualUpToClangTypes().check(Reconstructed, Ty)) {
914925
// [FIXME: Include-Clang-type-in-mangling] Remove second check
915926
llvm::errs() << "Incorrect reconstructed type for " << Result << "\n";

stdlib/public/Reflection/TypeRefBuilder.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
using namespace swift;
2727
using namespace reflection;
2828

29-
TypeRefBuilder::BuiltType TypeRefBuilder::decodeMangledType(Node *node) {
30-
return swift::Demangle::decodeMangledType(*this, node).getType();
29+
TypeRefBuilder::BuiltType
30+
TypeRefBuilder::decodeMangledType(Node *node, bool forRequirement) {
31+
return swift::Demangle::decodeMangledType(*this, node, forRequirement)
32+
.getType();
3133
}
3234

3335
RemoteRef<char> TypeRefBuilder::readTypeRef(uint64_t remoteAddr) {

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,8 +1309,10 @@ class DecodedMetadataBuilder {
13091309
using BuiltTypeDecl = const ContextDescriptor *;
13101310
using BuiltProtocolDecl = ProtocolDescriptorRef;
13111311

1312-
BuiltType decodeMangledType(NodePointer node) {
1313-
return Demangle::decodeMangledType(*this, node).getType();
1312+
BuiltType decodeMangledType(NodePointer node,
1313+
bool forRequirement = true) {
1314+
return Demangle::decodeMangledType(*this, node, forRequirement)
1315+
.getType();
13141316
}
13151317

13161318
Demangle::NodeFactory &getNodeFactory() { return demangler; }
@@ -1478,7 +1480,8 @@ class DecodedMetadataBuilder {
14781480

14791481
TypeLookupErrorOr<BuiltType>
14801482
createProtocolCompositionType(llvm::ArrayRef<BuiltProtocolDecl> protocols,
1481-
BuiltType superclass, bool isClassBound) const {
1483+
BuiltType superclass, bool isClassBound,
1484+
bool forRequirement = true) const {
14821485
// Determine whether we have a class bound.
14831486
ProtocolClassConstraint classConstraint = ProtocolClassConstraint::Any;
14841487
if (isClassBound || superclass) {

0 commit comments

Comments
 (0)