SIL: Add support for capturing the dynamic Self metatype

If a closure captures the dynamic 'Self' type, but no value of type 'Self'
(for example, it is possible to have a weak capture of 'self'; if the weak
reference becomes nil, there's no way for the closure to get the dynamic
'Self' type from the value).

In this case, add a hidden argument of type $Self.Type, and pass in the
Self metatype.

Fixes <https://bugs.swift.org/browse/SR-1558> / <rdar://problem/22299905>.
This commit is contained in:
Slava Pestov
2016-06-27 15:29:55 -07:00
parent b246d09470
commit 2a59ad7d05
8 changed files with 211 additions and 12 deletions

View File

@@ -357,6 +357,7 @@ void SILGenFunction::bindParametersForForwarding(const ParameterList *params,
static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture,
unsigned ArgNo) {
auto *VD = capture.getDecl();
auto type = VD->getType();
SILLocation Loc(VD);
@@ -428,8 +429,21 @@ void SILGenFunction::emitProlog(AnyFunctionRef TheClosure,
// Emit the capture argument variables. These are placed last because they
// become the first curry level of the SIL function.
auto captureInfo = SGM.Types.getLoweredLocalCaptures(TheClosure);
for (auto capture : captureInfo.getCaptures())
for (auto capture : captureInfo.getCaptures()) {
if (capture.isDynamicSelfMetadata()) {
auto selfMetatype = MetatypeType::get(
captureInfo.getDynamicSelfType()->getSelfType(),
MetatypeRepresentation::Thick)
->getCanonicalType();
SILType ty = SILType::getPrimitiveObjectType(selfMetatype);
SILValue val = new (SGM.M) SILArgument(F.begin(), ty);
(void) val;
return;
}
emitCaptureArguments(*this, capture, ++ArgNo);
}
}
static void emitIndirectResultParameters(SILGenFunction &gen, Type resultType,