Skip to content

[AST/Sema] SE-0478: Implement using declaration under an experimental flag #81863

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SwiftCompilerSources/Sources/AST/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ final public class TopLevelCodeDecl: Decl {}

final public class ImportDecl: Decl {}

final public class UsingDecl: Decl {}

final public class PrecedenceGroupDecl: Decl {}

final public class MissingDecl: Decl {}
Expand Down
1 change: 1 addition & 0 deletions SwiftCompilerSources/Sources/AST/Registration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public func registerAST() {
registerDecl(ExtensionDecl.self)
registerDecl(TopLevelCodeDecl.self)
registerDecl(ImportDecl.self)
registerDecl(UsingDecl.self)
registerDecl(PrecedenceGroupDecl.self)
registerDecl(MissingDecl.self)
registerDecl(MissingMemberDecl.self)
Expand Down
13 changes: 13 additions & 0 deletions include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,19 @@ BridgedImportDecl BridgedImportDecl_createParsed(
BridgedSourceLoc cImportKeywordLoc, BridgedImportKind cImportKind,
BridgedSourceLoc cImportKindLoc, BridgedArrayRef cImportPathElements);

enum ENUM_EXTENSIBILITY_ATTR(open) BridgedUsingSpecifier {
BridgedUsingSpecifierMainActor,
BridgedUsingSpecifierNonisolated,
};

SWIFT_NAME("BridgedUsingDecl.createParsed(_:declContext:usingKeywordLoc:"
"specifierLoc:specifier:)")
BridgedUsingDecl BridgedUsingDecl_createParsed(BridgedASTContext cContext,
BridgedDeclContext cDeclContext,
BridgedSourceLoc usingKeywordLoc,
BridgedSourceLoc specifierLoc,
BridgedUsingSpecifier specifier);

SWIFT_NAME("BridgedSubscriptDecl.createParsed(_:declContext:staticLoc:"
"staticSpelling:subscriptKeywordLoc:genericParamList:parameterList:"
"arrowLoc:returnType:genericWhereClause:)")
Expand Down
45 changes: 44 additions & 1 deletion include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ enum class DescriptiveDeclKind : uint8_t {
OpaqueResultType,
OpaqueVarType,
Macro,
MacroExpansion
MacroExpansion,
Using
};

/// Describes which spelling was used in the source for the 'static' or 'class'
Expand Down Expand Up @@ -267,6 +268,16 @@ static_assert(uint8_t(SelfAccessKind::LastSelfAccessKind) <
"Self Access Kind is too small to fit in SelfAccess kind bits. "
"Please expand ");

enum class UsingSpecifier : uint8_t {
MainActor,
Nonisolated,
LastSpecifier = Nonisolated,
};
enum : unsigned {
NumUsingSpecifierBits =
countBitsUsed(static_cast<unsigned>(UsingSpecifier::LastSpecifier))
};

/// Diagnostic printing of \c SelfAccessKind.
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SelfAccessKind SAK);

Expand Down Expand Up @@ -827,6 +838,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
NumPathElements : 8
);

SWIFT_INLINE_BITFIELD(UsingDecl, Decl, NumUsingSpecifierBits,
Specifier : NumUsingSpecifierBits
);

SWIFT_INLINE_BITFIELD(ExtensionDecl, Decl, 4+1,
/// An encoding of the default and maximum access level for this extension.
/// The value 4 corresponds to AccessLevel::Public
Expand Down Expand Up @@ -9737,6 +9752,34 @@ class MacroExpansionDecl : public Decl, public FreestandingMacroExpansion {
}
};

/// UsingDecl - This represents a single `using` declaration, e.g.:
/// using @MainActor
class UsingDecl : public Decl {
friend class Decl;

private:
SourceLoc UsingLoc, SpecifierLoc;

UsingDecl(SourceLoc usingLoc, SourceLoc specifierLoc,
UsingSpecifier specifier, DeclContext *parent);

public:
UsingSpecifier getSpecifier() const {
return static_cast<UsingSpecifier>(Bits.UsingDecl.Specifier);
}

std::string getSpecifierName() const;

SourceLoc getLocFromSource() const { return UsingLoc; }
SourceRange getSourceRange() const { return {UsingLoc, SpecifierLoc}; }

static UsingDecl *create(ASTContext &ctx, SourceLoc usingLoc,
SourceLoc specifierLoc, UsingSpecifier specifier,
DeclContext *parent);

static bool classof(const Decl *D) { return D->getKind() == DeclKind::Using; }
};

inline void
AbstractStorageDecl::overwriteSetterAccess(AccessLevel accessLevel) {
Accessors.setInt(accessLevel);
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/DeclExportabilityVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class DeclExportabilityVisitor
UNREACHABLE(MissingMember);
UNREACHABLE(GenericTypeParam);
UNREACHABLE(Param);
UNREACHABLE(Using);

#undef UNREACHABLE

Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/DeclNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ DECL(Missing, Decl)
DECL(MissingMember, Decl)
DECL(PatternBinding, Decl)
DECL(EnumCase, Decl)
DECL(Using, Decl)

ABSTRACT_DECL(Operator, Decl)
OPERATOR_DECL(InfixOperator, OperatorDecl)
Expand Down
9 changes: 9 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -2187,5 +2187,14 @@ ERROR(nonisolated_nonsending_expected_rparen,PointsToFirstBadToken,
ERROR(nonisolated_nonsending_repeated,none,
"parameter may have at most one 'nonisolated(nonsending)' specifier", ())

//------------------------------------------------------------------------------
// MARK: using @<attribute> or using <identifier>
//------------------------------------------------------------------------------
ERROR(using_decl_invalid_specifier,PointsToFirstBadToken,
"default isolation can only be set to '@MainActor' or 'nonisolated'",
())
ERROR(experimental_using_decl_disabled,PointsToFirstBadToken,
"'using' is an experimental feature that is currently disabled", ())

#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
8 changes: 8 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -8776,5 +8776,13 @@ ERROR(extensible_attr_on_internal_type,none,
ERROR(pre_enum_extensibility_without_extensible,none,
"%0 can only be used together with '@extensible' attribute", (DeclAttribute))

//===----------------------------------------------------------------------===//
// MARK: `using` declaration
//===----------------------------------------------------------------------===//
ERROR(invalid_redecl_of_file_isolation,none,
"invalid redeclaration of file-level default actor isolation", ())
NOTE(invalid_redecl_of_file_isolation_prev,none,
"default isolation was previously declared here", ())

#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
6 changes: 6 additions & 0 deletions include/swift/AST/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class GeneratedSourceInfo;
class PersistentParserState;
struct SourceFileExtras;
class Token;
enum class DefaultIsolation : uint8_t;

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

/// Retrieve default action isolation to be used for this source file.
/// It's determine based on on top-level `using <<isolation>>` declaration
/// found in the file.
std::optional<DefaultIsolation> getDefaultIsolation() const;

SWIFT_DEBUG_DUMP;
void
dump(raw_ostream &os,
Expand Down
17 changes: 17 additions & 0 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -5332,6 +5332,23 @@ class SemanticAvailabilitySpecRequest
void cacheResult(std::optional<SemanticAvailabilitySpec> value) const;
};

class DefaultIsolationInSourceFileRequest
: public SimpleRequest<DefaultIsolationInSourceFileRequest,
std::optional<DefaultIsolation>(const SourceFile *),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

std::optional<DefaultIsolation> evaluate(Evaluator &evaluator,
const SourceFile *file) const;

public:
bool isCached() const { return true; }
};

#define SWIFT_TYPEID_ZONE TypeChecker
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,7 @@ SWIFT_REQUEST(TypeChecker, SemanticAvailabilitySpecRequest,
std::optional<SemanticAvailabilitySpec>
(const AvailabilitySpec *, const DeclContext *),
SeparatelyCached, NoLocationInfo)

SWIFT_REQUEST(TypeChecker, DefaultIsolationInSourceFileRequest,
std::optional<DefaultIsolation>(const SourceFile *),
Cached, NoLocationInfo)
1 change: 1 addition & 0 deletions include/swift/AST/TypeMemberVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class TypeMemberVisitor : public DeclVisitor<ImplClass, RetTy> {
BAD_MEMBER(Operator)
BAD_MEMBER(PrecedenceGroup)
BAD_MEMBER(Macro)
BAD_MEMBER(Using)

RetTy visitMacroExpansionDecl(MacroExpansionDecl *D) {
// Expansion already visited as auxiliary decls.
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,10 @@ SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ExtensibleAttribute, false)
/// Allow use of `Module::name` syntax
EXPERIMENTAL_FEATURE(ModuleSelector, false)

/// Allow use of `using` declaration that control default isolation
/// in a file scope.
EXPERIMENTAL_FEATURE(DefaultIsolationPerFile, false)

#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
#undef EXPERIMENTAL_FEATURE
#undef UPCOMING_FEATURE
Expand Down
1 change: 1 addition & 0 deletions include/swift/IDE/CodeCompletionResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ enum class CodeCompletionKeywordKind : uint8_t {
enum class CompletionKind : uint8_t {
None,
Import,
Using,
UnresolvedMember,
DotExpr,
StmtOrExpr,
Expand Down
2 changes: 2 additions & 0 deletions include/swift/IDE/CompletionLookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {

void addImportModuleNames();

void addUsingSpecifiers();

SemanticContextKind getSemanticContext(const Decl *D,
DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo);
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Parse/IDEInspectionCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ class CodeCompletionCallbacks {
virtual void
completeImportDecl(ImportPath::Builder &Path) {};

/// Complete the 'using' decl with supported specifiers.
virtual void
completeUsingDecl() {};

/// Complete unresolved members after dot.
virtual void completeUnresolvedMember(CodeCompletionExpr *E,
SourceLoc DotLoc) {};
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,9 @@ class Parser {
ParserResult<ImportDecl> parseDeclImport(ParseDeclOptions Flags,
DeclAttributes &Attributes);

ParserResult<UsingDecl> parseDeclUsing(ParseDeclOptions Flags,
DeclAttributes &Attributes);

/// Parse an inheritance clause into a vector of InheritedEntry's.
///
/// \param allowClassRequirement whether to permit parsing of 'class'
Expand Down
5 changes: 3 additions & 2 deletions include/swift/Parse/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,9 @@ class Token {
#define CONTEXTUAL_SIMPLE_DECL_ATTR(KW, ...) CONTEXTUAL_CASE(KW)
#include "swift/AST/DeclAttr.def"
#undef CONTEXTUAL_CASE
.Case("macro", true)
.Default(false);
.Case("macro", true)
.Case("using", true)
.Default(false);
}

bool isContextualPunctuator(StringRef ContextPunc) const {
Expand Down
5 changes: 5 additions & 0 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2114,6 +2114,11 @@ namespace {
printFoot();
}

void visitUsingDecl(UsingDecl *UD, Label label) {
printCommon(UD, "using_decl", label);
printFieldQuoted(UD->getSpecifierName(), Label::always("specifier"));
}

void visitExtensionDecl(ExtensionDecl *ED, Label label) {
printCommon(ED, "extension_decl", label, ExtensionColor);
printFlag(!ED->hasBeenBound(), "unbound");
Expand Down
1 change: 1 addition & 0 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5426,6 +5426,7 @@ ASTMangler::BaseEntitySignature::BaseEntitySignature(const Decl *decl)
case DeclKind::PrefixOperator:
case DeclKind::PostfixOperator:
case DeclKind::MacroExpansion:
case DeclKind::Using:
break;
};
}
Expand Down
10 changes: 10 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
}
}

// The `using` declarations are private to the file at the moment
// and shouldn't appear in swift interfaces.
if (isa<UsingDecl>(D))
return false;

return ShouldPrintChecker::shouldPrint(D, options);
}
};
Expand Down Expand Up @@ -3052,6 +3057,11 @@ void PrintAST::visitImportDecl(ImportDecl *decl) {
[&] { Printer << "."; });
}

void PrintAST::visitUsingDecl(UsingDecl *decl) {
Printer.printIntroducerKeyword("using", Options, " ");
Printer << decl->getSpecifierName();
}

void PrintAST::printExtendedTypeName(TypeLoc ExtendedTypeLoc) {
bool OldFullyQualifiedTypesIfAmbiguous =
Options.FullyQualifiedTypesIfAmbiguous;
Expand Down
1 change: 1 addition & 0 deletions lib/AST/ASTScopeCreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ class NodeAdder
VISIT_AND_IGNORE(ParamDecl)
VISIT_AND_IGNORE(MissingDecl)
VISIT_AND_IGNORE(MissingMemberDecl)
VISIT_AND_IGNORE(UsingDecl)

// This declaration is handled from the PatternBindingDecl
VISIT_AND_IGNORE(VarDecl)
Expand Down
4 changes: 4 additions & 0 deletions lib/AST/ASTWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
return false;
}

bool visitUsingDecl(UsingDecl *UD) {
return false;
}

bool visitExtensionDecl(ExtensionDecl *ED) {
if (auto *typeRepr = ED->getExtendedTypeRepr())
if (doIt(typeRepr))
Expand Down
11 changes: 11 additions & 0 deletions lib/AST/Bridging/DeclBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,17 @@ BridgedImportDecl BridgedImportDecl_createParsed(
std::move(builder).get());
}

BridgedUsingDecl BridgedUsingDecl_createParsed(BridgedASTContext cContext,
BridgedDeclContext cDeclContext,
BridgedSourceLoc usingKeywordLoc,
BridgedSourceLoc specifierLoc,
BridgedUsingSpecifier specifier) {
ASTContext &ctx = cContext.unbridged();
return UsingDecl::create(
ctx, usingKeywordLoc.unbridged(), specifierLoc.unbridged(),
static_cast<UsingSpecifier>(specifier), cDeclContext.unbridged());
}

BridgedSubscriptDecl BridgedSubscriptDecl_createParsed(
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
BridgedSourceLoc cStaticLoc, BridgedStaticSpelling cStaticSpelling,
Expand Down
Loading