Skip to content

Commit a9f9f15

Browse files
authored
Merge pull request swiftlang#23787 from sl/slazarus/allow-access-through-existential-metatype
Sema: Fixed a crash when accessing a concrete associated type through an existential metatype
2 parents 1e41b13 + ebdb3cf commit a9f9f15

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

lib/AST/ASTVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1819,7 +1819,7 @@ class Verifier : public ASTWalker {
18191819

18201820
// The base of a member reference cannot be an existential type.
18211821
if (E->getBase()->getType()->getWithoutSpecifierType()
1822-
->isAnyExistentialType()) {
1822+
->isExistentialType()) {
18231823
Out << "Member reference into an unopened existential type\n";
18241824
E->dump(Out);
18251825
Out << "\n";

lib/Sema/CSApply.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -811,8 +811,10 @@ namespace {
811811
// Figure out the actual base type, and whether we have an instance of
812812
// that type or its metatype.
813813
bool baseIsInstance = true;
814+
bool isExistentialMetatype = false;
814815
if (auto baseMeta = baseTy->getAs<AnyMetatypeType>()) {
815816
baseIsInstance = false;
817+
isExistentialMetatype = baseMeta->is<ExistentialMetatypeType>();
816818
baseTy = baseMeta->getInstanceType();
817819
}
818820

@@ -900,11 +902,15 @@ namespace {
900902
base, selfParamTy, member, semantics,
901903
locator.withPathElement(ConstraintLocator::MemberRefBase));
902904
} else {
903-
// Convert the base to an rvalue of the appropriate metatype.
904-
base = coerceToType(base,
905-
MetatypeType::get(isDynamic ? selfTy : containerTy),
906-
locator.withPathElement(
907-
ConstraintLocator::MemberRefBase));
905+
if (!isExistentialMetatype || openedExistential) {
906+
// Convert the base to an rvalue of the appropriate metatype.
907+
base = coerceToType(base,
908+
MetatypeType::get(
909+
isDynamic ? selfTy : containerTy),
910+
locator.withPathElement(
911+
ConstraintLocator::MemberRefBase));
912+
}
913+
908914
if (!base)
909915
return nullptr;
910916

test/Constraints/protocols.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ protocol P : Initable {
107107
func bar(_ x: Int)
108108
mutating func mut(_ x: Int)
109109
static func tum()
110+
111+
typealias E = Int
112+
typealias F = Self.E
110113
}
111114

112115
protocol ClassP : class {
@@ -216,6 +219,13 @@ func staticExistential(_ p: P.Type, pp: P.Protocol) {
216219
// Static member of metatype -- not allowed
217220
_ = pp.tum // expected-error{{static member 'tum' cannot be used on protocol metatype 'P.Protocol'}}
218221
_ = P.tum // expected-error{{static member 'tum' cannot be used on protocol metatype 'P.Protocol'}}
222+
223+
// Access typealias through protocol and existential metatypes
224+
_ = pp.E.self
225+
_ = p.E.self
226+
227+
_ = pp.F.self
228+
_ = p.F.self
219229
}
220230

221231
protocol StaticP {

0 commit comments

Comments
 (0)