@@ -1421,6 +1421,18 @@ namespace {
1421
1421
OptionSet<OpenedExistentialAdjustmentFlags>;
1422
1422
}
1423
1423
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
+
1424
1436
/// Determine whether we should open up the existential argument to the
1425
1437
/// given parameters.
1426
1438
///
@@ -1457,6 +1469,14 @@ shouldOpenExistentialCallArgument(
1457
1469
return None;
1458
1470
1459
1471
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
+
1460
1480
case DeclTypeCheckingSemantics::WithoutActuallyEscaping:
1461
1481
break;
1462
1482
}
@@ -1501,15 +1521,22 @@ shouldOpenExistentialCallArgument(
1501
1521
if (!argTy->isAnyExistentialType())
1502
1522
return None;
1503
1523
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();
1508
1534
auto module = cs.DC->getParentModule();
1509
1535
bool containsNonSelfConformance = false;
1510
1536
for (auto proto : layout.getProtocols()) {
1511
1537
auto protoDecl = proto->getDecl();
1512
- auto conformance = module->lookupExistentialConformance(argTy, protoDecl);
1538
+ auto conformance = module->lookupExistentialConformance(
1539
+ existentialObjectType, protoDecl);
1513
1540
if (conformance.isInvalid()) {
1514
1541
containsNonSelfConformance = true;
1515
1542
break;
0 commit comments