Skip to content

Commit 6891452

Browse files
committed
Make (Raw)ConformanceIsolation requests work on the normal protocol conformance
Reduce the burden on the evaluator's caching mechanism by handling the unwrapping of a conformance down to its normal protocol conformance outside of these requests. Thanks, Slava!
1 parent 9f0dda5 commit 6891452

File tree

5 files changed

+41
-42
lines changed

5 files changed

+41
-42
lines changed

include/swift/AST/ProtocolConformance.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
148148
Kind : bitmax(NumProtocolConformanceKindBits, 8),
149149

150150
/// Whether the "raw" conformance isolation is "inferred", which applies to most conformances.
151-
IsRawConformanceInferred : 1,
151+
IsRawIsolationInferred : 1,
152152

153153
/// Whether the computed actor isolation is nonisolated.
154154
IsComputedNonisolated : 1
@@ -205,16 +205,16 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
205205
ProtocolConformance(ProtocolConformanceKind kind, Type conformingType)
206206
: ConformingType(conformingType) {
207207
Bits.ProtocolConformance.Kind = unsigned(kind);
208-
Bits.ProtocolConformance.IsRawConformanceInferred = false;
208+
Bits.ProtocolConformance.IsRawIsolationInferred = false;
209209
Bits.ProtocolConformance.IsComputedNonisolated = false;
210210
}
211211

212-
bool isRawConformanceInferred() const {
213-
return Bits.ProtocolConformance.IsRawConformanceInferred;
212+
bool isRawIsolationInferred() const {
213+
return Bits.ProtocolConformance.IsRawIsolationInferred;
214214
}
215215

216216
void setRawConformanceInferred(bool value = true) {
217-
Bits.ProtocolConformance.IsRawConformanceInferred = value;
217+
Bits.ProtocolConformance.IsRawIsolationInferred = value;
218218
}
219219

220220
bool isComputedNonisolated() const {

include/swift/AST/TypeCheckRequests.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ class ConformanceHasEffectRequest :
477477

478478
class RawConformanceIsolationRequest :
479479
public SimpleRequest<RawConformanceIsolationRequest,
480-
std::optional<ActorIsolation>(ProtocolConformance *),
480+
std::optional<ActorIsolation>(NormalProtocolConformance *),
481481
RequestFlags::SeparatelyCached |
482482
RequestFlags::SplitCached> {
483483
public:
@@ -488,7 +488,7 @@ class RawConformanceIsolationRequest :
488488

489489
// Evaluation.
490490
std::optional<ActorIsolation>
491-
evaluate(Evaluator &evaluator, ProtocolConformance *conformance) const;
491+
evaluate(Evaluator &evaluator, NormalProtocolConformance *conformance) const;
492492

493493
public:
494494
// Separate caching.
@@ -499,7 +499,7 @@ class RawConformanceIsolationRequest :
499499

500500
class ConformanceIsolationRequest :
501501
public SimpleRequest<ConformanceIsolationRequest,
502-
ActorIsolation(ProtocolConformance *),
502+
ActorIsolation(NormalProtocolConformance *),
503503
RequestFlags::SeparatelyCached |
504504
RequestFlags::SplitCached> {
505505
public:
@@ -510,7 +510,7 @@ class ConformanceIsolationRequest :
510510

511511
// Evaluation.
512512
ActorIsolation
513-
evaluate(Evaluator &evaluator, ProtocolConformance *conformance) const;
513+
evaluate(Evaluator &evaluator, NormalProtocolConformance *conformance) const;
514514

515515
public:
516516
// Separate caching.

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,11 @@ SWIFT_REQUEST(TypeChecker, ConformanceHasEffectRequest,
407407
bool(EffectKind, ProtocolConformanceRef),
408408
Cached, NoLocationInfo)
409409
SWIFT_REQUEST(TypeChecker, RawConformanceIsolationRequest,
410-
std::optional<ActorIsolation>(ProtocolConformance *),
410+
std::optional<ActorIsolation>(NormalProtocolConformance *),
411411
SeparatelyCached | SplitCached,
412412
NoLocationInfo)
413413
SWIFT_REQUEST(TypeChecker, ConformanceIsolationRequest,
414-
ActorIsolation(ProtocolConformance *),
414+
ActorIsolation(NormalProtocolConformance *),
415415
SeparatelyCached | SplitCached,
416416
NoLocationInfo)
417417
SWIFT_REQUEST(TypeChecker, ResolveTypeRequest,

lib/AST/TypeCheckRequests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,7 @@ RawConformanceIsolationRequest::getCachedResult() const {
13781378
auto conformance = std::get<0>(getStorage());
13791379

13801380
// Was actor isolation non-isolated?
1381-
if (conformance->isRawConformanceInferred())
1381+
if (conformance->isRawIsolationInferred())
13821382
return std::optional<ActorIsolation>();
13831383

13841384
ASTContext &ctx = conformance->getDeclContext()->getASTContext();

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7979,46 +7979,55 @@ bool swift::diagnoseNonSendableFromDeinit(
79797979
}
79807980

79817981
std::optional<ActorIsolation> ProtocolConformance::getRawIsolation() const {
7982+
// Only normal protocol conformances can be isolated.
7983+
auto rootNormal =
7984+
dyn_cast<NormalProtocolConformance>(this->getRootConformance());
7985+
if (!rootNormal)
7986+
return ActorIsolation::forNonisolated(false);
7987+
7988+
if (this != rootNormal)
7989+
return rootNormal->getRawIsolation();
7990+
79827991
ASTContext &ctx = getDeclContext()->getASTContext();
7983-
auto conformance = const_cast<ProtocolConformance *>(this);
7992+
auto conformance = const_cast<NormalProtocolConformance *>(rootNormal);
79847993
return evaluateOrDefault(
79857994
ctx.evaluator, RawConformanceIsolationRequest{conformance},
79867995
ActorIsolation());
79877996
}
79887997

79897998
ActorIsolation ProtocolConformance::getIsolation() const {
7999+
// Only normal protocol conformances can be isolated.
8000+
auto rootNormal =
8001+
dyn_cast<NormalProtocolConformance>(this->getRootConformance());
8002+
if (!rootNormal)
8003+
return ActorIsolation::forNonisolated(false);
8004+
8005+
if (this != rootNormal)
8006+
return rootNormal->getIsolation();
8007+
79908008
ASTContext &ctx = getDeclContext()->getASTContext();
7991-
auto conformance = const_cast<ProtocolConformance *>(this);
8009+
auto conformance = const_cast<NormalProtocolConformance *>(rootNormal);
79928010
return evaluateOrDefault(
79938011
ctx.evaluator, ConformanceIsolationRequest{conformance},
79948012
ActorIsolation());
79958013
}
79968014

79978015
std::optional<ActorIsolation>
79988016
RawConformanceIsolationRequest::evaluate(
7999-
Evaluator &evaluator, ProtocolConformance *conformance
8017+
Evaluator &evaluator, NormalProtocolConformance *conformance
80008018
) const {
8001-
// Only normal protocol conformances can be isolated.
8002-
auto rootNormal =
8003-
dyn_cast<NormalProtocolConformance>(conformance->getRootConformance());
8004-
if (!rootNormal)
8005-
return ActorIsolation::forNonisolated(false);
8006-
8007-
if (conformance != rootNormal)
8008-
return rootNormal->getRawIsolation();
8009-
80108019
// If the conformance is explicitly non-isolated, report that.
8011-
if (rootNormal->getOptions().contains(ProtocolConformanceFlags::Nonisolated))
8020+
if (conformance->getOptions().contains(ProtocolConformanceFlags::Nonisolated))
80128021
return ActorIsolation::forNonisolated(false);
80138022

80148023
// If there is an explicitly-specified global actor on the isolation,
80158024
// resolve it and report it.
8016-
if (auto globalActorTypeExpr = rootNormal->getExplicitGlobalActorIsolation()) {
8025+
if (auto globalActorTypeExpr = conformance->getExplicitGlobalActorIsolation()) {
80178026
// If we don't already have a resolved global actor type, resolve it now.
80188027
Type globalActorType = globalActorTypeExpr->getInstanceType();
80198028
if (!globalActorType) {
80208029
const auto resolution = TypeResolution::forInterface(
8021-
rootNormal->getDeclContext(), std::nullopt,
8030+
conformance->getDeclContext(), std::nullopt,
80228031
/*unboundTyOpener*/ nullptr,
80238032
/*placeholderHandler*/ nullptr,
80248033
/*packElementOpener*/ nullptr);
@@ -8036,9 +8045,9 @@ RawConformanceIsolationRequest::evaluate(
80368045
return ActorIsolation::forGlobalActor(globalActorType);
80378046
}
80388047

8039-
auto dc = rootNormal->getDeclContext();
8048+
auto dc = conformance->getDeclContext();
80408049
ASTContext &ctx = dc->getASTContext();
8041-
auto proto = rootNormal->getProtocol();
8050+
auto proto = conformance->getProtocol();
80428051

80438052
// If the protocol itself is isolated, don't infer isolation for the
80448053
// conformance.
@@ -8052,7 +8061,7 @@ RawConformanceIsolationRequest::evaluate(
80528061
return ActorIsolation::forNonisolated(false);
80538062

80548063
// @preconcurrency disables isolation inference.
8055-
if (rootNormal->isPreconcurrency())
8064+
if (conformance->isPreconcurrency())
80568065
return ActorIsolation::forNonisolated(false);
80578066

80588067
return std::nullopt;
@@ -8117,25 +8126,15 @@ ActorIsolation swift::inferConformanceIsolation(
81178126

81188127
ActorIsolation
81198128
ConformanceIsolationRequest::evaluate(
8120-
Evaluator &evaluator, ProtocolConformance *conformance
8129+
Evaluator &evaluator, NormalProtocolConformance *conformance
81218130
) const {
81228131
// If there is raw isolation, use that.
81238132
if (auto rawIsolation = conformance->getRawIsolation())
81248133
return *rawIsolation;
81258134

81268135
// Otherwise, we may infer isolation.
8127-
8128-
// Only normal protocol conformances can be isolated.
8129-
auto rootNormal =
8130-
dyn_cast<NormalProtocolConformance>(conformance->getRootConformance());
8131-
if (!rootNormal)
8132-
return ActorIsolation::forNonisolated(false);
8133-
8134-
if (conformance != rootNormal)
8135-
return rootNormal->getIsolation();
8136-
81378136
return inferConformanceIsolation(
8138-
rootNormal, /*hasKnownIsolatedWitness=*/false);
8137+
conformance, /*hasKnownIsolatedWitness=*/false);
81398138
}
81408139

81418140
namespace {

0 commit comments

Comments
 (0)