Skip to content

Commit f56a941

Browse files
authored
Eagerly create init(from:) when looking up 'init' on a Decodable type (#17732)
Otherwise, the initializer won't be inherited properly onto a subclass, resulting in the base class being allocated instead of the subclass when using Sub.init(from:). https://bugs.swift.org/browse/SR-8083 (cherry picked from commit 9ee996c)
1 parent a8f4675 commit f56a941

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9032,6 +9032,9 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
90329032
//
90339033
// Returns whether the target conforms to the protocol.
90349034
auto evaluateTargetConformanceTo = [&](ProtocolDecl *protocol) {
9035+
if (!protocol)
9036+
return false;
9037+
90359038
auto targetType = target->getDeclaredInterfaceType();
90369039
if (auto ref = conformsToProtocol(
90379040
targetType, protocol, target,
@@ -9069,12 +9072,11 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
90699072
}
90709073
} else {
90719074
auto argumentNames = member.getArgumentNames();
9072-
if (argumentNames.size() != 1)
9075+
if (member.isCompoundName() && argumentNames.size() != 1)
90739076
return;
90749077

9075-
auto argumentName = argumentNames.front();
90769078
if (baseName == DeclBaseName::createConstructor() &&
9077-
argumentName == Context.Id_from) {
9079+
(member.isSimpleName() || argumentNames.front() == Context.Id_from)) {
90789080
// init(from:) may be synthesized as part of derived conformance to the
90799081
// Decodable protocol.
90809082
// If the target should conform to the Decodable protocol, check the
@@ -9083,7 +9085,8 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
90839085
(void)evaluateTargetConformanceTo(decodableProto);
90849086
} else if (!baseName.isSpecial() &&
90859087
baseName.getIdentifier() == Context.Id_encode &&
9086-
argumentName == Context.Id_to) {
9088+
(member.isSimpleName() ||
9089+
argumentNames.front() == Context.Id_to)) {
90879090
// encode(to:) may be synthesized as part of derived conformance to the
90889091
// Encodable protocol.
90899092
// If the target should conform to the Encodable protocol, check the
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
2+
3+
class SR8083_Base: Codable {
4+
var thing: String { return "Abstract" }
5+
}
6+
7+
class SR8083_Sub: SR8083_Base {
8+
override var thing: String { return "Yo" }
9+
}
10+
11+
func sr8083(decoder: Decoder) throws {
12+
_ = try SR8083_Sub(from: decoder)
13+
}
14+
15+
// CHECK-LABEL: sil_vtable SR8083_Base {
16+
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseCACycfc // SR8083_Base.init()
17+
// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfC
18+
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfc // SR8083_Base.init(from:)
19+
// CHECK: {{^}$}}
20+
21+
// CHECK-LABEL: sil_vtable SR8083_Sub {
22+
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubCACycfc [override] // SR8083_Sub.init()
23+
// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfC [override] // SR8083_Sub.__allocating_init(from:)
24+
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfc [override] // SR8083_Sub.init(from:)
25+
// CHECK: {{^}$}}

0 commit comments

Comments
 (0)