Skip to content

Commit 9962e86

Browse files
committed
Factor out the ConcurrentValue checking of instance data.
1 parent 07b4747 commit 9962e86

File tree

1 file changed

+63
-55
lines changed

1 file changed

+63
-55
lines changed

lib/Sema/TypeCheckConcurrency.cpp

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

2359+
/// Check the instance storage of the given nominal type to verify whether
2360+
/// it is comprised only of ConcurrentValue instance storage.
2361+
static bool checkConcurrentValueInstanceStorage(
2362+
NominalTypeDecl *nominal, DeclContext *dc, ConcurrentValueCheck check) {
2363+
// Stored properties of structs and classes must have
2364+
// ConcurrentValue-conforming types.
2365+
bool asWarning = (check == ConcurrentValueCheck::ImpliedByStandardProtocol);
2366+
bool invalid = false;
2367+
if (isa<StructDecl>(nominal) || isa<ClassDecl>(nominal)) {
2368+
auto classDecl = dyn_cast<ClassDecl>(nominal);
2369+
for (auto property : nominal->getStoredProperties()) {
2370+
if (classDecl && property->supportsMutation()) {
2371+
property->diagnose(
2372+
asWarning ? diag::concurrent_value_class_mutable_property_warn
2373+
: diag::concurrent_value_class_mutable_property,
2374+
property->getName(), nominal->getDescriptiveKind(),
2375+
nominal->getName());
2376+
invalid = true;
2377+
continue;
2378+
}
2379+
2380+
auto propertyType = dc->mapTypeIntoContext(property->getInterfaceType());
2381+
if (!isConcurrentValueType(dc, propertyType)) {
2382+
property->diagnose(
2383+
asWarning ? diag::non_concurrent_type_member_warn
2384+
: diag::non_concurrent_type_member,
2385+
false, property->getName(),
2386+
nominal->getDescriptiveKind(), nominal->getName(), propertyType);
2387+
invalid = true;
2388+
continue;
2389+
}
2390+
}
2391+
2392+
return invalid;
2393+
}
2394+
2395+
// Associated values of enum cases must have ConcurrentValue-conforming
2396+
// types.
2397+
if (auto enumDecl = dyn_cast<EnumDecl>(nominal)) {
2398+
for (auto caseDecl : enumDecl->getAllCases()) {
2399+
for (auto element : caseDecl->getElements()) {
2400+
if (!element->hasAssociatedValues())
2401+
continue;
2402+
2403+
auto elementType = dc->mapTypeIntoContext(
2404+
element->getArgumentInterfaceType());
2405+
if (!isConcurrentValueType(dc, elementType)) {
2406+
element->diagnose(
2407+
asWarning ? diag::non_concurrent_type_member_warn
2408+
: diag::non_concurrent_type_member,
2409+
true, element->getName(),
2410+
nominal->getDescriptiveKind(), nominal->getName(), elementType);
2411+
invalid = true;
2412+
continue;
2413+
}
2414+
}
2415+
}
2416+
}
2417+
2418+
return invalid;
2419+
}
2420+
23592421
bool swift::checkConcurrentValueConformance(
23602422
ProtocolConformance *conformance, ConcurrentValueCheck check) {
23612423
auto conformanceDC = conformance->getDeclContext();
@@ -2415,59 +2477,5 @@ bool swift::checkConcurrentValueConformance(
24152477
}
24162478
}
24172479

2418-
// Stored properties of structs and classes must have
2419-
// ConcurrentValue-conforming types.
2420-
bool invalid = false;
2421-
if (isa<StructDecl>(nominal) || classDecl) {
2422-
for (auto property : nominal->getStoredProperties()) {
2423-
if (classDecl && property->supportsMutation()) {
2424-
property->diagnose(
2425-
asWarning ? diag::concurrent_value_class_mutable_property_warn
2426-
: diag::concurrent_value_class_mutable_property,
2427-
property->getName(), nominal->getDescriptiveKind(),
2428-
nominal->getName());
2429-
invalid = true;
2430-
continue;
2431-
}
2432-
2433-
auto propertyType =
2434-
conformanceDC->mapTypeIntoContext(property->getInterfaceType());
2435-
if (!isConcurrentValueType(conformanceDC, propertyType)) {
2436-
property->diagnose(
2437-
asWarning ? diag::non_concurrent_type_member_warn
2438-
: diag::non_concurrent_type_member,
2439-
false, property->getName(),
2440-
nominal->getDescriptiveKind(), nominal->getName(), propertyType);
2441-
invalid = true;
2442-
continue;
2443-
}
2444-
}
2445-
2446-
return invalid;
2447-
}
2448-
2449-
// Associated values of enum cases must have ConcurrentValue-conforming
2450-
// types.
2451-
if (auto enumDecl = dyn_cast<EnumDecl>(nominal)) {
2452-
for (auto caseDecl : enumDecl->getAllCases()) {
2453-
for (auto element : caseDecl->getElements()) {
2454-
if (!element->hasAssociatedValues())
2455-
continue;
2456-
2457-
auto elementType = conformanceDC->mapTypeIntoContext(
2458-
element->getArgumentInterfaceType());
2459-
if (!isConcurrentValueType(conformanceDC, elementType)) {
2460-
element->diagnose(
2461-
asWarning ? diag::non_concurrent_type_member_warn
2462-
: diag::non_concurrent_type_member,
2463-
true, element->getName(),
2464-
nominal->getDescriptiveKind(), nominal->getName(), elementType);
2465-
invalid = true;
2466-
continue;
2467-
}
2468-
}
2469-
}
2470-
}
2471-
2472-
return invalid;
2480+
return checkConcurrentValueInstanceStorage(nominal, conformanceDC, check);
24732481
}

0 commit comments

Comments
 (0)