Skip to content

Commit e7131cf

Browse files
committed
Sema: Fix existential-metatype-to-Any conversion
We were incorrectly unwrapping too many levels of metatype, and our ErasureExpr would end up with conformances for the instance type and not the metatype itself. In the old universe, this was not a problem, but now Any has two protocol conformance members, so suddently this violated invariants. This was a regression, introduced in 6027bf4. Fixes rdar://125460667.
1 parent 5cf05ec commit e7131cf

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

lib/Sema/CSApply.cpp

+17-13
Original file line numberDiff line numberDiff line change
@@ -6688,13 +6688,24 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType,
66886688
Type fromInstanceType = fromType;
66896689
Type toInstanceType = toType;
66906690

6691-
// Look through metatypes
6691+
// For existential-to-existential coercions, open the source existential.
6692+
Type openedFromType;
6693+
if (fromType->isAnyExistentialType()) {
6694+
openedFromType = OpenedArchetypeType::getAny(fromType->getCanonicalType(),
6695+
dc->getGenericSignatureOfContext());
6696+
}
6697+
6698+
Type openedFromInstanceType = openedFromType;
6699+
6700+
// Look through metatypes.
66926701
while ((fromInstanceType->is<UnresolvedType>() ||
66936702
fromInstanceType->is<AnyMetatypeType>()) &&
66946703
toInstanceType->is<ExistentialMetatypeType>()) {
66956704
if (!fromInstanceType->is<UnresolvedType>())
6696-
fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
6697-
toInstanceType = toInstanceType->castTo<ExistentialMetatypeType>()->getExistentialInstanceType();
6705+
fromInstanceType = fromInstanceType->getMetatypeInstanceType();
6706+
if (openedFromInstanceType && !openedFromInstanceType->is<UnresolvedType>())
6707+
openedFromInstanceType = openedFromInstanceType->getMetatypeInstanceType();
6708+
toInstanceType = toInstanceType->getMetatypeInstanceType();
66986709
}
66996710

67006711
ASTContext &ctx = cs.getASTContext();
@@ -6758,20 +6769,13 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType,
67586769
}
67596770

67606771
// For existential-to-existential coercions, open the source existential.
6761-
if (fromType->isAnyExistentialType()) {
6762-
fromType = OpenedArchetypeType::getAny(fromType->getCanonicalType(),
6763-
dc->getGenericSignatureOfContext());
6764-
6772+
if (openedFromType) {
67656773
auto *archetypeVal = cs.cacheType(
6766-
new (ctx) OpaqueValueExpr(expr->getSourceRange(), fromType));
6767-
6768-
fromInstanceType = fromType;
6769-
while (auto *metatypeType = fromInstanceType->getAs<MetatypeType>())
6770-
fromInstanceType = metatypeType->getInstanceType();
6774+
new (ctx) OpaqueValueExpr(expr->getSourceRange(), openedFromType));
67716775

67726776
auto conformances =
67736777
dc->getParentModule()
6774-
->collectExistentialConformances(fromInstanceType->getCanonicalType(),
6778+
->collectExistentialConformances(openedFromInstanceType->getCanonicalType(),
67756779
toInstanceType->getCanonicalType(),
67766780
/*allowMissing=*/true);
67776781

test/SILOptimizer/rdar125460667.swift

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend -emit-sil %s
2+
3+
@_transparent func f(a: Any.Type) -> Any {
4+
return a
5+
}
6+
7+
func g(a: Any.Type) {
8+
f(a: a)
9+
}

0 commit comments

Comments
 (0)