Skip to content

Commit 07b4747

Browse files
committed
Clarify interface to swift::checkConcurrentValueConformance
1 parent 114f856 commit 07b4747

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,30 +2356,33 @@ static bool shouldDiagnoseExistingDataRaces(const DeclContext *dc) {
23562356
return false;
23572357
}
23582358

2359-
void swift::checkConcurrentValueConformance(
2360-
ProtocolConformance *conformance, bool asWarning) {
2359+
bool swift::checkConcurrentValueConformance(
2360+
ProtocolConformance *conformance, ConcurrentValueCheck check) {
23612361
auto conformanceDC = conformance->getDeclContext();
23622362
auto nominal = conformance->getType()->getAnyNominal();
23632363
if (!nominal)
2364-
return;
2364+
return false;
23652365

23662366
auto classDecl = dyn_cast<ClassDecl>(nominal);
23672367
if (classDecl) {
23682368
// Actors implicitly conform to ConcurrentValue and protect their state.
23692369
if (classDecl->isActor())
2370-
return;
2370+
return false;
23712371
}
23722372

23732373
// ConcurrentValue can only be used in the same source file.
23742374
auto conformanceDecl = conformanceDC->getAsDecl();
2375+
bool asWarning = (check == ConcurrentValueCheck::ImpliedByStandardProtocol);
23752376
if (!conformanceDC->getParentSourceFile() ||
23762377
conformanceDC->getParentSourceFile() != nominal->getParentSourceFile()) {
23772378
conformanceDecl->diagnose(
23782379
asWarning
23792380
? diag::concurrent_value_outside_source_file_warn
23802381
: diag::concurrent_value_outside_source_file,
23812382
nominal->getDescriptiveKind(), nominal->getName());
2382-
return;
2383+
2384+
if (!asWarning)
2385+
return true;
23832386
}
23842387

23852388
if (classDecl) {
@@ -2389,8 +2392,9 @@ void swift::checkConcurrentValueConformance(
23892392
asWarning ? diag::concurrent_value_open_class_warn
23902393
: diag::concurrent_value_open_class,
23912394
classDecl->getName());
2395+
23922396
if (!asWarning)
2393-
return;
2397+
return true;
23942398
}
23952399

23962400
// A 'ConcurrentValue' class cannot inherit from another class, although
@@ -2403,15 +2407,17 @@ void swift::checkConcurrentValueConformance(
24032407
: diag::concurrent_value_inherit,
24042408
nominal->getASTContext().LangOpts.EnableObjCInterop,
24052409
classDecl->getName());
2410+
24062411
if (!asWarning)
2407-
return;
2412+
return true;
24082413
}
24092414
}
24102415
}
24112416
}
24122417

24132418
// Stored properties of structs and classes must have
24142419
// ConcurrentValue-conforming types.
2420+
bool invalid = false;
24152421
if (isa<StructDecl>(nominal) || classDecl) {
24162422
for (auto property : nominal->getStoredProperties()) {
24172423
if (classDecl && property->supportsMutation()) {
@@ -2420,6 +2426,7 @@ void swift::checkConcurrentValueConformance(
24202426
: diag::concurrent_value_class_mutable_property,
24212427
property->getName(), nominal->getDescriptiveKind(),
24222428
nominal->getName());
2429+
invalid = true;
24232430
continue;
24242431
}
24252432

@@ -2431,11 +2438,12 @@ void swift::checkConcurrentValueConformance(
24312438
: diag::non_concurrent_type_member,
24322439
false, property->getName(),
24332440
nominal->getDescriptiveKind(), nominal->getName(), propertyType);
2441+
invalid = true;
24342442
continue;
24352443
}
24362444
}
24372445

2438-
return;
2446+
return invalid;
24392447
}
24402448

24412449
// Associated values of enum cases must have ConcurrentValue-conforming
@@ -2454,9 +2462,12 @@ void swift::checkConcurrentValueConformance(
24542462
: diag::non_concurrent_type_member,
24552463
true, element->getName(),
24562464
nominal->getDescriptiveKind(), nominal->getName(), elementType);
2465+
invalid = true;
24572466
continue;
24582467
}
24592468
}
24602469
}
24612470
}
2471+
2472+
return invalid;
24622473
}

lib/Sema/TypeCheckConcurrency.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,22 @@ bool diagnoseNonConcurrentTypesInReference(
190190
ConcreteDeclRef declRef, const DeclContext *dc, SourceLoc loc,
191191
ConcurrentReferenceKind refKind);
192192

193+
/// How the concurrent value check should be performed.
194+
enum class ConcurrentValueCheck {
195+
/// ConcurrentValue conformance was explicitly stated and should be
196+
/// fully checked.
197+
Explicit,
198+
199+
/// ConcurrentValue conformance was implied by one of the standard library
200+
/// protocols that added ConcurrentValue after-the-fact.
201+
ImpliedByStandardProtocol,
202+
};
203+
193204
/// Check the correctness of the given ConcurrentValue conformance.
194-
void checkConcurrentValueConformance(
195-
ProtocolConformance *conformance, bool asWarning);
205+
///
206+
/// \returns true if an error occurred.
207+
bool checkConcurrentValueConformance(
208+
ProtocolConformance *conformance, ConcurrentValueCheck check);
196209

197210
} // end namespace swift
198211

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5715,8 +5715,10 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
57155715

57165716
// Check constraints of ConcurrentValue.
57175717
if (concurrentValueConformance && !unsafeConcurrentValueConformance) {
5718-
bool asWarning = errorConformance || codingKeyConformance;
5719-
checkConcurrentValueConformance(concurrentValueConformance, asWarning);
5718+
ConcurrentValueCheck check = ConcurrentValueCheck::Explicit;
5719+
if (errorConformance || codingKeyConformance)
5720+
check = ConcurrentValueCheck::ImpliedByStandardProtocol;
5721+
checkConcurrentValueConformance(concurrentValueConformance, check);
57205722
}
57215723

57225724
// Check all conformances.

0 commit comments

Comments
 (0)