Skip to content

Commit 853913d

Browse files
committed
SILGen: Strip off DynamicSelfType when tranforming values
We lower away a top-level DynamicSelfType, so let's just strip them off before trying the other conversions. For now this is NFC, but we can end up here after the next patch. Even then we shouldn't end up here except when emitting protocol witnesses. The relevant case is when a base class method (return @dynamic_self Base) is used by a derived class to witness a requirement on a protocol (which returns @dynamic_self Derived since its a derived class conformance). In this case, we know both values have the same type, but the lowered types are $Base and $Derived, respectively, so we must emit an unchecked downcast.
1 parent 61c114c commit 853913d

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

lib/SILGen/SILGenPoly.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,15 @@ ManagedValue Transform::transform(ManagedValue v,
466466

467467
// Subtype conversions:
468468

469+
// A base class method returning Self can be used in place of a derived
470+
// class method returning Self.
471+
if (auto outputSelfType = dyn_cast<DynamicSelfType>(outputSubstType)) {
472+
if (auto inputSelfType = dyn_cast<DynamicSelfType>(inputSubstType)) {
473+
inputSubstType = inputSelfType.getSelfType();
474+
outputSubstType = outputSelfType.getSelfType();
475+
}
476+
}
477+
469478
// - upcasts for classes
470479
if (outputSubstType->getClassOrBoundGenericClass() &&
471480
inputSubstType->getClassOrBoundGenericClass()) {
@@ -482,7 +491,9 @@ ManagedValue Transform::transform(ManagedValue v,
482491
// Upcast to a superclass.
483492
return SGF.B.createUpcast(Loc, v, loweredResultTy);
484493
} else {
485-
// Unchecked-downcast to a covariant return type.
494+
// FIXME: Should only happen with the DynamicSelfType case above,
495+
// except that convenience inits return the static self and not
496+
// DynamicSelfType.
486497
assert(inputSubstType->isExactSuperclassOf(outputSubstType)
487498
&& "should be inheritance relationship between input and output");
488499
return SGF.B.createUncheckedRefCast(Loc, v, loweredResultTy);

0 commit comments

Comments
 (0)