Skip to content

Commit 6246e7e

Browse files
committed
[Constraint solver] Fix effective-overload-type for constructors, dynamic Self
Implement support for querying the effective overload type for constructors and fix a semi-related bug for methods returning dynamic Self, which I had not accounted for.
1 parent 603d5d6 commit 6246e7e

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1537,12 +1537,27 @@ Type ConstraintSystem::getEffectiveOverloadType(const OverloadChoice &overload,
15371537
type = var->getValueInterfaceType();
15381538
if (doesStorageProduceLValue(var, overload.getBaseType(), useDC))
15391539
type = LValueType::get(type);
1540-
} else if (isa<FuncDecl>(decl) || isa<EnumElementDecl>(decl)) {
1540+
} else if (isa<AbstractFunctionDecl>(decl) || isa<EnumElementDecl>(decl)) {
15411541
if (decl->isInstanceMember() &&
15421542
(!overload.getBaseType() ||
15431543
!overload.getBaseType()->getAnyNominal()))
15441544
return Type();
15451545

1546+
// Cope with 'Self' returns.
1547+
if (!decl->getDeclContext()->getSelfProtocolDecl()) {
1548+
if ((isa<FuncDecl>(decl) && cast<FuncDecl>(decl)->hasDynamicSelf()) ||
1549+
(isa<ConstructorDecl>(decl) &&
1550+
!overload.getBaseType()->getOptionalObjectType())) {
1551+
if (!overload.getBaseType())
1552+
return Type();
1553+
1554+
Type selfType = overload.getBaseType()->getRValueType()
1555+
->getMetatypeInstanceType()
1556+
->lookThroughAllOptionalTypes();
1557+
type = type->replaceCovariantResultType(selfType, 2);
1558+
}
1559+
}
1560+
15461561
type = type->castTo<FunctionType>()->getResult();
15471562
} else {
15481563
return type;

test/Constraints/common_type.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,35 @@ func testCommonTypeIUO() {
4848
// CHECK-NOT: common result type
4949
_ = f(0).iuo(0)
5050
}
51+
52+
struct Z {
53+
init(a: Int) { }
54+
init(a: Double) { }
55+
56+
init(b: Int) { }
57+
init?(b: Double) { }
58+
}
59+
60+
func testCommonTypeInit() {
61+
// CHECK: common result type for {{.*}} is Z
62+
_ = Z(a: 0)
63+
64+
// CHECK-NOT: common result type
65+
_ = Z(b: 0)
66+
}
67+
68+
class DynamicSelf {
69+
func foo(_ a: Int) -> Self { return self }
70+
func foo(_ a: Double) -> Self { return self }
71+
}
72+
73+
class InheritsDynamicSelf: DynamicSelf {
74+
}
75+
76+
func testCommonTypeDynamicSelf(ds: DynamicSelf, ids: InheritsDynamicSelf) {
77+
// CHECK: common result type for {{.*}} is DynamicSelf
78+
_ = ds.foo(0)
79+
// CHECK: common result type for {{.*}} is InheritsDynamicSelf
80+
_ = ids.foo(0)
81+
}
82+

0 commit comments

Comments
 (0)