|
25 | 25 | #include "swift/AST/ModuleLoader.h"
|
26 | 26 | #include "swift/AST/TypeCheckRequests.h"
|
27 | 27 | #include "swift/AST/CanTypeVisitor.h"
|
| 28 | +#include "swift/Basic/Defer.h" |
28 | 29 | #include "swift/SIL/TypeLowering.h"
|
29 | 30 | #include "swift/SIL/AbstractionPatternGenerators.h"
|
30 | 31 | #include "clang/AST/ASTContext.h"
|
@@ -234,6 +235,8 @@ bool AbstractionPattern::requiresClass() const {
|
234 | 235 | case Kind::Discard:
|
235 | 236 | case Kind::ClangType: {
|
236 | 237 | auto type = getType();
|
| 238 | + if (auto element = dyn_cast<PackElementType>(type)) |
| 239 | + type = element.getPackType(); |
237 | 240 | if (auto archetype = dyn_cast<ArchetypeType>(type))
|
238 | 241 | return archetype->requiresClass();
|
239 | 242 | if (type->isTypeParameter()) {
|
@@ -616,6 +619,40 @@ void AbstractionPattern::forEachExpandedTupleElement(CanType substType,
|
616 | 619 | assert(substEltIndex == substEltTypes.size());
|
617 | 620 | }
|
618 | 621 |
|
| 622 | +AbstractionPattern |
| 623 | +AbstractionPattern::getPackElementPackType() const { |
| 624 | + switch (getKind()) { |
| 625 | + case Kind::Invalid: |
| 626 | + llvm_unreachable("querying invalid abstraction pattern!"); |
| 627 | + case Kind::PartialCurriedObjCMethodType: |
| 628 | + case Kind::CurriedObjCMethodType: |
| 629 | + case Kind::PartialCurriedCFunctionAsMethodType: |
| 630 | + case Kind::CurriedCFunctionAsMethodType: |
| 631 | + case Kind::CFunctionAsMethodType: |
| 632 | + case Kind::ObjCMethodType: |
| 633 | + case Kind::CXXMethodType: |
| 634 | + case Kind::CurriedCXXMethodType: |
| 635 | + case Kind::PartialCurriedCXXMethodType: |
| 636 | + case Kind::OpaqueFunction: |
| 637 | + case Kind::OpaqueDerivativeFunction: |
| 638 | + case Kind::ClangType: |
| 639 | + case Kind::Tuple: |
| 640 | + case Kind::ObjCCompletionHandlerArgumentsType: |
| 641 | + llvm_unreachable("not a pack type"); |
| 642 | + case Kind::Opaque: |
| 643 | + return *this; |
| 644 | + case Kind::Discard: |
| 645 | + llvm_unreachable("operation not needed on discarded abstractions yet"); |
| 646 | + case Kind::Type: |
| 647 | + if (isTypeParameterOrOpaqueArchetype()) |
| 648 | + return AbstractionPattern::getOpaque(); |
| 649 | + return AbstractionPattern(getGenericSubstitutions(), |
| 650 | + getGenericSignature(), |
| 651 | + cast<PackElementType>(getType()).getPackType()); |
| 652 | + } |
| 653 | + llvm_unreachable("bad kind"); |
| 654 | +} |
| 655 | + |
619 | 656 | static CanType getCanPackElementType(CanType type, unsigned index) {
|
620 | 657 | return cast<PackType>(type).getElementType(index);
|
621 | 658 | }
|
@@ -1905,31 +1942,34 @@ class SubstFunctionTypePatternVisitor
|
1905 | 1942 | SmallVector<Requirement, 2> substRequirements;
|
1906 | 1943 | SmallVector<Type, 2> substReplacementTypes;
|
1907 | 1944 | CanType substYieldType;
|
1908 |
| - bool WithinExpansion = false; |
| 1945 | + unsigned packExpansionLevel; |
1909 | 1946 |
|
1910 | 1947 | SubstFunctionTypePatternVisitor(TypeConverter &TC)
|
1911 |
| - : TC(TC) {} |
| 1948 | + : TC(TC), packExpansionLevel(0) {} |
1912 | 1949 |
|
1913 | 1950 | // Creates and returns a fresh type parameter in the substituted generic
|
1914 | 1951 | // signature if `pattern` is a type parameter or opaque archetype. Returns
|
1915 | 1952 | // null otherwise.
|
1916 |
| - CanType handleTypeParameter(AbstractionPattern pattern, CanType substTy) { |
| 1953 | + CanType handleTypeParameter(AbstractionPattern pattern, CanType substTy, |
| 1954 | + unsigned level) { |
1917 | 1955 | if (!pattern.isTypeParameterOrOpaqueArchetype())
|
1918 | 1956 | return CanType();
|
1919 | 1957 |
|
1920 | 1958 | unsigned paramIndex = substGenericParams.size();
|
1921 | 1959 |
|
| 1960 | + bool withinExpansion = (level < packExpansionLevel); |
| 1961 | + |
1922 | 1962 | // Pack parameters that aren't within expansions should just be
|
1923 | 1963 | // abstracted as scalars.
|
1924 |
| - bool isParameterPack = (WithinExpansion && pattern.isTypeParameterPack()); |
| 1964 | + bool isParameterPack = (withinExpansion && pattern.isTypeParameterPack()); |
1925 | 1965 |
|
1926 | 1966 | auto gp = GenericTypeParamType::get(isParameterPack, 0, paramIndex,
|
1927 | 1967 | TC.Context);
|
1928 | 1968 | substGenericParams.push_back(gp);
|
1929 | 1969 |
|
1930 | 1970 | CanType replacement;
|
1931 | 1971 |
|
1932 |
| - if (WithinExpansion) { |
| 1972 | + if (withinExpansion) { |
1933 | 1973 | // If we're within an expansion, and there are substitutions in the
|
1934 | 1974 | // abstraction pattern, use those instead of substTy. substTy is not
|
1935 | 1975 | // contextually meaningful in this case; see handlePackExpansion.
|
@@ -2005,11 +2045,21 @@ class SubstFunctionTypePatternVisitor
|
2005 | 2045 | }
|
2006 | 2046 | }
|
2007 | 2047 |
|
| 2048 | + if (level > 0) |
| 2049 | + return CanType(PackElementType::get(gp, level)); |
| 2050 | + |
2008 | 2051 | return CanType(gp);
|
2009 | 2052 | }
|
2010 | 2053 |
|
2011 | 2054 | CanType visit(CanType t, AbstractionPattern pattern) {
|
2012 |
| - if (auto gp = handleTypeParameter(pattern, t)) |
| 2055 | + unsigned level = 0; |
| 2056 | + if (auto elementType = dyn_cast<PackElementType>(t)) { |
| 2057 | + level = elementType->getLevel(); |
| 2058 | + t = elementType.getPackType(); |
| 2059 | + pattern = pattern.getPackElementPackType(); |
| 2060 | + } |
| 2061 | + |
| 2062 | + if (auto gp = handleTypeParameter(pattern, t, level)) |
2013 | 2063 | return gp;
|
2014 | 2064 |
|
2015 | 2065 | return CanTypeVisitor::visit(t, pattern);
|
@@ -2180,9 +2230,11 @@ class SubstFunctionTypePatternVisitor
|
2180 | 2230 | // the pack substitution for that parameter recorded in the pattern.
|
2181 | 2231 |
|
2182 | 2232 | // Remember that we're within an expansion.
|
2183 |
| - // FIXME: when we introduce PackElementType we'll need to be clear |
2184 |
| - // about which pack expansions to treat this way. |
2185 |
| - llvm::SaveAndRestore<bool> scope(WithinExpansion, true); |
| 2233 | + ++packExpansionLevel; |
| 2234 | + |
| 2235 | + SWIFT_DEFER { |
| 2236 | + --packExpansionLevel; |
| 2237 | + }; |
2186 | 2238 |
|
2187 | 2239 | auto origPatternType = origExpansion.getPackExpansionPatternType();
|
2188 | 2240 |
|
|
0 commit comments