Merge pull request #4538 from apple/stdlib-warning-suppression
[stdlib] Suppress noisy warnings
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index a549804..bbae689 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,68 +1,13 @@
-<!-- Please complete this template before creating the pull request. -->
-#### What's in this pull request?
-<!-- Description about pull request. -->
+<!-- What's in this pull request? -->
+Replace this paragraph with a description of your changes and rationale. Provide links to external references/discussions if appropriate.
-#### Resolved bug number: ([SR-](https://bugs.swift.org/browse/SR-))
-<!-- If this pull request resolves any bugs from Swift bug tracker -->
+<!-- If this pull request resolves any bugs in the Swift bug tracker, provide a link: -->
+Resolves [SR-NNNN](https://bugs.swift.org/browse/SR-NNNN).
-* * * *
+<!--
+Before merging this pull request, you must run the Swift continuous integration tests.
+For information about triggering CI builds via @swift-ci, see:
+https://github.com/apple/swift/blob/master/docs/ContinuousIntegration.md#swift-ci
-<!-- This selection should only be completed by Swift admin -->
-Before merging this pull request to apple/swift repository:
-- [ ] Test pull request on Swift continuous integration.
-
-<details>
- <summary>Triggering Swift CI</summary>
-
-The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
-
-**Smoke Testing**
-
- Platform | Comment
- ------------ | -------------
- All supported platforms | @swift-ci Please smoke test
- All supported platforms | @swift-ci Please smoke test and merge
- OS X platform | @swift-ci Please smoke test OS X platform
- Linux platform | @swift-ci Please smoke test Linux platform
-
-A smoke test on macOS does the following:
-
-1. Builds the compiler incrementally.
-2. Builds the standard library only for macOS. Simulator standard libraries and
- device standard libraries are not built.
-3. lldb is not built.
-4. The test and validation-test targets are run only for macOS. The optimized
- version of these tests are not run.
-
-A smoke test on Linux does the following:
-
-1. Builds the compiler incrementally.
-2. Builds the standard library incrementally.
-3. lldb is built incrementally.
-4. The swift test and validation-test targets are run. The optimized version of these
- tests are not run.
-5. lldb is tested.
-
-**Validation Testing**
-
- Platform | Comment
- ------------ | -------------
- All supported platforms | @swift-ci Please test
- All supported platforms | @swift-ci Please clean test
- All supported platforms | @swift-ci Please test and merge
- OS X platform | @swift-ci Please test OS X platform
- OS X platform | @swift-ci Please clean test OS X platform
- OS X platform | @swift-ci Please benchmark
- Linux platform | @swift-ci Please test Linux platform
- Linux platform | @swift-ci Please clean test Linux platform
-
-
-**Lint Testing**
-
- Language | Comment
- ------------ | -------------
- Python | @swift-ci Please Python lint
-
-Note: Only members of the Apple organization can trigger swift-ci.
-</details>
-<!-- Thank you for your contribution to Swift! -->
+Thank you for your contribution to Swift!
+-->
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e883e04..9af53bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -126,10 +126,6 @@
set(SWIFT_ENABLE_GOLD_LINKER FALSE CACHE BOOL
"Enable using the gold linker when available")
-# Configure and initialize swift components.
-include(SwiftComponents)
-swift_configure_components()
-
set(SWIFT_SDKS "" CACHE STRING
"If non-empty, limits building target binaries only to specified SDKs (despite other SDKs being available)")
@@ -331,6 +327,7 @@
include(CheckCXXSourceRuns)
include(CMakeParseArguments)
+include(SwiftComponents)
include(SwiftHandleGybSources)
include(SwiftSetIfArchBitness)
include(SwiftSource)
@@ -339,7 +336,8 @@
include(SwiftComponents)
include(SwiftList)
-swift_configure_install_components("${SWIFT_INSTALL_COMPONENTS}")
+# Configure swift include, install, build components.
+swift_configure_components()
if("${CMAKE_VERSION}" VERSION_LESS "3.0")
set(SWIFT_CMAKE_HAS_GENERATOR_EXPRESSIONS FALSE)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e36bf96..0283424 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,6 +5,7 @@
---
-Before submitting the pull request, please make sure you have tested your
-changes and that they follow the Swift project [guidelines for contributing
+Before submitting the pull request, please make sure you have [tested your
+changes](https://github.com/apple/swift/blob/master/docs/ContinuousIntegration.md)
+and that they follow the Swift project [guidelines for contributing
code](https://swift.org/contributing/#contributing-code).
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 3d3033f..51ea877 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -1881,3 +1881,22 @@
macro(add_swift_lib_subdirectory name)
add_llvm_subdirectory(SWIFT LIB ${name})
endmacro()
+
+function(add_swift_host_tool executable)
+ cmake_parse_arguments(
+ ADDSWIFTHOSTTOOL # prefix
+ "" # options
+ "" # single-value args
+ "SWIFT_COMPONENT" # multi-value args
+ ${ARGN})
+
+ # Create the executable rule.
+ add_swift_executable(${executable} ${ADDSWIFTHOSTTOOL_UNPARSED_ARGUMENTS})
+
+ # And then create the install rule if we are asked to.
+ if (ADDSWIFTHOSTTOOL_SWIFT_COMPONENT)
+ swift_install_in_component(${ADDSWIFTHOSTTOOL_SWIFT_COMPONENT}
+ TARGETS ${executable}
+ RUNTIME DESTINATION bin)
+ endif()
+endfunction()
diff --git a/cmake/modules/SwiftComponents.cmake b/cmake/modules/SwiftComponents.cmake
index 92734d5..3d58409 100644
--- a/cmake/modules/SwiftComponents.cmake
+++ b/cmake/modules/SwiftComponents.cmake
@@ -71,6 +71,23 @@
# Set the SWIFT_INSTALL_COMPONENTS variable to the default value if it is not passed in via -D
set(SWIFT_INSTALL_COMPONENTS "${_SWIFT_DEFINED_COMPONENTS}" CACHE STRING
"A semicolon-separated list of components to install ${_SWIFT_DEFINED_COMPONENTS}")
+
+ foreach(component ${_SWIFT_DEFINED_COMPONENTS})
+ string(TOUPPER "${component}" var_name_piece)
+ string(REPLACE "-" "_" var_name_piece "${var_name_piece}")
+ set(SWIFT_INSTALL_${var_name_piece} FALSE)
+ endforeach()
+
+ foreach(component ${SWIFT_INSTALL_COMPONENTS})
+ list(FIND _SWIFT_DEFINED_COMPONENTS "${component}" index)
+ if(${index} EQUAL -1)
+ message(FATAL_ERROR "unknown install component: ${component}")
+ endif()
+
+ string(TOUPPER "${component}" var_name_piece)
+ string(REPLACE "-" "_" var_name_piece "${var_name_piece}")
+ set(SWIFT_INSTALL_${var_name_piece} TRUE)
+ endforeach()
endmacro()
function(swift_is_installing_component component result_var_name)
@@ -105,22 +122,3 @@
install(${ARGN})
endif()
endfunction()
-
-macro(swift_configure_install_components install_components)
- foreach(component ${_SWIFT_DEFINED_COMPONENTS})
- string(TOUPPER "${component}" var_name_piece)
- string(REPLACE "-" "_" var_name_piece "${var_name_piece}")
- set(SWIFT_INSTALL_${var_name_piece} FALSE)
- endforeach()
-
- foreach(component ${install_components})
- list(FIND _SWIFT_DEFINED_COMPONENTS "${component}" index)
- if(${index} EQUAL -1)
- message(FATAL_ERROR "unknown install component: ${component}")
- endif()
-
- string(TOUPPER "${component}" var_name_piece)
- string(REPLACE "-" "_" var_name_piece "${var_name_piece}")
- set(SWIFT_INSTALL_${var_name_piece} TRUE)
- endforeach()
-endmacro()
diff --git a/cmake/modules/SwiftUtils.cmake b/cmake/modules/SwiftUtils.cmake
index 3484f7c..05b4cc9 100644
--- a/cmake/modules/SwiftUtils.cmake
+++ b/cmake/modules/SwiftUtils.cmake
@@ -106,3 +106,20 @@
message(FATAL_ERROR "Unknown build type: ${build_type}")
endif()
endfunction()
+
+# Set variable to value if value is not null or false. Otherwise set variable to
+# default_value.
+function(set_with_default variable value)
+ cmake_parse_argument(
+ SWD
+ ""
+ "DEFAULT"
+ "" ${ARGN})
+ precondition(SWD_DEFAULT
+ MESSAGE "Must specify a default argument")
+ if (value)
+ set(${variable} ${value} PARENT_SCOPE)
+ else()
+ set(${variable} ${SWD_DEFAULT} PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md
index 8a2a713..ec91751 100644
--- a/docs/ContinuousIntegration.md
+++ b/docs/ContinuousIntegration.md
@@ -33,12 +33,12 @@
### Smoke Testing
- Platform | Comment
- ------------ | -------------
- All supported platforms | @swift-ci Please smoke test
- All supported platforms | @swift-ci Please smoke test and merge
- OS X platform | @swift-ci Please smoke test OS X platform
- Linux platform | @swift-ci Please smoke test Linux platform
+ Platform | Comment | Check Status
+ ------------ | ------- | ------------
+ All supported platforms | @swift-ci Please smoke test | Swift Test Linux Platform (smoke test) <br> Swift Test OS X Platform (smoke test)
+ All supported platforms | @swift-ci Please smoke test and merge | Swift Test Linux Platform (smoke test) <br> Swift Test OS X Platform (smoke test)
+ OS X platform | @swift-ci Please smoke test OS X platform | Swift Test OS X Platform (smoke test)
+ Linux platform | @swift-ci Please smoke test Linux platform | Swift Test Linux Platform (smoke test)
A smoke test on macOS does the following:
@@ -64,12 +64,16 @@
### Validation Testing
- Platform | Comment
- ------------ | -------------
- All supported platforms | @swift-ci Please test
- All supported platforms | @swift-ci Please test and merge
- OS X platform | @swift-ci Please test OS X platform
- Linux platform | @swift-ci Please test Linux platform
+ Platform | Comment | Check Status
+ ------------ | ------- | ------------
+ All supported platforms | @swift-ci Please test | Swift Test Linux Platform (smoke test)<br>Swift Test OS X Platform (smoke test)<br>Swift Test Linux Platform<br>Swift Test OS X Platform<br>
+ All supported platforms | @swift-ci Please clean test | Swift Test Linux Platform (smoke test)<br>Swift Test OS X Platform (smoke test)<br>Swift Test Linux Platform<br>Swift Test OS X Platform<br>
+ All supported platforms | @swift-ci Please test and merge | Swift Test Linux Platform (smoke test) <br> Swift Test OS X Platform (smoke test)<br> Swift Test Linux Platform <br>Swift Test OS X Platform
+ OS X platform | @swift-ci Please test OS X platform | Swift Test OS X Platform (smoke test)<br>Swift Test OS X Platform
+ OS X platform | @swift-ci Please clean test OS X platform | Swift Test OS X Platform (smoke test)<br>Swift Test OS X Platform
+ OS X platform | @swift-ci Please benchmark | Swift Benchmark on OS X Platform
+ Linux platform | @swift-ci Please test Linux platform | Swift Test Linux Platform (smoke test) <br> Swift Test Linux Platform
+ Linux platform | @swift-ci Please clean test Linux platform | Swift Test Linux Platform (smoke test) <br> Swift Test Linux Platform
The core principles of validation testing is that:
@@ -102,15 +106,15 @@
### Benchmarking
- Platform | Comment
- ------------ | -------------
- OS X platform | @swift-ci Please benchmark
+ Platform | Comment | Check Status
+ ------------ | ------- | ------------
+ OS X platform | @swift-ci Please benchmark | Swift Benchmark on OS X Platform
### Lint Testing
- Language | Comment
- ------------ | -------------
- Python | @swift-ci Please Python lint
+ Language | Comment | Check Status
+ ------------ | ------- | ------------
+ Python | @swift-ci Please Python lint | Python lint
## Cross Repository Testing
@@ -134,6 +138,7 @@
6. Watch the public incremental build on ci.swift.org to make sure that you did not make any mistakes. It should complete within 30-40 minutes depending on what else was being committed in the mean time.
+
## ci.swift.org bots
FIXME: FILL ME IN!
diff --git a/include/swift/AST/ArchetypeBuilder.h b/include/swift/AST/ArchetypeBuilder.h
index 78e8c15..9c7a5b0 100644
--- a/include/swift/AST/ArchetypeBuilder.h
+++ b/include/swift/AST/ArchetypeBuilder.h
@@ -250,11 +250,19 @@
/// \brief Get a generic signature based on the provided complete list
/// of generic parameter types.
///
- /// \returns a generic signature build based on the provided list of
+ /// \returns a generic signature built from the provided list of
/// generic parameter types.
GenericSignature *
getGenericSignature(ArrayRef<GenericTypeParamType *> genericParamsTypes);
+ /// \brief Get a generic context based on the complete list of generic
+ /// parameter types.
+ ///
+ /// \returns a generic context built from the provided list of
+ /// generic parameter types.
+ GenericEnvironment *getGenericEnvironment(
+ ArrayRef<GenericTypeParamType *> genericParamsTypes);
+
/// Infer requirements from the given type, recursively.
///
/// This routine infers requirements from a type that occurs within the
@@ -315,27 +323,20 @@
/// parameter.
ArchetypeType *getArchetype(GenericTypeParamDecl *GenericParam);
- /// \brief Retrieve the array of all of the archetypes produced during
- /// archetype assignment. The 'primary' archetypes will occur first in this
- /// list.
- ArrayRef<ArchetypeType *> getAllArchetypes();
-
/// Map an interface type to a contextual type.
- static Type mapTypeIntoContext(const DeclContext *dc, Type type,
- LazyResolver *resolver = nullptr);
+ static Type mapTypeIntoContext(const DeclContext *dc, Type type);
/// Map an interface type to a contextual type.
static Type mapTypeIntoContext(ModuleDecl *M,
- GenericParamList *genericParams,
- Type type,
- LazyResolver *resolver = nullptr);
+ GenericEnvironment *genericEnv,
+ Type type);
/// Map a contextual type to an interface type.
static Type mapTypeOutOfContext(const DeclContext *dc, Type type);
/// Map a contextual type to an interface type.
static Type mapTypeOutOfContext(ModuleDecl *M,
- GenericParamList *genericParams,
+ GenericEnvironment *genericEnv,
Type type);
using SameTypeRequirement
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 964a2dc..e1512f0 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -35,6 +35,7 @@
enum class AccessSemantics : unsigned char;
class ApplyExpr;
class ArchetypeBuilder;
+ class GenericEnvironment;
class ArchetypeType;
class ASTContext;
class ASTPrinter;
@@ -1059,7 +1060,6 @@
unsigned NumParams;
SourceLoc WhereLoc;
MutableArrayRef<RequirementRepr> Requirements;
- ArrayRef<ArchetypeType *> AllArchetypes;
GenericParamList *OuterParameters;
@@ -1109,28 +1109,6 @@
MutableArrayRef<RequirementRepr> Requirements,
SourceLoc RAngleLoc);
- /// Create a new generic parameter list with the same parameters and
- /// requirements as this one, but parented to a different outer parameter
- /// list.
- GenericParamList *cloneWithOuterParameters(const ASTContext &Context,
- GenericParamList *Outer) {
- auto clone = create(Context,
- SourceLoc(),
- getParams(),
- SourceLoc(),
- getRequirements(),
- SourceLoc());
- clone->setAllArchetypes(getAllArchetypes());
- clone->setOuterParameters(Outer);
- return clone;
- }
-
- /// Create an empty generic parameter list.
- static GenericParamList *getEmpty(ASTContext &Context) {
- // TODO: Could probably unique this in the AST context.
- return create(Context, SourceLoc(), {}, SourceLoc(), {}, SourceLoc());
- }
-
MutableArrayRef<GenericTypeParamDecl *> getParams() {
return {getTrailingObjects<GenericTypeParamDecl *>(), NumParams};
}
@@ -1148,12 +1126,6 @@
const_iterator begin() const { return getParams().begin(); }
const_iterator end() const { return getParams().end(); }
- /// Get the total number of parameters, including those from parent generic
- /// parameter lists.
- unsigned totalSize() const {
- return NumParams + (OuterParameters ? OuterParameters->totalSize() : 0);
- }
-
/// \brief Retrieve the location of the 'where' keyword, or an invalid
/// location if 'where' was not present.
SourceLoc getWhereLoc() const { return WhereLoc; }
@@ -1199,24 +1171,7 @@
/// main part of a declaration's signature.
void addTrailingWhereClause(ASTContext &ctx, SourceLoc trailingWhereLoc,
ArrayRef<RequirementRepr> trailingRequirements);
-
- /// \brief Retrieves the list containing all archetypes described by this
- /// generic parameter clause.
- ///
- /// In this list of archetypes, the primary archetypes come first followed by
- /// any non-primary archetypes (i.e., those archetypes that encode associated
- /// types of another archetype).
- ///
- /// This does not include archetypes from the outer generic parameter list(s).
- ArrayRef<ArchetypeType *> getAllArchetypes() const { return AllArchetypes; }
- /// \brief Sets all archetypes *without* copying the source array.
- void setAllArchetypes(ArrayRef<ArchetypeType *> AA) {
- assert(AA.size() >= size()
- && "allArchetypes is smaller than number of generic params?!");
- AllArchetypes = AA;
- }
-
/// \brief Retrieve the outer generic parameter list, which provides the
/// generic parameters of the context in which this generic parameter list
/// exists.
@@ -1270,36 +1225,6 @@
return depth;
}
- /// Derive a contextual type substitution map from a substitution array.
- /// This is just like GenericSignature::getSubstitutionMap(), except
- /// with contextual types instead of interface types.
- void
- getSubstitutionMap(ModuleDecl *mod,
- GenericSignature *sig,
- ArrayRef<Substitution> subs,
- TypeSubstitutionMap &subsMap,
- ArchetypeConformanceMap &conformanceMap) const;
-
- /// Derive the all-archetypes list for the given list of generic
- /// parameters.
- static ArrayRef<ArchetypeType*>
- deriveAllArchetypes(ArrayRef<GenericTypeParamDecl*> params,
- SmallVectorImpl<ArchetypeType*> &archetypes);
-
- void getForwardingSubstitutionMap(TypeSubstitutionMap &result) const;
-
- ArrayRef<Substitution>
- getForwardingSubstitutions(GenericSignature *sig) const;
-
- /// Collect the nested archetypes of an archetype into the given
- /// collection.
- ///
- /// \param known - the set of archetypes already present in `all`
- /// \param all - the output list of archetypes
- static void addNestedArchetypes(ArchetypeType *archetype,
- SmallPtrSetImpl<ArchetypeType*> &known,
- SmallVectorImpl<ArchetypeType*> &all);
-
void print(raw_ostream &OS);
void dump();
};
@@ -1472,6 +1397,12 @@
/// the parsed representation, and not part of the module file.
GenericSignature *GenericSig = nullptr;
+ /// \brief The generic context of this extension.
+ ///
+ /// This is the mapping between interface types and archetypes for the
+ /// generic parameters of this extension.
+ GenericEnvironment *GenericEnv = nullptr;
+
MutableArrayRef<TypeLoc> Inherited;
/// The trailing where clause.
@@ -1555,7 +1486,19 @@
GenericSignature *getGenericSignature() const { return GenericSig; }
/// Set the generic signature of this extension.
- void setGenericSignature(GenericSignature *sig);
+ void setGenericSignature(GenericSignature *sig) {
+ assert(!GenericSig && "Already have generic signature");
+ GenericSig = sig;
+ }
+
+ /// Retrieve the generic context for this extension.
+ GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }
+
+ /// Set the generic context of this extension.
+ void setGenericEnvironment(GenericEnvironment *env) {
+ assert(!GenericEnv && "Already have generic context");
+ GenericEnv = env;
+ }
/// Retrieve the generic requirements.
ArrayRef<Requirement> getGenericRequirements() const;
@@ -2306,6 +2249,12 @@
/// the parsed representation, and not part of the module file.
GenericSignature *GenericSig = nullptr;
+ /// \brief The generic context of this type.
+ ///
+ /// This is the mapping between interface types and archetypes for the
+ /// generic parameters of this type.
+ GenericEnvironment *GenericEnv = nullptr;
+
/// \brief Whether or not the generic signature of the type declaration is
/// currently being validated.
// TODO: Merge into GenericSig bits.
@@ -2324,7 +2273,10 @@
void setGenericParams(GenericParamList *params);
/// Set the generic signature of this type.
- void setGenericSignature(GenericSignature *sig);
+ void setGenericSignature(GenericSignature *sig) {
+ assert(!GenericSig && "Already have generic signature");
+ GenericSig = sig;
+ }
/// Retrieve the innermost generic parameter types.
ArrayRef<GenericTypeParamType *> getInnermostGenericParamTypes() const {
@@ -2355,6 +2307,15 @@
return ValidatingGenericSignature;
}
+ /// Retrieve the generic context for this type.
+ GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }
+
+ /// Set the generic context of this type.
+ void setGenericEnvironment(GenericEnvironment *env) {
+ assert(!this->GenericEnv && "already have generic context?");
+ this->GenericEnv = env;
+ }
+
// Resolve ambiguity due to multiple base classes.
using TypeDecl::getASTContext;
using DeclContext::operator new;
@@ -4573,6 +4534,7 @@
GenericParamList *GenericParams;
GenericSignature *GenericSig;
+ GenericEnvironment *GenericEnv;
CaptureInfo Captures;
@@ -4589,7 +4551,7 @@
: ValueDecl(Kind, Parent, Name, NameLoc),
DeclContext(DeclContextKind::AbstractFunctionDecl, Parent),
Body(nullptr), GenericParams(nullptr), GenericSig(nullptr),
- ThrowsLoc(ThrowsLoc) {
+ GenericEnv(nullptr), ThrowsLoc(ThrowsLoc) {
setBodyKind(BodyKind::None);
setGenericParams(GenericParams);
AbstractFunctionDeclBits.NumParameterLists = NumParameterLists;
@@ -4616,6 +4578,15 @@
return GenericSig;
}
+ /// Retrieve the generic context for this function.
+ GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }
+
+ /// Set the generic context of this function.
+ void setGenericEnvironment(GenericEnvironment *GenericEnv) {
+ assert(!this->GenericEnv && "already have generic context?");
+ this->GenericEnv = GenericEnv;
+ }
+
// Expose our import as member status
bool isImportAsMember() const { return IAMStatus.isImportAsMember(); }
bool isImportAsInstanceMember() const { return IAMStatus.isInstance(); }
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index 041d4fe..0e8fee9 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -35,6 +35,7 @@
namespace swift {
class AbstractFunctionDecl;
+ class GenericEnvironment;
class ASTContext;
class ASTWalker;
class CanType;
@@ -284,14 +285,19 @@
/// type for non-type contexts.
Type getDeclaredInterfaceType() const;
- /// \brief Retrieve the innermost generic parameters introduced by this
- /// context or one of its parent contexts, or null if this context is not
- /// directly dependent on any generic parameters.
+ /// \brief Retrieve the innermost generic parameters of this context or any
+ /// of its parents.
+ ///
+ /// FIXME: Remove this
GenericParamList *getGenericParamsOfContext() const;
- /// \brief Retrieve the interface generic type parameters and requirements
- /// exposed by this context.
+ /// \brief Retrieve the innermost generic signature of this context or any
+ /// of its parents.
GenericSignature *getGenericSignatureOfContext() const;
+
+ /// \brief Retrieve the innermost archetypes of this context or any
+ /// of its parents.
+ GenericEnvironment *getGenericEnvironmentOfContext() const;
/// Returns this or the first local parent context, or nullptr if it is not
/// contained in one.
diff --git a/include/swift/AST/GenericEnvironment.h b/include/swift/AST/GenericEnvironment.h
new file mode 100644
index 0000000..14592b4
--- /dev/null
+++ b/include/swift/AST/GenericEnvironment.h
@@ -0,0 +1,77 @@
+//===--- GenericEnvironment.h - Generic Environment AST ---------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the GenericEnvironment class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_AST_GENERIC_ENVIRONMENT_H
+#define SWIFT_AST_GENERIC_ENVIRONMENT_H
+
+#include "swift/AST/ProtocolConformance.h"
+
+namespace swift {
+
+class ASTContext;
+
+/// Describes the mapping between archetypes and interface types for the
+/// generic parameters of a DeclContext.
+class GenericEnvironment final {
+ TypeSubstitutionMap ArchetypeToInterfaceMap;
+ TypeSubstitutionMap InterfaceToArchetypeMap;
+
+public:
+ const TypeSubstitutionMap &getArchetypeToInterfaceMap() const {
+ return ArchetypeToInterfaceMap;
+ }
+
+ const TypeSubstitutionMap &getInterfaceToArchetypeMap() const {
+ return InterfaceToArchetypeMap;
+ }
+
+ explicit GenericEnvironment(TypeSubstitutionMap interfaceToArchetypeMap);
+
+ static GenericEnvironment *get(ASTContext &ctx,
+ TypeSubstitutionMap interfaceToArchetypeMap);
+
+ /// Make vanilla new/delete illegal.
+ void *operator new(size_t Bytes) = delete;
+ void operator delete(void *Data) = delete;
+
+ /// Only allow allocation of GenericEnvironments using the allocator
+ /// in ASTContext.
+ void *operator new(size_t bytes, const ASTContext &ctx);
+
+ /// Map a contextual type to an interface type.
+ Type mapTypeOutOfContext(ModuleDecl *M, Type type) const;
+
+ /// Map an interface type to a contextual type.
+ Type mapTypeIntoContext(ModuleDecl *M, Type type) const;
+
+ /// Derive a contextual type substitution map from a substitution array.
+ /// This is just like GenericSignature::getSubstitutionMap(), except
+ /// with contextual types instead of interface types.
+ void
+ getSubstitutionMap(ModuleDecl *mod,
+ GenericSignature *sig,
+ ArrayRef<Substitution> subs,
+ TypeSubstitutionMap &subsMap,
+ ArchetypeConformanceMap &conformanceMap) const;
+
+ ArrayRef<Substitution>
+ getForwardingSubstitutions(ModuleDecl *M, GenericSignature *sig) const;
+};
+
+} // end namespace swift
+
+#endif // SWIFT_AST_GENERIC_ENVIRONMENT_H
+
diff --git a/include/swift/AST/GenericSignature.h b/include/swift/AST/GenericSignature.h
index 6cd223b..9768dbd 100644
--- a/include/swift/AST/GenericSignature.h
+++ b/include/swift/AST/GenericSignature.h
@@ -184,10 +184,6 @@
/// Return a range that iterates through first all of the generic parameters
/// of the signature, followed by all of their recursive member types exposed
/// through protocol requirements.
- ///
- /// The member types are presented in the
- /// same order as GenericParamList::getAllArchetypes would present for an
- /// equivalent GenericParamList.
GenericSignatureWitnessIterator getAllDependentTypes() const {
return GenericSignatureWitnessIterator(getRequirements());
}
@@ -204,8 +200,10 @@
/// for mangling purposes.
///
/// TODO: This is what getCanonicalSignature() ought to do, but currently
- /// cannot due to implementation dependencies on 'getAllDependentTypes'
- /// order matching 'getAllArchetypes' order of a generic param list.
+ /// does not due to former implementation dependencies on
+ /// 'getAllDependentTypes' order matching 'getAllArchetypes' order of a
+ /// generic param list. Now that 'getAllArchetypes' is gone, we might
+ /// be able to move forward here.
CanGenericSignature getCanonicalManglingSignature(ModuleDecl &M) const;
/// Uniquing for the ASTContext.
diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h
index 40047ba..54122e7 100644
--- a/include/swift/AST/PrintOptions.h
+++ b/include/swift/AST/PrintOptions.h
@@ -20,7 +20,7 @@
#include <vector>
namespace swift {
-class GenericParamList;
+class GenericEnvironment;
class CanType;
class Decl;
class ValueDecl;
@@ -336,9 +336,8 @@
/// formatting.
bool PrintOriginalSourceText = false;
- /// \brief Print dependent types as references into this generic parameter
- /// list.
- GenericParamList *ContextGenericParams = nullptr;
+ /// \brief Print dependent types as references into this generic environment.
+ GenericEnvironment *GenericEnv = nullptr;
/// \brief Print types with alternative names from their canonical names.
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr;
diff --git a/include/swift/AST/ProtocolConformance.h b/include/swift/AST/ProtocolConformance.h
index 23963d2..34e2b87 100644
--- a/include/swift/AST/ProtocolConformance.h
+++ b/include/swift/AST/ProtocolConformance.h
@@ -236,10 +236,9 @@
/// Retrieve the complete set of protocol conformances for directly inherited
/// protocols.
const InheritedConformanceMap &getInheritedConformances() const;
-
+
/// Get the generic parameters open on the conforming type.
- /// FIXME: Retire in favor of getGenericSignature().
- GenericParamList *getGenericParams() const;
+ GenericEnvironment *getGenericEnvironment() const;
/// Get the generic signature containing the parameters open on the conforming
/// interface type.
diff --git a/include/swift/AST/Substitution.h b/include/swift/AST/Substitution.h
index bedcfa9..c5c0717 100644
--- a/include/swift/AST/Substitution.h
+++ b/include/swift/AST/Substitution.h
@@ -26,6 +26,7 @@
namespace swift {
class ArchetypeType;
+ class GenericEnvironment;
class ProtocolConformanceRef;
/// DenseMap type used internally by Substitution::subst to track conformances
@@ -63,11 +64,11 @@
/// conformances.
///
/// Our replacement type must be written in terms of the context
- /// archetypes of 'context', which in turn must be derived from the
+ /// archetypes of 'env', which in turn must be derived from the
/// generic requirements of 'sig'.
Substitution subst(ModuleDecl *module,
GenericSignature *sig,
- GenericParamList *context,
+ GenericEnvironment *env,
ArrayRef<Substitution> subs) const;
private:
diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h
index c5a0d1e..039b0ce 100644
--- a/include/swift/AST/TypeRepr.h
+++ b/include/swift/AST/TypeRepr.h
@@ -364,9 +364,10 @@
/// Foo -> Bar
/// \endcode
class FunctionTypeRepr : public TypeRepr {
- // These two are only used in SIL mode, which is the only time
+ // These three are only used in SIL mode, which is the only time
// we can have polymorphic function values.
GenericParamList *GenericParams;
+ GenericEnvironment *GenericEnv;
GenericSignature *GenericSig;
TypeRepr *ArgsTy;
@@ -378,12 +379,15 @@
FunctionTypeRepr(GenericParamList *genericParams, TypeRepr *argsTy,
SourceLoc throwsLoc, SourceLoc arrowLoc, TypeRepr *retTy)
: TypeRepr(TypeReprKind::Function),
- GenericParams(genericParams), GenericSig(nullptr),
+ GenericParams(genericParams),
+ GenericEnv(nullptr),
+ GenericSig(nullptr),
ArgsTy(argsTy), RetTy(retTy),
ArrowLoc(arrowLoc), ThrowsLoc(throwsLoc) {
}
GenericParamList *getGenericParams() const { return GenericParams; }
+ GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }
GenericSignature *getGenericSignature() const { return GenericSig; }
void setGenericSignature(GenericSignature *genericSig) {
@@ -391,6 +395,11 @@
GenericSig = genericSig;
}
+ void setGenericEnvironment(GenericEnvironment *genericEnv) {
+ assert(GenericEnv == nullptr);
+ GenericEnv = genericEnv;
+ }
+
TypeRepr *getArgsTypeRepr() const { return ArgsTy; }
TypeRepr *getResultTypeRepr() const { return RetTy; }
bool throws() const { return ThrowsLoc.isValid(); }
diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h
index 99321e7..ab93ee0 100644
--- a/include/swift/SIL/SILFunction.h
+++ b/include/swift/SIL/SILFunction.h
@@ -92,7 +92,7 @@
CanSILFunctionType LoweredType;
/// The context archetypes of the function.
- GenericParamList *ContextGenericParams;
+ GenericEnvironment *GenericEnv;
/// The forwarding substitutions, lazily computed.
Optional<ArrayRef<Substitution>> ForwardingSubs;
@@ -178,7 +178,7 @@
SILFunction(SILModule &module, SILLinkage linkage,
StringRef mangledName, CanSILFunctionType loweredType,
- GenericParamList *contextGenericParams,
+ GenericEnvironment *genericEnv,
Optional<SILLocation> loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
@@ -192,7 +192,7 @@
static SILFunction *create(SILModule &M, SILLinkage linkage, StringRef name,
CanSILFunctionType loweredType,
- GenericParamList *contextGenericParams,
+ GenericEnvironment *genericEnv,
Optional<SILLocation> loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
@@ -545,16 +545,14 @@
return (ClangNodeOwner ? ClangNodeOwner->getClangDecl() : nullptr);
}
- /// Retrieve the generic parameter list containing the contextual archetypes
- /// of the function.
- ///
- /// FIXME: We should remove this in favor of lazy archetype instantiation
- /// using the 'getArchetype' and 'mapTypeIntoContext' interfaces.
- GenericParamList *getContextGenericParams() const {
- return ContextGenericParams;
+ /// Retrieve the generic environment containing the mapping from interface
+ /// types to context archetypes for this function. Only present if the
+ /// function has a body.
+ GenericEnvironment *getGenericEnvironment() const {
+ return GenericEnv;
}
- void setContextGenericParams(GenericParamList *params) {
- ContextGenericParams = params;
+ void setGenericEnvironment(GenericEnvironment *env) {
+ GenericEnv = env;
}
/// Map the given type, which is based on an interface SILFunctionType and may
diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h
index a5f41f8..cbc9c35 100644
--- a/include/swift/SIL/SILModule.h
+++ b/include/swift/SIL/SILModule.h
@@ -480,7 +480,7 @@
/// SILModule. Eventually the uses should probably be refactored.
SILFunction *createFunction(
SILLinkage linkage, StringRef name, CanSILFunctionType loweredType,
- GenericParamList *contextGenericParams, Optional<SILLocation> loc,
+ GenericEnvironment *genericEnv, Optional<SILLocation> loc,
IsBare_t isBareSILFunction, IsTransparent_t isTrans,
IsFragile_t isFragile, IsThunk_t isThunk = IsNotThunk,
SILFunction::ClassVisibility_t classVisibility = SILFunction::NotRelevant,
diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h
index 368afef..687ab87 100644
--- a/include/swift/SIL/TypeLowering.h
+++ b/include/swift/SIL/TypeLowering.h
@@ -366,16 +366,9 @@
/// The SIL function type of the constant.
CanSILFunctionType SILFnType;
- /// The context generic parameters used by the constant.
- /// This will be the innermost generic parameter list that applies to the
- /// constant, which may be the generic parameter list of an enclosing context.
- GenericParamList *ContextGenericParams;
+ /// The generic environment used by the constant.
+ GenericEnvironment *GenericEnv;
- /// The generic parameter list of the function.
- /// If the function does not have any generic parameters of its own, this
- /// will be null.
- GenericParamList *InnerGenericParams;
-
SILType getSILType() const {
return SILType::getPrimitiveObjectType(SILFnType);
}
@@ -384,8 +377,7 @@
return lhs.FormalInterfaceType == rhs.FormalInterfaceType &&
lhs.LoweredInterfaceType == rhs.LoweredInterfaceType &&
lhs.SILFnType == rhs.SILFnType &&
- lhs.ContextGenericParams == rhs.ContextGenericParams &&
- lhs.InnerGenericParams == rhs.InnerGenericParams;
+ lhs.GenericEnv == rhs.GenericEnv;
}
friend bool operator!=(SILConstantInfo lhs, SILConstantInfo rhs) {
return !(lhs == rhs);
@@ -521,11 +513,8 @@
CanAnyFunctionType makeConstantInterfaceType(SILDeclRef constant);
- /// Get the context parameters for a constant. Returns a pair of the innermost
- /// generic parameter list and the generic param list that directly applies
- /// to the constant, if any.
- std::pair<GenericParamList *, GenericParamList*>
- getConstantContextGenericParams(SILDeclRef constant);
+ /// Get the generic environment for a constant.
+ GenericEnvironment *getConstantGenericEnvironment(SILDeclRef constant);
// Types converted during foreign bridging.
#define BRIDGING_KNOWN_TYPE(BridgedModule,BridgedType) \
@@ -746,8 +735,8 @@
Type lvalueType);
/// Retrieve the set of archetypes closed over by the given function.
- GenericParamList *getEffectiveGenericParams(AnyFunctionRef fn,
- CaptureInfo captureInfo);
+ GenericEnvironment *getEffectiveGenericEnvironment(AnyFunctionRef fn,
+ CaptureInfo captureInfo);
/// Retrieve the set of generic parameters closed over by the given function.
CanGenericSignature getEffectiveGenericSignature(AnyFunctionRef fn,
diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h
index 76ac61c..260704a 100644
--- a/include/swift/SIL/TypeSubstCloner.h
+++ b/include/swift/SIL/TypeSubstCloner.h
@@ -90,9 +90,9 @@
Substitution remapSubstitution(Substitution sub) {
if (!ApplySubs.empty()) {
- auto *params = Original.getContextGenericParams();
auto sig = Original.getLoweredFunctionType()->getGenericSignature();
- sub = sub.subst(SwiftMod, sig, params, ApplySubs);
+ auto *env = Original.getGenericEnvironment();
+ sub = sub.subst(SwiftMod, sig, env, ApplySubs);
}
// Remap opened archetypes into the cloned context.
return Substitution(getASTTypeInClonedContext(sub.getReplacement()
@@ -209,9 +209,9 @@
auto sub = Inst->getSelfSubstitution();
if (!ApplySubs.empty()) {
auto sig = Original.getLoweredFunctionType()->getGenericSignature();
- auto *params = Original.getContextGenericParams();
+ auto *env = Original.getGenericEnvironment();
sub = sub.subst(Inst->getModule().getSwiftModule(),
- sig, params, ApplySubs);
+ sig, env, ApplySubs);
}
assert(sub.getConformances().size() == 1 &&
diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def
index 6de1c6d..ff8cdd3 100644
--- a/include/swift/Serialization/DeclTypeRecordNodes.def
+++ b/include/swift/Serialization/DeclTypeRecordNodes.def
@@ -169,6 +169,7 @@
TRAILING_INFO(GENERIC_PARAM)
TRAILING_INFO(GENERIC_REQUIREMENT)
TRAILING_INFO(LAST_GENERIC_REQUIREMENT)
+TRAILING_INFO(GENERIC_ENVIRONMENT)
OTHER(LOCAL_DISCRIMINATOR, 248)
OTHER(PRIVATE_DISCRIMINATOR, 249)
diff --git a/include/swift/Serialization/ModuleFile.h b/include/swift/Serialization/ModuleFile.h
index d3aeb00..ba1ef5f 100644
--- a/include/swift/Serialization/ModuleFile.h
+++ b/include/swift/Serialization/ModuleFile.h
@@ -426,12 +426,36 @@
ParameterList *readParameterList();
GenericParamList *maybeGetOrReadGenericParams(serialization::DeclID contextID,
- DeclContext *DC,
- llvm::BitstreamCursor &Cursor);
+ DeclContext *DC);
+
+ /// Reads a generic param list from \c DeclTypeCursor.
+ ///
+ /// If the record at the cursor is not a generic param list, returns null
+ /// without moving the cursor.
+ GenericParamList *maybeReadGenericParams(DeclContext *DC,
+ GenericParamList *outerParams = nullptr);
/// Reads a set of requirements from \c DeclTypeCursor.
void readGenericRequirements(SmallVectorImpl<Requirement> &requirements);
+ /// Reads a GenericEnvironment from \c DeclTypeCursor.
+ ///
+ /// Also returns the set of generic parameters read, in order, to help with
+ /// forming a GenericSignature.
+ GenericEnvironment *readGenericEnvironment(
+ SmallVectorImpl<GenericTypeParamType *> ¶mTypes,
+ llvm::BitstreamCursor &Cursor);
+
+ /// Reads a GenericEnvironment followed by requirements from \c DeclTypeCursor.
+ ///
+ /// Returns the GenericEnvironment and the signature formed from the
+ /// generic parameters of the environment, together with the
+ /// read requirements.
+ ///
+ /// Returns nullptr if there's no generic signature here.
+ std::pair<GenericSignature *, GenericEnvironment *>
+ maybeReadGenericSignature();
+
/// Populates the vector with members of a DeclContext from \c DeclTypeCursor.
///
/// Returns true if there is an error.
@@ -691,14 +715,6 @@
NormalProtocolConformance *
readNormalConformance(serialization::NormalConformanceID id);
- /// Reads a generic param list from \c DeclTypeCursor.
- ///
- /// If the record at the cursor is not a generic param list, returns null
- /// without moving the cursor.
- GenericParamList *maybeReadGenericParams(DeclContext *DC,
- llvm::BitstreamCursor &Cursor,
- GenericParamList *outerParams = nullptr);
-
/// Reads a foreign error conformance from \c DeclTypeCursor, if present.
Optional<ForeignErrorConvention> maybeReadForeignErrorConvention();
};
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 2585dde..7c58975 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -53,7 +53,7 @@
/// in source control, you should also update the comment to briefly
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
-const uint16_t VERSION_MINOR = 261; // Last change: remove AllArchetypes indexing
+const uint16_t VERSION_MINOR = 264; // Last change: remove AllArchetypes
using DeclID = PointerEmbeddedInt<unsigned, 31>;
using DeclIDField = BCFixed<31>;
@@ -1082,8 +1082,7 @@
>;
using GenericParamListLayout = BCRecordLayout<
- GENERIC_PARAM_LIST,
- BCArray<TypeIDField> // Archetypes
+ GENERIC_PARAM_LIST
// The actual parameters and requirements trail the record.
>;
@@ -1092,6 +1091,24 @@
DeclIDField // Typealias
>;
+ // Subtlety here: GENERIC_ENVIRONMENT is serialized for both Decls and
+ // SILFunctions.
+ //
+ // For Decls, the interface type is non-canonical, so it points back
+ // to the GenericParamListDecl. This allows us to use the serialized
+ // GENERIC_ENVIRONMENT records to form the GenericSignature, as well.
+ // The type is canonicalized when forming the actual GenericEnvironment
+ // instance.
+ //
+ // For SILFunctions, the interface type below is always canonical,
+ // since SILFunctions never point back to any original
+ // GenericTypeParamDecls.
+ using GenericEnvironmentLayout = BCRecordLayout<
+ GENERIC_ENVIRONMENT,
+ TypeIDField, // interface type
+ TypeIDField // contextual type
+ >;
+
using GenericRequirementLayout = BCRecordLayout<
GENERIC_REQUIREMENT,
GenericRequirementKindField, // requirement kind
diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h
index 5f0d28e..151bafa 100644
--- a/include/swift/Subsystems.h
+++ b/include/swift/Subsystems.h
@@ -43,6 +43,7 @@
class DiagnosticConsumer;
class DiagnosticEngine;
class FileUnit;
+ class GenericEnvironment;
class GenericParamList;
class GenericSignature;
class IRGenOptions;
@@ -208,9 +209,10 @@
bool ProduceDiagnostics = true);
/// Expose TypeChecker's handling of GenericParamList to SIL parsing.
- GenericSignature *handleSILGenericParams(ASTContext &Ctx,
- GenericParamList *genericParams,
- DeclContext *DC);
+ std::pair<GenericSignature *, GenericEnvironment *>
+ handleSILGenericParams(ASTContext &Ctx,
+ GenericParamList *genericParams,
+ DeclContext *DC);
/// Turn the given module into SIL IR.
///
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7e2c040..c702ee2 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -24,6 +24,7 @@
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/ExprHandle.h"
#include "swift/AST/ForeignErrorConvention.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/KnownProtocols.h"
#include "swift/AST/LazyResolver.h"
#include "swift/AST/ModuleLoader.h"
@@ -3754,8 +3755,7 @@
GenericSignature *GenericSignature::get(ArrayRef<GenericTypeParamType *> params,
ArrayRef<Requirement> requirements,
bool isKnownCanonical) {
- if (params.empty() && requirements.empty())
- return nullptr;
+ assert(!params.empty());
// Check for an existing generic signature.
llvm::FoldingSetNodeID ID;
@@ -3781,6 +3781,12 @@
return newSig;
}
+GenericEnvironment *
+GenericEnvironment::get(ASTContext &ctx,
+ TypeSubstitutionMap interfaceToArchetypeMap) {
+ return new (ctx) GenericEnvironment(interfaceToArchetypeMap);
+}
+
void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,
Identifier baseName,
ArrayRef<Identifier> argumentNames) {
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 2905219..88d5310 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -21,6 +21,7 @@
#include "swift/AST/Attr.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Module.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/ParameterList.h"
@@ -4274,25 +4275,14 @@
}
}
- GenericParamList *getGenericParamListAtDepth(unsigned depth) {
- assert(Options.ContextGenericParams);
- if (!UnwrappedGenericParams) {
- std::vector<GenericParamList *> paramLists;
- for (auto *params = Options.ContextGenericParams;
- params;
- params = params->getOuterParameters()) {
- paramLists.push_back(params);
- }
- UnwrappedGenericParams = std::move(paramLists);
- }
- return UnwrappedGenericParams->rbegin()[depth];
- }
-
void visitGenericTypeParamType(GenericTypeParamType *T) {
// Substitute a context archetype if we have context generic params.
- if (Options.ContextGenericParams) {
- return visit(getGenericParamListAtDepth(T->getDepth())
- ->getParams()[T->getIndex()]->getArchetype());
+ if (Options.GenericEnv) {
+ auto *paramTy = T->getCanonicalType().getPointer();
+ auto &map = Options.GenericEnv->getInterfaceToArchetypeMap();
+ auto found = map.find(paramTy);
+ if (found != map.end())
+ return visit(found->second);
}
auto Name = T->getName();
@@ -4483,18 +4473,11 @@
void ProtocolConformance::printName(llvm::raw_ostream &os,
const PrintOptions &PO) const {
if (getKind() == ProtocolConformanceKind::Normal) {
- if (PO.PrintForSIL) {
- if (auto genericSig = getGenericSignature()) {
- StreamPrinter sPrinter(os);
- TypePrinter typePrinter(sPrinter, PO);
- typePrinter.printGenericSignature(genericSig->getGenericParams(),
- genericSig->getRequirements());
- os << ' ';
- }
- } else if (auto gp = getGenericParams()) {
- StreamPrinter SPrinter(os);
- PrintAST Printer(SPrinter, PO);
- Printer.printGenericParams(gp);
+ if (auto genericSig = getGenericSignature()) {
+ StreamPrinter sPrinter(os);
+ TypePrinter typePrinter(sPrinter, PO);
+ typePrinter.printGenericSignature(genericSig->getGenericParams(),
+ genericSig->getRequirements());
os << ' ';
}
}
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index f83926c..cc14d5d 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -20,6 +20,7 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/ForeignErrorConvention.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Mangle.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/Basic/SourceManager.h"
@@ -1957,7 +1958,44 @@
}
}
}
-
+
+ void verifyGenericEnvironment(Decl *D,
+ GenericSignature *sig,
+ GenericEnvironment *env) {
+ if (!sig && !env)
+ return;
+
+ if (sig && env) {
+ auto &map = env->getInterfaceToArchetypeMap();
+ if (sig->getGenericParams().size() != map.size()) {
+ Out << "Mismatch between signature and environment parameter count\n";
+ abort();
+ }
+
+ for (auto *paramTy : sig->getGenericParams()) {
+ auto found = map.find(paramTy->getCanonicalType().getPointer());
+ if (found == map.end()) {
+ Out << "Generic parameter present in signature but not "
+ "in environment\n";
+ paramTy->dump();
+ abort();
+ }
+ }
+
+ return;
+ }
+
+ Out << "Decl must have both signature and environment, or neither\n";
+ D->dump(Out);
+ abort();
+ }
+
+ void verifyChecked(GenericTypeDecl *generic) {
+ verifyGenericEnvironment(generic,
+ generic->getGenericSignature(),
+ generic->getGenericEnvironment());
+ }
+
void verifyChecked(NominalTypeDecl *nominal) {
// Make sure that the protocol list is fully expanded.
verifyProtocolList(nominal, nominal->getLocalProtocols());
@@ -2084,195 +2122,6 @@
verifyParsedBase(DD);
}
- bool checkAllArchetypes(const GenericParamList *generics) {
- ArrayRef<ArchetypeType*> storedArchetypes = generics->getAllArchetypes();
-
- SmallVector<ArchetypeType*, 16> derivedBuffer;
- ArrayRef<ArchetypeType*> derivedArchetypes =
- GenericParamList::deriveAllArchetypes(generics->getParams(),
- derivedBuffer);
-
- return (storedArchetypes == derivedArchetypes);
- }
-
- /// Check that the generic requirements line up with the archetypes.
- void checkGenericRequirements(Decl *decl,
- DeclContext *dc,
- GenericFunctionType *genericTy) {
-
- PrettyStackTraceDecl debugStack("verifying generic requirements", decl);
-
- // We need to have generic parameters here.
- auto genericParams = dc->getGenericParamsOfContext();
- if (!genericParams) {
- Out << "Missing generic parameters\n";
- decl->dump(Out);
- abort();
- }
-
- // Verify that the list of all archetypes matches what we would
- // derive from the generic params.
- if (!checkAllArchetypes(genericParams)) {
- Out << "Archetypes list in generic parameter list doesn't "
- "match what would have been derived\n";
- decl->dump(Out);
- abort();
- }
-
- // Step through the list of requirements in the generic type.
- auto requirements = genericTy->getRequirements();
-
- // Skip over same-type requirements.
- auto skipUnrepresentedRequirements = [&]() {
- for (; !requirements.empty(); requirements = requirements.slice(1)) {
- bool done = false;
- switch (requirements.front().getKind()) {
- case RequirementKind::Conformance:
- // If the second type is a protocol type, we're done.
- done = true;
- break;
-
- case RequirementKind::Superclass:
- break;
-
- case RequirementKind::SameType:
- // Skip the next same-type constraint.
- continue;
-
- case RequirementKind::WitnessMarker:
- done = true;
- break;
- }
-
- if (done)
- break;
- }
- };
- skipUnrepresentedRequirements();
-
- // Collect all of the generic parameter lists.
- SmallVector<GenericParamList *, 4> allGenericParamLists;
- for (auto gpList = genericParams; gpList;
- gpList = gpList->getOuterParameters()) {
- allGenericParamLists.push_back(gpList);
- }
- std::reverse(allGenericParamLists.begin(), allGenericParamLists.end());
-
- // Helpers that diagnose failures when generic requirements mismatch.
- bool failed = false;
- auto noteFailure =[&]() {
- if (failed)
- return;
-
- Out << "Generic requirements don't match all archetypes\n";
- decl->dump(Out);
-
- Out << "\nGeneric type: " << genericTy->getString() << "\n";
- Out << "Expected requirements: ";
- bool first = true;
- for (auto gpList : allGenericParamLists) {
- for (auto archetype : gpList->getAllArchetypes()) {
- for (auto proto : archetype->getConformsTo()) {
- if (first)
- first = false;
- else
- Out << ", ";
-
- Out << archetype->getString() << " : "
- << proto->getDeclaredType()->getString();
- }
- }
- }
- Out << "\n";
-
- failed = true;
- };
-
- // Walk through all of the archetypes in the generic parameter lists,
- // matching up their conformance requirements with those in the
- for (auto gpList : allGenericParamLists) {
- for (auto archetype : gpList->getAllArchetypes()) {
- // Make sure we have the value witness marker.
- if (requirements.empty()) {
- noteFailure();
- Out << "Ran out of requirements before we ran out of archetypes\n";
- break;
- }
-
- if (requirements.front().getKind()
- == RequirementKind::WitnessMarker) {
- auto type = ArchetypeBuilder::mapTypeIntoContext(
- dc,
- requirements.front().getFirstType());
- if (type->isEqual(archetype)) {
- requirements = requirements.slice(1);
- skipUnrepresentedRequirements();
- } else {
- noteFailure();
- Out << "Value witness marker for " << type->getString()
- << " does not match expected " << archetype->getString()
- << "\n";
- }
- } else {
- noteFailure();
- Out << "Missing value witness marker for "
- << archetype->getString() << "\n";
- }
-
- for (auto proto : archetype->getConformsTo()) {
- // If there are no requirements left, we're missing requirements.
- if (requirements.empty()) {
- noteFailure();
- Out << "No requirement for " << archetype->getString()
- << " : " << proto->getDeclaredType()->getString() << "\n";
- continue;
- }
-
- auto firstReqType = ArchetypeBuilder::mapTypeIntoContext(
- dc,
- requirements.front().getFirstType());
- auto secondReqType = ArchetypeBuilder::mapTypeIntoContext(
- dc,
- requirements.front().getSecondType());
-
- // If the requirements match up, move on to the next requirement.
- if (firstReqType->isEqual(archetype) &&
- secondReqType->isEqual(proto->getDeclaredType())) {
- requirements = requirements.slice(1);
- skipUnrepresentedRequirements();
- continue;
- }
-
- noteFailure();
-
- // If the requirements don't match up, complain.
- if (!firstReqType->isEqual(archetype)) {
- Out << "Mapped archetype " << firstReqType->getString()
- << " does not match expected " << archetype->getString()
- << "\n";
- continue;
- }
-
- Out << "Mapped conformance " << secondReqType->getString()
- << " does not match expected "
- << proto->getDeclaredType()->getString() << "\n";
- }
- }
- }
-
- if (!requirements.empty()) {
- noteFailure();
- Out << "Extra requirement "
- << requirements.front().getFirstType()->getString()
- << " : "
- << requirements.front().getSecondType()->getString()
- << "\n";
- }
-
- if (failed)
- abort();
- }
-
void verifyChecked(AbstractFunctionDecl *AFD) {
PrettyStackTraceDecl debugStack("verifying AbstractFunctionDecl", AFD);
@@ -2326,6 +2175,10 @@
abort();
}
+ verifyGenericEnvironment(AFD,
+ AFD->getGenericSignature(),
+ AFD->getGenericEnvironment());
+
// If there is an interface type, it shouldn't have any unresolved
// dependent member types.
// FIXME: This is a general property of the type system.
@@ -2347,12 +2200,6 @@
abort();
}
- // If the interface type is generic, make sure its requirements
- // line up with the archetypes.
- if (auto genericTy = interfaceTy->getAs<GenericFunctionType>()) {
- checkGenericRequirements(AFD, AFD, genericTy);
- }
-
// Throwing @objc methods must have a foreign error convention.
if (AFD->isObjC() &&
static_cast<bool>(AFD->getForeignErrorConvention())
diff --git a/lib/AST/ArchetypeBuilder.cpp b/lib/AST/ArchetypeBuilder.cpp
index d468d85..f21f4e6 100644
--- a/lib/AST/ArchetypeBuilder.cpp
+++ b/lib/AST/ArchetypeBuilder.cpp
@@ -20,6 +20,7 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/DiagnosticEngine.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Module.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/ProtocolConformance.h"
@@ -169,11 +170,6 @@
/// archetypes.
llvm::MapVector<GenericTypeParamKey, PotentialArchetype*> PotentialArchetypes;
- /// A vector containing all of the archetypes, expanded out.
- /// FIXME: This notion should go away, because it's impossible to expand
- /// out "all" archetypes
- SmallVector<ArchetypeType *, 4> AllArchetypes;
-
/// A vector containing the same-type requirements introduced into the
/// system.
SmallVector<SameTypeRequirement, 4> SameTypeRequirements;
@@ -1765,41 +1761,6 @@
return known->second->getType(*this).getAsArchetype();
}
-ArrayRef<ArchetypeType *> ArchetypeBuilder::getAllArchetypes() {
- // This should be kept in sync with GenericParamList::deriveAllArchetypes().
- if (Impl->AllArchetypes.empty()) {
- // Collect the primary archetypes first.
- unsigned depth = Impl->PotentialArchetypes.back().first.Depth;
- llvm::SmallPtrSet<ArchetypeType *, 8> KnownArchetypes;
- for (const auto &Entry : Impl->PotentialArchetypes) {
- // Skip outer potential archetypes.
- if (Entry.first.Depth < depth)
- continue;
-
- PotentialArchetype *PA = Entry.second;
- auto Archetype = PA->getType(*this).castToArchetype();
- if (KnownArchetypes.insert(Archetype).second)
- Impl->AllArchetypes.push_back(Archetype);
- }
-
- // Collect all of the remaining archetypes.
- for (const auto &Entry : Impl->PotentialArchetypes) {
- // Skip outer potential archetypes.
- if (Entry.first.Depth < depth)
- continue;
-
- PotentialArchetype *PA = Entry.second;
- if (!PA->isConcreteType() && !PA->getTypeAliasDecl()) {
- auto Archetype = PA->getType(*this).castToArchetype();
- GenericParamList::addNestedArchetypes(Archetype, KnownArchetypes,
- Impl->AllArchetypes);
- }
- }
- }
-
- return Impl->AllArchetypes;
-}
-
ArrayRef<ArchetypeBuilder::SameTypeRequirement>
ArchetypeBuilder::getSameTypeRequirements() const {
return Impl->SameTypeRequirements;
@@ -2010,88 +1971,44 @@
out << "\n";
}
-Type ArchetypeBuilder::mapTypeIntoContext(const DeclContext *dc, Type type,
- LazyResolver *resolver) {
- auto genericParams = dc->getGenericParamsOfContext();
- return mapTypeIntoContext(dc->getParentModule(), genericParams, type,
- resolver);
+Type ArchetypeBuilder::mapTypeIntoContext(const DeclContext *dc, Type type) {
+ return mapTypeIntoContext(dc->getParentModule(),
+ dc->getGenericEnvironmentOfContext(),
+ type);
}
-Type ArchetypeBuilder::mapTypeIntoContext(Module *M,
- GenericParamList *genericParams,
- Type type,
- LazyResolver *resolver) {
+Type ArchetypeBuilder::mapTypeIntoContext(ModuleDecl *M,
+ GenericEnvironment *env,
+ Type type) {
auto canType = type->getCanonicalType();
assert(!canType->hasArchetype() && "already have a contextual type");
if (!canType->hasTypeParameter())
return type;
- assert(genericParams && "dependent type in non-generic context");
+ assert(env && "dependent type in non-generic context");
- unsigned genericParamsDepth = genericParams->getDepth();
- type = type.transform([&](Type type) -> Type {
- // Map a generic parameter type to its archetype.
- if (auto gpType = type->getAs<GenericTypeParamType>()) {
- auto index = gpType->getIndex();
- unsigned depth = gpType->getDepth();
-
- // Skip down to the generic parameter list that houses the corresponding
- // generic parameter.
- auto myGenericParams = genericParams;
- assert(genericParamsDepth >= depth);
- unsigned skipLevels = genericParamsDepth - depth;
- while (skipLevels > 0) {
- myGenericParams = myGenericParams->getOuterParameters();
- assert(myGenericParams && "Wrong number of levels?");
- --skipLevels;
- }
-
- return myGenericParams->getParams()[index]->getArchetype();
- }
-
- // Map a dependent member to the corresponding nested archetype.
- if (auto dependentMember = type->getAs<DependentMemberType>()) {
- auto base = mapTypeIntoContext(M, genericParams,
- dependentMember->getBase(), resolver);
- return dependentMember->substBaseType(M, base, resolver);
- }
-
- return type;
- });
-
- assert(!type->hasTypeParameter() && "not fully substituted");
- return type;
+ return env->mapTypeIntoContext(M, type);
}
Type
ArchetypeBuilder::mapTypeOutOfContext(const DeclContext *dc, Type type) {
- GenericParamList *genericParams = dc->getGenericParamsOfContext();
- return mapTypeOutOfContext(dc->getParentModule(), genericParams, type);
+ return mapTypeOutOfContext(dc->getParentModule(),
+ dc->getGenericEnvironmentOfContext(),
+ type);
}
-Type ArchetypeBuilder::mapTypeOutOfContext(ModuleDecl *M,
- GenericParamList *genericParams,
- Type type) {
+Type
+ArchetypeBuilder::mapTypeOutOfContext(ModuleDecl *M,
+ GenericEnvironment *env,
+ Type type) {
auto canType = type->getCanonicalType();
assert(!canType->hasTypeParameter() && "already have an interface type");
if (!canType->hasArchetype())
return type;
- assert(genericParams && "dependent type in non-generic context");
+ assert(env && "dependent type in non-generic context");
- // Capture the archetype -> interface type mapping.
- TypeSubstitutionMap subs;
- for (auto params = genericParams; params != nullptr;
- params = params->getOuterParameters()) {
- for (auto param : *params) {
- subs[param->getArchetype()] = param->getDeclaredType();
- }
- }
-
- type = type.subst(M, subs, SubstFlags::AllowLoweredTypes);
-
- assert(!type->hasArchetype() && "not fully substituted");
- return type;
+ return env->mapTypeOutOfContext(M, type);
}
void ArchetypeBuilder::addGenericSignature(GenericSignature *sig,
@@ -2213,6 +2130,10 @@
auto nestedType =
rep->getDependentType(builder, /*allowUnresolved*/ false);
+ // Skip unresolved nested types.
+ if (nestedType->is<ErrorType>())
+ continue;
+
addRequirements(builder, nestedType, rep, knownPAs, requirements);
addNestedRequirements(builder, rep, knownPAs, requirements);
}
@@ -2303,3 +2224,25 @@
return sig;
}
+GenericEnvironment *ArchetypeBuilder::getGenericEnvironment(
+ ArrayRef<GenericTypeParamType *> genericParamTypes) {
+ TypeSubstitutionMap interfaceToArchetypeMap;
+
+ for (auto paramTy : genericParamTypes) {
+ auto known = Impl->PotentialArchetypes.find(
+ GenericTypeParamKey::forType(paramTy));
+ assert(known != Impl->PotentialArchetypes.end());
+
+ auto archetypeTy = known->second->getType(*this).getAsArchetype();
+ auto concreteTy = known->second->getType(*this).getAsConcreteType();
+ if (archetypeTy)
+ interfaceToArchetypeMap[paramTy] = archetypeTy;
+ else if (concreteTy)
+ interfaceToArchetypeMap[paramTy] = concreteTy;
+ else
+ llvm_unreachable("broken generic parameter");
+ }
+
+ return GenericEnvironment::get(Context, interfaceToArchetypeMap);
+}
+
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index 6ce7b30..2b04975 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -14,8 +14,9 @@
//
//===----------------------------------------------------------------------===//
-#include "swift/AST/Builtins.h"
#include "swift/AST/AST.h"
+#include "swift/AST/Builtins.h"
+#include "swift/AST/GenericEnvironment.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Attributes.h"
@@ -182,7 +183,7 @@
Type ResType,
Type ResBodyType,
GenericParamList *GenericParams,
- FunctionType::ExtInfo Info = FunctionType::ExtInfo()){
+ TypeSubstitutionMap InterfaceToArchetypeMap) {
assert(GenericParams && "Missing generic parameters");
auto &Context = ResType->getASTContext();
@@ -200,11 +201,13 @@
requirements.push_back(Requirement(RequirementKind::WitnessMarker,
param, Type()));
}
- GenericSignature *Sig = GenericSignature::get(GenericParamTypes,requirements);
-
- Type InterfaceType = GenericFunctionType::get(Sig,
- ArgParamType, ResType,
- Info);
+ GenericSignature *Sig =
+ GenericSignature::get(GenericParamTypes, requirements);
+ GenericEnvironment *Env =
+ GenericEnvironment::get(Context, InterfaceToArchetypeMap);
+
+ Type InterfaceType = GenericFunctionType::get(Sig, ArgParamType, ResType,
+ AnyFunctionType::ExtInfo());
Module *M = Context.TheBuiltinModule;
DeclContext *DC = &M->getMainFile(FileUnitKind::Builtin);
@@ -223,7 +226,8 @@
// Compute the function type.
Type FnType = PolymorphicFunctionType::get(paramList->getType(Context),
- ResBodyType, GenericParams, Info);
+ ResBodyType, GenericParams,
+ AnyFunctionType::ExtInfo());
DeclName Name(Context, Id, paramList);
auto func = FuncDecl::create(Context, /*StaticLoc=*/SourceLoc(),
@@ -237,6 +241,7 @@
func->setInterfaceType(InterfaceType);
func->setGenericSignature(Sig);
+ func->setGenericEnvironment(Env);
func->setImplicit();
func->setAccessibility(Accessibility::Public);
@@ -435,7 +440,7 @@
new (ctx) GenericTypeParamDecl(&M->getMainFile(FileUnitKind::Builtin),
ident, SourceLoc(), 0, index);
genericParam->setArchetype(archetype);
- return { archetype, genericParam };
+ return std::make_pair(archetype, genericParam);
}
/// Create a generic parameter list with multiple generic parameters.
@@ -444,7 +449,7 @@
SmallVectorImpl<ArchetypeType*> &archetypes,
SmallVectorImpl<GenericTypeParamDecl*> &genericParams) {
assert(numParameters <= llvm::array_lengthof(GenericParamNames));
- assert(archetypes.empty() && genericParams.empty());
+ assert(genericParams.empty());
for (unsigned i = 0; i != numParameters; ++i) {
auto archetypeAndParam = createGenericParam(ctx, GenericParamNames[i], i);
@@ -454,7 +459,6 @@
auto paramList = GenericParamList::create(ctx, SourceLoc(), genericParams,
SourceLoc());
- paramList->setAllArchetypes(ctx.AllocateCopy(archetypes));
return paramList;
}
@@ -469,6 +473,8 @@
SmallVector<GenericTypeParamDecl*, 2> GenericTypeParams;
SmallVector<ArchetypeType*, 2> Archetypes;
+ TypeSubstitutionMap InterfaceToArchetypeMap;
+
SmallVector<TupleTypeElt, 4> InterfaceParams;
SmallVector<Type, 4> BodyParams;
@@ -480,6 +486,12 @@
: Context(ctx) {
TheGenericParamList = getGenericParams(ctx, numGenericParams,
Archetypes, GenericTypeParams);
+
+ for (unsigned i = 0, e = GenericTypeParams.size(); i < e; i++) {
+ auto paramTy = GenericTypeParams[i]->getDeclaredType()
+ ->getCanonicalType().getPointer();
+ InterfaceToArchetypeMap[paramTy] = Archetypes[i];
+ }
}
template <class G>
@@ -497,7 +509,8 @@
ValueDecl *build(Identifier name) {
return getBuiltinGenericFunction(name, InterfaceParams, BodyParams,
InterfaceResult, BodyResult,
- TheGenericParamList);
+ TheGenericParamList,
+ InterfaceToArchetypeMap);
}
// Don't use these generator classes directly; call the make{...}
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 0bd0b85..caf1838 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -21,6 +21,7 @@
DiagnosticList.cpp
DocComment.cpp
Expr.cpp
+ GenericEnvironment.cpp
GenericSignature.cpp
Identifier.cpp
LookupVisibleDecls.cpp
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 3c2cd9d..e108527 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -536,81 +536,6 @@
Requirements = newRequirements;
}
-void GenericParamList::
-getForwardingSubstitutionMap(TypeSubstitutionMap &result) const {
- // Add forwarding substitutions from the outer context if we have
- // a type nested inside a generic function.
- for (auto *params = this;
- params != nullptr;
- params = params->getOuterParameters()) {
- for (auto *param : params->getParams())
- result[param->getDeclaredType()->getCanonicalType().getPointer()]
- = param->getArchetype();
- }
-}
-
-ArrayRef<Substitution>
-GenericParamList::getForwardingSubstitutions(GenericSignature *sig) const {
- // This is stupid. We don't really need a module, because we
- // should not be looking up concrete conformances when we
- // substitute types here.
- auto *mod = getParams()[0]->getDeclContext()->getParentModule();
-
- TypeSubstitutionMap subs;
- getForwardingSubstitutionMap(subs);
-
- auto lookupConformanceFn =
- [&](Type replacement, ProtocolType *protoType)
- -> ProtocolConformanceRef {
- return ProtocolConformanceRef(protoType->getDecl());
- };
-
- SmallVector<Substitution, 4> result;
- sig->getSubstitutions(*mod, subs, lookupConformanceFn, result);
- return sig->getASTContext().AllocateCopy(result);
-}
-
-/// \brief Add the nested archetypes of the given archetype to the set
-/// of all archetypes.
-void GenericParamList::addNestedArchetypes(ArchetypeType *archetype,
- SmallPtrSetImpl<ArchetypeType*> &known,
- SmallVectorImpl<ArchetypeType*> &all) {
- for (auto nested : archetype->getNestedTypes()) {
- auto nestedArch = nested.second.getAsArchetype();
- if (!nestedArch)
- continue;
- if (known.insert(nestedArch).second) {
- assert(!nestedArch->isPrimary() && "Unexpected primary archetype");
- all.push_back(nestedArch);
- addNestedArchetypes(nestedArch, known, all);
- }
- }
-}
-
-ArrayRef<ArchetypeType*>
-GenericParamList::deriveAllArchetypes(ArrayRef<GenericTypeParamDecl *> params,
- SmallVectorImpl<ArchetypeType*> &all) {
- // This should be kept in sync with ArchetypeBuilder::getAllArchetypes().
-
- assert(all.empty());
- llvm::SmallPtrSet<ArchetypeType*, 8> known;
-
- // Collect all the primary archetypes.
- for (auto param : params) {
- auto archetype = param->getArchetype();
- if (known.insert(archetype).second)
- all.push_back(archetype);
- }
-
- // Collect all the nested archetypes.
- for (auto param : params) {
- auto archetype = param->getArchetype();
- addNestedArchetypes(archetype, known, all);
- }
-
- return all;
-}
-
TrailingWhereClause::TrailingWhereClause(
SourceLoc whereLoc,
ArrayRef<RequirementRepr> requirements)
@@ -818,11 +743,6 @@
}
}
-void ExtensionDecl::setGenericSignature(GenericSignature *sig) {
- assert(!GenericSig && "Already have generic signature");
- GenericSig = sig;
-}
-
DeclRange ExtensionDecl::getMembers() const {
loadAllMembers();
return IterableDeclContext::getMembers();
@@ -2216,11 +2136,6 @@
Param->setDeclContext(this);
}
-void GenericTypeDecl::setGenericSignature(GenericSignature *sig) {
- assert(!GenericSig && "Already have generic signature");
- GenericSig = sig;
-}
-
TypeAliasDecl::TypeAliasDecl(SourceLoc TypeAliasLoc, Identifier Name,
SourceLoc NameLoc, TypeLoc UnderlyingTy,
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index abef65f..dcce052 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -257,6 +257,47 @@
}
}
+GenericEnvironment *DeclContext::getGenericEnvironmentOfContext() const {
+ for (const DeclContext *dc = this; ; dc = dc->getParent()) {
+ switch (dc->getContextKind()) {
+ case DeclContextKind::Module:
+ case DeclContextKind::FileUnit:
+ case DeclContextKind::TopLevelCodeDecl:
+ return nullptr;
+
+ case DeclContextKind::Initializer:
+ case DeclContextKind::SerializedLocal:
+ case DeclContextKind::AbstractClosureExpr:
+ case DeclContextKind::SubscriptDecl:
+ // Closures and initializers can't themselves be generic, but they
+ // can occur in generic contexts.
+ continue;
+
+ case DeclContextKind::AbstractFunctionDecl: {
+ auto *AFD = cast<AbstractFunctionDecl>(dc);
+ if (auto genericCtx = AFD->getGenericEnvironment())
+ return genericCtx;
+ continue;
+ }
+
+ case DeclContextKind::GenericTypeDecl: {
+ auto GTD = cast<GenericTypeDecl>(dc);
+ if (auto genericCtx = GTD->getGenericEnvironment())
+ return genericCtx;
+ continue;
+ }
+
+ case DeclContextKind::ExtensionDecl: {
+ auto ED = cast<ExtensionDecl>(dc);
+ if (auto genericCtx = ED->getGenericEnvironment())
+ return genericCtx;
+ continue;
+ }
+ }
+ llvm_unreachable("bad DeclContextKind");
+ }
+}
+
DeclContext *DeclContext::getLocalContext() {
if (isLocalContext())
return this;
diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp
new file mode 100644
index 0000000..e13b02c
--- /dev/null
+++ b/lib/AST/GenericEnvironment.cpp
@@ -0,0 +1,105 @@
+//===--- GenericEnvironment.h - GenericEnvironment AST --------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the GenericEnvironment class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/AST/ASTContext.h"
+#include "swift/AST/GenericEnvironment.h"
+
+using namespace swift;
+
+GenericEnvironment::GenericEnvironment(
+ TypeSubstitutionMap interfaceToArchetypeMap) {
+
+ assert(!interfaceToArchetypeMap.empty());
+
+ // Build a mapping in both directions, making sure to canonicalize the
+ // interface type where it is used as a key, so that substitution can
+ // find them, and to preserve sugar otherwise, so that
+ // mapTypeOutOfContext() produces a human-readable type.
+ for (auto entry : interfaceToArchetypeMap) {
+ // We're going to pass InterfaceToArchetypeMap to Type::subst(), which
+ // expects the keys to be canonical, otherwise it won't be able to
+ // find them.
+ auto canParamTy = cast<GenericTypeParamType>(entry.first->getCanonicalType());
+ auto contextTy = entry.second;
+
+ auto result = InterfaceToArchetypeMap.insert(
+ std::make_pair(canParamTy, contextTy));
+ assert(result.second && "duplicate generic parameters in environment");
+
+ // If we mapped the generic parameter to an archetype, add it to the
+ // reverse mapping.
+ if (auto *archetypeTy = entry.second->getAs<ArchetypeType>())
+ ArchetypeToInterfaceMap[archetypeTy] = entry.first;
+
+ // FIXME: If multiple generic parameters map to the same archetype,
+ // the reverse mapping order is not deterministic.
+ }
+}
+
+void *GenericEnvironment::operator new(size_t bytes, const ASTContext &ctx) {
+ return ctx.Allocate(bytes, alignof(GenericEnvironment), AllocationArena::Permanent);
+}
+
+Type GenericEnvironment::mapTypeOutOfContext(ModuleDecl *M, Type type) const {
+ type = type.subst(M, ArchetypeToInterfaceMap, SubstFlags::AllowLoweredTypes);
+ assert(!type->hasArchetype() && "not fully substituted");
+ return type;
+}
+
+Type GenericEnvironment::mapTypeIntoContext(ModuleDecl *M, Type type) const {
+ type = type.subst(M, InterfaceToArchetypeMap, SubstFlags::AllowLoweredTypes);
+ assert(!type->hasTypeParameter() && "not fully substituted");
+ return type;
+}
+
+ArrayRef<Substitution>
+GenericEnvironment::getForwardingSubstitutions(
+ ModuleDecl *M, GenericSignature *sig) const {
+ auto lookupConformanceFn =
+ [&](Type replacement, ProtocolType *protoType)
+ -> ProtocolConformanceRef {
+ return ProtocolConformanceRef(protoType->getDecl());
+ };
+
+ SmallVector<Substitution, 4> result;
+ sig->getSubstitutions(*M, InterfaceToArchetypeMap,
+ lookupConformanceFn, result);
+ return sig->getASTContext().AllocateCopy(result);
+}
+
+void GenericEnvironment::
+getSubstitutionMap(ModuleDecl *mod,
+ GenericSignature *sig,
+ ArrayRef<Substitution> subs,
+ TypeSubstitutionMap &subsMap,
+ ArchetypeConformanceMap &conformanceMap) const {
+
+ for (auto depTy : sig->getAllDependentTypes()) {
+
+ // Map the interface type to a context type.
+ auto contextTy = depTy.subst(mod, InterfaceToArchetypeMap, SubstOptions());
+ auto *archetype = contextTy->castTo<ArchetypeType>();
+
+ auto sub = subs.front();
+ subs = subs.slice(1);
+
+ // Record the replacement type and its conformances.
+ subsMap[archetype] = sub.getReplacement();
+ conformanceMap[archetype] = sub.getConformances();
+ }
+
+ assert(subs.empty() && "did not use all substitutions?!");
+}
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index 09c5395..b3d85ae 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -13,11 +13,13 @@
// This file implements the GenericSignature class.
//
//===----------------------------------------------------------------------===//
+
#include "swift/AST/GenericSignature.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Module.h"
#include "swift/AST/Types.h"
+
using namespace swift;
GenericSignature::GenericSignature(ArrayRef<GenericTypeParamType *> params,
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 1cb1331..5f94d05 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -19,6 +19,7 @@
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/DiagnosticsSema.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/LazyResolver.h"
#include "swift/AST/LinkLibrary.h"
#include "swift/AST/ModuleLoader.h"
@@ -587,16 +588,15 @@
auto *parentDC = gpContext;
while (parent) {
if (auto boundGeneric = dyn_cast<BoundGenericType>(parent)) {
- auto genericParams = parentDC->getGenericParamsOfContext();
+ auto genericSig = parentDC->getGenericSignatureOfContext();
unsigned index = 0;
assert(boundGeneric->getGenericArgs().size() ==
- genericParams->getParams().size());
+ genericSig->getInnermostGenericParams().size());
for (Type arg : boundGeneric->getGenericArgs()) {
- auto gp = genericParams->getParams()[index++];
- substitutions[gp->getDeclaredType()->getCanonicalType()
- .getPointer()] = arg;
+ auto paramTy = genericSig->getInnermostGenericParams()[index++];
+ substitutions[paramTy->getCanonicalType().getPointer()] = arg;
}
parent = CanType(boundGeneric->getParent());
@@ -615,8 +615,11 @@
// Add forwarding substitutions from the outer context if we have
// a type nested inside a generic function.
- if (auto *outerParams = parentDC->getGenericParamsOfContext())
- outerParams->getForwardingSubstitutionMap(substitutions);
+ if (auto *outerEnv = parentDC->getGenericEnvironmentOfContext())
+ for (auto pair : outerEnv->getInterfaceToArchetypeMap()) {
+ auto result = substitutions.insert(pair);
+ assert(result.second);
+ }
auto lookupConformanceFn =
[&](Type replacement, ProtocolType *protoType)
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index c9083f2..37555cf 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -18,6 +18,7 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/LazyResolver.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Module.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/Substitution.h"
@@ -180,18 +181,20 @@
CONFORMANCE_SUBCLASS_DISPATCH(usesDefaultDefinition, (requirement))
}
-GenericParamList *ProtocolConformance::getGenericParams() const {
+GenericEnvironment *ProtocolConformance::getGenericEnvironment() const {
switch (getKind()) {
case ProtocolConformanceKind::Inherited:
case ProtocolConformanceKind::Normal:
// If we have a normal or inherited protocol conformance, look for its
// generic parameters.
- return getDeclContext()->getGenericParamsOfContext();
+ return getDeclContext()->getGenericEnvironmentOfContext();
case ProtocolConformanceKind::Specialized:
// If we have a specialized protocol conformance, since we do not support
// currently partial specialization, we know that it cannot have any open
// type variables.
+ //
+ // FIXME: We could return a meaningful GenericEnvironment here
return nullptr;
}
}
@@ -354,7 +357,7 @@
auto conformingDC = getDeclContext();
auto conformingModule = conformingDC->getParentModule();
- auto *genericParams = GenericConformance->getGenericParams();
+ auto *genericEnv = GenericConformance->getGenericEnvironment();
auto *genericSig = GenericConformance->getGenericSignature();
TypeSubstitutionMap substitutionMap;
@@ -366,10 +369,10 @@
// Compute a context type substitution map from the
// substitution array stored in this conformance
- genericParams->getSubstitutionMap(conformingModule, genericSig,
- GenericSubstitutions,
- substitutionMap,
- conformanceMap);
+ genericEnv->getSubstitutionMap(conformingModule, genericSig,
+ GenericSubstitutions,
+ substitutionMap,
+ conformanceMap);
auto genericWitnessAndDecl
= GenericConformance->getTypeWitnessSubstAndDecl(assocType, resolver);
@@ -523,10 +526,10 @@
auto *conformingModule = conformingDC->getParentModule();
auto *sig = conformingDC->getGenericSignatureOfContext();
- auto *params = conformingDC->getGenericParamsOfContext();
+ auto *env = conformingDC->getGenericEnvironmentOfContext();
- params->getSubstitutionMap(conformingModule, sig, subs,
- subMap, conformanceMap);
+ env->getSubstitutionMap(conformingModule, sig, subs,
+ subMap, conformanceMap);
auto r = inherited->subst(conformingModule, getType(), subs,
subMap, conformanceMap);
diff --git a/lib/AST/Substitution.cpp b/lib/AST/Substitution.cpp
index 598c57f..2e2b92b2 100644
--- a/lib/AST/Substitution.cpp
+++ b/lib/AST/Substitution.cpp
@@ -17,6 +17,7 @@
#include "swift/AST/Substitution.h"
#include "swift/AST/ASTContext.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Module.h"
#include "swift/AST/Types.h"
#include "llvm/ADT/DenseMap.h"
@@ -42,13 +43,13 @@
Substitution Substitution::subst(Module *module,
GenericSignature *sig,
- GenericParamList *context,
+ GenericEnvironment *env,
ArrayRef<Substitution> subs) const {
TypeSubstitutionMap subMap;
ArchetypeConformanceMap conformanceMap;
- assert(sig && context);
- context->getSubstitutionMap(module, sig, subs, subMap, conformanceMap);
+ assert(sig && env);
+ env->getSubstitutionMap(module, sig, subs, subMap, conformanceMap);
return subst(module, subs, subMap, conformanceMap);
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index e10a0be..9706fab 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2767,34 +2767,6 @@
return Params->getParams();
}
-void GenericParamList::
-getSubstitutionMap(ModuleDecl *mod,
- GenericSignature *sig,
- ArrayRef<Substitution> subs,
- TypeSubstitutionMap &subsMap,
- ArchetypeConformanceMap &conformanceMap) const {
-
- // Map from interface types to archetypes
- TypeSubstitutionMap map;
- getForwardingSubstitutionMap(map);
-
- for (auto depTy : sig->getAllDependentTypes()) {
-
- // Map the interface type to a context type.
- auto contextTy = depTy.subst(mod, map, SubstOptions());
- auto *archetype = contextTy->castTo<ArchetypeType>();
-
- auto sub = subs.front();
- subs = subs.slice(1);
-
- // Record the replacement type and its conformances.
- subsMap[archetype] = sub.getReplacement();
- conformanceMap[archetype] = sub.getConformances();
- }
-
- assert(subs.empty() && "did not use all substitutions?!");
-}
-
FunctionType *
GenericFunctionType::substGenericArgs(Module *M, ArrayRef<Substitution> args) {
auto params = getGenericParams();
@@ -3489,8 +3461,6 @@
anyChanges = true;
}
- auto sig = GenericSignature::get(genericParams, requirements);
-
// Transform input type.
auto inputTy = function->getInput().transform(fn);
if (!inputTy)
@@ -3508,11 +3478,12 @@
return *this;
// If no generic parameters remain, this is a non-generic function type.
- if (genericParams.empty())
+ if (genericParams.empty()) {
return FunctionType::get(inputTy, resultTy, function->getExtInfo());
+ }
// Produce the new generic function type.
-
+ auto sig = GenericSignature::get(genericParams, requirements);
return GenericFunctionType::get(sig, inputTy, resultTy,
function->getExtInfo());
}
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index ab6dab4..e5added 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -23,6 +23,8 @@
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsClangImporter.h"
#include "swift/AST/Expr.h"
+#include "swift/AST/GenericEnvironment.h"
+#include "swift/AST/GenericSignature.h"
#include "swift/AST/Module.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/ParameterList.h"
@@ -1365,12 +1367,14 @@
// Handle generic types.
GenericParamList *genericParams = nullptr;
GenericSignature *genericSig = nullptr;
+ GenericEnvironment *genericEnv = nullptr;
auto underlyingType = typeDecl->getDeclaredInterfaceType();
if (auto generic = dyn_cast<GenericTypeDecl>(typeDecl)) {
if (generic->getGenericSignature() && !isa<ProtocolDecl>(typeDecl)) {
genericParams = generic->getGenericParams();
genericSig = generic->getGenericSignature();
+ genericEnv = generic->getGenericEnvironment();
underlyingType = ArchetypeBuilder::mapTypeIntoContext(
generic, underlyingType);
@@ -1395,6 +1399,7 @@
genericParams, dc);
alias->computeType();
alias->setGenericSignature(genericSig);
+ alias->setGenericEnvironment(genericEnv);
// Record that this is the Swift 2 version of this declaration.
Impl.ImportedDecls[{decl->getCanonicalDecl(), true}] = alias;
@@ -3133,6 +3138,7 @@
result->setType(fnType);
result->setInterfaceType(interfaceType);
result->setGenericSignature(dc->getGenericSignatureOfContext());
+ result->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
result->setBodyResultType(swiftResultTy);
result->setAccessibility(Accessibility::Public);
@@ -3912,6 +3918,7 @@
result->setType(type);
result->setInterfaceType(interfaceType);
result->setGenericSignature(dc->getGenericSignatureOfContext());
+ result->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
// Optional methods in protocols.
if (decl->getImplementationControl() == clang::ObjCMethodDecl::Optional &&
@@ -4386,6 +4393,7 @@
result->setInitializerInterfaceType(interfaceInitType);
result->setInterfaceType(interfaceAllocType);
result->setGenericSignature(dc->getGenericSignatureOfContext());
+ result->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
result->setType(allocType);
@@ -4523,6 +4531,8 @@
thunk->setBodyResultType(elementTy);
thunk->setInterfaceType(interfaceType);
thunk->setGenericSignature(dc->getGenericSignatureOfContext());
+ thunk->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
+
thunk->setAccessibility(getOverridableAccessibility(dc));
auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>();
@@ -4594,6 +4604,8 @@
thunk->setBodyResultType(TupleType::getEmpty(C));
thunk->setInterfaceType(interfaceType);
thunk->setGenericSignature(dc->getGenericSignatureOfContext());
+ thunk->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
+
thunk->setAccessibility(getOverridableAccessibility(dc));
auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>();
@@ -5143,22 +5155,24 @@
Impl.importSourceLoc(typeParamList->getRAngleLoc()));
}
- // Calculate the generic signature for the given imported generic param
- // list. If there are any errors in doing so, return 'nullptr'.
- GenericSignature *calculateGenericSignature(GenericParamList *genericParams,
- DeclContext *dc) {
+ // Calculate the generic signature and interface type to archetype mapping
+ // from an imported generic param list.
+ std::pair<GenericSignature *, GenericEnvironment *>
+ calculateGenericSignature(GenericParamList *genericParams,
+ DeclContext *dc) {
ArchetypeBuilder builder(*dc->getParentModule(), Impl.SwiftContext.Diags);
for (auto param : *genericParams)
builder.addGenericParameter(param);
for (auto param : *genericParams) {
- if (builder.addGenericParameterRequirements(param)) {
- return nullptr;
- }
+ bool result = builder.addGenericParameterRequirements(param);
+ assert(!result);
+ (void) result;
}
// TODO: any need to infer requirements?
- if (builder.finalize(genericParams->getSourceRange().Start)) {
- return nullptr;
- }
+ bool result = builder.finalize(genericParams->getSourceRange().Start);
+ assert(!result);
+ (void) result;
+
SmallVector<GenericTypeParamType *, 4> genericParamTypes;
for (auto param : *genericParams) {
genericParamTypes.push_back(
@@ -5166,10 +5180,11 @@
auto *archetype = builder.getArchetype(param);
param->setArchetype(archetype);
}
- genericParams->setAllArchetypes(
- Impl.SwiftContext.AllocateCopy(builder.getAllArchetypes()));
- return builder.getGenericSignature(genericParamTypes);
+ auto *sig = builder.getGenericSignature(genericParamTypes);
+ auto *env = builder.getGenericEnvironment(genericParamTypes);
+
+ return std::make_pair(sig, env);
}
/// Import members of the given Objective-C container and add them to the
@@ -5507,11 +5522,14 @@
auto genericParams = GenericParamList::create(Impl.SwiftContext,
SourceLoc(), toGenericParams, SourceLoc());
result->setGenericParams(genericParams);
- if (auto sig = calculateGenericSignature(genericParams, result)) {
- result->setGenericSignature(sig);
- } else {
- return nullptr;
- }
+
+ GenericSignature *sig;
+ GenericEnvironment *env;
+ std::tie(sig, env) = calculateGenericSignature(genericParams, result);
+
+ result->setGenericSignature(sig);
+ result->setGenericEnvironment(env);
+
// Calculate the correct bound-generic extended type.
SmallVector<Type, 2> genericArgs;
for (auto gp : *genericParams) {
@@ -5669,12 +5687,6 @@
Type(result->getDeclaredType()),
Type(), false);
selfDecl->setArchetype(selfArchetype);
-
- // Set AllArchetypes of the protocol. ObjC protocols don't have associated
- // types so only the Self archetype is present.
-
- result->getGenericParams()->setAllArchetypes(
- Impl.SwiftContext.AllocateCopy(llvm::makeArrayRef(selfArchetype)));
// Set the generic parameters and requirements.
auto genericParam = selfDecl->getDeclaredType()
@@ -5687,6 +5699,15 @@
auto sig = GenericSignature::get(genericParam, genericRequirements);
result->setGenericSignature(sig);
+ TypeSubstitutionMap interfaceToArchetypeMap;
+
+ auto paramTy = selfDecl->getDeclaredType()->getCanonicalType();
+ interfaceToArchetypeMap[paramTy.getPointer()] = selfArchetype;
+
+ auto *env =
+ GenericEnvironment::get(Impl.SwiftContext, interfaceToArchetypeMap);
+ result->setGenericEnvironment(env);
+
result->setCircularityCheck(CircularityCheck::Checked);
// Import protocols this protocol conforms to.
@@ -5818,11 +5839,13 @@
auto genericParams = *gpImportResult;
if (genericParams) {
result->setGenericParams(genericParams);
- if (auto sig = calculateGenericSignature(genericParams, result)) {
- result->setGenericSignature(sig);
- } else {
- return nullptr;
- }
+
+ GenericSignature *sig;
+ GenericEnvironment *env;
+ std::tie(sig, env) = calculateGenericSignature(genericParams, result);
+
+ result->setGenericSignature(sig);
+ result->setGenericEnvironment(env);
}
} else {
return nullptr;
@@ -6967,8 +6990,6 @@
conformsTo, protoArchetype->getSuperclass(),
protoArchetype->getIsRecursive());
extSelf->setArchetype(extSelfArchetype);
- ext->getGenericParams()->setAllArchetypes(
- SwiftContext.AllocateCopy(llvm::makeArrayRef(extSelfArchetype)));
auto genericParam =
extSelf->getDeclaredType()->castTo<GenericTypeParamType>();
@@ -6976,8 +6997,17 @@
Requirement(RequirementKind::WitnessMarker, genericParam, Type()),
Requirement(RequirementKind::Conformance, genericParam,
protoDecl->getDeclaredType())};
- auto sig = GenericSignature::get(genericParam, genericRequirements);
+ auto *sig = GenericSignature::get(genericParam, genericRequirements);
ext->setGenericSignature(sig);
+
+ TypeSubstitutionMap interfaceToArchetypeMap;
+
+ auto paramTy = extSelf->getDeclaredType()->getCanonicalType();
+ interfaceToArchetypeMap[paramTy.getPointer()] = extSelfArchetype;
+
+ auto *env =
+ GenericEnvironment::get(SwiftContext, interfaceToArchetypeMap);
+ ext->setGenericEnvironment(env);
}
// Add the extension to the nominal type.
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 3333be2..8d9a5db 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -236,7 +236,7 @@
array = IGF.Builder.CreateElementBitCast(array, IGF.IGM.TypeMetadataPtrTy);
auto getInContext = [&](CanType type) -> CanType {
- return ArchetypeBuilder::mapTypeIntoContext(typeDecl, type, nullptr)
+ return ArchetypeBuilder::mapTypeIntoContext(typeDecl, type)
->getCanonicalType();
};
@@ -2767,7 +2767,7 @@
auto declCtxt = type;
if (auto generics = declCtxt->getGenericSignatureOfContext()) {
auto getInContext = [&](CanType type) -> CanType {
- return ArchetypeBuilder::mapTypeIntoContext(declCtxt, type, nullptr)
+ return ArchetypeBuilder::mapTypeIntoContext(declCtxt, type)
->getCanonicalType();
};
bindArchetypeAccessPaths(IGF, generics, getInContext);
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 5da8cb1..1c93bf6 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -1281,7 +1281,7 @@
auto declCtx = Conformance.getDeclContext();
if (auto generics = declCtx->getGenericSignatureOfContext()) {
auto getInContext = [&](CanType type) -> CanType {
- return ArchetypeBuilder::mapTypeIntoContext(declCtx, type, nullptr)
+ return ArchetypeBuilder::mapTypeIntoContext(declCtx, type)
->getCanonicalType();
};
bindArchetypeAccessPaths(IGF, generics, getInContext);
diff --git a/lib/Parse/ParseSIL.cpp b/lib/Parse/ParseSIL.cpp
index fa2bee0..c8dc4a6 100644
--- a/lib/Parse/ParseSIL.cpp
+++ b/lib/Parse/ParseSIL.cpp
@@ -13,6 +13,7 @@
#include "swift/Basic/Defer.h"
#include "swift/Basic/Fallthrough.h"
#include "swift/AST/ArchetypeBuilder.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/NameLookup.h"
#include "swift/Parse/Parser.h"
#include "swift/Parse/Lexer.h"
@@ -213,12 +214,14 @@
bool parseASTType(CanType &result);
bool parseSILType(SILType &Result,
GenericSignature *&genericSig,
+ GenericEnvironment *&genericEnv,
GenericParamList *&genericParams,
bool IsFuncDecl = false);
bool parseSILType(SILType &Result) {
GenericSignature *IgnoredSig;
+ GenericEnvironment *IgnoredEnv;
GenericParamList *IgnoredParams;
- return parseSILType(Result, IgnoredSig, IgnoredParams);
+ return parseSILType(Result, IgnoredSig, IgnoredEnv, IgnoredParams);
}
bool parseSILType(SILType &Result, SourceLoc &TypeLoc) {
TypeLoc = P.Tok.getLoc();
@@ -226,9 +229,10 @@
}
bool parseSILType(SILType &Result, SourceLoc &TypeLoc,
GenericSignature *&GenericSig,
+ GenericEnvironment *&GenericEnv,
GenericParamList *&GenericParams) {
TypeLoc = P.Tok.getLoc();
- return parseSILType(Result, GenericSig, GenericParams);
+ return parseSILType(Result, GenericSig, GenericEnv, GenericParams);
}
/// Parse a SIL type without the leading '$' or value category specifier.
@@ -236,15 +240,18 @@
SILValueCategory category,
const TypeAttributes &attrs,
GenericSignature *&genericSig,
+ GenericEnvironment *&genericEnv,
GenericParamList *&genericParams,
bool IsFuncDecl = false);
bool parseSILTypeWithoutQualifiers(SILType &Result,
SILValueCategory category,
const TypeAttributes &attrs) {
GenericSignature *IgnoredSig;
+ GenericEnvironment *IgnoredEnv;
GenericParamList *IgnoredParams;
return parseSILTypeWithoutQualifiers(Result, category, attrs,
- IgnoredSig, IgnoredParams);
+ IgnoredSig, IgnoredEnv,
+ IgnoredParams);
}
bool parseSILDottedPath(ValueDecl *&Decl,
@@ -305,13 +312,15 @@
ProtocolConformance *parseProtocolConformance(ProtocolDecl *&proto,
GenericSignature *&genericSig,
+ GenericEnvironment *&genericEnv,
GenericParamList *&genericParams,
bool localScope);
ProtocolConformance *parseProtocolConformance() {
ProtocolDecl *dummy;
GenericSignature *sig;
+ GenericEnvironment *env;
GenericParamList *gp;
- return parseProtocolConformance(dummy, sig, gp, true);
+ return parseProtocolConformance(dummy, sig, env, gp, true);
}
Optional<llvm::coverage::Counter>
@@ -838,9 +847,11 @@
SILValueCategory category,
const TypeAttributes &attrs,
GenericSignature *&GenericSig,
+ GenericEnvironment *&GenericEnv,
GenericParamList *&GenericParams,
bool IsFuncDecl){
GenericSig = nullptr;
+ GenericEnv = nullptr;
GenericParams = nullptr;
// If this is part of a function decl, generic parameters are visible in the
@@ -862,8 +873,10 @@
if (auto generics = fnType->getGenericParams()) {
GenericParams = generics;
- GenericSig = handleSILGenericParams(P.Context, generics, &P.SF);
+ std::tie(GenericSig, GenericEnv) =
+ handleSILGenericParams(P.Context, generics, &P.SF);
fnType->setGenericSignature(GenericSig);
+ fnType->setGenericEnvironment(GenericEnv);
}
}
@@ -888,9 +901,11 @@
///
bool SILParser::parseSILType(SILType &Result,
GenericSignature *&GenericSig,
+ GenericEnvironment *&GenericEnv,
GenericParamList *&GenericParams,
bool IsFuncDecl){
GenericSig = nullptr;
+ GenericEnv = nullptr;
GenericParams = nullptr;
if (P.parseToken(tok::sil_dollar, diag::expected_sil_type))
@@ -914,7 +929,7 @@
attrs.convention = "thin";
}
return parseSILTypeWithoutQualifiers(Result, category, attrs,
- GenericSig, GenericParams,
+ GenericSig, GenericEnv, GenericParams,
IsFuncDecl);
}
@@ -1479,20 +1494,22 @@
/// from a SILFunctionType.
bool getApplySubstitutionsFromParsed(
SILParser &SP,
- GenericSignature *sig,
GenericParamList *params,
+ GenericSignature *sig,
+ GenericEnvironment *env,
ArrayRef<ParsedSubstitution> parses,
SmallVectorImpl<Substitution> &subs) {
if (parses.empty()) {
- assert (!sig && !params);
+ assert (!sig && !env);
return false;
}
- assert(sig && params);
+ assert(sig && env);
+
+ auto loc = params->getRAngleLoc();
// Map from interface types to archetypes
- TypeSubstitutionMap map;
- params->getForwardingSubstitutionMap(map);
+ TypeSubstitutionMap map = env->getInterfaceToArchetypeMap();
auto *mod = SP.SILMod.getSwiftModule();
@@ -1504,7 +1521,7 @@
auto *archetype = contextTy->castTo<ArchetypeType>();
if (parses.empty()) {
- SP.P.diagnose(params->getRAngleLoc(), diag::sil_missing_substitutions);
+ SP.P.diagnose(loc, diag::sil_missing_substitutions);
return true;
}
auto parsed = parses.front();
@@ -1520,7 +1537,7 @@
SP.P.Context.AllocateCopy(conformances)});
}
if (!parses.empty()) {
- SP.P.diagnose(params->getRAngleLoc(), diag::sil_too_many_substitutions);
+ SP.P.diagnose(loc, diag::sil_too_many_substitutions);
return true;
}
return false;
@@ -1882,6 +1899,7 @@
auto *builtinFunc = cast<FuncDecl>(foundBuiltins[0]);
GenericSignature *genericSig = builtinFunc->getGenericSignature();
+ GenericEnvironment *genericEnv = builtinFunc->getGenericEnvironment();
GenericParamList *genericParams = builtinFunc->getGenericParams();
SmallVector<ParsedSubstitution, 4> parsedSubs;
@@ -1894,7 +1912,10 @@
P.diagnose(P.Tok, diag::sil_substitutions_on_non_polymorphic_type);
return true;
}
- if (getApplySubstitutionsFromParsed(*this, genericSig, genericParams,
+ if (getApplySubstitutionsFromParsed(*this,
+ genericParams,
+ genericSig,
+ genericEnv,
parsedSubs, subs))
return true;
}
@@ -2381,6 +2402,7 @@
ParsedSetterSubs;
GenericSignature *InitStorageSig, *SetterSig;
GenericParamList *InitStorageParams, *SetterParams;
+ GenericEnvironment *InitStorageEnv, *SetterEnv;
SILType InitStorageTy, SetterTy;
// mark_uninitialized_behavior %init<Subs>(%storage) : $T -> U,
@@ -2391,7 +2413,7 @@
|| parseValueName(StorageName)
|| P.parseToken(tok::r_paren, diag::expected_tok_in_sil_instr, ")")
|| P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":")
- || parseSILType(InitStorageTy, InitStorageSig, InitStorageParams)
+ || parseSILType(InitStorageTy, InitStorageSig, InitStorageEnv, InitStorageParams)
|| P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",")
|| parseValueName(SetterFuncName)
|| parseApplySubstitutions(ParsedSetterSubs)
@@ -2399,7 +2421,7 @@
|| parseValueName(SelfName)
|| P.parseToken(tok::r_paren, diag::expected_tok_in_sil_instr, ")")
|| P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":")
- || parseSILType(SetterTy, SetterSig, SetterParams))
+ || parseSILType(SetterTy, SetterSig, SetterEnv, SetterParams))
return true;
// Resolve the types of the operands.
@@ -2409,9 +2431,12 @@
SmallVector<Substitution, 4> InitStorageSubs, SetterSubs;
if (getApplySubstitutionsFromParsed(*this,
- InitStorageSig, InitStorageParams,
+ InitStorageParams,
+ InitStorageSig, InitStorageEnv,
ParsedInitStorageSubs, InitStorageSubs)
- || getApplySubstitutionsFromParsed(*this, SetterSig, SetterParams,
+ || getApplySubstitutionsFromParsed(*this,
+ SetterParams,
+ SetterSig, SetterEnv,
ParsedSetterSubs, SetterSubs))
return true;
@@ -2913,8 +2938,12 @@
if (auto generics = fnType->getGenericParams()) {
assert(!Ty.wasValidated() && Ty.getType().isNull());
- auto *genericSig = handleSILGenericParams(P.Context, generics, &P.SF);
+ GenericSignature *genericSig;
+ GenericEnvironment *genericEnv;
+ std::tie(genericSig, genericEnv) =
+ handleSILGenericParams(P.Context, generics, &P.SF);
fnType->setGenericSignature(genericSig);
+ fnType->setGenericEnvironment(genericEnv);
}
}
@@ -3615,6 +3644,7 @@
UnresolvedValueName invokeName;
SILType invokeTy;
GenericSignature *invokeGenericSig;
+ GenericEnvironment *invokeGenericEnv;
GenericParamList *invokeGenericParams;
SILType blockType;
@@ -3628,7 +3658,7 @@
parseValueName(invokeName) ||
parseApplySubstitutions(parsedSubs) ||
P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":") ||
- parseSILType(invokeTy, invokeGenericSig, invokeGenericParams) ||
+ parseSILType(invokeTy, invokeGenericSig, invokeGenericEnv, invokeGenericParams) ||
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
parseSILIdentifier(type, typeLoc,
diag::expected_tok_in_sil_instr, "type") ||
@@ -3654,8 +3684,9 @@
return true;
}
if (getApplySubstitutionsFromParsed(*this,
- invokeGenericSig,
invokeGenericParams,
+ invokeGenericSig,
+ invokeGenericEnv,
parsedSubs, subs))
return true;
}
@@ -3702,10 +3733,11 @@
SILType Ty;
SourceLoc TypeLoc;
GenericSignature *GenericSig = nullptr;
+ GenericEnvironment *GenericEnv = nullptr;
GenericParamList *GenericParams = nullptr;
if (P.parseToken(tok::r_paren, diag::expected_tok_in_sil_instr, ")") ||
P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":") ||
- parseSILType(Ty, TypeLoc, GenericSig, GenericParams))
+ parseSILType(Ty, TypeLoc, GenericSig, GenericEnv, GenericParams))
return true;
auto FTI = Ty.getAs<SILFunctionType>();
@@ -3716,11 +3748,13 @@
SmallVector<Substitution, 4> subs;
if (!parsedSubs.empty()) {
- if (!GenericParams) {
+ if (!GenericSig) {
P.diagnose(TypeLoc, diag::sil_substitutions_on_non_polymorphic_type);
return true;
}
- if (getApplySubstitutionsFromParsed(*this, GenericSig, GenericParams,
+ if (getApplySubstitutionsFromParsed(*this,
+ GenericParams,
+ GenericSig, GenericEnv,
parsedSubs, subs))
return true;
}
@@ -3958,8 +3992,10 @@
// the scope.
Scope Body(this, ScopeKind::FunctionBody);
GenericSignature *GenericSig;
- GenericParamList *ContextParams;
- if (FunctionState.parseSILType(FnType, GenericSig, ContextParams,
+ GenericEnvironment *GenericEnv;
+ GenericParamList *GenericParams;
+ if (FunctionState.parseSILType(FnType,
+ GenericSig, GenericEnv, GenericParams,
true/*IsFuncDecl*/))
return true;
auto SILFnType = FnType.getAs<SILFunctionType>();
@@ -3989,17 +4025,15 @@
if (consumeIf(tok::l_brace)) {
isDefinition = true;
- // FIXME: Get the generic parameters from the function type. We'll want
- // to parse this from the TypeRepr when SILFunctionType loses its context
- // params.
- FunctionState.F->setContextGenericParams(ContextParams);
+ FunctionState.F->setGenericEnvironment(GenericEnv);
- // Resolve specialization attributes after setting ContextParams.
+ // Resolve specialization attributes after setting GenericEnv.
for (auto &Attr : SpecAttrs) {
SmallVector<Substitution, 4> Subs;
if (getApplySubstitutionsFromParsed(FunctionState,
+ GenericParams,
GenericSig,
- ContextParams,
+ GenericEnv,
Attr.subs, Subs)) {
return true;
}
@@ -4341,6 +4375,7 @@
ProtocolConformance *SILParser::parseProtocolConformance(
ProtocolDecl *&proto,
GenericSignature *&genericSig,
+ GenericEnvironment *&genericEnv,
GenericParamList *&genericParams,
bool localScope) {
// Parse generic params for the protocol conformance. We need to make sure
@@ -4354,7 +4389,8 @@
genericParams = P.maybeParseGenericParams().getPtrOrNull();
if (genericParams) {
- genericSig = handleSILGenericParams(P.Context, genericParams, &P.SF);
+ std::tie(genericSig, genericEnv) =
+ handleSILGenericParams(P.Context, genericParams, &P.SF);
}
ProtocolConformance *retVal = parseProtocolConformanceHelper(proto,
@@ -4402,15 +4438,19 @@
return nullptr;
ProtocolDecl *dummy;
GenericSignature *sig;
+ GenericEnvironment *env;
GenericParamList *gp;
- auto genericConform = parseProtocolConformance(dummy, sig, gp, localScope);
+ auto genericConform = parseProtocolConformance(dummy, sig, env, gp,
+ localScope);
if (!genericConform)
return nullptr;
if (P.parseToken(tok::r_paren, diag::expected_sil_witness_rparen))
return nullptr;
SmallVector<Substitution, 4> subs;
- if (getApplySubstitutionsFromParsed(*this, sig, gp, parsedSubs, subs))
+ if (getApplySubstitutionsFromParsed(*this,
+ gp,
+ sig, env, parsedSubs, subs))
return nullptr;
auto result = P.Context.getSpecializedConformance(
@@ -4471,9 +4511,12 @@
// Parse the protocol conformance.
ProtocolDecl *proto;
GenericSignature *dummySig;
+ GenericEnvironment *dummyEnv;
GenericParamList *dummyParams;
auto conf = WitnessState.parseProtocolConformance(proto,
- dummySig, dummyParams,
+ dummySig,
+ dummyEnv,
+ dummyParams,
false/*localScope*/);
NormalProtocolConformance *theConformance = conf ?
@@ -4906,12 +4949,13 @@
// We need to turn on InSILBody to parse the function reference.
Lexer::SILBodyRAII Tmp(*L);
GenericSignature *IgnoredSig;
+ GenericEnvironment *IgnoredEnv;
GenericParamList *IgnoredParams;
Scope S(this, ScopeKind::TopLevel);
Scope Body(this, ScopeKind::FunctionBody);
if ((ScopeState.parseGlobalName(FnName)) ||
parseToken(tok::colon, diag::expected_sil_colon_value_ref) ||
- ScopeState.parseSILType(Ty, IgnoredSig, IgnoredParams, true))
+ ScopeState.parseSILType(Ty, IgnoredSig, IgnoredEnv, IgnoredParams, true))
return true;
// The function doesn't exist yet. Create a zombie forward declaration.
diff --git a/lib/SIL/SILFunction.cpp b/lib/SIL/SILFunction.cpp
index 533b470..9637a63 100644
--- a/lib/SIL/SILFunction.cpp
+++ b/lib/SIL/SILFunction.cpp
@@ -16,8 +16,8 @@
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/CFG.h"
-// FIXME: For mapTypeInContext
#include "swift/AST/ArchetypeBuilder.h"
+#include "swift/AST/GenericEnvironment.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/GraphWriter.h"
@@ -41,7 +41,7 @@
SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
StringRef name,
CanSILFunctionType loweredType,
- GenericParamList *contextGenericParams,
+ GenericEnvironment *genericEnv,
Optional<SILLocation> loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
@@ -62,7 +62,7 @@
}
auto fn = new (M) SILFunction(M, linkage, name,
- loweredType, contextGenericParams, loc,
+ loweredType, genericEnv, loc,
isBareSILFunction, isTrans, isFragile, isThunk,
classVisibility, inlineStrategy, E,
insertBefore, debugScope, DC);
@@ -73,7 +73,7 @@
SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
StringRef Name, CanSILFunctionType LoweredType,
- GenericParamList *contextGenericParams,
+ GenericEnvironment *genericEnv,
Optional<SILLocation> Loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
@@ -87,8 +87,7 @@
: Module(Module),
Name(Name),
LoweredType(LoweredType),
- // FIXME: Context params should be independent of the function type.
- ContextGenericParams(contextGenericParams),
+ GenericEnv(genericEnv),
DeclCtx(DC),
DebugScope(DebugScope),
Bare(isBareSILFunction),
@@ -188,7 +187,7 @@
Type SILFunction::mapTypeIntoContext(Type type) const {
return ArchetypeBuilder::mapTypeIntoContext(getModule().getSwiftModule(),
- getContextGenericParams(),
+ getGenericEnvironment(),
type);
}
@@ -290,7 +289,7 @@
Type SILFunction::mapTypeOutOfContext(Type type) const {
return ArchetypeBuilder::mapTypeOutOfContext(getModule().getSwiftModule(),
- getContextGenericParams(),
+ getGenericEnvironment(),
type);
}
@@ -558,12 +557,13 @@
if (ForwardingSubs)
return *ForwardingSubs;
- auto *params = getContextGenericParams();
- if (!params)
+ auto *env = getGenericEnvironment();
+ if (!env)
return {};
auto sig = getLoweredFunctionType()->getGenericSignature();
- ForwardingSubs = params->getForwardingSubstitutions(sig);
+ auto *M = getModule().getSwiftModule();
+ ForwardingSubs = env->getForwardingSubstitutions(M, sig);
return *ForwardingSubs;
}
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 7754fd6..da2c1cc 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -1682,9 +1682,7 @@
// First, get a function type for the constant. This creates the
// right type for a getter or setter.
auto formalInterfaceType = makeConstantInterfaceType(constant);
- GenericParamList *contextGenerics, *innerGenerics;
- std::tie(contextGenerics, innerGenerics)
- = getConstantContextGenericParams(constant);
+ auto *genericEnv = getConstantGenericEnvironment(constant);
// The formal type is just that with the right representation.
auto rep = getDeclRefRepresentation(constant);
@@ -1714,8 +1712,7 @@
formalInterfaceType,
loweredInterfaceType,
silFnType,
- contextGenerics,
- innerGenerics,
+ genericEnv
};
ConstantTypes[constant] = result;
return result;
@@ -2091,8 +2088,7 @@
SILConstantInfo overrideInfo;
overrideInfo.LoweredInterfaceType = overrideLoweredInterfaceTy;
overrideInfo.SILFnType = fnTy;
- overrideInfo.ContextGenericParams = derivedInfo.ContextGenericParams;
- overrideInfo.InnerGenericParams = derivedInfo.InnerGenericParams;
+ overrideInfo.GenericEnv = derivedInfo.GenericEnv;
ConstantOverrideTypes[{derived, base}] = overrideInfo;
return overrideInfo;
diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp
index 8c2ef8d..dc73acb 100644
--- a/lib/SIL/SILModule.cpp
+++ b/lib/SIL/SILModule.cpp
@@ -409,13 +409,13 @@
SILFunction *SILModule::createFunction(
SILLinkage linkage, StringRef name, CanSILFunctionType loweredType,
- GenericParamList *contextGenericParams, Optional<SILLocation> loc,
+ GenericEnvironment *genericEnv, Optional<SILLocation> loc,
IsBare_t isBareSILFunction, IsTransparent_t isTrans, IsFragile_t isFragile,
IsThunk_t isThunk, SILFunction::ClassVisibility_t classVisibility,
Inline_t inlineStrategy, EffectsKind EK, SILFunction *InsertBefore,
const SILDebugScope *DebugScope, DeclContext *DC) {
return SILFunction::create(*this, linkage, name, loweredType,
- contextGenericParams, loc, isBareSILFunction,
+ genericEnv, loc, isBareSILFunction,
isTrans, isFragile, isThunk, classVisibility,
inlineStrategy, EK, InsertBefore, DebugScope, DC);
}
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index ad3bb3e..4baac97 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -1794,33 +1794,35 @@
llvm::DenseMap<CanType, Identifier> Aliases;
llvm::DenseSet<Identifier> UsedNames;
- auto params = ContextGenericParams;
- llvm::SmallString<16> disambiguatedNameBuf;
- unsigned disambiguatedNameCounter = 1;
- while (params) {
- for (GenericTypeParamDecl *param : params->getParams()) {
- Identifier name = param->getName();
+ auto sig = getLoweredFunctionType()->getGenericSignature();
+ auto *env = getGenericEnvironment();
+ if (sig && env) {
+ llvm::SmallString<16> disambiguatedNameBuf;
+ unsigned disambiguatedNameCounter = 1;
+ for (auto *paramTy : sig->getGenericParams()) {
+ auto *archetypeTy = mapTypeIntoContext(paramTy)->getAs<ArchetypeType>();
+ assert(archetypeTy);
+
+ Identifier name = archetypeTy->getName();
while (!UsedNames.insert(name).second) {
disambiguatedNameBuf.clear();
{
llvm::raw_svector_ostream names(disambiguatedNameBuf);
- names << param->getName() << disambiguatedNameCounter++;
+ names << archetypeTy->getName() << disambiguatedNameCounter++;
}
name = getASTContext().getIdentifier(disambiguatedNameBuf);
}
- if (name != param->getName())
- Aliases[CanType(param->getArchetype())] = name;
+ if (name != archetypeTy->getName())
+ Aliases[CanType(archetypeTy)] = name;
}
-
- params = params->getOuterParameters();
}
{
- PrintOptions withContextGenericParams = PrintOptions::printSIL();
- withContextGenericParams.ContextGenericParams = ContextGenericParams;
- withContextGenericParams.AlternativeTypeNames =
+ PrintOptions withGenericEnvironment = PrintOptions::printSIL();
+ withGenericEnvironment.GenericEnv = env;
+ withGenericEnvironment.AlternativeTypeNames =
Aliases.empty() ? nullptr : &Aliases;
- LoweredType->print(OS, withContextGenericParams);
+ LoweredType->print(OS, withGenericEnvironment);
}
if (!isExternalDeclaration()) {
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 9b9e892..beb3fa4 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -22,6 +22,7 @@
#include "swift/AST/AnyFunctionRef.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Module.h"
#include "swift/AST/Types.h"
#include "swift/SIL/PrettyStackTrace.h"
@@ -59,15 +60,10 @@
A = A->getPrimary();
// Ok, we have a primary archetype, make sure it is in the nested generic
- // parameters of our caller.
- for (auto *params = F->getContextGenericParams();
- params != nullptr;
- params = params->getOuterParameters()) {
-
- for (auto param : params->getParams())
- if (param->getArchetype()->isEqual(A))
- return true;
- }
+ // environment of our caller.
+ if (auto *genericEnv = F->getGenericEnvironment())
+ if (genericEnv->getArchetypeToInterfaceMap().count(A))
+ return true;
return false;
}
@@ -1757,9 +1753,9 @@
auto methodTy = constantInfo.SILFnType;
// Map interface types to archetypes.
- if (auto *params = constantInfo.ContextGenericParams) {
+ if (auto *env = constantInfo.GenericEnv) {
auto sig = constantInfo.SILFnType->getGenericSignature();
- auto subs = params->getForwardingSubstitutions(sig);
+ auto subs = env->getForwardingSubstitutions(M, sig);
methodTy = methodTy->substGenericArgs(F.getModule(), M, subs);
}
assert(!methodTy->isPolymorphic());
@@ -3308,13 +3304,13 @@
// Make sure that our SILFunction only has context generic params if our
// SILFunctionType is non-polymorphic.
- if (F->getContextGenericParams()) {
+ if (F->getGenericEnvironment()) {
require(FTy->isPolymorphic(),
- "non-generic function definitions cannot have context "
- "archetypes");
+ "non-generic function definitions cannot have a "
+ "generic environment");
} else {
require(!FTy->isPolymorphic(),
- "generic function definition must have context archetypes");
+ "generic function definition must have a generic environment");
}
// Otherwise, verify the body of the function.
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index e4d4c6c..14aca5f 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -1658,7 +1658,7 @@
sig = genTy->getGenericSignature()->getCanonicalSignature();
resultTy = ArchetypeBuilder::mapTypeOutOfContext(
TC.M.getSwiftModule(),
- funcInfo.ContextGenericParams,
+ funcInfo.GenericEnv,
resultTy)->getCanonicalType();
}
@@ -1748,16 +1748,16 @@
return CanFunctionType::get(classType, resultType, extInfo);
}
-GenericParamList *
-TypeConverter::getEffectiveGenericParams(AnyFunctionRef fn,
- CaptureInfo captureInfo) {
+GenericEnvironment *
+TypeConverter::getEffectiveGenericEnvironment(AnyFunctionRef fn,
+ CaptureInfo captureInfo) {
auto dc = fn.getAsDeclContext();
if (dc->getParent()->isLocalContext() &&
!captureInfo.hasGenericParamCaptures())
return nullptr;
- return dc->getGenericParamsOfContext();
+ return dc->getGenericEnvironmentOfContext();
}
CanGenericSignature
@@ -1904,9 +1904,9 @@
}
}
-/// Get the context generic parameters for an entity.
-std::pair<GenericParamList *, GenericParamList *>
-TypeConverter::getConstantContextGenericParams(SILDeclRef c) {
+/// Get the generic environment for an entity.
+GenericEnvironment *
+TypeConverter::getConstantGenericEnvironment(SILDeclRef c) {
ValueDecl *vd = c.loc.dyn_cast<ValueDecl *>();
/// Get the function generic params, including outer params.
@@ -1915,48 +1915,37 @@
if (auto *ACE = c.getAbstractClosureExpr()) {
auto captureInfo = getLoweredLocalCaptures(ACE);
- // Closures are currently never natively generic.
- return {getEffectiveGenericParams(ACE, captureInfo), nullptr};
+ return getEffectiveGenericEnvironment(ACE, captureInfo);
}
FuncDecl *func = cast<FuncDecl>(vd);
auto captureInfo = getLoweredLocalCaptures(func);
- return {getEffectiveGenericParams(func, captureInfo),
- func->getGenericParams()};
+ return getEffectiveGenericEnvironment(func, captureInfo);
}
case SILDeclRef::Kind::EnumElement: {
auto eltDecl = cast<EnumElementDecl>(vd);
- return {
- eltDecl->getDeclContext()->getGenericParamsOfContext(),
- nullptr
- };
+ return eltDecl->getDeclContext()->getGenericEnvironmentOfContext();
}
case SILDeclRef::Kind::Allocator:
case SILDeclRef::Kind::Initializer:
case SILDeclRef::Kind::Destroyer:
case SILDeclRef::Kind::Deallocator: {
auto *afd = cast<AbstractFunctionDecl>(vd);
- return {afd->getGenericParamsOfContext(), afd->getGenericParams()};
+ return afd->getGenericEnvironmentOfContext();
}
case SILDeclRef::Kind::GlobalAccessor:
case SILDeclRef::Kind::GlobalGetter: {
- return {
- cast<VarDecl>(vd)->getDeclContext()->getGenericParamsOfContext(),
- nullptr,
- };
+ return vd->getDeclContext()->getGenericEnvironmentOfContext();
}
case SILDeclRef::Kind::IVarInitializer:
case SILDeclRef::Kind::IVarDestroyer:
- return {cast<ClassDecl>(vd)->getGenericParamsOfContext(), nullptr};
+ return cast<ClassDecl>(vd)->getGenericEnvironmentOfContext();
case SILDeclRef::Kind::DefaultArgGenerator:
- // Use the context generic parameters of the original declaration.
- return getConstantContextGenericParams(SILDeclRef(c.getDecl()));
+ // Use the generic environment of the original function.
+ return getConstantGenericEnvironment(SILDeclRef(c.getDecl()));
case SILDeclRef::Kind::StoredPropertyInitializer:
- // Use the context generic parameters of the containing type.
- return {
- c.getDecl()->getDeclContext()->getGenericParamsOfContext(),
- nullptr,
- };
+ // Use the generic environment of the containing type.
+ return c.getDecl()->getDeclContext()->getGenericEnvironmentOfContext();
}
}
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index 43d637f..e8682ec 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -575,8 +575,7 @@
assert(F->empty() && "already emitted function?!");
- F->setContextGenericParams(
- Types.getConstantInfo(constant).ContextGenericParams);
+ F->setGenericEnvironment(Types.getConstantInfo(constant).GenericEnv);
// Create a debug scope for the function using astNode as source location.
F->setDebugScope(new (M) SILDebugScope(Loc, F));
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index e019161..ba393c7 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -185,7 +185,7 @@
/// Get or create the declaration of a reabstraction thunk with the
/// given signature.
SILFunction *getOrCreateReabstractionThunk(
- GenericParamList *thunkContextParams,
+ GenericEnvironment *genericEnv,
CanSILFunctionType thunkType,
CanSILFunctionType fromType,
CanSILFunctionType toType,
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index ce9c2bf..5e247c3 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -321,14 +321,10 @@
// Build the invoke function signature. The block will capture the original
// function value.
auto fnTy = fn.getType().castTo<SILFunctionType>();
- auto fnInterfaceTy = cast<SILFunctionType>(CanType(
- ArchetypeBuilder::mapTypeOutOfContext(SGM.M.getSwiftModule(),
- F.getContextGenericParams(),
- fnTy)));
- auto blockInterfaceTy = cast<SILFunctionType>(CanType(
- ArchetypeBuilder::mapTypeOutOfContext(SGM.M.getSwiftModule(),
- F.getContextGenericParams(),
- blockTy)));
+ auto fnInterfaceTy = cast<SILFunctionType>(
+ F.mapTypeOutOfContext(fnTy)->getCanonicalType());
+ auto blockInterfaceTy = cast<SILFunctionType>(
+ F.mapTypeOutOfContext(blockTy)->getCanonicalType());
auto storageTy = SILBlockStorageType::get(fnTy);
auto storageInterfaceTy = SILBlockStorageType::get(fnInterfaceTy);
@@ -363,7 +359,7 @@
// Create the invoke function. Borrow the mangling scheme from reabstraction
// thunks, which is what we are in spirit.
- auto thunk = SGM.getOrCreateReabstractionThunk(F.getContextGenericParams(),
+ auto thunk = SGM.getOrCreateReabstractionThunk(F.getGenericEnvironment(),
invokeTy,
fnTy,
blockTy,
@@ -371,7 +367,7 @@
// Build it if necessary.
if (thunk->empty()) {
- thunk->setContextGenericParams(F.getContextGenericParams());
+ thunk->setGenericEnvironment(F.getGenericEnvironment());
SILGenFunction thunkSGF(SGM, *thunk);
auto loc = RegularLocation::getAutoGeneratedLocation();
buildFuncToBlockInvokeBody(thunkSGF, loc, blockTy, storageTy, fnTy);
@@ -612,7 +608,7 @@
// Declare the thunk.
auto blockTy = block.getType().castTo<SILFunctionType>();
auto thunkTy = buildThunkType(block, funcTy, substFnTy, subs);
- auto thunk = SGM.getOrCreateReabstractionThunk(F.getContextGenericParams(),
+ auto thunk = SGM.getOrCreateReabstractionThunk(F.getGenericEnvironment(),
thunkTy,
blockTy,
funcTy,
@@ -621,7 +617,7 @@
// Build it if necessary.
if (thunk->empty()) {
SILGenFunction thunkSGF(SGM, *thunk);
- thunk->setContextGenericParams(F.getContextGenericParams());
+ thunk->setGenericEnvironment(F.getGenericEnvironment());
auto loc = RegularLocation::getAutoGeneratedLocation();
buildBlockToFuncThunkBody(thunkSGF, loc, blockTy, funcTy);
}
@@ -852,7 +848,7 @@
auto swiftFnTy = swiftInfo.SILFnType->substGenericArgs(gen.SGM.M, mod, subs);
// We must have the same context archetypes as the unthunked function.
- assert(objcInfo.ContextGenericParams == swiftInfo.ContextGenericParams);
+ assert(objcInfo.GenericEnv == swiftInfo.GenericEnv);
SmallVector<ManagedValue, 8> bridgedArgs;
bridgedArgs.reserve(objcFnTy->getParameters().size());
@@ -959,8 +955,8 @@
SGM.M, SGM.M.getSwiftModule(), subs);
SILType substSILTy = SILType::getPrimitiveObjectType(substTy);
- // Use the same context generic params as the native entry point.
- F.setContextGenericParams(nativeInfo.ContextGenericParams);
+ // Use the same generic environment as the native entry point.
+ F.setGenericEnvironment(nativeInfo.GenericEnv);
auto loc = thunk.getAsRegularLocation();
loc.markAutoGenerated();
@@ -1121,8 +1117,8 @@
auto nativeFnTy = F.getLoweredFunctionType();
assert(nativeFnTy == nativeCI.SILFnType);
- // Use the same context generic params as the native entry point.
- F.setContextGenericParams(nativeCI.ContextGenericParams);
+ // Use the same generic environment as the native entry point.
+ F.setGenericEnvironment(nativeCI.GenericEnv);
// Find the foreign error convention and 'self' parameter index.
Optional<ForeignErrorConvention> foreignError;
@@ -1282,8 +1278,9 @@
auto fnType = fn->getType().castTo<SILFunctionType>();
fnType = fnType->substGenericArgs(SGM.M, SGM.SwiftModule, subs);
- CanType substResultTy{
- ArchetypeBuilder::mapTypeIntoContext(fd, nativeFormalResultTy)};
+ auto substResultTy =
+ ArchetypeBuilder::mapTypeIntoContext(fd, nativeFormalResultTy)
+ ->getCanonicalType();
auto resultMV = emitApply(fd, ManagedValue::forUnmanaged(fn),
subs, args, fnType,
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index 55559e4..9abe4e3 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -17,6 +17,7 @@
#include "RValue.h"
#include "Scope.h"
#include "swift/AST/AST.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Mangle.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILUndef.h"
@@ -491,9 +492,10 @@
ArrayRef<Substitution> subs;
// Call the initializer.
ArrayRef<Substitution> forwardingSubs;
- if (auto *genericParamList = ctor->getGenericParamsOfContext()) {
+ if (auto *genericEnv = ctor->getGenericEnvironmentOfContext()) {
auto *genericSig = ctor->getGenericSignatureOfContext();
- forwardingSubs = genericParamList->getForwardingSubstitutions(genericSig);
+ forwardingSubs = genericEnv->getForwardingSubstitutions(
+ SGM.SwiftModule, genericSig);
}
std::tie(initVal, initTy, subs)
= emitSiblingMethodRef(Loc, selfValue, initConstant, forwardingSubs);
@@ -871,10 +873,11 @@
// Get the substitutions for the constructor context.
ArrayRef<Substitution> subs;
- auto *genericParams = dc->getGenericParamsOfContext();
- if (genericParams) {
+ auto *genericEnv = dc->getGenericEnvironmentOfContext();
+ if (genericEnv) {
auto *genericSig = dc->getGenericSignatureOfContext();
- subs = genericParams->getForwardingSubstitutions(genericSig);
+ subs = genericEnv->getForwardingSubstitutions(
+ SGM.SwiftModule, genericSig);
}
// Get the type of the initialization result, in terms
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index 9c923e0..362846c 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -23,6 +23,7 @@
#include "swift/SIL/SILWitnessVisitor.h"
#include "swift/SIL/TypeLowering.h"
#include "swift/AST/AST.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Mangle.h"
#include "swift/AST/Module.h"
#include "swift/AST/NameLookup.h"
@@ -1768,34 +1769,36 @@
nameBuffer = mangler.finalize();
}
- // Collect the context generic parameters for the witness.
- //
- // FIXME: SILFunction::ContextGenericParams needs to be a GenericSignature
- // instead.
- GenericParamList *witnessContextParams = nullptr;
+ // Collect the generic environment for the witness.
+ TypeSubstitutionMap witnessContextParams;
// Concrete witness thunks use the context archetypes of the conformance.
if (conformance) {
- witnessContextParams = conformance->getGenericParams();
+ if (auto *genericEnv = conformance->getGenericEnvironment())
+ witnessContextParams = genericEnv->getInterfaceToArchetypeMap();
// If the requirement is generic, reparent the requirement parameters to
// the conformance parameters.
- if (auto reqtParams = requirementInfo.InnerGenericParams) {
- // Preserve the depth of generic arguments by adding an empty outer generic
- // param list if the conformance is concrete.
- if (!witnessContextParams)
- witnessContextParams = GenericParamList::getEmpty(getASTContext());
+ for (auto pair : requirementInfo.GenericEnv->getInterfaceToArchetypeMap()) {
+ // Skip the 'Self' parameter.
+ if (auto *archetypeTy = pair.second->getAs<ArchetypeType>())
+ if (archetypeTy->getSelfProtocol() != nullptr)
+ continue;
- witnessContextParams
- = reqtParams->cloneWithOuterParameters(getASTContext(),
- witnessContextParams);
+ auto result = witnessContextParams.insert(pair);
+ assert(result.second);
}
// Default witness thunks use the context archetypes of the requirement.
} else {
- witnessContextParams = requirementInfo.ContextGenericParams;
+ witnessContextParams = requirementInfo.GenericEnv
+ ->getInterfaceToArchetypeMap();
}
+ GenericEnvironment *witnessEnv = nullptr;
+ if (!witnessContextParams.empty())
+ witnessEnv = GenericEnvironment::get(getASTContext(), witnessContextParams);
+
// If the thunked-to function is set to be always inlined, do the
// same with the witness, on the theory that the user wants all
// calls removed if possible, e.g. when we're able to devirtualize
@@ -1814,7 +1817,7 @@
auto *f = M.createFunction(
linkage, nameBuffer, witnessSILFnType,
- witnessContextParams, SILLocation(witness.getDecl()),
+ witnessEnv, SILLocation(witness.getDecl()),
IsNotBare, IsTransparent, isFragile, IsThunk,
SILFunction::NotRelevant, InlineStrategy);
@@ -1959,7 +1962,7 @@
}
SILFunction *SILGenModule::
-getOrCreateReabstractionThunk(GenericParamList *thunkContextParams,
+getOrCreateReabstractionThunk(GenericEnvironment *genericEnv,
CanSILFunctionType thunkType,
CanSILFunctionType fromType,
CanSILFunctionType toType,
@@ -1981,11 +1984,11 @@
// Substitute context parameters out of the "from" and "to" types.
auto fromInterfaceType
= ArchetypeBuilder::mapTypeOutOfContext(
- M.getSwiftModule(), thunkContextParams, fromType)
+ M.getSwiftModule(), genericEnv, fromType)
->getCanonicalType();
auto toInterfaceType
= ArchetypeBuilder::mapTypeOutOfContext(
- M.getSwiftModule(), thunkContextParams, toType)
+ M.getSwiftModule(), genericEnv, toType)
->getCanonicalType();
mangler.mangleType(fromInterfaceType, /*uncurry*/ 0);
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index 6a6a111..4bc9057 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -20,6 +20,7 @@
#include "Scope.h"
#include "swift/Basic/Fallthrough.h"
#include "swift/AST/AST.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILUndef.h"
@@ -816,9 +817,9 @@
// Forward substitutions.
ArrayRef<Substitution> subs;
auto constantInfo = getConstantInfo(to);
- if (auto gp = constantInfo.ContextGenericParams) {
+ if (auto *env = constantInfo.GenericEnv) {
auto sig = constantInfo.SILFnType->getGenericSignature();
- subs = gp->getForwardingSubstitutions(sig);
+ subs = env->getForwardingSubstitutions(SGM.SwiftModule, sig);
}
SILValue toFn = getNextUncurryLevelRef(*this, vd, to, from.isDirectReference,
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 16685d8..15d9d72 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -22,9 +22,8 @@
#include "Initialization.h"
#include "swift/AST/AST.h"
#include "swift/AST/DiagnosticsSIL.h"
-#include "swift/AST/Decl.h"
-#include "swift/AST/Types.h"
#include "swift/AST/DiagnosticsCommon.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Mangle.h"
#include "swift/SIL/PrettyStackTrace.h"
#include "swift/SIL/SILArgument.h"
@@ -1585,9 +1584,10 @@
getNonMemberVarDeclSubstitutions(SILGenModule &SGM, VarDecl *var) {
ArrayRef<Substitution> substitutions;
auto *dc = var->getDeclContext();
- if (auto genericParams = dc->getGenericParamsOfContext()) {
+ if (auto *genericEnv = dc->getGenericEnvironmentOfContext()) {
auto *genericSig = dc->getGenericSignatureOfContext();
- substitutions = genericParams->getForwardingSubstitutions(genericSig);
+ substitutions = genericEnv->getForwardingSubstitutions(
+ SGM.SwiftModule, genericSig);
}
return substitutions;
}
diff --git a/lib/SILGen/SILGenMaterializeForSet.cpp b/lib/SILGen/SILGenMaterializeForSet.cpp
index cf0063f..c1acbd1 100644
--- a/lib/SILGen/SILGenMaterializeForSet.cpp
+++ b/lib/SILGen/SILGenMaterializeForSet.cpp
@@ -98,7 +98,7 @@
ArrayRef<Substitution> WitnessSubs;
CanGenericSignature GenericSig;
- GenericParamList *GenericParams;
+ GenericEnvironment *GenericEnv;
// Assume that we don't need to reabstract 'self'. Right now,
// that's always true; if we ever reabstract Optional (or other
@@ -128,7 +128,7 @@
WitnessStorage(witness->getAccessorStorageDecl()),
WitnessStoragePattern(AbstractionPattern::getInvalid()),
WitnessSubs(subs),
- GenericParams(nullptr),
+ GenericEnv(nullptr),
SelfInterfaceType(selfInterfaceType->getCanonicalType()),
SubstSelfType(selfType->getCanonicalType()),
TheAccessSemantics(AccessSemantics::Ordinary),
@@ -178,11 +178,11 @@
if (conformance) {
if (auto signature = conformance->getGenericSignature())
emitter.GenericSig = signature->getCanonicalSignature();
- emitter.GenericParams = conformance->getGenericParams();
+ emitter.GenericEnv = conformance->getGenericEnvironment();
} else {
auto signature = requirement->getGenericSignatureOfContext();
emitter.GenericSig = signature->getCanonicalSignature();
- emitter.GenericParams = requirement->getGenericParamsOfContext();
+ emitter.GenericEnv = requirement->getGenericEnvironmentOfContext();
}
emitter.RequirementStorage = requirement->getAccessorStorageDecl();
@@ -218,7 +218,7 @@
if (auto signature = witness->getGenericSignatureOfContext())
emitter.GenericSig = signature->getCanonicalSignature();
- emitter.GenericParams = constantInfo.ContextGenericParams;
+ emitter.GenericEnv = constantInfo.GenericEnv;
emitter.RequirementStorage = emitter.WitnessStorage;
emitter.RequirementStoragePattern = emitter.WitnessStoragePattern;
@@ -552,7 +552,7 @@
F.isTransparent(),
F.isFragile());
- callback->setContextGenericParams(GenericParams);
+ callback->setGenericEnvironment(GenericEnv);
callback->setDebugScope(new (SGM.M) SILDebugScope(Witness, callback));
PrettyStackTraceSILFunction X("silgen materializeForSet callback", callback);
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 21b8c4d..8f47b27 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -2450,7 +2450,7 @@
auto thunkType = gen.buildThunkType(fn, expectedType,
substFnType, substitutions);
auto thunk = gen.SGM.getOrCreateReabstractionThunk(
- gen.F.getContextGenericParams(),
+ gen.F.getGenericEnvironment(),
thunkType,
fn.getType().castTo<SILFunctionType>(),
expectedType,
@@ -2459,7 +2459,7 @@
// Build it if necessary.
if (thunk->empty()) {
// Borrow the context archetypes from the enclosing function.
- thunk->setContextGenericParams(gen.F.getContextGenericParams());
+ thunk->setGenericEnvironment(gen.F.getGenericEnvironment());
SILGenFunction thunkSGF(gen.SGM, *thunk);
auto loc = RegularLocation::getAutoGeneratedLocation();
buildThunkBody(thunkSGF, loc,
@@ -2679,8 +2679,8 @@
auto fTy = implFn->getLoweredFunctionType();
ArrayRef<Substitution> subs;
- if (auto context = fd->getGenericParamsOfContext()) {
- F.setContextGenericParams(context);
+ if (auto *genericEnv = fd->getGenericEnvironment()) {
+ F.setGenericEnvironment(genericEnv);
subs = getForwardingSubstitutions();
fTy = fTy->substGenericArgs(SGM.M, SGM.SwiftModule, subs);
@@ -2824,7 +2824,7 @@
static void addConformanceToSubstitutionMap(SILGenModule &SGM,
TypeSubstitutionMap &subs,
- GenericParamList *context,
+ GenericEnvironment *genericEnv,
CanType base,
const ProtocolConformance *conformance) {
conformance->forEachTypeWitness(nullptr, [&](AssociatedTypeDecl *assocTy,
@@ -2834,14 +2834,14 @@
CanDependentMemberType::get(base, assocTy, SGM.getASTContext());
auto replacement = sub.getReplacement()->getCanonicalType();
replacement = ArchetypeBuilder::mapTypeOutOfContext(SGM.M.getSwiftModule(),
- context,
+ genericEnv,
replacement)
->getCanonicalType();
subs.insert({depTy.getPointer(), replacement});
for (auto conformance : sub.getConformances()) {
if (conformance.isAbstract())
continue;
- addConformanceToSubstitutionMap(SGM, subs, context,
+ addConformanceToSubstitutionMap(SGM, subs, genericEnv,
depTy, conformance.getConcrete());
}
return false;
@@ -2860,7 +2860,8 @@
TypeSubstitutionMap subs;
subs.insert({selfParamTy.getPointer(), conformance->getInterfaceType()
->getCanonicalType()});
- addConformanceToSubstitutionMap(*this, subs, conformance->getGenericParams(),
+ addConformanceToSubstitutionMap(*this, subs,
+ conformance->getGenericEnvironment(),
selfParamTy, conformance);
// Drop requirements rooted in the applied generic parameters.
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index e2532ae..443f14a 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -93,7 +93,7 @@
auto thunk =
M.createFunction(SILLinkage::Private,
name, overrideInfo.SILFnType,
- derivedDecl->getGenericParams(), loc, IsBare,
+ derivedDecl->getGenericEnvironment(), loc, IsBare,
IsNotTransparent, IsNotFragile);
thunk->setDebugScope(new (M) SILDebugScope(loc, thunk));
diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp
index e1c0e3f..748f8b8 100644
--- a/lib/SILOptimizer/IPO/CapturePromotion.cpp
+++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp
@@ -46,6 +46,7 @@
#include "swift/SIL/SILCloner.h"
#include "swift/SIL/TypeSubstCloner.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
+#include "swift/AST/GenericEnvironment.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
@@ -444,7 +445,7 @@
assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned");
auto *Fn = M.createFunction(
- Orig->getLinkage(), ClonedName, SubstTy, Orig->getContextGenericParams(),
+ Orig->getLinkage(), ClonedName, SubstTy, Orig->getGenericEnvironment(),
Orig->getLocation(), Orig->isBare(), IsNotTransparent, Fragile,
Orig->isThunk(), Orig->getClassVisibility(), Orig->getInlineStrategy(),
Orig->getEffectsKind(), Orig, Orig->getDebugScope());
@@ -866,7 +867,7 @@
ArrayRef<Substitution> ApplySubs = PAI->getSubstitutions();
auto genericSig = F->getLoweredFunctionType()->getGenericSignature();
- auto *genericParams = F->getContextGenericParams();
+ auto *genericParams = F->getGenericEnvironment();
if (!ApplySubs.empty()) {
InterfaceSubs = genericSig->getSubstitutionMap(ApplySubs);
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index 85297ce..bac3080 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -548,7 +548,7 @@
// original function was de-serialized) and would not be code-gen'd.
getSpecializedLinkage(ClosureUser, ClosureUser->getLinkage()),
ClonedName, ClonedTy,
- ClosureUser->getContextGenericParams(), ClosureUser->getLocation(),
+ ClosureUser->getGenericEnvironment(), ClosureUser->getLocation(),
IsBare, ClosureUser->isTransparent(), CallSiteDesc.isFragile(),
ClosureUser->isThunk(), ClosureUser->getClassVisibility(),
ClosureUser->getInlineStrategy(), ClosureUser->getEffectsKind(),
diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
index 8ac5794..8dd4032 100644
--- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
+++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
@@ -14,6 +14,7 @@
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/DiagnosticsSIL.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/SILOptimizer/Utils/Devirtualize.h"
#include "swift/SILOptimizer/Utils/Local.h"
#include "swift/SILOptimizer/Utils/SILInliner.h"
@@ -435,7 +436,7 @@
ApplySubs.insert(ApplySubs.end(), PAISubs.begin(), PAISubs.end());
}
- if (auto *params = CalleeFunction->getContextGenericParams()) {
+ if (auto *params = CalleeFunction->getGenericEnvironment()) {
auto sig = CalleeFunction->getLoweredFunctionType()
->getGenericSignature();
params->getSubstitutionMap(F->getModule().getSwiftModule(),
diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
index 3b43005..20daafe 100644
--- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
+++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
@@ -566,7 +566,7 @@
&& "SILFunction missing DebugScope");
assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned");
auto *Fn = M.createFunction(
- SILLinkage::Shared, ClonedName, ClonedTy, Orig->getContextGenericParams(),
+ SILLinkage::Shared, ClonedName, ClonedTy, Orig->getGenericEnvironment(),
Orig->getLocation(), Orig->isBare(), IsNotTransparent, Fragile,
Orig->isThunk(), Orig->getClassVisibility(), Orig->getInlineStrategy(),
Orig->getEffectsKind(), Orig, Orig->getDebugScope());
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index 737dbf2..9c54a3e 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -16,6 +16,7 @@
#include "swift/SILOptimizer/Utils/Generics.h"
#include "swift/SILOptimizer/Utils/GenericCloner.h"
#include "swift/SIL/DebugUtils.h"
+#include "swift/AST/GenericEnvironment.h"
using namespace swift;
@@ -187,13 +188,13 @@
assert(GenericFunc->isDefinition() && "Expected definition to specialize!");
- if (auto *params = GenericFunc->getContextGenericParams()) {
+ if (auto *env = GenericFunc->getGenericEnvironment()) {
auto sig = GenericFunc->getLoweredFunctionType()->getGenericSignature();
ArchetypeConformanceMap conformanceMap;
- params->getSubstitutionMap(M.getSwiftModule(), sig,
- ParamSubs, ContextSubs,
- conformanceMap);
+ env->getSubstitutionMap(M.getSwiftModule(), sig,
+ ParamSubs, ContextSubs,
+ conformanceMap);
}
Mangle::Mangler Mangler;
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 08b0253..f21defe 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -21,6 +21,7 @@
#include "swift/AST/ASTWalker.h"
#include "swift/AST/Availability.h"
#include "swift/AST/Expr.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/ParameterList.h"
#include "swift/Basic/Defer.h"
#include "llvm/ADT/SmallString.h"
@@ -1134,6 +1135,17 @@
return Get;
}
+static ArrayRef<Substitution>
+getForwardingSubstitutions(DeclContext *DC) {
+ if (auto *env = DC->getGenericEnvironmentOfContext()) {
+ auto *sig = DC->getGenericSignatureOfContext();
+ return env->getForwardingSubstitutions(
+ DC->getParentModule(), sig);
+ }
+
+ return { };
+}
+
void TypeChecker::completePropertyBehaviorStorage(VarDecl *VD,
VarDecl *BehaviorStorage,
FuncDecl *DefaultInitStorage,
@@ -1270,12 +1282,7 @@
addTrivialAccessorsToStorage(Storage, *this);
// Add the witnesses to the conformance.
- ArrayRef<Substitution> MemberSubs;
- if (auto *sig = DC->getGenericSignatureOfContext()) {
- MemberSubs = DC->getGenericParamsOfContext()
- ->getForwardingSubstitutions(sig);
- }
-
+ auto MemberSubs = getForwardingSubstitutions(DC);
BehaviorConformance->setWitness(BehaviorStorage,
ConcreteDeclRef(Context, Storage, MemberSubs));
BehaviorConformance->setWitness(BehaviorStorage->getGetter(),
@@ -1303,6 +1310,7 @@
->getResult();
GenericSignature *genericSig = nullptr;
+ GenericEnvironment *genericEnv = nullptr;
TypeSubstitutionMap interfaceMap = sig->getSubstitutionMap(SelfInterfaceSubs);
auto SubstInterfaceTy = ParameterTy.subst(VD->getModuleContext(),
@@ -1321,6 +1329,7 @@
if (DC->isTypeContext()) {
if (DC->isGenericContext()) {
genericSig = DC->getGenericSignatureOfContext();
+ genericEnv = DC->getGenericEnvironmentOfContext();
SubstInterfaceTy = GenericFunctionType::get(genericSig,
DC->getSelfInterfaceType(),
SubstInterfaceTy,
@@ -1398,6 +1407,7 @@
Parameter->setInterfaceType(SubstInterfaceTy);
Parameter->setGenericSignature(genericSig);
+ Parameter->setGenericEnvironment(genericEnv);
// Mark the method to be final, implicit, and private. In a class, this
// prevents it from being dynamically dispatched.
@@ -1439,12 +1449,7 @@
addMemberToContextIfNeeded(Parameter, DC);
// Add the witnesses to the conformance.
- ArrayRef<Substitution> MemberSubs;
- if (auto *sig = DC->getGenericSignatureOfContext()) {
- MemberSubs = DC->getGenericParamsOfContext()
- ->getForwardingSubstitutions(sig);
- }
-
+ auto MemberSubs = getForwardingSubstitutions(DC);
BehaviorConformance->setWitness(BehaviorParameter,
ConcreteDeclRef(Context, Parameter, MemberSubs));
}
@@ -2132,6 +2137,7 @@
// Set the interface type of the initializer.
ctor->setGenericSignature(classDecl->getGenericSignatureOfContext());
+ ctor->setGenericEnvironment(classDecl->getGenericEnvironmentOfContext());
tc.configureInterfaceType(ctor);
// Set the contextual type of the initializer. This will go away one day.
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 4ee22b1..207b839 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -258,6 +258,7 @@
Type selfIfaceTy = eqDecl->computeInterfaceSelfType(false);
if (auto genericSig = parentDC->getGenericSignatureOfContext()) {
eqDecl->setGenericSignature(genericSig);
+ eqDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
Type enumIfaceTy = parentDC->getDeclaredInterfaceType();
TupleTypeElt ifaceParamElts[] = {
@@ -411,6 +412,7 @@
Type selfIfaceType = getterDecl->computeInterfaceSelfType(false);
if (auto sig = parentDC->getGenericSignatureOfContext()) {
getterDecl->setGenericSignature(sig);
+ getterDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, selfIfaceType, methodType,
AnyFunctionType::ExtInfo());
} else
diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp
index 2a87972..d1dd805 100644
--- a/lib/Sema/DerivedConformanceRawRepresentable.cpp
+++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp
@@ -320,6 +320,7 @@
Type initIfaceType;
if (auto sig = parentDC->getGenericSignatureOfContext()) {
initDecl->setGenericSignature(sig);
+ initDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
allocIfaceType = GenericFunctionType::get(sig, selfInterfaceType,
interfaceType,
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index eaccf5a..7f939bf 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -148,6 +148,8 @@
Type selfInterfaceType = getterDecl->computeInterfaceSelfType(false);
if (auto sig = parentDC->getGenericSignatureOfContext()) {
getterDecl->setGenericSignature(sig);
+ getterDecl->setGenericEnvironment(
+ parentDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, selfInterfaceType,
interfaceType,
FunctionType::ExtInfo());
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 999b1b4..6ab832a 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -377,7 +377,17 @@
continue;
// Retrieve the interface type for this inherited type.
- if (inheritedTy->hasArchetype())
+ //
+ // If we have a generic parameter, mapTypeOutOfContext() might not
+ // work yet, if we're calling this while building the generic
+ // signature. However, we're also not storing inheritedTy back
+ // anywhere, so it's OK to leave it as an archetype.
+ //
+ // FIXME: Ideally, we wouldn't have code paths that take a mix
+ // of archetypes and interface types. Other than generic parameters,
+ // the only time we get an interface type here is with invalid
+ // circular cases. That should be diagnosed elsewhere.
+ if (inheritedTy->hasArchetype() && !isa<GenericTypeParamDecl>(decl))
inheritedTy = ArchetypeBuilder::mapTypeOutOfContext(DC, inheritedTy);
// Check whether we inherited from the same type twice.
@@ -696,9 +706,10 @@
}
/// Expose TypeChecker's handling of GenericParamList to SIL parsing.
-GenericSignature *TypeChecker::handleSILGenericParams(
- GenericParamList *genericParams,
- DeclContext *DC) {
+std::pair<GenericSignature *, GenericEnvironment *>
+TypeChecker::handleSILGenericParams(GenericParamList *genericParams,
+ DeclContext *DC) {
+
SmallVector<GenericParamList *, 2> nestedList;
for (; genericParams; genericParams = genericParams->getOuterParameters()) {
nestedList.push_back(genericParams);
@@ -712,23 +723,26 @@
// Since the innermost GenericParamList is in the beginning of the vector,
// we process in reverse order to handle the outermost list first.
GenericSignature *parentSig = nullptr;
+ GenericEnvironment *parentEnv = nullptr;
+
for (unsigned i = 0, e = nestedList.size(); i < e; i++) {
auto genericParams = nestedList.rbegin()[i];
bool invalid = false;
auto *genericSig = validateGenericSignature(genericParams, DC, parentSig,
nullptr, invalid);
if (invalid)
- return nullptr;
+ return std::make_pair(nullptr, nullptr);
revertGenericParamList(genericParams);
ArchetypeBuilder builder(*DC->getParentModule(), Diags);
checkGenericParamList(&builder, genericParams, parentSig);
- finalizeGenericParamList(builder, genericParams, DC);
-
+ parentEnv = finalizeGenericParamList(builder, genericParams,
+ genericSig, DC);
parentSig = genericSig;
}
- return parentSig;
+
+ return std::make_pair(parentSig, parentEnv);
}
/// Check whether the given type representation will be
@@ -2495,7 +2509,7 @@
return;
}
- if (ED->getGenericParamsOfContext() != nullptr)
+ if (ED->getGenericEnvironmentOfContext() != nullptr)
rawTy = ArchetypeBuilder::mapTypeIntoContext(ED, rawTy);
if (rawTy->is<ErrorType>())
return;
@@ -4698,7 +4712,8 @@
gp->setOuterParameters(FD->getDeclContext()->getGenericParamsOfContext());
if (TC.validateGenericFuncSignature(FD)) {
- TC.markInvalidGenericSignature(FD);
+ auto *env = TC.markInvalidGenericSignature(FD);
+ FD->setGenericEnvironment(env);
} else {
// Create a fresh archetype builder.
ArchetypeBuilder builder =
@@ -4721,14 +4736,18 @@
TC.revertGenericFuncSignature(FD);
// Assign archetypes.
- TC.finalizeGenericParamList(builder, gp, FD);
+ auto *env = TC.finalizeGenericParamList(builder, gp, nullptr, FD);
+ FD->setGenericEnvironment(env);
}
- } else if (FD->getDeclContext()->isGenericContext()) {
+ } else if (FD->getDeclContext()->getGenericSignatureOfContext()) {
if (TC.validateGenericFuncSignature(FD)) {
- TC.markInvalidGenericSignature(FD);
+ auto *env = TC.markInvalidGenericSignature(FD);
+ FD->setGenericEnvironment(env);
} else if (!FD->hasType()) {
// Revert all of the types within the signature of the function.
TC.revertGenericFuncSignature(FD);
+ FD->setGenericEnvironment(
+ FD->getDeclContext()->getGenericEnvironmentOfContext());
} else {
// Recursively satisfied.
// FIXME: This is an awful hack.
@@ -4741,7 +4760,7 @@
if (semaFuncDecl(FD, &resolver))
return;
- if (!FD->isGenericContext())
+ if (!FD->getGenericSignatureOfContext())
TC.configureInterfaceType(FD);
if (FD->isInvalid())
@@ -6127,7 +6146,7 @@
/// Compute the interface type of the given enum element.
void computeEnumElementInterfaceType(EnumElementDecl *elt) {
auto enumDecl = cast<EnumDecl>(elt->getDeclContext());
- assert(enumDecl->isGenericContext() && "Not a generic enum");
+ assert(enumDecl->getGenericSignatureOfContext() && "Not a generic enum");
// Build the generic function type.
auto funcTy = elt->getType()->castTo<AnyFunctionType>();
@@ -6223,7 +6242,7 @@
// case the enclosing enum type was illegally declared inside of a generic
// context. (In that case, we'll post a diagnostic while visiting the
// parent enum.)
- if (EED->getDeclContext()->isGenericContext())
+ if (EED->getDeclContext()->getGenericSignatureOfContext())
computeEnumElementInterfaceType(EED);
// Require the carried type to be materializable.
@@ -6384,7 +6403,8 @@
gp->setOuterParameters(CD->getDeclContext()->getGenericParamsOfContext());
if (TC.validateGenericFuncSignature(CD)) {
- TC.markInvalidGenericSignature(CD);
+ auto *env = TC.markInvalidGenericSignature(CD);
+ CD->setGenericEnvironment(env);
} else {
ArchetypeBuilder builder =
TC.createArchetypeBuilder(CD->getModuleContext());
@@ -6399,14 +6419,19 @@
TC.revertGenericFuncSignature(CD);
// Assign archetypes.
- TC.finalizeGenericParamList(builder, gp, CD);
+ auto *env = TC.finalizeGenericParamList(builder, gp, nullptr, CD);
+ CD->setGenericEnvironment(env);
}
- } else if (CD->getDeclContext()->isGenericContext()) {
+ } else if (CD->getDeclContext()->getGenericSignatureOfContext()) {
if (TC.validateGenericFuncSignature(CD)) {
- TC.markInvalidGenericSignature(CD);
+ auto *env = TC.markInvalidGenericSignature(CD);
+ CD->setGenericEnvironment(env);
} else {
// Revert all of the types within the signature of the constructor.
TC.revertGenericFuncSignature(CD);
+
+ CD->setGenericEnvironment(
+ CD->getDeclContext()->getGenericEnvironmentOfContext());
}
}
@@ -6419,7 +6444,7 @@
configureConstructorType(CD, SelfTy,
CD->getParameterList(1)->getType(TC.Context));
- if (!CD->isGenericContext())
+ if (!CD->getGenericSignatureOfContext())
TC.configureInterfaceType(CD);
}
@@ -6554,8 +6579,11 @@
Type SelfTy = configureImplicitSelf(TC, DD);
- if (DD->getDeclContext()->isGenericContext())
+ if (DD->getDeclContext()->getGenericSignatureOfContext()) {
TC.validateGenericFuncSignature(DD);
+ DD->setGenericEnvironment(
+ DD->getDeclContext()->getGenericEnvironmentOfContext());
+ }
if (semaFuncParamPatterns(DD)) {
DD->overwriteType(ErrorType::get(TC.Context));
@@ -6563,7 +6591,7 @@
DD->setInvalid();
}
- if (!DD->isGenericContext())
+ if (!DD->getGenericSignatureOfContext())
TC.configureInterfaceType(DD);
if (!DD->hasType()) {
@@ -7328,8 +7356,7 @@
/// the parameter lists within the extension.
static Type checkExtensionGenericParams(
TypeChecker &tc, ExtensionDecl *ext,
- Type type, GenericParamList *genericParams,
- GenericSignature *&sig) {
+ Type type, GenericParamList *genericParams) {
// Find the nominal type declaration and its parent type.
Type parentType;
NominalTypeDecl *nominal;
@@ -7352,8 +7379,7 @@
tc, ext, parentType,
nominal->getGenericParams()
? genericParams->getOuterParameters()
- : genericParams,
- sig);
+ : genericParams);
if (!newParentType)
return Type();
}
@@ -7396,9 +7422,14 @@
// Validate the generic type signature.
bool invalid = false;
- sig = tc.validateGenericSignature(genericParams, ext->getDeclContext(),
- nullptr, inferExtendedTypeReqs, invalid);
+ GenericSignature *sig = tc.validateGenericSignature(
+ genericParams, ext->getDeclContext(),
+ nullptr, inferExtendedTypeReqs, invalid);
+ ext->setGenericSignature(sig);
+
if (invalid) {
+ auto *env = tc.markInvalidGenericSignature(ext);
+ ext->setGenericEnvironment(env);
return nullptr;
}
@@ -7408,7 +7439,9 @@
auto *parentSig = ext->getDeclContext()->getGenericSignatureOfContext();
tc.checkGenericParamList(&builder, genericParams, parentSig);
inferExtendedTypeReqs(builder);
- tc.finalizeGenericParamList(builder, genericParams, ext);
+
+ auto *env = tc.finalizeGenericParamList(builder, genericParams, nullptr, ext);
+ ext->setGenericEnvironment(env);
if (isa<ProtocolDecl>(nominal)) {
// Retain type sugar if it's there.
@@ -7475,24 +7508,28 @@
assert(genericParams && "bindExtensionDecl didn't set generic params?");
// Check generic parameters.
- GenericSignature *sig = nullptr;
extendedType = checkExtensionGenericParams(*this, ext,
ext->getExtendedType(),
- ext->getGenericParams(),
- sig);
+ ext->getGenericParams());
if (!extendedType) {
ext->setInvalid();
ext->getExtendedTypeLoc().setInvalidType(Context);
return;
}
- ext->setGenericSignature(sig);
ext->getExtendedTypeLoc().setType(extendedType);
return;
}
// If we're extending a protocol, check the generic parameters.
- if (auto proto = extendedType->getAs<ProtocolType>()) {
+ //
+ // Canonicalize the type to work around the fact that getAs<> cannot
+ // "look through" protocol<X, Y> where X and Y both desugar to the same
+ // thing.
+ //
+ // FIXME: Probably the above comes up elsewhere, perhaps getAs<>()
+ // should be fixed.
+ if (auto proto = extendedType->getCanonicalType()->getAs<ProtocolType>()) {
if (!isa<ProtocolType>(extendedType.getPointer()) &&
proto->getDecl()->getParentModule() == ext->getParentModule()) {
// Protocols in the same module cannot be extended via a typealias;
@@ -7505,18 +7542,14 @@
return;
}
- GenericSignature *sig = nullptr;
- extendedType = checkExtensionGenericParams(*this, ext,
- ext->getExtendedType(),
- ext->getGenericParams(),
- sig);
+ extendedType = checkExtensionGenericParams(*this, ext, proto,
+ ext->getGenericParams());
if (!extendedType) {
ext->setInvalid();
ext->getExtendedTypeLoc().setInvalidType(Context);
return;
}
- ext->setGenericSignature(sig);
ext->getExtendedTypeLoc().setType(extendedType);
// Speculatively ban extension of AnyObject; it won't be a
@@ -7529,6 +7562,8 @@
}
return;
}
+
+ assert(extendedType->is<NominalType>());
}
ArrayRef<ProtocolDecl *>
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 3ef2858..53a7964 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -471,33 +471,36 @@
return resultType;
}
-void TypeChecker::markInvalidGenericSignature(ValueDecl *VD) {
- GenericParamList *genericParams;
- if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD))
- genericParams = AFD->getGenericParams();
- else
- genericParams = cast<GenericTypeDecl>(VD)->getGenericParams();
-
+GenericEnvironment *
+TypeChecker::markInvalidGenericSignature(DeclContext *DC) {
// If there aren't any generic parameters at this level, we're done.
- if (genericParams == nullptr)
- return;
+ if (!DC->isInnermostContextGeneric())
+ return nullptr;
- DeclContext *DC = VD->getDeclContext();
- ArchetypeBuilder builder = createArchetypeBuilder(DC->getParentModule());
+ GenericParamList *genericParams = DC->getGenericParamsOfContext();
+ GenericSignature *genericSig = DC->getGenericSignatureOfContext();
- if (auto sig = DC->getGenericSignatureOfContext())
- builder.addGenericSignature(sig, true);
+ // Build new archetypes without any generic requirements.
+ DeclContext *parentDC = DC->getParent();
+ auto builder = createArchetypeBuilder(parentDC->getParentModule());
+
+ auto parentSig = parentDC->getGenericSignatureOfContext();
+
+ if (parentSig != nullptr)
+ builder.addGenericSignature(parentSig, true);
// Visit each of the generic parameters.
for (auto param : *genericParams)
builder.addGenericParameter(param);
// Wire up the archetypes.
+ auto genericEnv = builder.getGenericEnvironment(
+ genericSig->getGenericParams());
+
for (auto GP : *genericParams)
GP->setArchetype(builder.getArchetype(GP));
- genericParams->setAllArchetypes(
- Context.AllocateCopy(builder.getAllArchetypes()));
+ return genericEnv;
}
bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
@@ -540,7 +543,7 @@
auto sig = builder.getGenericSignature(allGenericParams);
// Debugging of the archetype builder and generic signature generation.
- if (sig && Context.LangOpts.DebugGenericSignatures) {
+ if (Context.LangOpts.DebugGenericSignatures) {
func->dumpRef(llvm::errs());
llvm::errs() << "\n";
builder.dump(llvm::errs());
@@ -789,9 +792,11 @@
/// Finalize the given generic parameter list, assigning archetypes to
/// the generic parameters.
-void TypeChecker::finalizeGenericParamList(ArchetypeBuilder &builder,
- GenericParamList *genericParams,
- DeclContext *dc) {
+GenericEnvironment *
+TypeChecker::finalizeGenericParamList(ArchetypeBuilder &builder,
+ GenericParamList *genericParams,
+ GenericSignature *genericSig,
+ DeclContext *dc) {
Accessibility access;
if (auto *fd = dyn_cast<FuncDecl>(dc))
access = fd->getFormalAccess();
@@ -802,14 +807,17 @@
access = std::max(access, Accessibility::Internal);
// Wire up the archetypes.
+ if (genericSig == nullptr)
+ genericSig = dc->getGenericSignatureOfContext();
+ auto genericEnv = builder.getGenericEnvironment(
+ genericSig->getGenericParams());
+
for (auto GP : *genericParams) {
GP->setArchetype(builder.getArchetype(GP));
checkInheritanceClause(GP);
if (!GP->hasAccessibility())
GP->setAccessibility(access);
}
- genericParams->setAllArchetypes(
- Context.AllocateCopy(builder.getAllArchetypes()));
#ifndef NDEBUG
// Record archetype contexts.
@@ -859,6 +867,8 @@
break;
}
}
+
+ return genericEnv;
}
/// Revert the dependent types within the given generic parameter list.
@@ -903,13 +913,14 @@
auto *gp = typeDecl->getGenericParams();
auto *dc = typeDecl->getDeclContext();
- auto sig = validateGenericSignature(gp, dc, nullptr, nullptr, invalid);
+ auto *sig = validateGenericSignature(gp, dc, nullptr, nullptr, invalid);
assert(sig->getInnermostGenericParams().size()
== typeDecl->getGenericParams()->size());
typeDecl->setGenericSignature(sig);
if (invalid) {
- markInvalidGenericSignature(typeDecl);
+ auto *env = markInvalidGenericSignature(typeDecl);
+ typeDecl->setGenericEnvironment(env);
return invalid;
}
@@ -919,7 +930,9 @@
createArchetypeBuilder(typeDecl->getModuleContext());
auto *parentSig = dc->getGenericSignatureOfContext();
checkGenericParamList(&builder, gp, parentSig);
- finalizeGenericParamList(builder, gp, typeDecl);
+
+ auto *env = finalizeGenericParamList(builder, gp, nullptr, typeDecl);
+ typeDecl->setGenericEnvironment(env);
return invalid;
}
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index c9d4098..b0104cb 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -292,19 +292,12 @@
// extension MyProtocol where Self : YourProtocol { ... }
if (parentDC->getAsProtocolExtensionContext()) {
auto ED = cast<ExtensionDecl>(parentDC);
- if (auto genericParams = ED->getGenericParams()) {
- for (auto req : genericParams->getTrailingRequirements()) {
- // We might be resolving 'req.getSubject()' itself.
- // This whole case feels like a hack -- there should be a
- // more principled way to represent extensions of protocol
- // compositions.
- if (req.getKind() == RequirementReprKind::TypeConstraint) {
- if (!req.getSubject() ||
- !req.getSubject()->is<ArchetypeType>() ||
- !req.getSubject()->castTo<ArchetypeType>()->getSelfProtocol())
- continue;
-
- stack.push_back(req.getConstraint());
+ if (auto genericSig = ED->getGenericSignature()) {
+ for (auto req : genericSig->getRequirements()) {
+ if (req.getKind() == RequirementKind::Conformance ||
+ req.getKind() == RequirementKind::Superclass) {
+ if (req.getFirstType()->isEqual(ED->getSelfInterfaceType()))
+ stack.push_back(req.getSecondType());
}
}
}
@@ -2131,11 +2124,11 @@
}
// SIL uses polymorphic function types to resolve overloaded member functions.
- if (auto genericParams = repr->getGenericParams()) {
+ if (auto genericEnv = repr->getGenericEnvironment()) {
auto *genericSig = repr->getGenericSignature();
assert(genericSig != nullptr && "Did not call handleSILGenericParams()?");
- inputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericParams, inputTy);
- outputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericParams, outputTy);
+ inputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericEnv, inputTy);
+ outputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericEnv, outputTy);
return GenericFunctionType::get(genericSig, inputTy, outputTy, extInfo);
}
@@ -2224,24 +2217,24 @@
SmallVector<SILParameterInfo, 4> interfaceParams;
SmallVector<SILResultInfo, 4> interfaceResults;
Optional<SILResultInfo> interfaceErrorResult;
- if (auto *genericParams = repr->getGenericParams()) {
+ if (auto *genericEnv = repr->getGenericEnvironment()) {
genericSig = repr->getGenericSignature()->getCanonicalSignature();
for (auto ¶m : params) {
auto transParamType = ArchetypeBuilder::mapTypeOutOfContext(
- M, genericParams, param.getType())->getCanonicalType();
+ M, genericEnv, param.getType())->getCanonicalType();
interfaceParams.push_back(param.getWithType(transParamType));
}
for (auto &result : results) {
auto transResultType =
ArchetypeBuilder::mapTypeOutOfContext(
- M, genericParams, result.getType())->getCanonicalType();
+ M, genericEnv, result.getType())->getCanonicalType();
interfaceResults.push_back(result.getWithType(transResultType));
}
if (errorResult) {
auto transErrorResultType = ArchetypeBuilder::mapTypeOutOfContext(
- M, genericParams, errorResult->getType())->getCanonicalType();
+ M, genericEnv, errorResult->getType())->getCanonicalType();
interfaceErrorResult =
errorResult->getWithType(transErrorResultType);
}
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index d3c5f2b..c938524 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -706,9 +706,10 @@
}
/// Expose TypeChecker's handling of GenericParamList to SIL parsing.
-GenericSignature *swift::handleSILGenericParams(ASTContext &Ctx,
- GenericParamList *genericParams,
- DeclContext *DC) {
+std::pair<GenericSignature *, GenericEnvironment *>
+swift::handleSILGenericParams(ASTContext &Ctx,
+ GenericParamList *genericParams,
+ DeclContext *DC) {
return TypeChecker(Ctx).handleSILGenericParams(genericParams, DC);
}
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 0694cb7..05b146a 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -731,8 +731,9 @@
void checkUnsupportedProtocolType(Stmt *stmt);
/// Expose TypeChecker's handling of GenericParamList to SIL parsing.
- GenericSignature *handleSILGenericParams(GenericParamList *genericParams,
- DeclContext *DC);
+ std::pair<GenericSignature *, GenericEnvironment *>
+ handleSILGenericParams(GenericParamList *genericParams,
+ DeclContext *DC);
/// \brief Resolves a TypeRepr to a type.
///
@@ -996,7 +997,7 @@
bool isProtocolExtensionUsable(DeclContext *dc, Type type,
ExtensionDecl *protocolExtension) override;
- void markInvalidGenericSignature(ValueDecl *VD);
+ GenericEnvironment *markInvalidGenericSignature(DeclContext *dc);
/// Configure the interface type of a function declaration.
void configureInterfaceType(AbstractFunctionDecl *func);
@@ -1044,9 +1045,10 @@
/// Finalize the given generic parameter list, assigning archetypes to
/// the generic parameters.
- void finalizeGenericParamList(ArchetypeBuilder &builder,
- GenericParamList *genericParams,
- DeclContext *dc);
+ GenericEnvironment *finalizeGenericParamList(ArchetypeBuilder &builder,
+ GenericParamList *genericParams,
+ GenericSignature *genericSig,
+ DeclContext *dc);
/// Validate the signature of a generic type.
///
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 9e83da8..ff1ec85 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -15,6 +15,7 @@
#include "swift/AST/AST.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ForeignErrorConvention.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/Parse/Parser.h"
@@ -633,8 +634,7 @@
GenericParamList *
ModuleFile::maybeGetOrReadGenericParams(serialization::DeclID genericContextID,
- DeclContext *DC,
- llvm::BitstreamCursor &Cursor) {
+ DeclContext *DC) {
if (genericContextID) {
Decl *genericContext = getDecl(genericContextID);
assert(genericContext && "loading PolymorphicFunctionType before its decl");
@@ -647,93 +647,44 @@
return ext->getGenericParams();
llvm_unreachable("only functions and nominals can provide generic params");
} else {
- return maybeReadGenericParams(DC, Cursor);
+ return maybeReadGenericParams(DC);
}
}
GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC,
- llvm::BitstreamCursor &Cursor,
GenericParamList *outerParams) {
using namespace decls_block;
assert(DC && "need a context for the decls in the list");
- BCOffsetRAII lastRecordOffset(Cursor);
+ BCOffsetRAII lastRecordOffset(DeclTypeCursor);
SmallVector<uint64_t, 8> scratch;
StringRef blobData;
- auto next = Cursor.advance(AF_DontPopBlockAtEnd);
+ auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (next.Kind != llvm::BitstreamEntry::Record)
return nullptr;
- // Read the raw archetype IDs into a different scratch buffer
- // because we need to keep this alive for longer.
- SmallVector<uint64_t, 4> rawArchetypeIDsBuffer;
- unsigned kind = Cursor.readRecord(next.ID, rawArchetypeIDsBuffer, &blobData);
+ unsigned kind = DeclTypeCursor.readRecord(next.ID, scratch, &blobData);
if (kind != GENERIC_PARAM_LIST)
return nullptr;
- // Read in the raw-archetypes buffer, but don't try to consume it yet.
- ArrayRef<uint64_t> rawArchetypeIDs;
- GenericParamListLayout::readRecord(rawArchetypeIDsBuffer, rawArchetypeIDs);
-
SmallVector<GenericTypeParamDecl *, 8> params;
SmallVector<RequirementRepr, 8> requirements;
- SmallVector<ArchetypeType *, 8> archetypes;
-
- // The GenericTypeParamDecls might be from a different module file.
- // If so, we need to map the archetype IDs from the serialized
- // all-archetypes list in this module file over to the corresponding
- // archetypes from the original generic parameter decls, or else
- // we'll end up constructing fresh archetypes that don't match the
- // ones from the generic parameters.
-
- // We have to do this mapping before we might call getType on one of
- // those archetypes, but after we've read all the generic parameters.
- // Therefore we do it lazily.
- bool haveMappedArchetypes = false;
- auto mapArchetypes = [&] {
- if (haveMappedArchetypes) return;
-
- GenericParamList::deriveAllArchetypes(params, archetypes);
- assert(rawArchetypeIDs.size() == archetypes.size());
- for (unsigned index : indices(rawArchetypeIDs)) {
- TypeID TID = rawArchetypeIDs[index];
- auto &typeOrOffset = Types[TID-1];
- if (typeOrOffset.isComplete()) {
- // FIXME: this assertion is absolutely correct, but it's
- // currently fouled up by the presence of archetypes in
- // substitutions. Those *should* be irrelevant for all the
- // cases where this is wrong, but...
-
- //assert(typeOrOffset.get().getPointer() == archetypes[index] &&
- // "already deserialized this archetype to a different type!");
-
- // TODO: remove unsafeOverwrite when this hack goes away
- typeOrOffset.unsafeOverwrite(archetypes[index]);
- } else {
- typeOrOffset = archetypes[index];
- }
- }
-
- haveMappedArchetypes = true;
- };
while (true) {
lastRecordOffset.reset();
bool shouldContinue = true;
- auto entry = Cursor.advance(AF_DontPopBlockAtEnd);
+ auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (entry.Kind != llvm::BitstreamEntry::Record)
break;
scratch.clear();
- unsigned recordID = Cursor.readRecord(entry.ID, scratch,
+ unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch,
&blobData);
switch (recordID) {
case GENERIC_PARAM: {
- assert(!haveMappedArchetypes &&
- "generic parameters interleaved with requirements?");
DeclID paramDeclID;
GenericParamLayout::readRecord(scratch, paramDeclID);
auto genericParam = cast<GenericTypeParamDecl>(getDecl(paramDeclID, DC));
@@ -760,8 +711,6 @@
GenericRequirementLayout::readRecord(scratch, rawKind,
rawTypeIDs[0], rawTypeIDs[1]);
- mapArchetypes();
-
switch (rawKind) {
case GenericRequirementKind::Conformance: {
auto subject = TypeLoc::withoutLoc(getType(rawTypeIDs[0]));
@@ -817,13 +766,9 @@
break;
}
- // Make sure we map the archetypes if we haven't yet.
- mapArchetypes();
-
auto paramList = GenericParamList::create(getContext(), SourceLoc(),
params, SourceLoc(), requirements,
SourceLoc());
- paramList->setAllArchetypes(getContext().AllocateCopy(archetypes));
paramList->setOuterParameters(outerParams ? outerParams :
DC->getGenericParamsOfContext());
@@ -847,8 +792,7 @@
break;
scratch.clear();
- unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch,
- &blobData);
+ unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch, &blobData);
switch (recordID) {
case GENERIC_REQUIREMENT: {
uint8_t rawKind;
@@ -906,6 +850,78 @@
}
}
+GenericEnvironment *ModuleFile::readGenericEnvironment(
+ SmallVectorImpl<GenericTypeParamType *> ¶mTypes,
+ llvm::BitstreamCursor &Cursor) {
+ using namespace decls_block;
+
+ BCOffsetRAII lastRecordOffset(Cursor);
+ SmallVector<uint64_t, 8> scratch;
+ StringRef blobData;
+
+ TypeSubstitutionMap interfaceToArchetypeMap;
+
+ while (true) {
+ lastRecordOffset.reset();
+ bool shouldContinue = true;
+
+ auto entry = Cursor.advance(AF_DontPopBlockAtEnd);
+ if (entry.Kind != llvm::BitstreamEntry::Record)
+ break;
+
+ scratch.clear();
+ unsigned recordID = Cursor.readRecord(entry.ID, scratch, &blobData);
+ switch (recordID) {
+ case GENERIC_ENVIRONMENT: {
+ uint64_t rawTypeIDs[2];
+ GenericEnvironmentLayout::readRecord(scratch,
+ rawTypeIDs[0], rawTypeIDs[1]);
+
+ auto paramTy = getType(rawTypeIDs[0])->castTo<GenericTypeParamType>();
+ auto contextTy = getType(rawTypeIDs[1]);
+
+ auto result = interfaceToArchetypeMap.insert(
+ std::make_pair(paramTy, contextTy));
+
+ assert(result.second);
+ paramTypes.push_back(paramTy);
+ break;
+ }
+ default:
+ // This record is not part of the GenericEnvironment.
+ shouldContinue = false;
+ break;
+ }
+
+ if (!shouldContinue)
+ break;
+ }
+
+ if (interfaceToArchetypeMap.empty())
+ return nullptr;
+
+ return GenericEnvironment::get(getContext(), interfaceToArchetypeMap);
+}
+
+std::pair<GenericSignature *, GenericEnvironment *>
+ModuleFile::maybeReadGenericSignature() {
+ SmallVector<GenericTypeParamType *, 4> paramTypes;
+
+ // Read the generic environment.
+ auto env = readGenericEnvironment(paramTypes, DeclTypeCursor);
+
+ if (env == nullptr)
+ return std::make_pair(nullptr, nullptr);
+
+ // Read the generic requirements.
+ SmallVector<Requirement, 4> requirements;
+ readGenericRequirements(requirements);
+
+ auto sig = GenericSignature::get(paramTypes, requirements);
+
+ return std::make_pair(sig, env);
+}
+
bool ModuleFile::readMembers(SmallVectorImpl<Decl *> &Members) {
using namespace decls_block;
@@ -2150,7 +2166,7 @@
if (declOrOffset.isComplete())
return declOrOffset;
- auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor);
+ auto genericParams = maybeReadGenericParams(DC);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -2160,18 +2176,14 @@
declOrOffset = alias;
if (genericParams) {
- SmallVector<GenericTypeParamType *, 4> paramTypes;
- for (auto &genericParam : *genericParams) {
- paramTypes.push_back(genericParam->getDeclaredType()
- ->castTo<GenericTypeParamType>());
- }
+ GenericSignature *sig;
+ GenericEnvironment *env;
- // Read the generic requirements.
- SmallVector<Requirement, 4> requirements;
- readGenericRequirements(requirements);
+ std::tie(sig, env) = maybeReadGenericSignature();
- auto sig = GenericSignature::get(paramTypes, requirements);
+ assert(sig && "generic typealias without signature");
alias->setGenericSignature(sig);
+ alias->setGenericEnvironment(env);
}
alias->computeType();
@@ -2294,7 +2306,7 @@
if (declOrOffset.isComplete())
return declOrOffset;
- auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor);
+ auto genericParams = maybeReadGenericParams(DC);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -2312,20 +2324,14 @@
if (isImplicit)
theStruct->setImplicit();
- if (genericParams) {
- SmallVector<GenericTypeParamType *, 4> paramTypes;
- for (auto &genericParam : *theStruct->getGenericParams()) {
- paramTypes.push_back(genericParam->getDeclaredType()
- ->castTo<GenericTypeParamType>());
- }
- // Read the generic requirements.
- SmallVector<Requirement, 4> requirements;
- readGenericRequirements(requirements);
+ GenericSignature *sig;
+ GenericEnvironment *env;
- auto sig = GenericSignature::get(paramTypes, requirements);
- theStruct->setGenericSignature(sig);
- }
+ std::tie(sig, env) = maybeReadGenericSignature();
+
+ theStruct->setGenericSignature(sig);
+ theStruct->setGenericEnvironment(env);
theStruct->computeType();
@@ -2362,10 +2368,13 @@
if (declOrOffset.isComplete())
return declOrOffset;
- auto genericParams = maybeReadGenericParams(parent, DeclTypeCursor);
+ auto *genericParams = maybeReadGenericParams(parent);
if (declOrOffset.isComplete())
return declOrOffset;
+ SmallVector<GenericTypeParamType *, 2> genericParamTypes;
+ auto *genericEnv = readGenericEnvironment(genericParamTypes, DeclTypeCursor);
+
// Resolve the name ids.
SmallVector<Identifier, 2> argNames;
for (auto argNameID : argNameIDs)
@@ -2408,6 +2417,8 @@
ctor->setInterfaceType(interfaceType);
}
+ ctor->setGenericEnvironment(genericEnv);
+
// Set the initializer interface type of the constructor.
auto allocType = ctor->getInterfaceType();
auto selfTy = ctor->computeInterfaceSelfType(/*isInitializingCtor=*/true);
@@ -2571,7 +2582,10 @@
// Read generic params before reading the type, because the type may
// reference generic parameters, and we want them to have a dummy
// DeclContext for now.
- GenericParamList *genericParams = maybeReadGenericParams(DC, DeclTypeCursor);
+ GenericParamList *genericParams = maybeReadGenericParams(DC);
+
+ SmallVector<GenericTypeParamType *, 2> genericParamTypes;
+ auto *genericEnv = readGenericEnvironment(genericParamTypes, DeclTypeCursor);
auto staticSpelling = getActualStaticSpellingKind(rawStaticSpelling);
if (!staticSpelling.hasValue()) {
@@ -2640,6 +2654,8 @@
fn->setInterfaceType(interfaceType);
}
+ fn->setGenericEnvironment(genericEnv);
+
SmallVector<ParameterList*, 2> paramLists;
for (unsigned i = 0, e = numParamPatterns; i != e; ++i)
paramLists.push_back(readParameterList());
@@ -2752,21 +2768,16 @@
handleInherited(proto, rawProtocolAndInheritedIDs.slice(numProtocols));
- if (auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor)) {
+ if (auto genericParams = maybeReadGenericParams(DC))
proto->setGenericParams(genericParams);
- SmallVector<GenericTypeParamType *, 4> paramTypes;
- for (auto &genericParam : *proto->getGenericParams()) {
- paramTypes.push_back(genericParam->getDeclaredType()
- ->castTo<GenericTypeParamType>());
- }
- // Read the generic requirements.
- SmallVector<Requirement, 4> requirements;
- readGenericRequirements(requirements);
+ GenericSignature *sig;
+ GenericEnvironment *env;
- auto sig = GenericSignature::get(paramTypes, requirements);
- proto->setGenericSignature(sig);
- }
+ std::tie(sig, env) = maybeReadGenericSignature();
+
+ proto->setGenericSignature(sig);
+ proto->setGenericEnvironment(env);
if (isImplicit)
proto->setImplicit();
@@ -2919,7 +2930,7 @@
if (declOrOffset.isComplete())
return declOrOffset;
- auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor);
+ auto genericParams = maybeReadGenericParams(DC);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -2940,20 +2951,15 @@
theClass->setSuperclass(getType(superclassID));
if (requiresStoredPropertyInits)
theClass->setRequiresStoredPropertyInits(true);
- if (genericParams) {
- SmallVector<GenericTypeParamType *, 4> paramTypes;
- for (auto &genericParam : *theClass->getGenericParams()) {
- paramTypes.push_back(genericParam->getDeclaredType()
- ->castTo<GenericTypeParamType>());
- }
- // Read the generic requirements.
- SmallVector<Requirement, 4> requirements;
- readGenericRequirements(requirements);
+ GenericSignature *sig;
+ GenericEnvironment *env;
- GenericSignature *sig = GenericSignature::get(paramTypes, requirements);
- theClass->setGenericSignature(sig);
- }
+ std::tie(sig, env) = maybeReadGenericSignature();
+
+ theClass->setGenericSignature(sig);
+ theClass->setGenericEnvironment(env);
+
theClass->computeType();
handleInherited(theClass, rawInheritedIDs);
@@ -2987,7 +2993,7 @@
if (declOrOffset.isComplete())
return declOrOffset;
- auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor);
+ auto genericParams = maybeReadGenericParams(DC);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -3006,20 +3012,14 @@
if (isImplicit)
theEnum->setImplicit();
theEnum->setRawType(getType(rawTypeID));
- if (genericParams) {
- SmallVector<GenericTypeParamType *, 4> paramTypes;
- for (auto &genericParam : *theEnum->getGenericParams()) {
- paramTypes.push_back(genericParam->getDeclaredType()
- ->castTo<GenericTypeParamType>());
- }
- // Read the generic requirements.
- SmallVector<Requirement, 4> requirements;
- readGenericRequirements(requirements);
+ GenericSignature *sig;
+ GenericEnvironment *env;
- GenericSignature *sig = GenericSignature::get(paramTypes, requirements);
- theEnum->setGenericSignature(sig);
- }
+ std::tie(sig, env) = maybeReadGenericSignature();
+
+ theEnum->setGenericSignature(sig);
+ theEnum->setGenericEnvironment(env);
theEnum->computeType();
@@ -3198,28 +3198,16 @@
extension->setCheckedInheritanceClause();
// Generic parameters.
- GenericParamList *genericParams = maybeReadGenericParams(DC,
- DeclTypeCursor);
+ GenericParamList *genericParams = maybeReadGenericParams(DC);
extension->setGenericParams(genericParams);
- // Conjure up a generic signature from the generic parameters and
- // requirements.
- if (genericParams) {
- SmallVector<GenericTypeParamType *, 4> paramTypes;
- for (auto &genericParam : *genericParams) {
- paramTypes.push_back(genericParam->getDeclaredType()
- ->castTo<GenericTypeParamType>());
- }
+ GenericSignature *sig;
+ GenericEnvironment *env;
- // Read the generic requirements.
- SmallVector<Requirement, 4> requirements;
- readGenericRequirements(requirements);
+ std::tie(sig, env) = maybeReadGenericSignature();
- if (!paramTypes.empty()) {
- GenericSignature *sig = GenericSignature::get(paramTypes, requirements);
- extension->setGenericSignature(sig);
- }
- }
+ extension->setGenericSignature(sig);
+ extension->setGenericEnvironment(env);
extension->setMemberLoader(this, DeclTypeCursor.GetCurrentBitNo());
skipRecord(DeclTypeCursor, decls_block::MEMBERS);
@@ -3266,6 +3254,8 @@
dtor->setGenericSignature(genericFnType->getGenericSignature());
dtor->setInterfaceType(interfaceType);
+ dtor->setGenericEnvironment(DC->getGenericEnvironmentOfContext());
+
if (isImplicit)
dtor->setImplicit();
@@ -3846,7 +3836,7 @@
rawRep,
throws);
GenericParamList *paramList =
- maybeGetOrReadGenericParams(genericContextID, FileContext, DeclTypeCursor);
+ maybeGetOrReadGenericParams(genericContextID, FileContext);
assert(paramList && "missing generic params for polymorphic function");
auto rep = getActualFunctionTypeRepresentation(rawRep);
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 64fcf9b..31a3bbf 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -490,34 +490,18 @@
fn->addSpecializeAttr(SILSpecializeAttr::create(SILMod, Substitutions));
}
- GenericParamList *contextParams = nullptr;
+ GenericEnvironment *genericEnv = nullptr;
if (!declarationOnly) {
- // We need to construct a linked list of GenericParamList. The outermost
- // list appears first in the module file. Force the declaration's context to
- // be the current module, not the original module associated with this
- // module file. A generic param decl at module scope cannot refer to another
- // module because we would have no way lookup the original module when
- // serializing a copy of the function. This comes up with generic
- // reabstraction thunks which have shared linkage.
- DeclContext *outerParamContext = SILMod.getSwiftModule();
- while (true) {
- // Params' OuterParameters will point to contextParams.
- auto *Params = MF->maybeReadGenericParams(outerParamContext,
- SILCursor, contextParams);
- if (!Params)
- break;
- // contextParams will point to the last deserialized list, which is the
- // innermost one.
- contextParams = Params;
- }
+ SmallVector<GenericTypeParamType *, 4> genericParamTypes;
+ genericEnv = MF->readGenericEnvironment(genericParamTypes, SILCursor);
}
// If the next entry is the end of the block, then this function has
// no contents.
entry = SILCursor.advance(AF_DontPopBlockAtEnd);
bool isEmptyFunction = (entry.Kind == llvm::BitstreamEntry::EndBlock);
- assert((!isEmptyFunction || !contextParams) &&
- "context params without body?!");
+ assert((!isEmptyFunction || !genericEnv) &&
+ "generic environment without body?!");
// Remember this in our cache in case it's a recursive function.
// Increase the reference count to keep it alive.
@@ -536,10 +520,10 @@
NumDeserializedFunc++;
- assert(!(fn->getContextGenericParams() && !fn->empty())
+ assert(!(fn->getGenericEnvironment() && !fn->empty())
&& "function already has context generic params?!");
- if (contextParams)
- fn->setContextGenericParams(contextParams);
+ if (genericEnv)
+ fn->setGenericEnvironment(genericEnv);
scratch.clear();
kind = SILCursor.readRecord(entry.ID, scratch);
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index f67b222..842116a 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -16,6 +16,7 @@
#include "swift/AST/ASTWalker.h"
#include "swift/AST/DiagnosticsCommon.h"
#include "swift/AST/ForeignErrorConvention.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/LinkLibrary.h"
#include "swift/AST/Mangle.h"
#include "swift/AST/RawComment.h"
@@ -527,6 +528,8 @@
decls_block::GENERIC_REQUIREMENT);
BLOCK_RECORD_WITH_NAMESPACE(sil_block,
decls_block::LAST_GENERIC_REQUIREMENT);
+ BLOCK_RECORD_WITH_NAMESPACE(sil_block,
+ decls_block::GENERIC_ENVIRONMENT);
BLOCK(SIL_INDEX_BLOCK);
BLOCK_RECORD(sil_index_block, SIL_FUNC_NAMES);
@@ -931,7 +934,7 @@
#undef CASE
}
-void Serializer::writeRequirements(ArrayRef<Requirement> requirements) {
+void Serializer::writeGenericRequirements(ArrayRef<Requirement> requirements) {
using namespace decls_block;
if (requirements.empty())
@@ -948,29 +951,23 @@
}
}
-bool Serializer::writeGenericParams(const GenericParamList *genericParams,
- const std::array<unsigned, 256> &abbrCodes) {
+bool Serializer::writeGenericParams(const GenericParamList *genericParams) {
using namespace decls_block;
// Don't write anything if there are no generic params.
if (!genericParams)
return true;
- SmallVector<TypeID, 8> archetypeIDs;
- for (auto archetype : genericParams->getAllArchetypes())
- archetypeIDs.push_back(addTypeRef(archetype));
+ unsigned abbrCode = DeclTypeAbbrCodes[GenericParamListLayout::Code];
+ GenericParamListLayout::emitRecord(Out, ScratchRecord, abbrCode);
- unsigned abbrCode = abbrCodes[GenericParamListLayout::Code];
- GenericParamListLayout::emitRecord(Out, ScratchRecord, abbrCode,
- archetypeIDs);
-
- abbrCode = abbrCodes[GenericParamLayout::Code];
+ abbrCode = DeclTypeAbbrCodes[GenericParamLayout::Code];
for (auto next : genericParams->getParams()) {
GenericParamLayout::emitRecord(Out, ScratchRecord, abbrCode,
addDeclRef(next));
}
- abbrCode = abbrCodes[GenericRequirementLayout::Code];
+ abbrCode = DeclTypeAbbrCodes[GenericRequirementLayout::Code];
SmallString<64> ReqStr;
for (auto next : genericParams->getRequirements()) {
ReqStr.clear();
@@ -996,12 +993,37 @@
}
}
- abbrCode = abbrCodes[LastGenericRequirementLayout::Code];
+ abbrCode = DeclTypeAbbrCodes[LastGenericRequirementLayout::Code];
uint8_t dummy = 0;
LastGenericRequirementLayout::emitRecord(Out, ScratchRecord, abbrCode, dummy);
return true;
}
+void Serializer::writeGenericEnvironment(GenericSignature *sig,
+ GenericEnvironment *env,
+ const std::array<unsigned, 256> &abbrCodes) {
+ using namespace decls_block;
+
+ if (env == nullptr)
+ return;
+
+ auto &map = env->getInterfaceToArchetypeMap();
+
+ auto envAbbrCode = abbrCodes[GenericEnvironmentLayout::Code];
+
+ // Iterate over the signature's generic parameters, for stable
+ // iteration order.
+ for (auto *paramTy : sig->getGenericParams()) {
+ auto found = map.find(paramTy->getCanonicalType().getPointer());
+ assert(found != map.end() && "missing generic parameter");
+ auto contextTy = found->second;
+ GenericEnvironmentLayout::emitRecord(
+ Out, ScratchRecord, envAbbrCode,
+ addTypeRef(paramTy),
+ addTypeRef(contextTy));
+ }
+}
+
void Serializer::writeNormalConformance(
const NormalProtocolConformance *conformance) {
using namespace decls_block;
@@ -1363,7 +1385,7 @@
genericParams);
if (genericSig) {
- writeRequirements(genericSig->getRequirements());
+ writeGenericRequirements(genericSig->getRequirements());
}
break;
}
@@ -2063,8 +2085,11 @@
isa<ProtocolDecl>(baseNominal);
}
- writeGenericParams(extension->getGenericParams(), DeclTypeAbbrCodes);
- writeRequirements(extension->getGenericRequirements());
+ writeGenericParams(extension->getGenericParams());
+ writeGenericEnvironment(extension->getGenericSignature(),
+ extension->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
+ writeGenericRequirements(extension->getGenericRequirements());
writeMembers(extension->getMembers(), isClassExtension);
writeConformances(conformances, DeclTypeAbbrCodes);
@@ -2184,8 +2209,11 @@
addTypeRef(typeAlias->getInterfaceType()),
typeAlias->isImplicit(),
rawAccessLevel);
- writeGenericParams(typeAlias->getGenericParams(), DeclTypeAbbrCodes);
- writeRequirements(typeAlias->getGenericRequirements());
+ writeGenericParams(typeAlias->getGenericParams());
+ writeGenericEnvironment(typeAlias->getGenericSignature(),
+ typeAlias->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
+ writeGenericRequirements(typeAlias->getGenericRequirements());
break;
}
@@ -2260,8 +2288,11 @@
inheritedTypes);
- writeGenericParams(theStruct->getGenericParams(), DeclTypeAbbrCodes);
- writeRequirements(theStruct->getGenericRequirements());
+ writeGenericParams(theStruct->getGenericParams());
+ writeGenericEnvironment(theStruct->getGenericSignature(),
+ theStruct->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
+ writeGenericRequirements(theStruct->getGenericRequirements());
writeMembers(theStruct->getMembers(), false);
writeConformances(conformances, DeclTypeAbbrCodes);
break;
@@ -2294,8 +2325,11 @@
conformances.size(),
inheritedTypes);
- writeGenericParams(theEnum->getGenericParams(), DeclTypeAbbrCodes);
- writeRequirements(theEnum->getGenericRequirements());
+ writeGenericParams(theEnum->getGenericParams());
+ writeGenericEnvironment(theEnum->getGenericSignature(),
+ theEnum->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
+ writeGenericRequirements(theEnum->getGenericRequirements());
writeMembers(theEnum->getMembers(), false);
writeConformances(conformances, DeclTypeAbbrCodes);
break;
@@ -2331,8 +2365,11 @@
conformances.size(),
inheritedTypes);
- writeGenericParams(theClass->getGenericParams(), DeclTypeAbbrCodes);
- writeRequirements(theClass->getGenericRequirements());
+ writeGenericParams(theClass->getGenericParams());
+ writeGenericEnvironment(theClass->getGenericSignature(),
+ theClass->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
+ writeGenericRequirements(theClass->getGenericRequirements());
writeMembers(theClass->getMembers(), true);
writeConformances(conformances, DeclTypeAbbrCodes);
break;
@@ -2367,8 +2404,11 @@
numProtocols,
protocolsAndInherited);
- writeGenericParams(proto->getGenericParams(), DeclTypeAbbrCodes);
- writeRequirements(proto->getGenericRequirements());
+ writeGenericParams(proto->getGenericParams());
+ writeGenericEnvironment(proto->getGenericSignature(),
+ proto->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
+ writeGenericRequirements(proto->getGenericRequirements());
writeMembers(proto->getMembers(), true);
writeDefaultWitnessTable(proto, DeclTypeAbbrCodes);
break;
@@ -2468,7 +2508,10 @@
rawAccessLevel,
nameComponents);
- writeGenericParams(fn->getGenericParams(), DeclTypeAbbrCodes);
+ writeGenericParams(fn->getGenericParams());
+ writeGenericEnvironment(fn->getGenericSignature(),
+ fn->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
// Write the body parameters.
for (auto pattern : fn->getParameterLists())
@@ -2585,7 +2628,11 @@
rawAccessLevel,
nameComponents);
- writeGenericParams(ctor->getGenericParams(), DeclTypeAbbrCodes);
+ writeGenericParams(ctor->getGenericParams());
+ writeGenericEnvironment(ctor->getGenericSignature(),
+ ctor->getGenericEnvironment(),
+ DeclTypeAbbrCodes);
+
assert(ctor->getParameterLists().size() == 2);
// Why is this writing out the param list for self?
for (auto paramList : ctor->getParameterLists())
@@ -2961,7 +3008,7 @@
getRawStableFunctionTypeRepresentation(fnTy->getRepresentation()),
fnTy->throws());
if (!genericContext)
- writeGenericParams(&fnTy->getGenericParams(), DeclTypeAbbrCodes);
+ writeGenericParams(&fnTy->getGenericParams());
break;
}
@@ -2979,7 +3026,7 @@
genericParams);
// Write requirements.
- writeRequirements(fnTy->getRequirements());
+ writeGenericRequirements(fnTy->getRequirements());
break;
}
@@ -3045,9 +3092,7 @@
fnTy->getNumAllResults(),
variableData);
if (sig)
- writeRequirements(sig->getRequirements());
- else
- writeRequirements({});
+ writeGenericRequirements(sig->getRequirements());
break;
}
@@ -3243,6 +3288,7 @@
registerDeclTypeAbbr<GenericParamLayout>();
registerDeclTypeAbbr<GenericRequirementLayout>();
registerDeclTypeAbbr<LastGenericRequirementLayout>();
+ registerDeclTypeAbbr<GenericEnvironmentLayout>();
registerDeclTypeAbbr<ForeignErrorConventionLayout>();
registerDeclTypeAbbr<DeclContextLayout>();
diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h
index 6b5e05c..7f4ae2c 100644
--- a/lib/Serialization/Serialization.h
+++ b/lib/Serialization/Serialization.h
@@ -241,8 +241,11 @@
/// Writes the given pattern, recursively.
void writePattern(const Pattern *pattern);
+ /// Writes a generic parameter list.
+ bool writeGenericParams(const GenericParamList *genericParams);
+
/// Writes a set of generic requirements.
- void writeRequirements(ArrayRef<Requirement> requirements);
+ void writeGenericRequirements(ArrayRef<Requirement> requirements);
/// Writes a list of protocol conformances.
void writeConformances(ArrayRef<ProtocolConformanceRef> conformances,
@@ -411,9 +414,10 @@
void writeConformance(ProtocolConformance *conformance,
const std::array<unsigned, 256> &abbrCodes);
- /// Writes a generic parameter list.
- bool writeGenericParams(const GenericParamList *genericParams,
- const std::array<unsigned, 256> &abbrCodes);
+ /// Writes a generic environment.
+ void writeGenericEnvironment(GenericSignature *sig,
+ GenericEnvironment *env,
+ const std::array<unsigned, 256> &abbrCodes);
};
} // end namespace serialization
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index 90ec7f4..d483902 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -374,15 +374,9 @@
// Write the body's context archetypes, unless we don't actually have a body.
if (!F.isExternalDeclaration()) {
- if (auto gp = F.getContextGenericParams()) {
- // To help deserializing the context generic params, we serialize the
- // outer-most list first. In most cases, we do not have decls associated
- // with these parameter lists, so serialize the lists directly.
- std::vector<GenericParamList *> paramLists;
- for (; gp; gp = gp->getOuterParameters())
- paramLists.push_back(gp);
- for (unsigned i = 0, e = paramLists.size(); i < e; i++)
- S.writeGenericParams(paramLists.rbegin()[i], SILAbbrCodes);
+ if (auto genericEnv = F.getGenericEnvironment()) {
+ auto genericSig = F.getLoweredFunctionType()->getGenericSignature();
+ S.writeGenericEnvironment(genericSig, genericEnv, SILAbbrCodes);
}
}
@@ -1850,10 +1844,8 @@
registerSILAbbr<decls_block::InheritedProtocolConformanceLayout>();
registerSILAbbr<decls_block::NormalProtocolConformanceIdLayout>();
registerSILAbbr<decls_block::ProtocolConformanceXrefLayout>();
- registerSILAbbr<decls_block::GenericParamListLayout>();
- registerSILAbbr<decls_block::GenericParamLayout>();
registerSILAbbr<decls_block::GenericRequirementLayout>();
- registerSILAbbr<decls_block::LastGenericRequirementLayout>();
+ registerSILAbbr<decls_block::GenericEnvironmentLayout>();
for (const SILGlobalVariable &g : SILMod->getSILGlobals())
writeSILGlobalVar(g);
diff --git a/stdlib/public/Platform/CMakeLists.txt b/stdlib/public/Platform/CMakeLists.txt
index 47d7b24..f4bfd98 100644
--- a/stdlib/public/Platform/CMakeLists.txt
+++ b/stdlib/public/Platform/CMakeLists.txt
@@ -36,70 +36,72 @@
set(glibc_modulemap_target_list)
foreach(sdk ${SWIFT_SDKS})
- if("${sdk}" STREQUAL "LINUX" OR
- "${sdk}" STREQUAL "FREEBSD" OR
- "${sdk}" STREQUAL "ANDROID" OR
- "${sdk}" STREQUAL "CYGWIN")
- foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES})
- set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}")
- set(module_dir "${SWIFTLIB_DIR}/${arch_subdir}")
-
- # Determine the location of glibc headers based on the target.
- set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "/usr/include")
- set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH ${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH})
-
- # Some SDKs place their headers in architecture-specific subfolders.
- if((${sdk} STREQUAL "LINUX" OR ${sdk} STREQUAL "FREEBSD") AND CMAKE_LIBRARY_ARCHITECTURE)
- set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}/${CMAKE_LIBRARY_ARCHITECTURE}")
- endif()
+ if(NOT "${sdk}" STREQUAL "LINUX" AND
+ NOT "${sdk}" STREQUAL "FREEBSD" AND
+ NOT "${sdk}" STREQUAL "ANDROID" AND
+ NOT "${sdk}" STREQUAL "CYGWIN")
+ continue()
+ endif()
- set(GLIBC_INCLUDE_PATH "${SWIFT_SDK_${sdk}_PATH}/${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH}")
- set(GLIBC_ARCH_INCLUDE_PATH "${SWIFT_SDK_${sdk}_PATH}/${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}")
+ foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES})
+ set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}")
+ set(module_dir "${SWIFTLIB_DIR}/${arch_subdir}")
- set(glibc_modulemap_source "glibc.modulemap.gyb")
- set(glibc_modulemap_out "${module_dir}/glibc.modulemap")
+ # Determine the location of glibc headers based on the target.
+ set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "/usr/include")
+ set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH ${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH})
- # Configure the module map based on the target. Each platform needs to
- # reference different headers, based on what's available in their glibc.
- # This is the 'glibc.modulemap' in the 'resource-dir', so
- # it's the one we'll look at during the build process.
- handle_gyb_source_single(glibc_modulemap_target
+ # Some SDKs place their headers in architecture-specific subfolders.
+ if((${sdk} STREQUAL "LINUX" OR ${sdk} STREQUAL "FREEBSD") AND CMAKE_LIBRARY_ARCHITECTURE)
+ set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}/${CMAKE_LIBRARY_ARCHITECTURE}")
+ endif()
+
+ set(GLIBC_INCLUDE_PATH "${SWIFT_SDK_${sdk}_PATH}/${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH}")
+ set(GLIBC_ARCH_INCLUDE_PATH "${SWIFT_SDK_${sdk}_PATH}/${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}")
+
+ set(glibc_modulemap_source "glibc.modulemap.gyb")
+ set(glibc_modulemap_out "${module_dir}/glibc.modulemap")
+
+ # Configure the module map based on the target. Each platform needs to
+ # reference different headers, based on what's available in their glibc.
+ # This is the 'glibc.modulemap' in the 'resource-dir', so
+ # it's the one we'll look at during the build process.
+ handle_gyb_source_single(glibc_modulemap_target
+ SOURCE "${glibc_modulemap_source}"
+ OUTPUT "${glibc_modulemap_out}"
+ FLAGS
+ "-DCMAKE_SDK=${sdk}"
+ "-DGLIBC_INCLUDE_PATH=${GLIBC_INCLUDE_PATH}"
+ "-DGLIBC_ARCH_INCLUDE_PATH=${GLIBC_ARCH_INCLUDE_PATH}")
+
+ list(APPEND glibc_modulemap_target_list ${glibc_modulemap_target})
+
+ # If this SDK is a target for a non-native host, create a native modulemap
+ # without a sysroot prefix. This is the one we'll install instead.
+ if(NOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_PATH}" STREQUAL "/")
+
+ set(glibc_sysroot_relative_modulemap_out "${module_dir}/sysroot-relative-modulemaps/glibc.modulemap")
+ handle_gyb_source_single(glibc_modulemap_native_target
SOURCE "${glibc_modulemap_source}"
- OUTPUT "${glibc_modulemap_out}"
+ OUTPUT "${glibc_sysroot_relative_modulemap_out}"
FLAGS
"-DCMAKE_SDK=${sdk}"
- "-DGLIBC_INCLUDE_PATH=${GLIBC_INCLUDE_PATH}"
- "-DGLIBC_ARCH_INCLUDE_PATH=${GLIBC_ARCH_INCLUDE_PATH}")
+ "-DGLIBC_INCLUDE_PATH=${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH}"
+ "-DGLIBC_ARCH_INCLUDE_PATH=${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}")
- list(APPEND glibc_modulemap_target_list ${glibc_modulemap_target})
+ list(APPEND glibc_modulemap_target_list ${glibc_modulemap_native_target})
+ set(glibc_modulemap_out ${glibc_sysroot_relative_modulemap_out})
+ endif()
- # If this SDK is a target for a non-native host, create a native modulemap
- # without a sysroot prefix. This is the one we'll install instead.
- if(NOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_PATH}" STREQUAL "/")
+ # FIXME: When SDK is a cross-compile target (SDK != Host), the generated
+ # modulemap will be relative to the Host, with hardcoded paths.
+ # It is not relocatable to the target platform itself.
+ # This only affects ANDROID right now, but could affect cross-compiled LINUX targets
- set(glibc_sysroot_relative_modulemap_out "${module_dir}/sysroot-relative-modulemaps/glibc.modulemap")
- handle_gyb_source_single(glibc_modulemap_native_target
- SOURCE "${glibc_modulemap_source}"
- OUTPUT "${glibc_sysroot_relative_modulemap_out}"
- FLAGS
- "-DCMAKE_SDK=${sdk}"
- "-DGLIBC_INCLUDE_PATH=${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH}"
- "-DGLIBC_ARCH_INCLUDE_PATH=${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}")
+ swift_install_in_component(sdk-overlay
+ FILES "${glibc_modulemap_out}"
+ DESTINATION "lib/swift/${arch_subdir}")
- list(APPEND glibc_modulemap_target_list ${glibc_modulemap_native_target})
- set(glibc_modulemap_out ${glibc_sysroot_relative_modulemap_out})
- endif()
-
- # FIXME: When SDK is a cross-compile target (SDK != Host), the generated
- # modulemap will be relative to the Host, with hardcoded paths.
- # It is not relocatable to the target platform itself.
- # This only affects ANDROID right now, but could affect cross-compiled LINUX targets
-
- swift_install_in_component(sdk-overlay
- FILES "${glibc_modulemap_out}"
- DESTINATION "lib/swift/${arch_subdir}")
-
- endforeach()
- endif()
+ endforeach()
endforeach()
add_custom_target(glibc_modulemap DEPENDS ${glibc_modulemap_target_list})
diff --git a/test/SILGen/witnesses.swift b/test/SILGen/witnesses.swift
index cff0d5e..34f18fc 100644
--- a/test/SILGen/witnesses.swift
+++ b/test/SILGen/witnesses.swift
@@ -426,14 +426,14 @@
struct GenericParameterNameCollision<T: HasAssoc> :
GenericParameterNameCollisionProtocol {
- // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTW{{.*}}GenericParameterNameCollision{{.*}}GenericParameterNameCollisionProtocol{{.*}}foo{{.*}} : $@convention(witness_method) <T1 where T1 : HasAssoc><T> (@in T, @in_guaranteed GenericParameterNameCollision<T1>) -> () {
- // CHECK: bb0(%0 : $*T, %1 : $*GenericParameterNameCollision<T1>):
- // CHECK: apply {{%.*}}<T1, T1.Assoc, T>
+ // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTW{{.*}}GenericParameterNameCollision{{.*}}GenericParameterNameCollisionProtocol{{.*}}foo{{.*}} : $@convention(witness_method) <T where T : HasAssoc><T1> (@in T1, @in_guaranteed GenericParameterNameCollision<T>) -> () {
+ // CHECK: bb0(%0 : $*T1, %1 : $*GenericParameterNameCollision<T>):
+ // CHECK: apply {{%.*}}<T, T.Assoc, T1>
func foo<U>(_ x: U) {}
- // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTW{{.*}}GenericParameterNameCollision{{.*}}GenericParameterNameCollisionProtocol{{.*}}bar{{.*}} : $@convention(witness_method) <T1 where T1 : HasAssoc><T> (@owned @callee_owned (@in T) -> @out T1.Assoc, @in_guaranteed GenericParameterNameCollision<T1>) -> () {
- // CHECK: bb0(%0 : $@callee_owned (@in T) -> @out T1.Assoc, %1 : $*GenericParameterNameCollision<T1>):
- // CHECK: apply {{%.*}}<T1, T1.Assoc, T>
+ // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTW{{.*}}GenericParameterNameCollision{{.*}}GenericParameterNameCollisionProtocol{{.*}}bar{{.*}} : $@convention(witness_method) <T where T : HasAssoc><T1> (@owned @callee_owned (@in T1) -> @out T.Assoc, @in_guaranteed GenericParameterNameCollision<T>) -> () {
+ // CHECK: bb0(%0 : $@callee_owned (@in T1) -> @out T.Assoc, %1 : $*GenericParameterNameCollision<T>):
+ // CHECK: apply {{%.*}}<T, T.Assoc, T1>
func bar<V>(_ x: (V) -> T.Assoc) {}
}
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index ad75a79..902b9fe 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_swift_executable(swift
+add_swift_host_tool(swift
api_notes.cpp
driver.cpp
autolink_extract_main.cpp
@@ -9,6 +9,7 @@
swiftFrontendTool
LLVM_COMPONENT_DEPENDS
DebugInfoCodeView
+ SWIFT_COMPONENT compiler
)
target_link_libraries(swift edit)
@@ -46,9 +47,6 @@
endif()
swift_install_in_component(compiler
- TARGETS swift
- RUNTIME DESTINATION "bin")
-swift_install_in_component(compiler
FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swiftc"
DESTINATION "bin")
swift_install_in_component(autolink-driver
diff --git a/tools/lldb-moduleimport-test/CMakeLists.txt b/tools/lldb-moduleimport-test/CMakeLists.txt
index 6c9cfdb..f1c8082 100644
--- a/tools/lldb-moduleimport-test/CMakeLists.txt
+++ b/tools/lldb-moduleimport-test/CMakeLists.txt
@@ -1,12 +1,9 @@
-add_swift_executable(lldb-moduleimport-test
+add_swift_host_tool(lldb-moduleimport-test
lldb-moduleimport-test.cpp
LINK_LIBRARIES
swiftASTSectionImporter swiftFrontend swiftClangImporter
LLVM_COMPONENT_DEPENDS
DebugInfoCodeView
+ SWIFT_COMPONENT testsuite-tools
)
-swift_install_in_component(testsuite-tools
- TARGETS lldb-moduleimport-test
- RUNTIME DESTINATION "bin")
-
diff --git a/tools/sil-extract/CMakeLists.txt b/tools/sil-extract/CMakeLists.txt
index 64be37c..982cdb1 100644
--- a/tools/sil-extract/CMakeLists.txt
+++ b/tools/sil-extract/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_swift_executable(sil-extract
+add_swift_host_tool(sil-extract
SILExtract.cpp
LINK_LIBRARIES
swiftFrontend
@@ -8,9 +8,5 @@
swiftClangImporter
LLVM_COMPONENT_DEPENDS
DebugInfoCodeView
+ SWIFT_COMPONENT tools
)
-
-swift_install_in_component(tools
- TARGETS sil-extract
- RUNTIME DESTINATION "bin")
-
diff --git a/tools/sil-opt/CMakeLists.txt b/tools/sil-opt/CMakeLists.txt
index fb5da2a..f2ccbb8 100644
--- a/tools/sil-opt/CMakeLists.txt
+++ b/tools/sil-opt/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_swift_executable(sil-opt
+add_swift_host_tool(sil-opt
SILOpt.cpp
LINK_LIBRARIES
swiftFrontend
@@ -7,9 +7,5 @@
swiftSILOptimizer
LLVM_COMPONENT_DEPENDS
DebugInfoCodeView
+ SWIFT_COMPONENT tools
)
-
-swift_install_in_component(tools
- TARGETS sil-opt
- RUNTIME DESTINATION bin)
-
diff --git a/tools/swift-demangle/CMakeLists.txt b/tools/swift-demangle/CMakeLists.txt
index ddb70af..7cefe19 100644
--- a/tools/swift-demangle/CMakeLists.txt
+++ b/tools/swift-demangle/CMakeLists.txt
@@ -1,9 +1,6 @@
-add_swift_executable(swift-demangle
+add_swift_host_tool(swift-demangle
swift-demangle.cpp
LINK_LIBRARIES swiftBasic
- LLVM_COMPONENT_DEPENDS support)
-
-swift_install_in_component(compiler
- TARGETS swift-demangle
- RUNTIME DESTINATION "bin")
-
+ LLVM_COMPONENT_DEPENDS support
+ SWIFT_COMPONENT compiler
+ )
diff --git a/tools/swift-ide-test/CMakeLists.txt b/tools/swift-ide-test/CMakeLists.txt
index 9d44b4d..eedd3ce 100644
--- a/tools/swift-ide-test/CMakeLists.txt
+++ b/tools/swift-ide-test/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_swift_executable(swift-ide-test
+add_swift_host_tool(swift-ide-test
swift-ide-test.cpp
ModuleAPIDiff.cpp
XMLValidator.cpp
@@ -8,6 +8,7 @@
swiftIDE
LLVM_COMPONENT_DEPENDS
DebugInfoCodeView
+ SWIFT_COMPONENT tools
)
# If libxml2 is available, make it available for swift-ide-test.
@@ -17,11 +18,6 @@
add_definitions(-DSWIFT_HAVE_LIBXML="1")
endif()
-swift_install_in_component(tools
- TARGETS swift-ide-test
- RUNTIME DESTINATION bin)
-
-
# Create a symlink for swift-api-dump.py in the bin directory
add_custom_command(TARGET swift-ide-test POST_BUILD
COMMAND
diff --git a/tools/swift-llvm-opt/CMakeLists.txt b/tools/swift-llvm-opt/CMakeLists.txt
index 1b76f40..628d7bd 100644
--- a/tools/swift-llvm-opt/CMakeLists.txt
+++ b/tools/swift-llvm-opt/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_swift_executable(swift-llvm-opt
+add_swift_host_tool(swift-llvm-opt
LLVMOpt.cpp
LINK_LIBRARIES
swiftIRGen
@@ -13,9 +13,6 @@
LLVM_COMPONENT_DEPENDS
DebugInfoCodeView
+
+ SWIFT_COMPONENT tools
)
-
-swift_install_in_component(tools
- TARGETS swift-llvm-opt
- RUNTIME DESTINATION bin)
-
diff --git a/tools/swift-reflection-dump/CMakeLists.txt b/tools/swift-reflection-dump/CMakeLists.txt
index c24edf3..2cdcda1 100644
--- a/tools/swift-reflection-dump/CMakeLists.txt
+++ b/tools/swift-reflection-dump/CMakeLists.txt
@@ -1,11 +1,7 @@
-add_swift_executable(swift-reflection-dump
+add_swift_host_tool(swift-reflection-dump
swift-reflection-dump.cpp
LINK_FAT_LIBRARIES
swiftReflection
LLVM_COMPONENT_DEPENDS object support
+ SWIFT_COMPONENT tools
)
-
-swift_install_in_component(tools
- TARGETS swift-reflection-dump
- RUNTIME DESTINATION bin)
-
diff --git a/tools/swift-remoteast-test/CMakeLists.txt b/tools/swift-remoteast-test/CMakeLists.txt
index 9fe95fc..4ab8f9c 100644
--- a/tools/swift-remoteast-test/CMakeLists.txt
+++ b/tools/swift-remoteast-test/CMakeLists.txt
@@ -1,8 +1,10 @@
-add_swift_executable(swift-remoteast-test
+add_swift_host_tool(swift-remoteast-test
swift-remoteast-test.cpp
LINK_LIBRARIES
swiftFrontendTool
- swiftRemoteAST)
+ swiftRemoteAST
+ SWIFT_COMPONENT tools
+)
target_link_libraries(swift-remoteast-test edit)
diff --git a/utils/resolve-crashes.py b/utils/resolve-crashes.py
index 1091ee8..5935e3d 100755
--- a/utils/resolve-crashes.py
+++ b/utils/resolve-crashes.py
@@ -16,7 +16,7 @@
# The regular expression we use to match compiler-crasher lines.
regex = re.compile(
'.*Swift(.*) :: '
- '(compiler_crashers|compiler_crashers_2|IDE/crashers)/(.*\.swift).*')
+ '(compiler_crashers|compiler_crashers_2|IDE/crashers|SIL/crashers)/(.*\.swift|.*\.sil).*')
# Take the output of lit as standard input.
for line in sys.stdin:
diff --git a/validation-test/SIL/crashers/008-swift-genericparamlist-getasgenericsignatureelements.sil b/validation-test/SIL/crashers/008-swift-genericparamlist-getasgenericsignatureelements.sil
deleted file mode 100644
index 1f6eaa6..0000000
--- a/validation-test/SIL/crashers/008-swift-genericparamlist-getasgenericsignatureelements.sil
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: not --crash %target-sil-opt %s
-// REQUIRES: asserts
-sil@__:$<__ where τ:k>()->(
diff --git a/validation-test/SIL/crashers/021-swift-typechecker-typecheckdecl.sil b/validation-test/SIL/crashers/021-swift-typechecker-typecheckdecl.sil
deleted file mode 100644
index bed95c5..0000000
--- a/validation-test/SIL/crashers/021-swift-typechecker-typecheckdecl.sil
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: not --crash %target-sil-opt %s
-// REQUIRES: asserts
-protocol P{var e:<T>()->(
diff --git a/validation-test/SIL/crashers/025-swift-typechecker-resolvetype.sil b/validation-test/SIL/crashers/025-swift-typechecker-resolvetype.sil
deleted file mode 100644
index ab7468a..0000000
--- a/validation-test/SIL/crashers/025-swift-typechecker-resolvetype.sil
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: not --crash %target-sil-opt %s
-// REQUIRES: asserts
-protocol l{func t-> <T>()->(
\ No newline at end of file
diff --git a/validation-test/SIL/crashers/028-swift-genericsignature-getcanonicalsignature.sil b/validation-test/SIL/crashers/028-swift-genericsignature-getcanonicalsignature.sil
deleted file mode 100644
index 5592b42..0000000
--- a/validation-test/SIL/crashers/028-swift-genericsignature-getcanonicalsignature.sil
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: not --crash %target-sil-opt %s
-// REQUIRES: asserts
-sil_global@d:$(<τ>()->(
\ No newline at end of file
diff --git a/validation-test/SIL/crashers_fixed/008-swift-genericparamlist-getasgenericsignatureelements.sil b/validation-test/SIL/crashers_fixed/008-swift-genericparamlist-getasgenericsignatureelements.sil
new file mode 100644
index 0000000..80c766e
--- /dev/null
+++ b/validation-test/SIL/crashers_fixed/008-swift-genericparamlist-getasgenericsignatureelements.sil
@@ -0,0 +1,3 @@
+// RUN: not %target-sil-opt %s
+// REQUIRES: asserts
+sil@__:$<__ where τ:k>()->(
diff --git a/validation-test/SIL/crashers_fixed/021-swift-typechecker-typecheckdecl.sil b/validation-test/SIL/crashers_fixed/021-swift-typechecker-typecheckdecl.sil
new file mode 100644
index 0000000..a04f138
--- /dev/null
+++ b/validation-test/SIL/crashers_fixed/021-swift-typechecker-typecheckdecl.sil
@@ -0,0 +1,3 @@
+// RUN: not %target-sil-opt %s
+// REQUIRES: asserts
+protocol P{var e:<T>()->(
diff --git a/validation-test/SIL/crashers_fixed/025-swift-typechecker-resolvetype.sil b/validation-test/SIL/crashers_fixed/025-swift-typechecker-resolvetype.sil
new file mode 100644
index 0000000..16aa0fb
--- /dev/null
+++ b/validation-test/SIL/crashers_fixed/025-swift-typechecker-resolvetype.sil
@@ -0,0 +1,3 @@
+// RUN: not %target-sil-opt %s
+// REQUIRES: asserts
+protocol l{func t-> <T>()->(
diff --git a/validation-test/SIL/crashers_fixed/028-swift-genericsignature-getcanonicalsignature.sil b/validation-test/SIL/crashers_fixed/028-swift-genericsignature-getcanonicalsignature.sil
new file mode 100644
index 0000000..e9af348
--- /dev/null
+++ b/validation-test/SIL/crashers_fixed/028-swift-genericsignature-getcanonicalsignature.sil
@@ -0,0 +1,3 @@
+// RUN: not %target-sil-opt %s
+// REQUIRES: asserts
+sil_global@d:$(<τ>()->(
diff --git a/validation-test/compiler_crashers/28369-swift-decl-walk.swift b/validation-test/compiler_crashers/28369-swift-decl-walk.swift
index 59d40a4..10fbf9f 100644
--- a/validation-test/compiler_crashers/28369-swift-decl-walk.swift
+++ b/validation-test/compiler_crashers/28369-swift-decl-walk.swift
@@ -8,6 +8,7 @@
// Credits: https://twitter.com/kiliankoe/status/752090953977036800
// RUN: not --crash %target-swift-frontend %s -parse
+// XFAIL: *
protocol P {
}
struct A<T> {