@@ -4166,23 +4166,31 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
41664166 auto ctorDecl = cast<ConstructorDecl>(selfDecl->getDeclContext ());
41674167 auto selfIfaceTy = ctorDecl->getDeclContext ()->getSelfInterfaceType ();
41684168 auto selfTy = ctorDecl->mapTypeIntoContext (selfIfaceTy);
4169-
4170- auto newSelfTy = E->getSubExpr ()->getType ();
4171- bool outerIsOptional = false ;
4172- bool innerIsOptional = false ;
4173- auto objTy = newSelfTy->getOptionalObjectType ();
4174- if (objTy) {
4175- outerIsOptional = true ;
4176- newSelfTy = objTy;
4177-
4178- // "try? self.init()" can give us two levels of optional if the initializer
4179- // we delegate to is failable.
4180- objTy = newSelfTy->getOptionalObjectType ();
4181- if (objTy) {
4182- innerIsOptional = true ;
4183- newSelfTy = objTy;
4169+
4170+ bool isChaining; // Ignored
4171+ auto *otherCtor = E->getCalledConstructor (isChaining)->getDecl ();
4172+ assert (otherCtor);
4173+
4174+ auto getOptionalityDepth = [](Type ty) {
4175+ unsigned level = 0 ;
4176+ Type objTy = ty->getOptionalObjectType ();
4177+ while (objTy) {
4178+ ++level;
4179+ objTy = objTy->getOptionalObjectType ();
41844180 }
4185- }
4181+
4182+ return level;
4183+ };
4184+
4185+ // The optionality depth of the 'new self' value. This can be '2' if the ctor
4186+ // we are delegating/chaining to is both throwing and failable, or more if
4187+ // 'self' is optional.
4188+ auto srcOptionalityDepth = getOptionalityDepth (E->getSubExpr ()->getType ());
4189+
4190+ // The optionality depth of the result type of the enclosing initializer in
4191+ // this context.
4192+ const auto destOptionalityDepth = getOptionalityDepth (
4193+ ctorDecl->mapTypeIntoContext (ctorDecl->getResultInterfaceType ()));
41864194
41874195 // The subexpression consumes the current 'self' binding.
41884196 assert (SGF.SelfInitDelegationState == SILGenFunction::NormalSelf
@@ -4199,13 +4207,25 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
41994207 SGF.emitAddressOfLocalVarDecl (E, selfDecl, selfTy->getCanonicalType (),
42004208 SGFAccessKind::Write).getLValueAddress ();
42014209
4202- // Handle a nested optional case (see above).
4203- if (innerIsOptional)
4210+ // Flatten a nested optional if 'new self' is a deeper optional than we
4211+ // can return.
4212+ if (srcOptionalityDepth > destOptionalityDepth) {
4213+ assert (destOptionalityDepth > 0 );
4214+ assert (otherCtor->isFailable () && otherCtor->hasThrows ());
4215+
4216+ --srcOptionalityDepth;
42044217 newSelf = flattenOptional (SGF, E, newSelf);
42054218
4206- // If both the delegated-to initializer and our enclosing initializer can
4207- // fail, deal with the failure.
4208- if (outerIsOptional && ctorDecl->isFailable ()) {
4219+ assert (srcOptionalityDepth == destOptionalityDepth &&
4220+ " Flattening a single level was not enough?" );
4221+ }
4222+
4223+ // If the enclosing ctor is failable and the optionality depths match, switch
4224+ // on 'new self' to either return 'nil' or continue with the projected value.
4225+ if (srcOptionalityDepth == destOptionalityDepth && ctorDecl->isFailable ()) {
4226+ assert (destOptionalityDepth > 0 );
4227+ assert (otherCtor->isFailable () || otherCtor->hasThrows ());
4228+
42094229 SILBasicBlock *someBB = SGF.createBasicBlock ();
42104230
42114231 auto hasValue = SGF.emitDoesOptionalHaveValue (E, newSelf.getValue ());
@@ -4224,7 +4244,7 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
42244244 SGF.getTypeLowering (newSelf.getType ()),
42254245 SGFContext ());
42264246 }
4227-
4247+
42284248 // If we called a constructor that requires a downcast, perform the downcast.
42294249 auto destTy = SGF.getLoweredType (selfTy);
42304250 if (newSelf.getType () != destTy) {
0 commit comments