@@ -1421,6 +1421,18 @@ 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+
14241436/// Determine whether we should open up the existential argument to the
14251437/// given parameters.
14261438///
@@ -1457,6 +1469,14 @@ shouldOpenExistentialCallArgument(
14571469 return None;
14581470
14591471 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+
14601480 case DeclTypeCheckingSemantics::WithoutActuallyEscaping:
14611481 break;
14621482 }
@@ -1501,15 +1521,22 @@ shouldOpenExistentialCallArgument(
15011521 if (!argTy->isAnyExistentialType())
15021522 return None;
15031523
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();
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();
15081534 auto module = cs.DC->getParentModule();
15091535 bool containsNonSelfConformance = false;
15101536 for (auto proto : layout.getProtocols()) {
15111537 auto protoDecl = proto->getDecl();
1512- auto conformance = module->lookupExistentialConformance(argTy, protoDecl);
1538+ auto conformance = module->lookupExistentialConformance(
1539+ existentialObjectType, protoDecl);
15131540 if (conformance.isInvalid()) {
15141541 containsNonSelfConformance = true;
15151542 break;
0 commit comments