@@ -913,6 +913,9 @@ class AbstractionPattern {
913913 bool hasCachingKey () const {
914914 // Only the simplest Kind::Type pattern has a caching key; we
915915 // don't want to try to unique by Clang node.
916+ //
917+ // Even if we support Clang nodes someday, we *cannot* cache
918+ // by the open-coded patterns like Tuple and PackExpansion.
916919 return getKind () == Kind::Type || getKind () == Kind::Opaque
917920 || getKind () == Kind::Discard;
918921 }
@@ -1216,9 +1219,7 @@ class AbstractionPattern {
12161219 case Kind::Invalid:
12171220 llvm_unreachable (" querying invalid abstraction pattern!" );
12181221 case Kind::Opaque:
1219- return typename CanTypeWrapperTraits<TYPE>::type ();
12201222 case Kind::Tuple:
1221- return typename CanTypeWrapperTraits<TYPE>::type ();
12221223 case Kind::OpaqueFunction:
12231224 case Kind::OpaqueDerivativeFunction:
12241225 return typename CanTypeWrapperTraits<TYPE>::type ();
@@ -1275,7 +1276,7 @@ class AbstractionPattern {
12751276
12761277 // / Is the given tuple type a valid substitution of this abstraction
12771278 // / pattern?
1278- bool matchesTuple (CanTupleType substType);
1279+ bool matchesTuple (CanTupleType substType) const ;
12791280
12801281 bool isTuple () const {
12811282 switch (getKind ()) {
@@ -1346,6 +1347,40 @@ class AbstractionPattern {
13461347 return { { this , 0 }, { this , getNumTupleElements () } };
13471348 }
13481349
1350+ // / Perform a parallel visitation of the elements of a tuple type,
1351+ // / preserving structure about where pack expansions appear in the
1352+ // / original type and how many elements of the substituted type they
1353+ // / expand to.
1354+ // /
1355+ // / This pattern must be a tuple pattern.
1356+ // /
1357+ // / Calls handleScalar or handleExpansion as appropriate for each
1358+ // / element of the original tuple, in order.
1359+ void forEachTupleElement (CanTupleType substType,
1360+ llvm::function_ref<void (unsigned origEltIndex,
1361+ unsigned substEltIndex,
1362+ AbstractionPattern origEltType,
1363+ CanType substEltType)>
1364+ handleScalar,
1365+ llvm::function_ref<void(unsigned origEltIndex,
1366+ unsigned substEltIndex,
1367+ AbstractionPattern origExpansionType,
1368+ CanTupleEltTypeArrayRef substEltTypes)>
1369+ handleExpansion) const ;
1370+
1371+ // / Perform a parallel visitation of the elements of a tuple type,
1372+ // / expanding the elements of the type. This preserves the structure
1373+ // / of the *substituted* tuple type: it will be called once per element
1374+ // / of the substituted type, in order. The original element trappings
1375+ // / are also provided for convenience.
1376+ // /
1377+ // / This pattern must match the substituted type, but it may be an
1378+ // / opaque pattern.
1379+ void forEachExpandedTupleElement (CanTupleType substType,
1380+ llvm::function_ref<void (AbstractionPattern origEltType,
1381+ CanType substEltType,
1382+ const TupleTypeElt &elt)> handleElement) const ;
1383+
13491384 // / Is the given pack type a valid substitution of this abstraction
13501385 // / pattern?
13511386 bool matchesPack (CanPackType substType);
@@ -1420,13 +1455,20 @@ class AbstractionPattern {
14201455 // / the abstraction pattern for an element type.
14211456 AbstractionPattern getPackElementType (unsigned index) const ;
14221457
1423- // / Give that the value being abstracted is a pack expansion type, return the
1424- // / underlying pattern type.
1458+ // / Given that the value being abstracted is a pack expansion type,
1459+ // / return the underlying pattern type.
1460+ // /
1461+ // / If you're looking for getPackExpansionCountType(), it deliberately
1462+ // / does not exist. Count types are not lowered types, and the original
1463+ // / count types are not relevant to lowering. Only the substituted
1464+ // / components and expansion counts are significant.
14251465 AbstractionPattern getPackExpansionPatternType () const ;
14261466
1427- // / Give that the value being abstracted is a pack expansion type, return the
1428- // / underlying count type.
1429- AbstractionPattern getPackExpansionCountType () const ;
1467+ // / Given that the value being abstracted is a pack expansion type,
1468+ // / return the appropriate pattern type for the given expansion
1469+ // / component.
1470+ AbstractionPattern getPackExpansionComponentType (CanType substType) const ;
1471+ AbstractionPattern getPackExpansionComponentType (bool isExpansion) const ;
14301472
14311473 // / Given that the value being abstracted is a function, return the
14321474 // / abstraction pattern for its result type.
@@ -1446,6 +1488,30 @@ class AbstractionPattern {
14461488 // / parameters in the pattern.
14471489 unsigned getNumFunctionParams () const ;
14481490
1491+ // / Perform a parallel visitation of the parameters of a function.
1492+ // /
1493+ // / If this is a function pattern, calls handleScalar or
1494+ // / handleExpansion as appropriate for each parameter of the
1495+ // / original function, in order.
1496+ // /
1497+ // / If this is not a function pattern, calls handleScalar for each
1498+ // / parameter of the substituted function type. Functions with
1499+ // / pack expansions cannot be abstracted legally this way.
1500+ void forEachFunctionParam (AnyFunctionType::CanParamArrayRef substParams,
1501+ bool ignoreFinalParam,
1502+ llvm::function_ref<void (unsigned origParamIndex,
1503+ unsigned substParamIndex,
1504+ ParameterTypeFlags origFlags,
1505+ AbstractionPattern origParamType,
1506+ AnyFunctionType::CanParam substParam)>
1507+ handleScalar,
1508+ llvm::function_ref<void(unsigned origParamIndex,
1509+ unsigned substParamIndex,
1510+ ParameterTypeFlags origFlags,
1511+ AbstractionPattern origExpansionType,
1512+ AnyFunctionType::CanParamArrayRef substParams)>
1513+ handleExpansion) const ;
1514+
14491515 // / Given that the value being abstracted is optional, return the
14501516 // / abstraction pattern for its object type.
14511517 AbstractionPattern getOptionalObjectType () const ;
@@ -1477,16 +1543,14 @@ class AbstractionPattern {
14771543 AbstractionPattern getObjCMethodAsyncCompletionHandlerType (
14781544 CanType swiftCompletionHandlerType) const ;
14791545
1480- // / Given that this is a pack expansion, invoke the given callback for
1481- // / each component of the substituted expansion of this pattern. The
1482- // / pattern will be for a pack expansion type over a contextual type if
1483- // / the substituted component is still a pack expansion. If there aren't
1484- // / substitutions available, this will just invoke the callback with the
1485- // / component.
1486- void forEachPackExpandedComponent (
1487- llvm::function_ref<void (AbstractionPattern pattern)> fn) const ;
1488-
1489- SmallVector<AbstractionPattern, 4 > getPackExpandedComponents () const ;
1546+ // / Given that this is a pack expansion, return the number of components
1547+ // / that it should expand to. This, and the general correctness of
1548+ // / traversing variadically generic tuple and function types under
1549+ // / substitution, relies on substitutions having been set properly
1550+ // / on the abstraction pattern; without that, AbstractionPattern assumes
1551+ // / that every component expands to a single pack expansion component,
1552+ // / which will generally only work in specific situations.
1553+ size_t getNumPackExpandedComponents () const ;
14901554
14911555 // / If this pattern refers to a foreign ObjC method that was imported as
14921556 // / async, return the bridged-back-to-ObjC completion handler type.
0 commit comments