Skip to content

Commit 7d18588

Browse files
committed
[Concurrency] Add a request to retrieve default isolation of a file
The default isolation is computed based on `using` declaration found in the file, if any. (cherry picked from commit 36b7711)
1 parent 77a36f2 commit 7d18588

File tree

6 files changed

+79
-0
lines changed

6 files changed

+79
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8676,5 +8676,14 @@ GROUPED_WARNING(
86768676
"behavior",
86778677
(StringRef))
86788678

8679+
//===----------------------------------------------------------------------===//
8680+
// MARK: `using` declaration
8681+
//===----------------------------------------------------------------------===//
8682+
ERROR(invalid_redecl_of_file_isolation,none,
8683+
"invalid redeclaration of file-level default actor isolation", ())
8684+
NOTE(invalid_redecl_of_file_isolation_prev,none,
8685+
"default isolation was previously declared here", ())
8686+
8687+
86798688
#define UNDEFINE_DIAGNOSTIC_MACROS
86808689
#include "DefineDiagnosticMacros.h"

include/swift/AST/SourceFile.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class AvailabilityScope;
3131
class PersistentParserState;
3232
struct SourceFileExtras;
3333
class Token;
34+
enum class DefaultIsolation : uint8_t;
3435

3536
/// Kind of import affecting how a decl can be reexported.
3637
///
@@ -689,6 +690,11 @@ class SourceFile final : public FileUnit {
689690
DelayedParserState = std::move(state);
690691
}
691692

693+
/// Retrieve default action isolation to be used for this source file.
694+
/// It's determine based on on top-level `using <<isolation>>` declaration
695+
/// found in the file.
696+
std::optional<DefaultIsolation> getDefaultIsolation() const;
697+
692698
SWIFT_DEBUG_DUMP;
693699
void
694700
dump(raw_ostream &os,

include/swift/AST/TypeCheckRequests.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5313,6 +5313,23 @@ class SemanticAvailabilitySpecRequest
53135313
void cacheResult(std::optional<SemanticAvailabilitySpec> value) const;
53145314
};
53155315

5316+
class DefaultIsolationInSourceFileRequest
5317+
: public SimpleRequest<DefaultIsolationInSourceFileRequest,
5318+
std::optional<DefaultIsolation>(const SourceFile *),
5319+
RequestFlags::Cached> {
5320+
public:
5321+
using SimpleRequest::SimpleRequest;
5322+
5323+
private:
5324+
friend SimpleRequest;
5325+
5326+
std::optional<DefaultIsolation> evaluate(Evaluator &evaluator,
5327+
const SourceFile *file) const;
5328+
5329+
public:
5330+
bool isCached() const { return true; }
5331+
};
5332+
53165333
#define SWIFT_TYPEID_ZONE TypeChecker
53175334
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
53185335
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,3 +626,7 @@ SWIFT_REQUEST(TypeChecker, SemanticAvailabilitySpecRequest,
626626
std::optional<SemanticAvailabilitySpec>
627627
(const AvailabilitySpec *, const DeclContext *),
628628
SeparatelyCached, NoLocationInfo)
629+
630+
SWIFT_REQUEST(TypeChecker, DefaultIsolationInSourceFileRequest,
631+
std::optional<DefaultIsolation>(const SourceFile *),
632+
Cached, NoLocationInfo)

lib/AST/Module.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3829,6 +3829,12 @@ bool SourceFile::FileIDStr::matches(const SourceFile *file) const {
38293829
fileName == llvm::sys::path::filename(file->getFilename());
38303830
}
38313831

3832+
std::optional<DefaultIsolation> SourceFile::getDefaultIsolation() const {
3833+
auto &ctx = getASTContext();
3834+
return evaluateOrDefault(
3835+
ctx.evaluator, DefaultIsolationInSourceFileRequest{this}, std::nullopt);
3836+
}
3837+
38323838
namespace {
38333839
class LocalTypeDeclCollector : public ASTWalker {
38343840
SmallVectorImpl<TypeDecl *> &results;

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6462,6 +6462,43 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
64626462
return requiredIsolation;
64636463
}
64646464

6465+
std::optional<DefaultIsolation>
6466+
DefaultIsolationInSourceFileRequest::evaluate(Evaluator &evaluator,
6467+
const SourceFile *file) const {
6468+
llvm::SmallVector<Decl *> usingDecls;
6469+
llvm::copy_if(file->getTopLevelDecls(), std::back_inserter(usingDecls),
6470+
[](Decl *D) { return isa<UsingDecl>(D); });
6471+
6472+
if (usingDecls.empty())
6473+
return std::nullopt;
6474+
6475+
std::optional<std::pair<Decl *, DefaultIsolation>> isolation;
6476+
6477+
auto setIsolation = [&isolation](Decl *D, DefaultIsolation newIsolation) {
6478+
if (isolation) {
6479+
D->diagnose(diag::invalid_redecl_of_file_isolation);
6480+
isolation->first->diagnose(diag::invalid_redecl_of_file_isolation_prev);
6481+
return;
6482+
}
6483+
6484+
isolation = std::make_pair(D, newIsolation);
6485+
};
6486+
6487+
for (auto *D : usingDecls) {
6488+
switch (cast<UsingDecl>(D)->getSpecifier()) {
6489+
case UsingSpecifier::MainActor:
6490+
setIsolation(D, DefaultIsolation::MainActor);
6491+
break;
6492+
case UsingSpecifier::nonisolated:
6493+
setIsolation(D, DefaultIsolation::Nonisolated);
6494+
break;
6495+
}
6496+
}
6497+
6498+
return isolation.has_value() ? std::optional(isolation->second)
6499+
: std::nullopt;
6500+
}
6501+
64656502
void swift::checkOverrideActorIsolation(ValueDecl *value) {
64666503
if (isa<TypeDecl>(value))
64676504
return;

0 commit comments

Comments
 (0)