Skip to content

Commit 36b7711

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.
1 parent c019b66 commit 36b7711

File tree

6 files changed

+78
-0
lines changed

6 files changed

+78
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8776,5 +8776,13 @@ ERROR(extensible_attr_on_internal_type,none,
87768776
ERROR(pre_enum_extensibility_without_extensible,none,
87778777
"%0 can only be used together with '@extensible' attribute", (DeclAttribute))
87788778

8779+
//===----------------------------------------------------------------------===//
8780+
// MARK: `using` declaration
8781+
//===----------------------------------------------------------------------===//
8782+
ERROR(invalid_redecl_of_file_isolation,none,
8783+
"invalid redeclaration of file-level default actor isolation", ())
8784+
NOTE(invalid_redecl_of_file_isolation_prev,none,
8785+
"default isolation was previously declared here", ())
8786+
87798787
#define UNDEFINE_DIAGNOSTIC_MACROS
87808788
#include "DefineDiagnosticMacros.h"

include/swift/AST/SourceFile.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class GeneratedSourceInfo;
3232
class PersistentParserState;
3333
struct SourceFileExtras;
3434
class Token;
35+
enum class DefaultIsolation : uint8_t;
3536

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

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

include/swift/AST/TypeCheckRequests.h

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

5335+
class DefaultIsolationInSourceFileRequest
5336+
: public SimpleRequest<DefaultIsolationInSourceFileRequest,
5337+
std::optional<DefaultIsolation>(const SourceFile *),
5338+
RequestFlags::Cached> {
5339+
public:
5340+
using SimpleRequest::SimpleRequest;
5341+
5342+
private:
5343+
friend SimpleRequest;
5344+
5345+
std::optional<DefaultIsolation> evaluate(Evaluator &evaluator,
5346+
const SourceFile *file) const;
5347+
5348+
public:
5349+
bool isCached() const { return true; }
5350+
};
5351+
53355352
#define SWIFT_TYPEID_ZONE TypeChecker
53365353
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
53375354
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,3 +629,7 @@ SWIFT_REQUEST(TypeChecker, SemanticAvailabilitySpecRequest,
629629
std::optional<SemanticAvailabilitySpec>
630630
(const AvailabilitySpec *, const DeclContext *),
631631
SeparatelyCached, NoLocationInfo)
632+
633+
SWIFT_REQUEST(TypeChecker, DefaultIsolationInSourceFileRequest,
634+
std::optional<DefaultIsolation>(const SourceFile *),
635+
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
@@ -6456,6 +6456,43 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
64566456
return requiredIsolation;
64576457
}
64586458

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

0 commit comments

Comments
 (0)