Skip to content

Commit 25e71a3

Browse files
committed
Don't open an existential argument that's completely self-conforming.
Such existential arguments will already meet the requirements of a generic function they are passed to, but would change runtime semantics. Therefore, don't open the existential in such cases.
1 parent f20a52e commit 25e71a3

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,25 @@ shouldOpenExistentialCallArgument(
15011501
if (!argTy->isAnyExistentialType())
15021502
return None;
15031503

1504+
if (argTy->isExistentialType()) {
1505+
// If the existential argument type conforms to all of its protocol
1506+
// requirements, don't open the existential.
1507+
auto layout = argTy->getExistentialLayout();
1508+
auto module = cs.DC->getParentModule();
1509+
bool containsNonSelfConformance = false;
1510+
for (auto proto : layout.getProtocols()) {
1511+
auto protoDecl = proto->getDecl();
1512+
auto conformance = module->lookupExistentialConformance(argTy, protoDecl);
1513+
if (conformance.isInvalid()) {
1514+
containsNonSelfConformance = true;
1515+
break;
1516+
}
1517+
}
1518+
1519+
if (!containsNonSelfConformance)
1520+
return None;
1521+
}
1522+
15041523
auto param = getParameterAt(callee, paramIdx);
15051524
if (!param)
15061525
return None;

test/Constraints/opened_existentials_suppression.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ func acceptsBox<T>(_ value: T) { }
66

77
// CHECK: passBox
88
// CHECK-NOT: open_existential_expr
9-
func passBox(p: P) {
9+
func passBox(p: P, obj: AnyObject, err: Error) {
1010
acceptsBox(p as P)
11+
acceptsBox(obj)
12+
acceptsBox(err)
1113
}

0 commit comments

Comments
 (0)