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

@@ -232,6 +232,28 @@ void SILGenFunction::emitCaptures(SILLocation loc,
canGuarantee = false;
for (auto capture : captureInfo.getCaptures()) {
if (capture.isDynamicSelfMetadata()) {
// The parameter type is the static Self type, but the value we
// want to pass is the dynamic Self type, so upcast it.
auto dynamicSelfMetatype = MetatypeType::get(
captureInfo.getDynamicSelfType(),
MetatypeRepresentation::Thick)
->getCanonicalType();
auto staticSelfMetatype = MetatypeType::get(
captureInfo.getDynamicSelfType()->getSelfType(),
MetatypeRepresentation::Thick)
->getCanonicalType();
SILType dynamicSILType = SILType::getPrimitiveObjectType(
dynamicSelfMetatype);
SILType staticSILType = SILType::getPrimitiveObjectType(
staticSelfMetatype);
SILValue value = B.createMetatype(loc, dynamicSILType);
value = B.createUpcast(loc, value, staticSILType);
capturedArgs.push_back(ManagedValue::forUnmanaged(value));
continue;
}
auto *vd = capture.getDecl();
switch (SGM.Types.getDeclCaptureKind(capture)) {