@@ -1276,6 +1276,7 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C,
1276
1276
auto &diags = C.Diags ;
1277
1277
auto module = nominal->getParentModule ();
1278
1278
Type nominalTy = nominal->getDeclaredInterfaceType ();
1279
+ NominalTypeDecl *executorDecl = C.getExecutorDecl ();
1279
1280
1280
1281
// enqueue(_:)
1281
1282
auto enqueueDeclName = DeclName (C, DeclBaseName (C.Id_enqueue ), { Identifier () });
@@ -1324,18 +1325,18 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C,
1324
1325
assert (unownedEnqueueRequirement && " could not find the enqueue(UnownedJob) requirement, which should be always there" );
1325
1326
1326
1327
// try to find at least a single implementations of enqueue(_:)
1327
- ConcreteDeclRef unownedEnqueueWitness = concreteConformance->getWitnessDeclRef (unownedEnqueueRequirement);
1328
- ValueDecl *unownedEnqueueWitnessDecl = unownedEnqueueWitness.getDecl ();
1328
+ // auto unownedEnqueueWitness = concreteConformance->getWitnessDeclRef(unownedEnqueueRequirement);
1329
+ ValueDecl *unownedEnqueueWitnessDecl = concreteConformance-> getWitnessDecl (unownedEnqueueRequirement); // unownedEnqueueWitness.getDecl();
1329
1330
ValueDecl *moveOnlyEnqueueWitnessDecl = nullptr ;
1330
1331
ValueDecl *legacyMoveOnlyEnqueueWitnessDecl = nullptr ;
1331
1332
1332
1333
if (moveOnlyEnqueueRequirement) {
1333
- moveOnlyEnqueueWitnessDecl = concreteConformance->getWitnessDeclRef (
1334
- moveOnlyEnqueueRequirement). getDecl () ;
1334
+ moveOnlyEnqueueWitnessDecl = concreteConformance->getWitnessDecl (
1335
+ moveOnlyEnqueueRequirement);
1335
1336
}
1336
1337
if (legacyMoveOnlyEnqueueRequirement) {
1337
- legacyMoveOnlyEnqueueWitnessDecl = concreteConformance->getWitnessDeclRef (
1338
- legacyMoveOnlyEnqueueRequirement). getDecl () ;
1338
+ legacyMoveOnlyEnqueueWitnessDecl = concreteConformance->getWitnessDecl (
1339
+ legacyMoveOnlyEnqueueRequirement);
1339
1340
}
1340
1341
1341
1342
// --- Diagnose warnings and errors
@@ -1360,24 +1361,42 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C,
1360
1361
1361
1362
// If both old and new enqueue are implemented, but the old one cannot be removed,
1362
1363
// emit a warning that the new enqueue is unused.
1363
- if (!canRemoveOldDecls &&
1364
- unownedEnqueueWitnessDecl && unownedEnqueueWitnessDecl->getLoc ().isValid () &&
1365
- moveOnlyEnqueueWitnessDecl && moveOnlyEnqueueWitnessDecl->getLoc ().isValid ()) {
1364
+ if (!canRemoveOldDecls && unownedEnqueueWitnessDecl && moveOnlyEnqueueWitnessDecl) {
1366
1365
diags.diagnose (moveOnlyEnqueueWitnessDecl->getLoc (), diag::executor_enqueue_unused_implementation);
1367
1366
}
1368
1367
1369
1368
// Old UnownedJob based impl is present, warn about it suggesting the new protocol requirement.
1370
- if (canRemoveOldDecls && unownedEnqueueWitnessDecl && unownedEnqueueWitnessDecl-> getLoc (). isValid () ) {
1369
+ if (canRemoveOldDecls && unownedEnqueueWitnessDecl) {
1371
1370
diags.diagnose (unownedEnqueueWitnessDecl->getLoc (), diag::executor_enqueue_unowned_implementation, nominalTy);
1372
1371
}
1373
1372
// Old Job based impl is present, warn about it suggesting the new protocol requirement.
1374
- if (legacyMoveOnlyEnqueueWitnessDecl && legacyMoveOnlyEnqueueWitnessDecl-> getLoc (). isValid () ) {
1373
+ if (legacyMoveOnlyEnqueueWitnessDecl) {
1375
1374
diags.diagnose (legacyMoveOnlyEnqueueWitnessDecl->getLoc (), diag::executor_enqueue_deprecated_owned_job_implementation, nominalTy);
1376
1375
}
1377
1376
1378
- if ((!unownedEnqueueWitnessDecl || unownedEnqueueWitnessDecl->getLoc ().isInvalid ()) &&
1379
- (!moveOnlyEnqueueWitnessDecl || moveOnlyEnqueueWitnessDecl->getLoc ().isInvalid ()) &&
1380
- (!legacyMoveOnlyEnqueueWitnessDecl || legacyMoveOnlyEnqueueWitnessDecl->getLoc ().isInvalid ())) {
1377
+ auto isStdlibDefaultImplDecl = [executorDecl](ValueDecl *witness) -> bool {
1378
+ if (auto declContext = witness->getDeclContext ()) {
1379
+ if (auto *extension = dyn_cast<ExtensionDecl>(declContext)) {
1380
+ if (auto extendedNominal = extension->getExtendedNominal ()) {
1381
+ return extendedNominal->getDeclaredInterfaceType ()->isEqual (
1382
+ executorDecl->getDeclaredInterfaceType ());
1383
+ }
1384
+ }
1385
+ }
1386
+ return false ;
1387
+ };
1388
+ auto missingWitness = !unownedEnqueueWitnessDecl &&
1389
+ !moveOnlyEnqueueWitnessDecl &&
1390
+ !legacyMoveOnlyEnqueueWitnessDecl;
1391
+
1392
+ bool unownedEnqueueWitnessIsDefaultImpl = isStdlibDefaultImplDecl (unownedEnqueueWitnessDecl);
1393
+ bool moveOnlyEnqueueWitnessIsDefaultImpl = isStdlibDefaultImplDecl (moveOnlyEnqueueWitnessDecl);
1394
+ bool legacyMoveOnlyEnqueueWitnessDeclIsDefaultImpl = isStdlibDefaultImplDecl (legacyMoveOnlyEnqueueWitnessDecl);
1395
+ auto allWitnessesAreDefaultImpls = unownedEnqueueWitnessIsDefaultImpl &&
1396
+ moveOnlyEnqueueWitnessIsDefaultImpl &&
1397
+ legacyMoveOnlyEnqueueWitnessDeclIsDefaultImpl;
1398
+ if ((missingWitness) ||
1399
+ (!missingWitness && allWitnessesAreDefaultImpls)) {
1381
1400
// Neither old nor new implementation have been found, but we provide default impls for them
1382
1401
// that are mutually recursive, so we must error and suggest implementing the right requirement.
1383
1402
//
0 commit comments