@@ -4166,23 +4166,31 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
4166
4166
auto ctorDecl = cast<ConstructorDecl>(selfDecl->getDeclContext ());
4167
4167
auto selfIfaceTy = ctorDecl->getDeclContext ()->getSelfInterfaceType ();
4168
4168
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 ();
4184
4180
}
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 ()));
4186
4194
4187
4195
// The subexpression consumes the current 'self' binding.
4188
4196
assert (SGF.SelfInitDelegationState == SILGenFunction::NormalSelf
@@ -4199,13 +4207,25 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
4199
4207
SGF.emitAddressOfLocalVarDecl (E, selfDecl, selfTy->getCanonicalType (),
4200
4208
SGFAccessKind::Write).getLValueAddress ();
4201
4209
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;
4204
4217
newSelf = flattenOptional (SGF, E, newSelf);
4205
4218
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
+
4209
4229
SILBasicBlock *someBB = SGF.createBasicBlock ();
4210
4230
4211
4231
auto hasValue = SGF.emitDoesOptionalHaveValue (E, newSelf.getValue ());
@@ -4224,7 +4244,7 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
4224
4244
SGF.getTypeLowering (newSelf.getType ()),
4225
4245
SGFContext ());
4226
4246
}
4227
-
4247
+
4228
4248
// If we called a constructor that requires a downcast, perform the downcast.
4229
4249
auto destTy = SGF.getLoweredType (selfTy);
4230
4250
if (newSelf.getType () != destTy) {
0 commit comments