Skip to content

Commit 7ae040e

Browse files
committed
[Concurrency] Simplify the logic in computeDefaultInferredActorIsolation.
1 parent a7b8cb7 commit 7ae040e

File tree

3 files changed

+36
-53
lines changed

3 files changed

+36
-53
lines changed

include/swift/AST/SourceFile.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/Import.h"
2121
#include "swift/AST/SynthesizedFileUnit.h"
2222
#include "swift/Basic/Debug.h"
23+
#include "swift/Basic/LangOptions.h"
2324
#include "llvm/ADT/Hashing.h"
2425
#include "llvm/ADT/STLExtras.h"
2526
#include "llvm/ADT/SetVector.h"
@@ -57,9 +58,9 @@ using ImportAccessLevel = std::optional<AttributedImport<ImportedModule>>;
5758
///
5859
/// Vended by SourceFile::getLanguageOptions().
5960
struct SourceFileLangOptions {
60-
/// If unset, no value was provided. If a Type, that type is the type of the
61-
/// isolation. If set to an empty type, nil was specified explicitly.
62-
std::optional<Type> defaultIsolation;
61+
/// The default actor isolation to infer on declarations
62+
/// within the source file.
63+
std::optional<DefaultIsolation> defaultIsolation;
6364
};
6465

6566
/// A file containing Swift source code.

lib/AST/Module.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4218,12 +4218,11 @@ struct SwiftSettingsWalker : ASTWalker {
42184218
}
42194219

42204220
/// Given a specific CallExpr, pattern matches the CallExpr's first argument
4221-
/// to validate it is MainActor.self. Returns CanType() if the CallExpr has
4222-
/// multiple parameters or if its first parameter is not a MainActor.self.
4221+
/// to validate it is MainActor.self.
42234222
///
4224-
/// This is used when pattern matching against
4225-
/// .defaultIsolation(MainActor.self).
4226-
CanType patternMatchDefaultIsolationMainActor(CallExpr *callExpr);
4223+
/// \returns \c true if the call has one argument that matches
4224+
/// \c MainActor.self, and \c false otherwise.
4225+
bool patternMatchDefaultIsolationMainActor(CallExpr *callExpr);
42274226

42284227
/// Validates that macroExpr is a well formed "SwiftSettings" macro. Returns
42294228
/// true if we can process it and false otherwise.
@@ -4289,16 +4288,16 @@ struct SwiftSettingsWalker : ASTWalker {
42894288
}
42904289

42914290
// Otherwise, set things up appropriately.
4292-
if (auto actor = patternMatchDefaultIsolationMainActor(callExpr)) {
4291+
if (patternMatchDefaultIsolationMainActor(callExpr)) {
42934292
expr = callExpr;
4294-
result.defaultIsolation = actor;
4293+
result.defaultIsolation = DefaultIsolation::MainActor;
42954294
foundValidArg = true;
42964295
continue;
42974296
}
42984297

42994298
if (isa<NilLiteralExpr>(callExpr->getArgs()->getExpr(0))) {
43004299
expr = callExpr;
4301-
result.defaultIsolation = {Type()};
4300+
result.defaultIsolation = DefaultIsolation::Nonisolated;
43024301
foundValidArg = true;
43034302
continue;
43044303
}
@@ -4400,18 +4399,18 @@ SwiftSettingsWalker::getSwiftSettingArgDecl(Argument arg) {
44004399
return {{callExpr, f}};
44014400
}
44024401

4403-
CanType
4402+
bool
44044403
SwiftSettingsWalker::patternMatchDefaultIsolationMainActor(CallExpr *callExpr) {
44054404
// Grab the dot self expr.
44064405
auto *selfExpr = dyn_cast<DotSelfExpr>(callExpr->getArgs()->getExpr(0));
44074406
if (!selfExpr)
4408-
return CanType();
4407+
return false;
44094408

44104409
// Then validate we have something that is MainActor.
44114410
auto *declRefExpr = dyn_cast<UnresolvedDeclRefExpr>(selfExpr->getSubExpr());
44124411
if (!declRefExpr ||
44134412
!declRefExpr->getName().getBaseName().getIdentifier().is("MainActor"))
4414-
return CanType();
4413+
return false;
44154414

44164415
// Then use unqualified lookup descriptor to find our MainActor.
44174416
UnqualifiedLookupDescriptor lookupDesc{
@@ -4420,20 +4419,20 @@ SwiftSettingsWalker::patternMatchDefaultIsolationMainActor(CallExpr *callExpr) {
44204419
auto lookup = evaluateOrDefault(ctx.evaluator,
44214420
UnqualifiedLookupRequest{lookupDesc}, {});
44224421
if (lookup.allResults().empty())
4423-
return CanType();
4422+
return false;
44244423

44254424
// Then grab our nominal type decl and make sure it is from the concurrency
44264425
// module.
44274426
auto *nomDecl =
44284427
dyn_cast<NominalTypeDecl>(lookup.allResults().front().getValueDecl());
44294428
if (!nomDecl)
4430-
return CanType();
4429+
return false;
44314430
auto *nomDeclDC = nomDecl->getDeclContext();
44324431
auto *nomDeclModule = nomDecl->getParentModule();
44334432
if (!nomDeclDC->isModuleScopeContext() || !nomDeclModule->isConcurrencyModule())
4434-
return CanType();
4433+
return false;
44354434

4436-
return nomDecl->getDeclaredType()->getCanonicalType();
4435+
return true;
44374436
}
44384437

44394438
SourceFileLangOptions

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5753,12 +5753,21 @@ static std::tuple<InferredActorIsolation, ValueDecl *,
57535753
computeDefaultInferredActorIsolation(ValueDecl *value) {
57545754
auto &ctx = value->getASTContext();
57555755

5756-
// If we are supposed to infer main actor isolation by default for entities
5757-
// within our module, make our default isolation main actor.
5756+
// Determine whether default isolation is set to MainActor, either for
5757+
// the entire module or in this specific file.
57585758
if (value->getModuleContext() == ctx.MainModule) {
5759-
auto globalActorHelper = [&](Type globalActor)
5760-
-> std::optional<std::tuple<InferredActorIsolation, ValueDecl *,
5761-
std::optional<ActorIsolation>>> {
5759+
// See if we have one specified by our file unit.
5760+
auto defaultIsolation = ctx.LangOpts.DefaultIsolationBehavior;
5761+
if (ctx.LangOpts.hasFeature(Feature::SwiftSettings)) {
5762+
if (auto *sourceFile = value->getDeclContext()->getParentSourceFile()) {
5763+
auto options = sourceFile->getLanguageOptions();
5764+
if (auto isolation = options.defaultIsolation) {
5765+
defaultIsolation = *isolation;
5766+
}
5767+
}
5768+
}
5769+
5770+
if (defaultIsolation == DefaultIsolation::MainActor) {
57625771
// Default global actor isolation does not apply to any declarations
57635772
// within actors and distributed actors.
57645773
bool inActorContext = false;
@@ -5770,44 +5779,18 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
57705779
dc = dc->getParent();
57715780
}
57725781

5782+
auto mainActorType = ctx.getMainActorType()->mapTypeOutOfContext();
57735783
if (!inActorContext) {
57745784
// FIXME: deinit should be implicitly MainActor too.
57755785
if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
57765786
isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
57775787
isa<ConstructorDecl>(value)) {
5778-
return {
5779-
{{ActorIsolation::forGlobalActor(globalActor), {}}, nullptr, {}}};
5780-
}
5781-
}
5782-
5783-
return {};
5784-
};
5785-
5786-
// Otherwise, see if we have one specified by our file unit.
5787-
bool ignoreUnspecifiedMeansMainActorIsolated = false;
5788-
if (ctx.LangOpts.hasFeature(Feature::SwiftSettings)) {
5789-
if (auto *sourceFile = value->getDeclContext()->getParentSourceFile()) {
5790-
auto options = sourceFile->getLanguageOptions();
5791-
if (auto isolation = options.defaultIsolation) {
5792-
if (*isolation) {
5793-
auto result = globalActorHelper(*options.defaultIsolation);
5794-
if (result)
5795-
return *result;
5796-
} else {
5797-
// If we found a nil type, then we know we should ignore unspecified
5798-
// means main actor isolated.
5799-
ignoreUnspecifiedMeansMainActorIsolated = true;
5800-
}
5788+
auto mainActorIsolation =
5789+
ActorIsolation::forGlobalActor(mainActorType);
5790+
return {{mainActorIsolation, {}}, nullptr, {}};
58015791
}
58025792
}
58035793
}
5804-
5805-
// If we are required to use main actor... just use that.
5806-
if (!ignoreUnspecifiedMeansMainActorIsolated &&
5807-
ctx.LangOpts.DefaultIsolationBehavior == DefaultIsolation::MainActor)
5808-
if (auto result =
5809-
globalActorHelper(ctx.getMainActorType()->mapTypeOutOfContext()))
5810-
return *result;
58115794
}
58125795

58135796
// If we have an async function... by default we inherit isolation.

0 commit comments

Comments
 (0)