@@ -1421,18 +1421,6 @@ namespace {
14211421 OptionSet<OpenedExistentialAdjustmentFlags>;
14221422}
14231423
1424- /// Determine if this function is part of the _isUnique family of functions in
1425- /// the standard library.
1426- static bool isStdlibUniqueFunction(ValueDecl *callee) {
1427- if (!callee->isStdlibDecl())
1428- return false;
1429-
1430- auto baseName = callee->getName().getBaseName().userFacingName();
1431- return baseName == "_isUnique" || baseName == "_isUnique_native" ||
1432- baseName == "_COWBufferForReading" ||
1433- baseName == "_unsafeDowncastToAnyObject";
1434- }
1435-
14361424/// Determine whether we should open up the existential argument to the
14371425/// given parameters.
14381426///
@@ -1469,14 +1457,6 @@ shouldOpenExistentialCallArgument(
14691457 return None;
14701458
14711459 case DeclTypeCheckingSemantics::Normal:
1472- // _isUnique and friends are special because opening an existential when
1473- // calling them would make them non-unique.
1474- // FIXME: Borrowing properly from the existential box would probably
1475- // eliminate this.
1476- if (isStdlibUniqueFunction(callee))
1477- return None;
1478- break;
1479-
14801460 case DeclTypeCheckingSemantics::WithoutActuallyEscaping:
14811461 break;
14821462 }
@@ -1521,32 +1501,6 @@ shouldOpenExistentialCallArgument(
15211501 if (!argTy->isAnyExistentialType())
15221502 return None;
15231503
1524-
1525- // If the existential argument type conforms to all of its protocol
1526- // requirements, don't open the existential.
1527- {
1528- Type existentialObjectType;
1529- if (auto existentialMetaTy = argTy->getAs<ExistentialMetatypeType>())
1530- existentialObjectType = existentialMetaTy->getInstanceType();
1531- else
1532- existentialObjectType = argTy;
1533- auto layout = existentialObjectType->getExistentialLayout();
1534- auto module = cs.DC->getParentModule();
1535- bool containsNonSelfConformance = false;
1536- for (auto proto : layout.getProtocols()) {
1537- auto protoDecl = proto->getDecl();
1538- auto conformance = module->lookupExistentialConformance(
1539- existentialObjectType, protoDecl);
1540- if (conformance.isInvalid()) {
1541- containsNonSelfConformance = true;
1542- break;
1543- }
1544- }
1545-
1546- if (!containsNonSelfConformance)
1547- return None;
1548- }
1549-
15501504 auto param = getParameterAt(callee, paramIdx);
15511505 if (!param)
15521506 return None;
@@ -1588,6 +1542,31 @@ shouldOpenExistentialCallArgument(
15881542 genericSig.getGenericParams().back()->getDepth())
15891543 return None;
15901544
1545+ // If the existential argument conforms to all of protocol requirements on
1546+ // the formal parameter's type, don't open.
1547+ // If all of the conformance requirements on the formal parameter's type
1548+ // are self-conforming, don't open.
1549+ {
1550+ Type existentialObjectType;
1551+ if (auto existentialMetaTy = argTy->getAs<ExistentialMetatypeType>())
1552+ existentialObjectType = existentialMetaTy->getInstanceType();
1553+ else
1554+ existentialObjectType = argTy;
1555+ auto module = cs.DC->getParentModule();
1556+ bool containsNonSelfConformance = false;
1557+ for (auto proto : genericSig->getRequiredProtocols(genericParam)) {
1558+ auto conformance = module->lookupExistentialConformance(
1559+ existentialObjectType, proto);
1560+ if (conformance.isInvalid()) {
1561+ containsNonSelfConformance = true;
1562+ break;
1563+ }
1564+ }
1565+
1566+ if (!containsNonSelfConformance)
1567+ return None;
1568+ }
1569+
15911570 // Ensure that the formal parameter is only used in covariant positions,
15921571 // because it won't match anywhere else.
15931572 auto referenceInfo = findGenericParameterReferences(
0 commit comments