Skip to content

Commit 5c9c059

Browse files
authored
Merge pull request #64679 from slavapestov/varidic-generic-captures
IRGen support for closures that capture metadata and witness table packs
2 parents 8453978 + 8a6bb30 commit 5c9c059

20 files changed

+495
-350
lines changed

include/swift/IRGen/GenericRequirement.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ class GenericRequirement {
7676
}
7777

7878
static GenericRequirement forShape(CanType type) {
79-
assert(!isa<PackType>(type));
8079
assert(type->isParameterPack() || isa<PackArchetypeType>(type));
8180
return GenericRequirement(Kind::Shape, type, nullptr);
8281
}
@@ -92,7 +91,6 @@ class GenericRequirement {
9291
}
9392

9493
static GenericRequirement forMetadata(CanType type) {
95-
assert(!isa<PackType>(type));
9694
auto kind = ((type->isParameterPack() ||
9795
isa<PackArchetypeType>(type))
9896
? Kind::MetadataPack : Kind::Metadata);
@@ -110,7 +108,6 @@ class GenericRequirement {
110108
}
111109

112110
static GenericRequirement forWitnessTable(CanType type, ProtocolDecl *proto) {
113-
assert(!isa<PackType>(type));
114111
auto kind = ((type->isParameterPack() ||
115112
isa<PackArchetypeType>(type))
116113
? Kind::WitnessTablePack

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,28 @@ FUNCTION(CompareProtocolConformanceDescriptors,
10081008
ATTRS(NoUnwind, ReadNone, WillReturn),
10091009
EFFECT(NoEffect)) // ?
10101010

1011+
// SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
1012+
// const Metadata * const *
1013+
// swift_allocateMetadataPack(const Metadata * const *ptr, size_t count);
1014+
FUNCTION(AllocateMetadataPack,
1015+
swift_allocateMetadataPack, SwiftCC,
1016+
AlwaysAvailable, // FIXME
1017+
RETURNS(TypeMetadataPtrPtrTy),
1018+
ARGS(TypeMetadataPtrPtrTy, SizeTy),
1019+
ATTRS(NoUnwind, WillReturn),
1020+
EFFECT(MetaData)) // ?
1021+
1022+
// SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
1023+
// const WitnessTable * const *
1024+
// swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count);
1025+
FUNCTION(AllocateWitnessTablePack,
1026+
swift_allocateWitnessTablePack, SwiftCC,
1027+
AlwaysAvailable, // FIXME
1028+
RETURNS(WitnessTablePtrPtrTy),
1029+
ARGS(WitnessTablePtrPtrTy, SizeTy),
1030+
ATTRS(NoUnwind, WillReturn),
1031+
EFFECT(MetaData)) // ?
1032+
10111033
// Metadata *swift_getMetatypeMetadata(Metadata *instanceTy);
10121034
FUNCTION(GetMetatypeMetadata, swift_getMetatypeMetadata, C_CC, AlwaysAvailable,
10131035
RETURNS(TypeMetadataPtrTy),

lib/IRGen/GenArchetype.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -440,17 +440,10 @@ withOpaqueTypeGenericArgs(IRGenFunction &IGF,
440440
enumerateGenericSignatureRequirements(
441441
opaqueDecl->getGenericSignature().getCanonicalSignature(),
442442
[&](GenericRequirement reqt) {
443-
auto ty = reqt.getTypeParameter().subst(archetype->getSubstitutions())
444-
->getReducedType(opaqueDecl->getGenericSignature());
445-
if (reqt.isAnyWitnessTable()) {
446-
auto ref =
447-
ProtocolConformanceRef(reqt.getProtocol())
448-
.subst(reqt.getTypeParameter(), archetype->getSubstitutions());
449-
args.push_back(emitWitnessTableRef(IGF, ty, ref));
450-
} else {
451-
assert(reqt.isAnyMetadata());
452-
args.push_back(IGF.emitAbstractTypeMetadataRef(ty));
453-
}
443+
auto arg = emitGenericRequirementFromSubstitutions(
444+
IGF, reqt, MetadataState::Abstract,
445+
archetype->getSubstitutions());
446+
args.push_back(arg);
454447
types.push_back(args.back()->getType());
455448
});
456449
auto bufTy = llvm::StructType::get(IGF.IGM.getLLVMContext(), types);

lib/IRGen/GenFunc.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,8 @@ Optional<StackAddress> irgen::emitFunctionPartialApplication(
19491949

19501950
// Reserve space for polymorphic bindings.
19511951
auto bindings = NecessaryBindings::forPartialApplyForwarder(
1952-
IGF.IGM, origType, subs, considerParameterSources);
1952+
IGF.IGM, origType, subs, outType->isNoEscape(),
1953+
considerParameterSources);
19531954

19541955
if (!bindings.empty()) {
19551956
hasSingleSwiftRefcountedContext = No;

lib/IRGen/GenKeyPath.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,11 @@ bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF,
8989
args =
9090
IGF.Builder.CreateInBoundsGEP(IGF.IGM.Int8Ty, args, genericArgsOffset);
9191
}
92+
9293
bindFromGenericRequirementsBuffer(
9394
IGF, requirements,
9495
Address(args, IGF.IGM.Int8Ty, IGF.IGM.getPointerAlignment()),
95-
MetadataState::Complete, [&](CanType t) {
96-
return genericEnv->mapTypeIntoContext(t)->getCanonicalType();
97-
});
96+
MetadataState::Complete, genericEnv->getForwardingSubstitutionMap());
9897
}
9998

10099
static llvm::Function *
@@ -295,9 +294,7 @@ getLayoutFunctionForComputedComponent(IRGenModule &IGM,
295294
bindFromGenericRequirementsBuffer(
296295
IGF, requirements,
297296
Address(args, IGM.Int8Ty, IGF.IGM.getPointerAlignment()),
298-
MetadataState::Complete, [&](CanType t) {
299-
return genericEnv->mapTypeIntoContext(t)->getCanonicalType();
300-
});
297+
MetadataState::Complete, genericEnv->getForwardingSubstitutionMap());
301298
}
302299

303300
// Run through the captured index types to determine the size and alignment
@@ -583,9 +580,7 @@ getInitializerForComputedComponent(IRGenModule &IGM,
583580
bindFromGenericRequirementsBuffer(
584581
IGF, requirements,
585582
Address(src, IGM.Int8Ty, IGF.IGM.getPointerAlignment()),
586-
MetadataState::Complete, [&](CanType t) {
587-
return genericEnv->mapTypeIntoContext(t)->getCanonicalType();
588-
});
583+
MetadataState::Complete, genericEnv->getForwardingSubstitutionMap());
589584

590585
} else {
591586
offset = llvm::ConstantInt::get(IGM.SizeTy, 0);

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,11 +2318,10 @@ namespace {
23182318
bindFromGenericRequirementsBuffer(
23192319
IGF, requirements,
23202320
Address(bindingsBufPtr, IGM.Int8Ty, IGM.getPointerAlignment()),
2321-
MetadataState::Complete, [&](CanType t) {
2322-
return genericEnv ? genericEnv->mapTypeIntoContext(t)
2323-
->getCanonicalType()
2324-
: t;
2325-
});
2321+
MetadataState::Complete,
2322+
(genericEnv
2323+
? genericEnv->getForwardingSubstitutionMap()
2324+
: SubstitutionMap()));
23262325
}
23272326

23282327
SmallVector<llvm::BasicBlock *, 4> conditionalTypes;

0 commit comments

Comments
 (0)