Skip to content

Commit a5329bd

Browse files
committed
CSApply: Make buildOtherConstructorRef work for Optional initializers
Using `replaceCovariantResultType`, which looks through optionals, to substitute the container type for the result type would add an extra level of optionality to the result type whenever the container type was `Optional`, causing a crash later in the game. Besides, we don't have to do this in the first place, because we know these types match in the case of an initializer (neglecting optionality).
1 parent 649889f commit a5329bd

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,23 +2175,18 @@ namespace {
21752175

21762176
// The constructor was opened with the allocating type, not the
21772177
// initializer type. Map the former into the latter.
2178-
auto resultTy = solution.simplifyType(openedFullType);
2178+
auto *resultTy =
2179+
solution.simplifyType(openedFullType)->castTo<FunctionType>();
21792180

2180-
auto selfTy = getBaseType(resultTy->castTo<FunctionType>());
2181-
2182-
// Also replace the result type with the base type, so that calls
2183-
// to constructors defined in a superclass will know to cast the
2184-
// result to the derived type.
2185-
resultTy = resultTy->replaceCovariantResultType(selfTy, 2);
2181+
const auto selfTy = getBaseType(resultTy);
21862182

21872183
ParameterTypeFlags flags;
21882184
if (!selfTy->hasReferenceSemantics())
21892185
flags = flags.withInOut(true);
21902186

21912187
auto selfParam = AnyFunctionType::Param(selfTy, Identifier(), flags);
2192-
resultTy = FunctionType::get({selfParam},
2193-
resultTy->castTo<FunctionType>()->getResult(),
2194-
resultTy->castTo<FunctionType>()->getExtInfo());
2188+
resultTy = FunctionType::get({selfParam}, resultTy->getResult(),
2189+
resultTy->getExtInfo());
21952190

21962191
// Build the constructor reference.
21972192
Expr *ctorRef = cs.cacheType(
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
3+
extension Optional {
4+
init(nonFailable1: ()) {
5+
self = .none
6+
}
7+
8+
// CHECK-LABEL: sil hidden [ossa] @$sSq24init_delegation_optionalE12nonFailable2xSgyt_tcfC
9+
init(nonFailable2: ()) {
10+
// CHECK: bb0([[OUT:%[0-9]+]] : $*Optional<Wrapped>, [[SELF_META:%[0-9]+]] : $@thin Optional<Wrapped>.Type):
11+
// CHECK-NEXT: [[SELF_BOX:%[0-9]+]] = alloc_box $<τ_0_0> { var Optional<τ_0_0> } <Wrapped>, var
12+
// CHECK-NEXT: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
13+
// CHECK-NEXT: [[SELF_LIFETIME:%[0-9]+]] = begin_borrow [lexical] [[MARKED_SELF_BOX]]
14+
// CHECK-NEXT: [[PB:%[0-9]+]] = project_box [[SELF_LIFETIME]]
15+
// CHECK: [[RESULT_ADDR:%[0-9]+]] = alloc_stack $Optional<Wrapped>
16+
// CHECK: [[DELEG_INIT:%[0-9]+]] = function_ref @$sSq24init_delegation_optionalE12nonFailable1xSgyt_tcfC
17+
// CHECK-NEXT: apply [[DELEG_INIT]]<Wrapped>([[RESULT_ADDR]], [[SELF_META]])
18+
self.init(nonFailable1: ())
19+
// CHECK-NEXT: copy_addr [take] [[RESULT_ADDR]] to [[PB]]
20+
// CHECK-NEXT: dealloc_stack [[RESULT_ADDR]]
21+
// CHECK-NEXT: copy_addr [[PB]] to [initialization] [[OUT]]
22+
// CHECK-NEXT: end_borrow [[SELF_LIFETIME]]
23+
// CHECK-NEXT: destroy_value [[MARKED_SELF_BOX]]
24+
// CHECK-NEXT: [[RET:%[0-9]+]] = tuple ()
25+
// CHECK-NEXT: return [[RET]] : $()
26+
// CHECK-NEXT: }
27+
}
28+
}

0 commit comments

Comments
 (0)