Skip to content

Commit 6328f3f

Browse files
committed
Explicitly represent "pseudo-generic" functions in SIL, which do
not have access to their type arguments at runtime. Use this to fix the emission of native thunks for imported ObjC-generic initializers, since they may need to perform bridging. For now, pseudo-genericity is all-or-nothing, but we may want to make it apply only to certain type arguments. Also, clean up some code that was using dead mangling nodes.
1 parent c55b3c6 commit 6328f3f

26 files changed

+207
-246
lines changed

Diff for: docs/ABI.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ mangled in to disambiguate.
10161016
impl-function-attribute ::= 'Cw' // compatible with protocol witness
10171017
impl-function-attribute ::= 'N' // noreturn
10181018
impl-function-attribute ::= 'G' // generic
1019+
impl-function-attribute ::= 'g' // pseudogeneric
10191020
impl-parameter ::= impl-convention type
10201021
impl-result ::= impl-convention type
10211022

@@ -1025,7 +1026,8 @@ implementation details of a function type.
10251026

10261027
Any ``<impl-function-attribute>`` productions must appear in the order
10271028
in which they are specified above: e.g. a noreturn C function is
1028-
mangled with ``CcN``.
1029+
mangled with ``CcN``. ``g`` and ``G`` are exclusive and mark the presence
1030+
of a generic signature immediately following.
10291031

10301032
Note that the convention and function-attribute productions do not
10311033
need to be disambiguated from the start of a ``<type>``.

Diff for: include/swift/AST/Attr.def

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ TYPE_ATTR(callee_guaranteed)
5757
TYPE_ATTR(objc_metatype)
5858
TYPE_ATTR(opened)
5959
TYPE_ATTR(deallocating)
60+
TYPE_ATTR(pseudogeneric)
6061

6162
// SIL metatype attributes.
6263
TYPE_ATTR(thin)

Diff for: include/swift/AST/Types.h

+24-5
Original file line numberDiff line numberDiff line change
@@ -2869,11 +2869,12 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
28692869
// you'll need to adjust both the Bits field below and
28702870
// BaseType::AnyFunctionTypeBits.
28712871

2872-
// |representation|noReturn|
2873-
// | 0 .. 3 | 4 |
2872+
// |representation|noReturn|pseudogeneric|
2873+
// | 0 .. 3 | 4 | 5 |
28742874
//
28752875
enum : uint16_t { RepresentationMask = 0x00F };
28762876
enum : uint16_t { NoReturnMask = 0x010 };
2877+
enum : uint16_t { PseudogenericMask = 0x020 };
28772878

28782879
uint16_t Bits;
28792880

@@ -2886,12 +2887,20 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
28862887
ExtInfo() : Bits(0) { }
28872888

28882889
// Constructor for polymorphic type.
2889-
ExtInfo(Representation Rep, bool IsNoReturn) {
2890-
Bits = ((unsigned) Rep) |
2891-
(IsNoReturn ? NoReturnMask : 0);
2890+
ExtInfo(Representation rep, bool isNoReturn, bool isPseudogeneric) {
2891+
Bits = ((unsigned) rep) |
2892+
(isNoReturn ? NoReturnMask : 0) |
2893+
(isPseudogeneric ? PseudogenericMask : 0);
28922894
}
28932895

2896+
/// Is this function pseudo-generic? A pseudo-generic function
2897+
/// is not permitted to dynamically depend on its type arguments.
2898+
bool isPseudogeneric() const { return Bits & PseudogenericMask; }
2899+
2900+
/// Do functions of this type return normally?
28942901
bool isNoReturn() const { return Bits & NoReturnMask; }
2902+
2903+
/// What is the abstract representation of this function value?
28952904
Representation getRepresentation() const {
28962905
return Representation(Bits & RepresentationMask);
28972906
}
@@ -2954,6 +2963,12 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
29542963
else
29552964
return ExtInfo(Bits & ~NoReturnMask);
29562965
}
2966+
ExtInfo withIsPseudogeneric(bool isPseudogeneric = true) const {
2967+
if (isPseudogeneric)
2968+
return ExtInfo(Bits | PseudogenericMask);
2969+
else
2970+
return ExtInfo(Bits & ~PseudogenericMask);
2971+
}
29572972

29582973
uint16_t getFuncAttrKey() const {
29592974
return Bits;
@@ -3197,6 +3212,10 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
31973212
return getExtInfo().isNoReturn();
31983213
}
31993214

3215+
bool isPseudogeneric() const {
3216+
return getExtInfo().isPseudogeneric();
3217+
}
3218+
32003219
CanSILFunctionType substGenericArgs(SILModule &silModule,
32013220
ModuleDecl *astModule,
32023221
ArrayRef<Substitution> subs);

Diff for: include/swift/Basic/DemangleNodes.def

+4-5
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@ CONTEXT_NODE(Deallocator)
4444
NODE(DeclContext)
4545
CONTEXT_NODE(DefaultArgumentInitializer)
4646
NODE(DependentAssociatedTypeRef)
47-
NODE(DependentGenericSignature)
48-
NODE(DependentGenericParamCount)
4947
NODE(DependentGenericConformanceRequirement)
48+
NODE(DependentGenericParamCount)
49+
NODE(DependentGenericParamType)
5050
NODE(DependentGenericSameTypeRequirement)
51+
NODE(DependentGenericSignature)
5152
NODE(DependentGenericType)
5253
NODE(DependentMemberType)
53-
NODE(DependentGenericParamType)
54+
NODE(DependentPseudogenericSignature)
5455
CONTEXT_NODE(Destructor)
5556
CONTEXT_NODE(DidSet)
5657
NODE(Directness)
@@ -70,13 +71,11 @@ NODE(FunctionSignatureSpecializationParam)
7071
NODE(FunctionSignatureSpecializationParamKind)
7172
NODE(FunctionSignatureSpecializationParamPayload)
7273
NODE(FunctionType)
73-
NODE(Generics)
7474
NODE(GenericProtocolWitnessTable)
7575
NODE(GenericProtocolWitnessTableInstantiationFunction)
7676
NODE(GenericSpecialization)
7777
NODE(GenericSpecializationNotReAbstracted)
7878
NODE(GenericSpecializationParam)
79-
NODE(GenericType)
8079
NODE(GenericTypeMetadataPattern)
8180
CONTEXT_NODE(Getter)
8281
NODE(Global)

Diff for: include/swift/Serialization/ModuleFormat.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const uint16_t VERSION_MAJOR = 0;
5353
/// in source control, you should also update the comment to briefly
5454
/// describe what change you made. The content of this comment isn't important;
5555
/// it just ensures a conflict if two people change the module format.
56-
const uint16_t VERSION_MINOR = 250; // Last change: Add Throws bit
56+
const uint16_t VERSION_MINOR = 251; // Last change: SILFunctionType::isPseudogeneric
5757

5858
using DeclID = PointerEmbeddedInt<unsigned, 31>;
5959
using DeclIDField = BCFixed<31>;
@@ -702,6 +702,7 @@ namespace decls_block {
702702
ParameterConventionField, // callee convention
703703
SILFunctionTypeRepresentationField, // representation
704704
BCFixed<1>, // noreturn?
705+
BCFixed<1>, // pseudogeneric?
705706
BCFixed<1>, // error result?
706707
BCFixed<30>, // number of parameters
707708
BCFixed<30>, // number of results

Diff for: lib/AST/ASTPrinter.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -3721,6 +3721,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37213721
}
37223722
}
37233723

3724+
if (info.isPseudogeneric())
3725+
Printer << "@pseudogeneric ";
3726+
37243727
if (info.isNoReturn())
37253728
Printer << "@noreturn ";
37263729
}

Diff for: lib/AST/Mangle.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,7 @@ void Mangler::mangleType(Type type, unsigned uncurryLevel) {
11251125
// <impl-function-attribute> ::= 'Cm' // Swift method
11261126
// <impl-function-attribute> ::= 'CO' // ObjC method
11271127
// <impl-function-attribute> ::= 'N' // noreturn
1128+
// <impl-function-attribute> ::= 'g' // pseudogeneric
11281129
// <impl-function-attribute> ::= 'G' // generic
11291130
// <impl-parameter> ::= <impl-convention> <type>
11301131
// <impl-result> ::= <impl-convention> <type>
@@ -1188,7 +1189,7 @@ void Mangler::mangleType(Type type, unsigned uncurryLevel) {
11881189

11891190
if (fn->isNoReturn()) Buffer << 'N';
11901191
if (fn->isPolymorphic()) {
1191-
Buffer << 'G';
1192+
Buffer << (fn->isPseudogeneric() ? 'g' : 'G');
11921193
mangleGenericSignature(fn->getGenericSignature());
11931194
}
11941195
Buffer << '_';

Diff for: lib/Basic/Demangle.cpp

+13-31
Original file line numberDiff line numberDiff line change
@@ -1514,8 +1514,11 @@ class Demangler {
15141514
return nodeType;
15151515
}
15161516

1517-
NodePointer demangleGenericSignature() {
1518-
auto sig = NodeFactory::create(Node::Kind::DependentGenericSignature);
1517+
NodePointer demangleGenericSignature(bool isPseudogeneric = false) {
1518+
auto sig =
1519+
NodeFactory::create(isPseudogeneric
1520+
? Node::Kind::DependentPseudogenericSignature
1521+
: Node::Kind::DependentGenericSignature);
15191522
// First read in the parameter counts at each depth.
15201523
Node::IndexType count = ~(Node::IndexType)0;
15211524

@@ -2106,8 +2109,10 @@ class Demangler {
21062109

21072110
// Enter a new generic context if this type is generic.
21082111
// FIXME: replace with std::optional, when we have it.
2109-
if (Mangled.nextIf('G')) {
2110-
NodePointer generics = demangleGenericSignature();
2112+
bool isPseudogeneric = false;
2113+
if (Mangled.nextIf('G') ||
2114+
(isPseudogeneric = Mangled.nextIf('g'))) {
2115+
NodePointer generics = demangleGenericSignature(isPseudogeneric);
21112116
if (!generics)
21122117
return nullptr;
21132118
type->addChild(generics);
@@ -2382,6 +2387,7 @@ class NodePrinter {
23822387
case Node::Kind::DependentGenericParamCount:
23832388
case Node::Kind::DependentGenericConformanceRequirement:
23842389
case Node::Kind::DependentGenericSameTypeRequirement:
2390+
case Node::Kind::DependentPseudogenericSignature:
23852391
case Node::Kind::Destructor:
23862392
case Node::Kind::DidSet:
23872393
case Node::Kind::DirectMethodReferenceAttribute:
@@ -2397,13 +2403,11 @@ class NodePrinter {
23972403
case Node::Kind::FunctionSignatureSpecializationParamKind:
23982404
case Node::Kind::FunctionSignatureSpecializationParamPayload:
23992405
case Node::Kind::FunctionType:
2400-
case Node::Kind::Generics:
24012406
case Node::Kind::GenericProtocolWitnessTable:
24022407
case Node::Kind::GenericProtocolWitnessTableInstantiationFunction:
24032408
case Node::Kind::GenericSpecialization:
24042409
case Node::Kind::GenericSpecializationNotReAbstracted:
24052410
case Node::Kind::GenericSpecializationParam:
2406-
case Node::Kind::GenericType:
24072411
case Node::Kind::GenericTypeMetadataPattern:
24082412
case Node::Kind::Getter:
24092413
case Node::Kind::Global:
@@ -2783,8 +2787,7 @@ static bool useColonForEntityType(NodePointer entity, NodePointer type) {
27832787
case Node::Kind::IVarDestroyer: {
27842788
// We expect to see a function type here, but if we don't, use the colon.
27852789
type = type->getChild(0);
2786-
while (type->getKind() == Node::Kind::GenericType ||
2787-
type->getKind() == Node::Kind::DependentGenericType)
2790+
while (type->getKind() == Node::Kind::DependentGenericType)
27882791
type = type->getChild(1)->getChild(0);
27892792
return (type->getKind() != Node::Kind::FunctionType &&
27902793
type->getKind() != Node::Kind::UncurriedFunctionType &&
@@ -2822,8 +2825,7 @@ void NodePrinter::printSimplifiedEntityType(NodePointer context,
28222825
type = type->getChild(0);
28232826

28242827
NodePointer generics;
2825-
if (type->getKind() == Node::Kind::GenericType ||
2826-
type->getKind() == Node::Kind::DependentGenericType) {
2828+
if (type->getKind() == Node::Kind::DependentGenericType) {
28272829
generics = type->getChild(0);
28282830
type = type->getChild(1)->getChild(0);
28292831
}
@@ -3434,20 +3436,6 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
34343436
Printer << ">";
34353437
return;
34363438
}
3437-
case Node::Kind::Generics: {
3438-
if (pointer->getNumChildren() == 0)
3439-
return;
3440-
Printer << "<";
3441-
print(pointer->getChild(0));
3442-
for (unsigned i = 1, e = pointer->getNumChildren(); i != e; ++i) {
3443-
auto child = pointer->getChild(i);
3444-
if (child->getKind() != Node::Kind::Archetype) break;
3445-
Printer << ", ";
3446-
print(child);
3447-
}
3448-
Printer << ">";
3449-
return;
3450-
}
34513439
case Node::Kind::Archetype: {
34523440
Printer << pointer->getText();
34533441
if (pointer->hasChildren()) {
@@ -3473,13 +3461,6 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
34733461
Printer << ")";
34743462
return;
34753463
}
3476-
case Node::Kind::GenericType: {
3477-
NodePointer atype_list = pointer->getChild(0);
3478-
NodePointer fct_type = pointer->getChild(1)->getChild(0);
3479-
print(atype_list);
3480-
print(fct_type);
3481-
return;
3482-
}
34833464
case Node::Kind::OwningAddressor:
34843465
printEntity(true, true, ".owningAddressor");
34853466
return;
@@ -3580,6 +3561,7 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
35803561
Printer << "<ERROR TYPE>";
35813562
return;
35823563

3564+
case Node::Kind::DependentPseudogenericSignature:
35833565
case Node::Kind::DependentGenericSignature: {
35843566
Printer << '<';
35853567

Diff for: lib/Basic/Remangle.cpp

+8-45
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ namespace {
305305
void mangleEntityContext(Node *node, EntityContext &ctx);
306306
void mangleEntityType(Node *node, EntityContext &ctx);
307307
void mangleEntityGenericType(Node *node, EntityContext &ctx);
308-
void mangleGenerics(Node *node, EntityContext &ctx);
309308

310309
bool trySubstitution(Node *node, SubstitutionEntry &entry);
311310
void addSubstitution(const SubstitutionEntry &entry);
@@ -955,9 +954,6 @@ void Remangler::mangleEntityType(Node *node, EntityContext &ctx) {
955954

956955
// Expand certain kinds of type within the entity context.
957956
switch (node->getKind()) {
958-
case Node::Kind::GenericType:
959-
mangleEntityGenericType(node, ctx);
960-
return;
961957
case Node::Kind::FunctionType:
962958
case Node::Kind::UncurriedFunctionType: {
963959
Out << (node->getKind() == Node::Kind::FunctionType ? 'F' : 'f');
@@ -1109,9 +1105,12 @@ void Remangler::mangleImplFunctionType(Node *node) {
11091105
i->get()->getKind() == Node::Kind::ImplFunctionAttribute; ++i) {
11101106
mangle(i->get()); // impl function attribute
11111107
}
1112-
EntityContext ctx(*this);
1113-
if (i != e && i->get()->getKind() == Node::Kind::Generics) {
1114-
mangleGenerics((i++)->get(), ctx);
1108+
if (i != e &&
1109+
(i->get()->getKind() == Node::Kind::DependentGenericSignature ||
1110+
i->get()->getKind() == Node::Kind::DependentPseudogenericSignature)) {
1111+
Out << (i->get()->getKind() == Node::Kind::DependentGenericSignature
1112+
? 'G' : 'g');
1113+
mangleDependentGenericSignature((i++)->get());
11151114
}
11161115
Out << '_';
11171116
for (; i != e && i->get()->getKind() == Node::Kind::ImplParameter; ++i) {
@@ -1294,19 +1293,8 @@ void Remangler::mangleDependentGenericType(Node *node) {
12941293
mangleChildNodes(node); // generic signature, type
12951294
}
12961295

1297-
void Remangler::mangleGenericType(Node *node) {
1298-
EntityContext ctx(*this);
1299-
mangleEntityGenericType(node, ctx);
1300-
}
1301-
1302-
void Remangler::mangleEntityGenericType(Node *node, EntityContext &ctx) {
1303-
assert(node->getKind() == Node::Kind::GenericType);
1304-
1305-
Out << 'U';
1306-
assert(node->getNumChildren() == 2);
1307-
1308-
mangleGenerics(node->begin()[0].get(), ctx);
1309-
mangleEntityType(node->begin()[1].get(), ctx);
1296+
void Remangler::mangleDependentPseudogenericSignature(Node *node) {
1297+
mangleDependentGenericSignature(node);
13101298
}
13111299

13121300
void Remangler::mangleDependentGenericSignature(Node *node) {
@@ -1378,31 +1366,6 @@ void Remangler::mangleConstrainedType(Node *node) {
13781366
}
13791367
}
13801368

1381-
void Remangler::mangleGenerics(Node *node) {
1382-
unreachable("found independent generics node?");
1383-
}
1384-
1385-
void Remangler::mangleGenerics(Node *node, EntityContext &ctx) {
1386-
assert(node->getKind() == Node::Kind::Generics);
1387-
1388-
unsigned absoluteDepth = ++AbsoluteArchetypeDepth;
1389-
1390-
auto i = node->begin(), e = node->end();
1391-
unsigned index = 0;
1392-
for (; i != e && i->get()->getKind() == Node::Kind::Archetype; ++i) {
1393-
auto child = i->get();
1394-
Archetypes[child->getText()] = ArchetypeInfo{index++, absoluteDepth};
1395-
mangle(child); // archetype
1396-
}
1397-
if (i != e) {
1398-
Out << 'U';
1399-
mangleNodes(i, e); // associated types
1400-
Out << '_';
1401-
} else {
1402-
Out << '_';
1403-
}
1404-
}
1405-
14061369
void Remangler::mangleArchetype(Node *node) {
14071370
if (node->hasChildren()) {
14081371
assert(node->getNumChildren() == 1);

0 commit comments

Comments
 (0)