Skip to content

Requestify implicit imports #31016

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
1 change: 1 addition & 0 deletions include/swift/AST/ASTTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SWIFT_TYPEID(AncestryFlags)
SWIFT_TYPEID(CtorInitializerKind)
SWIFT_TYPEID(FunctionBuilderBodyPreCheck)
SWIFT_TYPEID(GenericSignature)
SWIFT_TYPEID(ImplicitImport)
SWIFT_TYPEID(ImplicitMemberAction)
SWIFT_TYPEID(ParamSpecifier)
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ASTTypeIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class GenericTypeParamType;
class InfixOperatorDecl;
class IterableDeclContext;
class ModuleDecl;
struct ImplicitImport;
class NamedPattern;
class NominalTypeDecl;
class OperatorDecl;
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3032,6 +3032,10 @@ class TypeAliasDecl : public GenericTypeDecl {
Type getUnderlyingType() const;
void setUnderlyingType(Type type);

/// Returns the interface type of the underlying type if computed, null
/// otherwise. Should only be used for dumping.
Type getCachedUnderlyingType() const { return UnderlyingTy.getType(); }

/// For generic typealiases, return the unbound generic type.
UnboundGenericType *getUnboundGenericType() const;

Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsCommon.def
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ ERROR(attr_only_on_parameters, none,
ERROR(function_type_no_parens,none,
"single argument function types require parentheses", ())

// Used by both the Frontend and Sema.
ERROR(error_underlying_module_not_found,none,
"underlying Objective-C module %0 not found", (Identifier))

// Used by -verify-generic-signatures
ERROR(generic_signature_not_minimal,none,
"generic requirement '%0' is redundant in %1", (StringRef, StringRef))
Expand Down
2 changes: 0 additions & 2 deletions include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ ERROR(error_stdlib_module_name,none,

ERROR(error_stdlib_not_found,Fatal,
"unable to load standard library for target '%0'", (StringRef))
ERROR(error_underlying_module_not_found,none,
"underlying Objective-C module %0 not found", (Identifier))

ERROR(error_unable_to_load_supplementary_output_file_map, none,
"unable to load supplementary output file map '%0': %1",
Expand Down
61 changes: 58 additions & 3 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace swift {
class FuncDecl;
class InfixOperatorDecl;
class LinkLibrary;
struct ImplicitImport;
class ModuleLoader;
class NominalTypeDecl;
class EnumElementDecl;
Expand Down Expand Up @@ -158,6 +159,42 @@ enum class ResilienceStrategy : unsigned {
Resilient
};

/// The kind of stdlib that should be imported.
enum class ImplicitStdlibKind {
/// No standard library should be implicitly imported.
None,

/// The Builtin module should be implicitly imported.
Builtin,

/// The regular Swift standard library should be implicitly imported.
Stdlib
};

struct ImplicitImportInfo {
/// The implicit stdlib to import.
ImplicitStdlibKind StdlibKind;

/// Whether we should attempt to import an underlying Clang half of this
/// module.
bool ShouldImportUnderlyingModule;

/// The bridging header path for this module, empty if there is none.
StringRef BridgingHeaderPath;

/// The names of additional modules to be implicitly imported.
SmallVector<Identifier, 4> ModuleNames;

/// An additional list of already-loaded modules which should be implicitly
/// imported.
SmallVector<std::pair<ModuleDecl *, /*exported*/ bool>, 4>
AdditionalModules;

ImplicitImportInfo()
: StdlibKind(ImplicitStdlibKind::None),
ShouldImportUnderlyingModule(false) {}
};

class OverlayFile;

/// The minimum unit of compilation.
Expand Down Expand Up @@ -245,6 +282,10 @@ class ModuleDecl : public DeclContext, public TypeDecl {
llvm::SmallDenseMap<Identifier, SmallVector<OverlayFile *, 1>>
declaredCrossImports;

/// A description of what should be implicitly imported by each file of this
/// module.
const ImplicitImportInfo ImportInfo;

std::unique_ptr<SourceLookupCache> Cache;
SourceLookupCache &getSourceLookupCache() const;

Expand Down Expand Up @@ -274,15 +315,29 @@ class ModuleDecl : public DeclContext, public TypeDecl {
/// \see EntryPointInfoTy
EntryPointInfoTy EntryPointInfo;

ModuleDecl(Identifier name, ASTContext &ctx);
ModuleDecl(Identifier name, ASTContext &ctx, ImplicitImportInfo importInfo);

public:
static ModuleDecl *create(Identifier name, ASTContext &ctx) {
return new (ctx) ModuleDecl(name, ctx);
/// Creates a new module with a given \p name.
///
/// \param importInfo Information about which modules should be implicitly
/// imported by each file of this module.
static ModuleDecl *
create(Identifier name, ASTContext &ctx,
ImplicitImportInfo importInfo = ImplicitImportInfo()) {
return new (ctx) ModuleDecl(name, ctx, importInfo);
}

using Decl::getASTContext;

/// Retrieves information about which modules are implicitly imported by
/// each file of this module.
const ImplicitImportInfo &getImplicitImportInfo() const { return ImportInfo; }

/// Retrieve a list of modules that each file of this module implicitly
/// imports.
ArrayRef<ImplicitImport> getImplicitImports() const;

ArrayRef<FileUnit *> getFiles() {
return Files;
}
Expand Down
19 changes: 7 additions & 12 deletions include/swift/AST/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ class SourceFile final : public FileUnit {
class Impl;
struct SourceFileSyntaxInfo;

/// The implicit module import that the SourceFile should get.
enum class ImplicitModuleImportKind {
None,
Builtin,
Stdlib
};

/// Possible attributes for imports in source files.
enum class ImportFlags {
/// The imported module is exposed to anyone who imports the parent module.
Expand Down Expand Up @@ -128,8 +121,8 @@ class SourceFile final : public FileUnit {

/// This is the list of modules that are imported by this module.
///
/// This is filled in by the import resolution phase.
ArrayRef<ImportedModuleDesc> Imports;
/// This is \c None until it is filled in by the import resolution phase.
Optional<ArrayRef<ImportedModuleDesc>> Imports;

/// A unique identifier representing this file; used to mark private decls
/// within the file to keep them from conflicting with other files in the
Expand Down Expand Up @@ -335,12 +328,14 @@ class SourceFile final : public FileUnit {
llvm::StringMap<SourceFilePathInfo> getInfoForUsedFilePaths() const;

SourceFile(ModuleDecl &M, SourceFileKind K, Optional<unsigned> bufferID,
ImplicitModuleImportKind ModImpKind, bool KeepParsedTokens = false,
bool KeepSyntaxTree = false, ParsingOptions parsingOpts = {});
bool KeepParsedTokens = false, bool KeepSyntaxTree = false,
ParsingOptions parsingOpts = {});

~SourceFile();

void addImports(ArrayRef<ImportedModuleDesc> IM);
/// Set the imports for this source file. This gets called by import
/// resolution.
void setImports(ArrayRef<ImportedModuleDesc> imports);

enum ImportQueryKind {
/// Return the results for testable or private imports.
Expand Down
40 changes: 40 additions & 0 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "swift/AST/Evaluator.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/SimpleRequest.h"
#include "swift/AST/SourceFile.h"
#include "swift/AST/TypeResolutionStage.h"
#include "swift/Basic/AnyValue.h"
#include "swift/Basic/Statistic.h"
Expand Down Expand Up @@ -2344,6 +2345,45 @@ class SimpleDidSetRequest
}
};

/// A module which has been implicitly imported.
struct ImplicitImport {
using ImportOptions = SourceFile::ImportOptions;

ModuleDecl *Module;
ImportOptions Options;

ImplicitImport(ModuleDecl *module, ImportOptions opts = {})
: Module(module), Options(opts) {}

friend bool operator==(const ImplicitImport &lhs,
const ImplicitImport &rhs) {
return lhs.Module == rhs.Module &&
lhs.Options.toRaw() == rhs.Options.toRaw();
}
};

void simple_display(llvm::raw_ostream &out, const ImplicitImport &import);

/// Computes the loaded modules that should be implicitly imported by each file
/// of a given module.
class ModuleImplicitImportsRequest
: public SimpleRequest<ModuleImplicitImportsRequest,
ArrayRef<ImplicitImport>(ModuleDecl *),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

ArrayRef<ImplicitImport>
evaluate(Evaluator &evaluator, ModuleDecl *module) const;

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

// Allow AnyValue to compare two Type values, even though Type doesn't
// support ==.
template<>
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ SWIFT_REQUEST(TypeChecker, ValidatePrecedenceGroupRequest,
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, MangleLocalTypeDeclRequest,
std::string(const TypeDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, ModuleImplicitImportsRequest,
ArrayRef<ImplicitImport>(ModuleDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, NamingPatternRequest,
NamedPattern *(VarDecl *), SeparatelyCached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, OpaqueReadOwnershipRequest,
Expand Down
41 changes: 10 additions & 31 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,15 @@ class CompilerInvocation {
/// in generating a cached PCH file for the bridging header.
std::string getPCHHash() const;

SourceFile::ImplicitModuleImportKind getImplicitModuleImportKind() const {
/// Retrieve the stdlib kind to implicitly import.
ImplicitStdlibKind getImplicitStdlibKind() const {
if (getInputKind() == InputFileKind::SIL) {
return SourceFile::ImplicitModuleImportKind::None;
return ImplicitStdlibKind::None;
}
if (getParseStdlib()) {
return SourceFile::ImplicitModuleImportKind::Builtin;
return ImplicitStdlibKind::Builtin;
}
return SourceFile::ImplicitModuleImportKind::Stdlib;
return ImplicitStdlibKind::Stdlib;
}

/// Performs input setup common to these tools:
Expand Down Expand Up @@ -654,7 +655,6 @@ class CompilerInstance {
private:
SourceFile *
createSourceFileForMainModule(SourceFileKind FileKind,
SourceFile::ImplicitModuleImportKind ImportKind,
Optional<unsigned> BufferID,
SourceFile::ParsingOptions options = {});

Expand All @@ -667,38 +667,17 @@ class CompilerInstance {
private:
/// Load stdlib & return true if should continue, i.e. no error
bool loadStdlib();
ModuleDecl *importUnderlyingModule();
ModuleDecl *importBridgingHeader();

void
getImplicitlyImportedModules(SmallVectorImpl<ModuleDecl *> &importModules);

public: // for static functions in Frontend.cpp
struct ImplicitImports {
SourceFile::ImplicitModuleImportKind kind;
ModuleDecl *objCModuleUnderlyingMixedFramework;
ModuleDecl *headerModule;
SmallVector<ModuleDecl *, 4> modules;

explicit ImplicitImports(CompilerInstance &compiler);
};

static void addAdditionalInitialImportsTo(
SourceFile *SF, const ImplicitImports &implicitImports);

private:
void addMainFileToModule(const ImplicitImports &implicitImports);
/// Retrieve a description of which modules should be implicitly imported.
ImplicitImportInfo getImplicitImportInfo() const;

void performSemaUpTo(SourceFile::ASTStage_t LimitStage);
void parseAndCheckTypesUpTo(const ImplicitImports &implicitImports,
SourceFile::ASTStage_t LimitStage);
void parseAndCheckTypesUpTo(SourceFile::ASTStage_t LimitStage);

void parseLibraryFile(unsigned BufferID,
const ImplicitImports &implicitImports);
void parseLibraryFile(unsigned BufferID);

/// Return true if had load error
bool
parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports);
bool parsePartialModulesAndLibraryFiles();

void forEachFileToTypeCheck(llvm::function_ref<void(SourceFile &)> fn);

Expand Down
12 changes: 9 additions & 3 deletions include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ namespace swift {
class FrontendOptions {
friend class ArgsToFrontendOptionsConverter;

/// A list of arbitrary modules to import and make implicitly visible.
std::vector<std::string> ImplicitImportModuleNames;

public:
FrontendInputsAndOutputs InputsAndOutputs;

Expand All @@ -44,9 +47,6 @@ class FrontendOptions {

bool isOutputFileDirectory() const;

/// A list of arbitrary modules to import and make implicitly visible.
std::vector<std::string> ImplicitImportModuleNames;

/// An Objective-C header to import and make implicitly visible.
std::string ImplicitObjCHeaderPath;

Expand Down Expand Up @@ -322,6 +322,12 @@ class FrontendOptions {
const PrimarySpecificPaths &
getPrimarySpecificPathsForPrimary(StringRef) const;

/// Retrieves the list of arbitrary modules to import and make implicitly
/// visible.
ArrayRef<std::string> getImplicitImportModuleNames() const {
return ImplicitImportModuleNames;
}

private:
static bool canActionEmitDependencies(ActionType);
static bool canActionEmitReferenceDependencies(ActionType);
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ namespace {
void visitTypeAliasDecl(TypeAliasDecl *TAD) {
printCommon(TAD, "typealias");
PrintWithColorRAII(OS, TypeColor) << " type='";
if (auto underlying = TAD->getUnderlyingType()) {
if (auto underlying = TAD->getCachedUnderlyingType()) {
PrintWithColorRAII(OS, TypeColor)
<< underlying.getString();
} else {
Expand Down
Loading