Skip to content

Commit 2a2a130

Browse files
committed
[concurrency] Add initial support for SwiftSettings to control defaultIsolation at the file level.
We introduce a new macro called #SwiftSettings that can be used in conjunction with a new stdlib type called SwiftSetting to control the default isolation at the file level. It overrides the current default isolation whether it is the current nonisolated state or main actor (when -enable-experimental-feature UnspecifiedMeansMainActorIsolated is set).
1 parent edc7420 commit 2a2a130

24 files changed

+532
-28
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,8 @@ enum ENUM_EXTENSIBILITY_ATTR(open) BridgedMacroDefinitionKind : size_t {
28822882
BridgedBuiltinExternalMacro,
28832883
/// The builtin definition for the "isolation" macro.
28842884
BridgedBuiltinIsolationMacro,
2885+
/// The builtin definition for the "SwiftSetting" macro.
2886+
BridgedBuiltinSwiftSettingsMacro,
28852887
};
28862888

28872889
struct BridgedASTType {

include/swift/AST/DiagnosticsSema.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8375,6 +8375,15 @@ ERROR(invalid_function_conversion_with_non_sendable,none,
83758375
NOTE(type_does_not_conform_to_Sendable,none,
83768376
"type %0 does not conform to 'Sendable' protocol", (Type))
83778377

8378+
//===----------------------------------------------------------------------===//
8379+
// MARK: SwiftSettings
8380+
//===----------------------------------------------------------------------===//
8381+
8382+
ERROR(swift_settings_invalid_setting, none,
8383+
"Unrecognized setting passed to #SwiftSettings", ())
8384+
8385+
ERROR(swift_settings_must_be_top_level, none,
8386+
"#SwiftSettings can only be invoked as a top level declaration", ())
83788387

83798388
#define UNDEFINE_DIAGNOSTIC_MACROS
83808389
#include "DefineDiagnosticMacros.h"

include/swift/AST/FileUnit.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
3939
friend class DirectOperatorLookupRequest;
4040
friend class DirectPrecedenceGroupLookupRequest;
4141

42-
// The pointer is FileUnit insted of SynthesizedFileUnit to break circularity.
42+
/// The pointer is FileUnit insted of SynthesizedFileUnit to break
43+
/// circularity.
4344
llvm::PointerIntPair<FileUnit *, 3, FileUnitKind> SynthesizedFileAndKind;
4445

4546
protected:

include/swift/AST/KnownStdlibTypes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,6 @@ KNOWN_STDLIB_TYPE_DECL(Result, NominalTypeDecl, 2)
101101

102102
KNOWN_STDLIB_TYPE_DECL(InlineArray, NominalTypeDecl, 2)
103103

104+
KNOWN_STDLIB_TYPE_DECL(SwiftSetting, NominalTypeDecl, 0)
105+
104106
#undef KNOWN_STDLIB_TYPE_DECL

include/swift/AST/MacroDefinition.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
#ifndef SWIFT_AST_MACRO_DEFINITION_H
1919
#define SWIFT_AST_MACRO_DEFINITION_H
2020

21+
#include "swift/AST/Identifier.h"
2122
#include "swift/Basic/StringExtras.h"
23+
24+
#include "llvm/ADT/ArrayRef.h"
2225
#include "llvm/ADT/PointerUnion.h"
2326

2427
namespace swift {
@@ -69,11 +72,14 @@ struct ExternalMacroReference {
6972
};
7073

7174
/// Describes the known kinds of builtin macros.
72-
enum class BuiltinMacroKind: uint8_t {
75+
enum class BuiltinMacroKind : uint8_t {
7376
/// #externalMacro, which references an external macro.
7477
ExternalMacro,
7578
/// #isolation, which produces the isolation of the current context
7679
IsolationMacro,
80+
/// #SwiftSettings, which allows for the user to set a compiler setting at
81+
/// the file level
82+
SwiftSettingsMacro,
7783
};
7884

7985
/// A single replacement

include/swift/AST/SourceFile.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ enum class RestrictedImportKind {
5353
/// Import that limits the access level of imported entities.
5454
using ImportAccessLevel = std::optional<AttributedImport<ImportedModule>>;
5555

56+
/// Language options only for use with a specific SourceFile.
57+
///
58+
/// Vended by SourceFile::getLanguageOptions().
59+
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;
63+
};
64+
5665
/// A file containing Swift source code.
5766
///
5867
/// This is a .swift or .sil file (or a virtual file, such as the contents of
@@ -562,6 +571,9 @@ class SourceFile final : public FileUnit {
562571
ObjCSelector selector,
563572
SmallVectorImpl<AbstractFunctionDecl *> &results) const override;
564573

574+
/// File level language options.
575+
SourceFileLangOptions getLanguageOptions() const;
576+
565577
protected:
566578
virtual void
567579
lookupOperatorDirect(Identifier name, OperatorFixity fixity,

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5228,6 +5228,25 @@ class SemanticAvailableAttrRequest
52285228
void cacheResult(std::optional<SemanticAvailableAttr> value) const;
52295229
};
52305230

5231+
class SourceFileLangOptionsRequest
5232+
: public SimpleRequest<SourceFileLangOptionsRequest,
5233+
SourceFileLangOptions(SourceFile *),
5234+
RequestFlags::Cached> {
5235+
public:
5236+
using SimpleRequest::SimpleRequest;
5237+
5238+
private:
5239+
friend SimpleRequest;
5240+
5241+
SourceFileLangOptions evaluate(Evaluator &evaluator,
5242+
SourceFile *sourceFile) const;
5243+
5244+
public:
5245+
bool isCached() const { return true; }
5246+
std::optional<SourceFileLangOptions> getCachedResult() const;
5247+
void cacheResult(SourceFileLangOptions value) const;
5248+
};
5249+
52315250
#define SWIFT_TYPEID_ZONE TypeChecker
52325251
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
52335252
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,6 @@ SWIFT_REQUEST(TypeChecker, SemanticAvailableAttrRequest,
616616
std::optional<SemanticAvailableAttr>
617617
(const AvailableAttr *, const Decl *),
618618
SeparatelyCached, NoLocationInfo)
619+
620+
SWIFT_REQUEST(TypeChecker, SourceFileLangOptionsRequest,
621+
SourceFileLangOptions (SourceFile *), Cached, NoLocationInfo)

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,9 @@ EXPERIMENTAL_FEATURE(ExtensibleEnums, true)
476476
/// Allow isolated conformances.
477477
EXPERIMENTAL_FEATURE(IsolatedConformances, true)
478478

479+
/// Allow SwiftSettings
480+
EXPERIMENTAL_FEATURE(SwiftSettings, false)
481+
479482
/// Syntax sugar features for concurrency.
480483
EXPERIMENTAL_FEATURE(ConcurrencySyntaxSugar, true)
481484

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4721,6 +4721,9 @@ void PrintAST::visitMacroDecl(MacroDecl *decl) {
47214721
case BuiltinMacroKind::IsolationMacro:
47224722
Printer << "IsolationMacro";
47234723
break;
4724+
case BuiltinMacroKind::SwiftSettingsMacro:
4725+
Printer << "SwiftSettingsMacro";
4726+
break;
47244727
}
47254728
break;
47264729

lib/AST/FeatureSet.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ using namespace swift;
2626

2727
/// Does the interface of this declaration use a type for which the
2828
/// given predicate returns true?
29-
static bool usesTypeMatching(Decl *decl, llvm::function_ref<bool(Type)> fn) {
29+
static bool usesTypeMatching(const Decl *decl,
30+
llvm::function_ref<bool(Type)> fn) {
3031
if (auto value = dyn_cast<ValueDecl>(decl)) {
3132
if (Type type = value->getInterfaceType()) {
3233
return type.findIf(fn);
@@ -390,6 +391,24 @@ UNINTERESTING_FEATURE(ImportNonPublicCxxMembers)
390391
UNINTERESTING_FEATURE(CoroutineAccessorsUnwindOnCallerError)
391392
UNINTERESTING_FEATURE(CoroutineAccessorsAllocateInCallee)
392393

394+
static bool usesFeatureSwiftSettings(const Decl *decl) {
395+
// If we cannot find the struct SwiftSetting decl, then we could not have
396+
// specified #SwiftSettings.
397+
if (!decl->getASTContext().getSwiftSettingDecl())
398+
return false;
399+
400+
if (auto *nom = dyn_cast<NominalTypeDecl>(decl))
401+
return nom == decl->getASTContext().getSwiftSettingDecl();
402+
if (auto *ext = dyn_cast<ExtensionDecl>(decl))
403+
if (auto *nominal = ext->getExtendedNominal())
404+
if (usesFeatureSwiftSettings(nominal))
405+
return true;
406+
return usesTypeMatching(decl, [&](Type type) -> bool {
407+
return type->getCanonicalType() ==
408+
decl->getASTContext().getSwiftSettingType()->getCanonicalType();
409+
});
410+
}
411+
393412
bool swift::usesFeatureIsolatedDeinit(const Decl *decl) {
394413
if (auto cd = dyn_cast<ClassDecl>(decl)) {
395414
return cd->getFormalAccess() == AccessLevel::Open &&

0 commit comments

Comments
 (0)