@@ -2356,30 +2356,33 @@ static bool shouldDiagnoseExistingDataRaces(const DeclContext *dc) {
2356
2356
return false ;
2357
2357
}
2358
2358
2359
- void swift::checkConcurrentValueConformance (
2360
- ProtocolConformance *conformance, bool asWarning ) {
2359
+ bool swift::checkConcurrentValueConformance (
2360
+ ProtocolConformance *conformance, ConcurrentValueCheck check ) {
2361
2361
auto conformanceDC = conformance->getDeclContext ();
2362
2362
auto nominal = conformance->getType ()->getAnyNominal ();
2363
2363
if (!nominal)
2364
- return ;
2364
+ return false ;
2365
2365
2366
2366
auto classDecl = dyn_cast<ClassDecl>(nominal);
2367
2367
if (classDecl) {
2368
2368
// Actors implicitly conform to ConcurrentValue and protect their state.
2369
2369
if (classDecl->isActor ())
2370
- return ;
2370
+ return false ;
2371
2371
}
2372
2372
2373
2373
// ConcurrentValue can only be used in the same source file.
2374
2374
auto conformanceDecl = conformanceDC->getAsDecl ();
2375
+ bool asWarning = (check == ConcurrentValueCheck::ImpliedByStandardProtocol);
2375
2376
if (!conformanceDC->getParentSourceFile () ||
2376
2377
conformanceDC->getParentSourceFile () != nominal->getParentSourceFile ()) {
2377
2378
conformanceDecl->diagnose (
2378
2379
asWarning
2379
2380
? diag::concurrent_value_outside_source_file_warn
2380
2381
: diag::concurrent_value_outside_source_file,
2381
2382
nominal->getDescriptiveKind (), nominal->getName ());
2382
- return ;
2383
+
2384
+ if (!asWarning)
2385
+ return true ;
2383
2386
}
2384
2387
2385
2388
if (classDecl) {
@@ -2389,8 +2392,9 @@ void swift::checkConcurrentValueConformance(
2389
2392
asWarning ? diag::concurrent_value_open_class_warn
2390
2393
: diag::concurrent_value_open_class,
2391
2394
classDecl->getName ());
2395
+
2392
2396
if (!asWarning)
2393
- return ;
2397
+ return true ;
2394
2398
}
2395
2399
2396
2400
// A 'ConcurrentValue' class cannot inherit from another class, although
@@ -2403,15 +2407,17 @@ void swift::checkConcurrentValueConformance(
2403
2407
: diag::concurrent_value_inherit,
2404
2408
nominal->getASTContext ().LangOpts .EnableObjCInterop ,
2405
2409
classDecl->getName ());
2410
+
2406
2411
if (!asWarning)
2407
- return ;
2412
+ return true ;
2408
2413
}
2409
2414
}
2410
2415
}
2411
2416
}
2412
2417
2413
2418
// Stored properties of structs and classes must have
2414
2419
// ConcurrentValue-conforming types.
2420
+ bool invalid = false ;
2415
2421
if (isa<StructDecl>(nominal) || classDecl) {
2416
2422
for (auto property : nominal->getStoredProperties ()) {
2417
2423
if (classDecl && property->supportsMutation ()) {
@@ -2420,6 +2426,7 @@ void swift::checkConcurrentValueConformance(
2420
2426
: diag::concurrent_value_class_mutable_property,
2421
2427
property->getName (), nominal->getDescriptiveKind (),
2422
2428
nominal->getName ());
2429
+ invalid = true ;
2423
2430
continue ;
2424
2431
}
2425
2432
@@ -2431,11 +2438,12 @@ void swift::checkConcurrentValueConformance(
2431
2438
: diag::non_concurrent_type_member,
2432
2439
false , property->getName (),
2433
2440
nominal->getDescriptiveKind (), nominal->getName (), propertyType);
2441
+ invalid = true ;
2434
2442
continue ;
2435
2443
}
2436
2444
}
2437
2445
2438
- return ;
2446
+ return invalid ;
2439
2447
}
2440
2448
2441
2449
// Associated values of enum cases must have ConcurrentValue-conforming
@@ -2454,9 +2462,12 @@ void swift::checkConcurrentValueConformance(
2454
2462
: diag::non_concurrent_type_member,
2455
2463
true , element->getName (),
2456
2464
nominal->getDescriptiveKind (), nominal->getName (), elementType);
2465
+ invalid = true ;
2457
2466
continue ;
2458
2467
}
2459
2468
}
2460
2469
}
2461
2470
}
2471
+
2472
+ return invalid;
2462
2473
}
0 commit comments