Skip to content

Commit a18c32a

Browse files
committed
Sema: Build type checked bodies for designated init overrides
Similarly to trivial accessors, the body of a synthesized designated initializer override is simple enough that we can build it directly without involving the constraint solver.
1 parent 0bab515 commit a18c32a

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,32 +2603,60 @@ static void synthesizeDesignatedInitOverride(AbstractFunctionDecl *fn,
26032603
auto *ctor = cast<ConstructorDecl>(fn);
26042604
auto &ctx = ctor->getASTContext();
26052605

2606-
auto *bodyParams = ctor->getParameters();
26072606
auto *superclassCtor = (ConstructorDecl *) context;
26082607

2608+
if (!superclassCtor->hasValidSignature())
2609+
ctx.getLazyResolver()->resolveDeclSignature(superclassCtor);
2610+
26092611
// Reference to super.init.
26102612
auto *selfDecl = ctor->getImplicitSelfDecl();
2611-
Expr *superRef = new (ctx) SuperRefExpr(selfDecl, SourceLoc(),
2612-
/*Implicit=*/true);
2613-
Expr *ctorRef = new (ctx) UnresolvedDotExpr(superRef, SourceLoc(),
2614-
superclassCtor->getFullName(),
2615-
DeclNameLoc(),
2616-
/*Implicit=*/true);
2613+
auto *superRef = buildSelfReference(selfDecl, SelfAccessorKind::Super,
2614+
/*isLValue=*/false, ctx, true);
26172615

2618-
auto ctorArgs = buildArgumentForwardingExpr(bodyParams->getArray(), ctx, false);
2616+
SubstitutionMap subs;
2617+
if (auto *genericEnv = fn->getGenericEnvironment())
2618+
subs = genericEnv->getForwardingSubstitutionMap();
2619+
subs = SubstitutionMap::getOverrideSubstitutions(superclassCtor, fn, subs);
2620+
ConcreteDeclRef ctorRef(superclassCtor, subs);
26192621

2620-
Expr *superCall =
2621-
CallExpr::create(ctx, ctorRef, ctorArgs,
2622+
auto type = superclassCtor->getInitializerInterfaceType()
2623+
.subst(subs, SubstFlags::UseErrorType);
2624+
auto *ctorRefExpr =
2625+
new (ctx) OtherConstructorDeclRefExpr(ctorRef, DeclNameLoc(),
2626+
IsImplicit, type);
2627+
2628+
if (auto *funcTy = type->getAs<FunctionType>())
2629+
type = funcTy->getResult();
2630+
auto *superclassCtorRefExpr =
2631+
new (ctx) DotSyntaxCallExpr(ctorRefExpr, SourceLoc(), superRef, type);
2632+
superclassCtorRefExpr->setIsSuper(true);
2633+
2634+
auto *bodyParams = ctor->getParameters();
2635+
auto ctorArgs = buildArgumentForwardingExpr(bodyParams->getArray(), ctx, true);
2636+
Expr *superclassCallExpr =
2637+
CallExpr::create(ctx, superclassCtorRefExpr, ctorArgs,
26222638
superclassCtor->getFullName().getArgumentNames(), { },
26232639
/*hasTrailingClosure=*/false, /*implicit=*/true);
2640+
2641+
if (auto *funcTy = type->getAs<FunctionType>())
2642+
type = funcTy->getResult();
2643+
superclassCallExpr->setType(type);
2644+
26242645
if (superclassCtor->hasThrows()) {
2625-
superCall = new (ctx) TryExpr(SourceLoc(), superCall, Type(),
2626-
/*implicit=*/true);
2646+
superclassCallExpr = new (ctx) TryExpr(SourceLoc(), superclassCallExpr,
2647+
type, /*implicit=*/true);
26272648
}
2628-
ctor->setBody(BraceStmt::create(ctx, SourceLoc(),
2629-
ASTNode(superCall),
2630-
SourceLoc(),
2649+
2650+
auto *rebindSelfExpr =
2651+
new (ctx) RebindSelfInConstructorExpr(superclassCallExpr,
2652+
selfDecl);
2653+
2654+
SmallVector<ASTNode, 2> stmts;
2655+
stmts.push_back(rebindSelfExpr);
2656+
stmts.push_back(new (ctx) ReturnStmt(SourceLoc(), /*Result=*/nullptr));
2657+
ctor->setBody(BraceStmt::create(ctx, SourceLoc(), stmts, SourceLoc(),
26312658
/*implicit=*/true));
2659+
ctor->setBodyTypeCheckedIfPresent();
26322660
}
26332661

26342662
ConstructorDecl *
@@ -2678,7 +2706,7 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
26782706
// like 'class A : B<Int>'.
26792707
for (auto *decl : *bodyParams) {
26802708
auto paramTy = decl->getInterfaceType();
2681-
auto substTy = paramTy.subst(subMap);
2709+
auto substTy = paramTy.subst(subMap, SubstFlags::UseErrorType);
26822710
decl->setInterfaceType(substTy);
26832711
}
26842712

0 commit comments

Comments
 (0)