SILGen: Fix some problems when generating delegating init calls

- If delegating to an initializing constructor for a value type,
  the ApplyInst takes an @out parameter for Self, instead of
  returning Self like with references. Fix the def-use traversal
  to handle that instead of crashing.

- When calling an allocating constructor, the formal type is
  the instance type because Sema constructs the constructor call
  as if it were an initializing constructor. This causes us to
  fail to re-abstract a @thin metatype to @thick. Fix this to
  use the correct metatype type for allocating constructors.

Fixes <rdar://problem/20945954>.

Swift SVN r29555
This commit is contained in:
Slava Pestov
2015-06-22 22:26:17 +00:00
parent 886bc277b2
commit a64d505a98
3 changed files with 46 additions and 3 deletions

View File

@@ -1393,10 +1393,14 @@ public:
// Load the 'self' argument.
Expr *arg = expr->getArg();
ManagedValue self;
CanType selfFormalType = arg->getType()->getCanonicalType();
// If we're using the allocating constructor, we need to pass along the
// metatype.
if (useAllocatingCtor) {
selfFormalType = CanMetatypeType::get(
selfFormalType->getInOutObjectType()->getCanonicalType());
if (SGF.AllocatorMetatype)
self = ManagedValue::forUnmanaged(SGF.AllocatorMetatype);
else
@@ -1417,7 +1421,6 @@ public:
}
}
CanType selfFormalType = arg->getType()->getCanonicalType();
setSelfParam(ArgumentSource(arg, RValue(SGF, expr, selfFormalType, self)),
expr);
@@ -1427,8 +1430,7 @@ public:
// that's the only thing that's witnessed. For classes,
// this is the initializing constructor, to which we will dynamically
// dispatch.
if (isa<ArchetypeType>(
SelfParam.getSubstRValueType().getLValueOrInOutObjectType())
if (SelfParam.getSubstRValueType()->getRValueInstanceType()->is<ArchetypeType>()
&& isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
// Look up the witness for the constructor.
auto constant = SILDeclRef(ctorRef->getDecl(),