Skip to content

Commit 189e58f

Browse files
committed
[Concurrency] Compute the source of actor isolation in ActorIsolationRequest.
1 parent 725dc3c commit 189e58f

11 files changed

+280
-59
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,13 @@ class ActorIsolation {
275275
void print(llvm::raw_ostream &os) const;
276276

277277
void printForSIL(llvm::raw_ostream &os) const;
278-
278+
279+
/// Print the given isolation for diagnostics. If \c asNoun is \c false,
280+
/// the participle adjective form is printed, e.g. "main actor-isolated".
281+
/// Otherwise, the noun form is printed, e.g. "main actor isolation".
279282
void printForDiagnostics(llvm::raw_ostream &os,
280-
StringRef openingQuotationMark = "'") const;
283+
StringRef openingQuotationMark = "'",
284+
bool asNoun = false) const;
281285

282286
SWIFT_DEBUG_DUMPER(dump());
283287

@@ -287,9 +291,61 @@ class ActorIsolation {
287291
SWIFT_DEBUG_DUMPER(dumpForDiagnostics());
288292
};
289293

294+
struct IsolationSource {
295+
enum Kind : uint8_t {
296+
/// Isolation is written in an explicit attribute.
297+
Explicit,
298+
/// Isolation is inferred from the enclosing lexical context.
299+
LexicalContext,
300+
/// Isolation is inferred from conformance to a protocol.
301+
Conformance,
302+
/// Isolation is inherited from a superclass.
303+
Superclass,
304+
/// Isolation is inferred from an overridden superclass method.
305+
Override,
306+
/// Isolation is inferred from \c @main.
307+
MainFunction,
308+
/// Isolation is inferred in top-level code.
309+
TopLevelCode,
310+
/// Something else.
311+
None,
312+
};
313+
314+
/// The declaration with the original isolation attribute.
315+
ValueDecl *inferenceSource;
316+
Kind kind;
317+
318+
IsolationSource(ValueDecl *inferenceSource = nullptr,
319+
Kind kind = Kind::None)
320+
: inferenceSource(inferenceSource), kind(kind) {}
321+
322+
void printForDiagnostics(llvm::raw_ostream &os,
323+
StringRef openingQuotationMark = "'") const;
324+
};
325+
326+
struct InferredActorIsolation {
327+
ActorIsolation isolation;
328+
IsolationSource source;
329+
330+
static InferredActorIsolation forUnspecified() {
331+
return {
332+
ActorIsolation::forUnspecified(),
333+
IsolationSource()
334+
};
335+
}
336+
337+
bool preconcurrency() const {
338+
return isolation.preconcurrency();
339+
}
340+
};
341+
290342
/// Determine how the given value declaration is isolated.
291343
ActorIsolation getActorIsolation(ValueDecl *value);
292344

345+
/// Infer the actor isolation of the given declaration, including
346+
/// the source of isolation inference.
347+
InferredActorIsolation getInferredActorIsolation(ValueDecl *value);
348+
293349
/// Trampoline for AbstractClosureExpr::getActorIsolation.
294350
ActorIsolation
295351
__AbstractClosureExpr_getActorIsolation(AbstractClosureExpr *CE);

include/swift/AST/DiagnosticEngine.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ namespace swift {
140140
VersionTuple,
141141
LayoutConstraint,
142142
ActorIsolation,
143+
IsolationSource,
143144
Diagnostic,
144145
ClangDecl
145146
};
@@ -175,6 +176,7 @@ namespace swift {
175176
llvm::VersionTuple VersionVal;
176177
LayoutConstraint LayoutConstraintVal;
177178
ActorIsolation ActorIsolationVal;
179+
IsolationSource IsolationSourceVal;
178180
DiagnosticInfo *DiagnosticVal;
179181
const clang::NamedDecl *ClangDecl;
180182
};
@@ -283,6 +285,11 @@ namespace swift {
283285
ActorIsolationVal(AI) {
284286
}
285287

288+
DiagnosticArgument(IsolationSource IS)
289+
: Kind(DiagnosticArgumentKind::IsolationSource),
290+
IsolationSourceVal(IS){
291+
}
292+
286293
DiagnosticArgument(DiagnosticInfo *D)
287294
: Kind(DiagnosticArgumentKind::Diagnostic),
288295
DiagnosticVal(D) {
@@ -402,6 +409,11 @@ namespace swift {
402409
return ActorIsolationVal;
403410
}
404411

412+
IsolationSource getAsIsolationSource() const {
413+
assert(Kind == DiagnosticArgumentKind::IsolationSource);
414+
return IsolationSourceVal;
415+
}
416+
405417
DiagnosticInfo *getAsDiagnostic() const {
406418
assert(Kind == DiagnosticArgumentKind::Diagnostic);
407419
return DiagnosticVal;

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5535,6 +5535,10 @@ NOTE(actor_isolated_sync_func_value,none,
55355535
"calls function of type %0 from outside of its actor context are "
55365536
"implicitly asynchronous",
55375537
(Type))
5538+
NOTE(actor_isolation_source,none,
5539+
"%noun0 inferred from %1",
5540+
(ActorIsolation, IsolationSource))
5541+
55385542
NOTE(note_distributed_actor_isolated_method,none,
55395543
"distributed actor-isolated %kind0 declared here",
55405544
(const ValueDecl *))

include/swift/AST/TypeCheckRequests.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,15 +1536,16 @@ class GlobalActorAttributeRequest
15361536
/// Determine the actor isolation for the given declaration.
15371537
class ActorIsolationRequest :
15381538
public SimpleRequest<ActorIsolationRequest,
1539-
ActorIsolation(ValueDecl *),
1539+
InferredActorIsolation(ValueDecl *),
15401540
RequestFlags::Cached> {
15411541
public:
15421542
using SimpleRequest::SimpleRequest;
15431543

15441544
private:
15451545
friend SimpleRequest;
15461546

1547-
ActorIsolation evaluate(Evaluator &evaluator, ValueDecl *value) const;
1547+
InferredActorIsolation evaluate(Evaluator &evaluator,
1548+
ValueDecl *value) const;
15481549

15491550
public:
15501551
// Caching

lib/AST/Decl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11295,10 +11295,15 @@ bool VarDecl::isSelfParamCaptureIsolated() const {
1129511295
}
1129611296

1129711297
ActorIsolation swift::getActorIsolation(ValueDecl *value) {
11298+
return getInferredActorIsolation(value).isolation;
11299+
}
11300+
11301+
InferredActorIsolation
11302+
swift::getInferredActorIsolation(ValueDecl *value) {
1129811303
auto &ctx = value->getASTContext();
1129911304
return evaluateOrDefault(
1130011305
ctx.evaluator, ActorIsolationRequest{value},
11301-
ActorIsolation::forUnspecified());
11306+
InferredActorIsolation::forUnspecified());
1130211307
}
1130311308

1130411309
ActorIsolation swift::getActorIsolationOfContext(

lib/AST/DiagnosticEngine.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,8 +1012,16 @@ static void formatDiagnosticArgument(StringRef Modifier,
10121012
<< FormatOpts.ClosingQuotationMark;
10131013
break;
10141014
case DiagnosticArgumentKind::ActorIsolation: {
1015-
assert(Modifier.empty() && "Improper modifier for ActorIsolation argument");
1015+
assert((Modifier.empty() || Modifier == "noun") &&
1016+
"Improper modifier for ActorIsolation argument");
10161017
auto isolation = Arg.getAsActorIsolation();
1018+
isolation.printForDiagnostics(Out, FormatOpts.OpeningQuotationMark,
1019+
/*asNoun*/ Modifier == "noun");
1020+
break;
1021+
}
1022+
case DiagnosticArgumentKind::IsolationSource: {
1023+
assert(Modifier.empty() && "Improper modifier for IsolationSource argument");
1024+
auto isolation = Arg.getAsIsolationSource();
10171025
isolation.printForDiagnostics(Out, FormatOpts.OpeningQuotationMark);
10181026
break;
10191027
}

lib/AST/TypeCheckRequests.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,19 +1804,20 @@ ActorIsolation ActorIsolation::subst(SubstitutionMap subs) const {
18041804
}
18051805

18061806
void ActorIsolation::printForDiagnostics(llvm::raw_ostream &os,
1807-
StringRef openingQuotationMark) const {
1807+
StringRef openingQuotationMark,
1808+
bool asNoun) const {
18081809
switch (*this) {
18091810
case ActorIsolation::ActorInstance:
1810-
os << "actor-isolated";
1811+
os << "actor" << (asNoun ? " isolation" : "-isolated");
18111812
break;
18121813

18131814
case ActorIsolation::GlobalActor: {
18141815
if (isMainActor()) {
1815-
os << "main actor-isolated";
1816+
os << "main actor" << (asNoun ? " isolation" : "-isolated");
18161817
} else {
18171818
Type globalActor = getGlobalActor();
18181819
os << "global actor " << openingQuotationMark << globalActor.getString()
1819-
<< openingQuotationMark << "-isolated";
1820+
<< openingQuotationMark << (asNoun ? " isolation" : "-isolated");
18201821
}
18211822
break;
18221823
}
@@ -1942,6 +1943,46 @@ void swift::simple_display(
19421943
}
19431944
}
19441945

1946+
void IsolationSource::printForDiagnostics(
1947+
llvm::raw_ostream &os,
1948+
StringRef openingQuotationMark) const {
1949+
switch (this->kind) {
1950+
case IsolationSource::Explicit:
1951+
case IsolationSource::None:
1952+
return;
1953+
1954+
case IsolationSource::MainFunction:
1955+
os << "@main";
1956+
return;
1957+
1958+
case IsolationSource::TopLevelCode:
1959+
os << "top-level code";
1960+
return;
1961+
1962+
case IsolationSource::LexicalContext: {
1963+
os << "isolation inheritance from ";
1964+
break;
1965+
}
1966+
1967+
case IsolationSource::Conformance:
1968+
os << "conformance to ";
1969+
break;
1970+
1971+
case IsolationSource::Superclass:
1972+
os << "inheritance from ";
1973+
break;
1974+
1975+
case IsolationSource::Override:
1976+
os << "overriding ";
1977+
break;
1978+
}
1979+
1980+
os << Decl::getDescriptiveKindName(inferenceSource->getDescriptiveKind()) << " ";
1981+
os << openingQuotationMark;
1982+
inferenceSource->getName().printPretty(os);
1983+
os << openingQuotationMark;
1984+
}
1985+
19451986
bool swift::areTypesEqual(Type type1, Type type2) {
19461987
if (!type1 || !type2)
19471988
return !type1 && !type2;

0 commit comments

Comments
 (0)