Skip to content

Commit 9e3432a

Browse files
committed
[ConstraintSystem] Fix a bug in existential Self erasure
`typeEraseExistentialSelfReferences` shouldn't account for contextual signature because that signature could have generic parameters of it's own unrelated to the reference which would be located before generic parameters of the member, e.g. when the code is located in a protocol extension, which invalidates the assumption that `Self` is located at depth = 0, index = 0. Resolves: rdar://91110069
1 parent 128d6e1 commit 9e3432a

File tree

4 files changed

+41
-12
lines changed

4 files changed

+41
-12
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5694,7 +5694,6 @@ Expr *getArgumentLabelTargetExpr(Expr *fn);
56945694
/// variable and anything that depends on it to their non-dependent bounds.
56955695
Type typeEraseOpenedExistentialReference(Type type, Type existentialBaseType,
56965696
TypeVariableType *openedTypeVar,
5697-
const DeclContext *useDC,
56985697
TypePosition outermostPosition);
56995698

57005699
/// Returns true if a reference to a member on a given base type will apply

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,7 +1872,7 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
18721872
for (const auto &opened : openedExistentials) {
18731873
paramTy = typeEraseOpenedExistentialReference(
18741874
paramTy, opened.second->getExistentialType(), opened.first,
1875-
/*FIXME*/cs.DC, TypePosition::Contravariant);
1875+
TypePosition::Contravariant);
18761876
}
18771877
}
18781878

@@ -11389,7 +11389,7 @@ ConstraintSystem::simplifyApplicableFnConstraint(
1138911389
if (result2->hasTypeVariable() && !openedExistentials.empty()) {
1139011390
for (const auto &opened : openedExistentials) {
1139111391
result2 = typeEraseOpenedExistentialReference(
11392-
result2, opened.second->getExistentialType(), opened.first, DC,
11392+
result2, opened.second->getExistentialType(), opened.first,
1139311393
TypePosition::Covariant);
1139411394
}
1139511395
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,16 +1795,16 @@ static bool isMainDispatchQueueMember(ConstraintLocator *locator) {
17951795
/// routine will recurse into the concrete type.
17961796
static Type
17971797
typeEraseExistentialSelfReferences(
1798-
Type refTy, Type baseTy, const DeclContext *useDC,
1798+
Type refTy, Type baseTy,
17991799
TypePosition outermostPosition) {
18001800
assert(baseTy->isExistentialType());
18011801
if (!refTy->hasTypeParameter()) {
18021802
return refTy;
18031803
}
18041804

1805-
auto contextSig = useDC->getGenericSignatureOfContext();
18061805
const auto existentialSig =
1807-
baseTy->getASTContext().getOpenedArchetypeSignature(baseTy, contextSig);
1806+
baseTy->getASTContext().getOpenedArchetypeSignature(baseTy,
1807+
GenericSignature());
18081808

18091809
unsigned metatypeDepth = 0;
18101810

@@ -1916,7 +1916,7 @@ typeEraseExistentialSelfReferences(
19161916

19171917
Type constraints::typeEraseOpenedExistentialReference(
19181918
Type type, Type existentialBaseType, TypeVariableType *openedTypeVar,
1919-
const DeclContext *useDC, TypePosition outermostPosition) {
1919+
TypePosition outermostPosition) {
19201920
Type selfGP = GenericTypeParamType::get(false, 0, 0, type->getASTContext());
19211921

19221922
// First, temporarily reconstitute the 'Self' generic parameter.
@@ -1933,8 +1933,8 @@ Type constraints::typeEraseOpenedExistentialReference(
19331933
});
19341934

19351935
// Then, type-erase occurrences of covariant 'Self'-rooted type parameters.
1936-
type = typeEraseExistentialSelfReferences(
1937-
type, existentialBaseType, useDC, outermostPosition);
1936+
type = typeEraseExistentialSelfReferences(type, existentialBaseType,
1937+
outermostPosition);
19381938

19391939
// Finally, swap the 'Self'-corresponding type variable back in.
19401940
return type.transformRec([&](TypeBase *t) -> Optional<Type> {
@@ -2260,9 +2260,8 @@ ConstraintSystem::getTypeOfMemberReference(
22602260
const auto selfGP = cast<GenericTypeParamType>(
22612261
outerDC->getSelfInterfaceType()->getCanonicalType());
22622262
auto openedTypeVar = replacements.lookup(selfGP);
2263-
type =
2264-
typeEraseOpenedExistentialReference(type, baseObjTy, openedTypeVar, DC,
2265-
TypePosition::Covariant);
2263+
type = typeEraseOpenedExistentialReference(type, baseObjTy, openedTypeVar,
2264+
TypePosition::Covariant);
22662265
}
22672266

22682267
// Construct an idealized parameter type of the initializer associated
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol Schema: RawRepresentable {
4+
var rawValue: String { get }
5+
}
6+
7+
enum MySchema: String, Schema {
8+
case hello = "hello"
9+
}
10+
11+
struct Parser<S: Schema> : Equatable {
12+
}
13+
14+
protocol Entity {
15+
}
16+
17+
protocol MyInitializable {
18+
init() throws
19+
}
20+
21+
typealias MyInitializableEntity = MyInitializable & Entity
22+
23+
extension Parser where S == MySchema {
24+
func test(kind: Entity.Type) throws {
25+
guard let entityType = kind as? MyInitializableEntity.Type else {
26+
return
27+
}
28+
29+
let _ = try entityType.init() // Ok
30+
}
31+
}

0 commit comments

Comments
 (0)