Skip to content

Commit 09b061b

Browse files
committed
SIL: Preliminary type lowering for PackType and PackExpansionType
1 parent f2d1e8d commit 09b061b

File tree

5 files changed

+328
-21
lines changed

5 files changed

+328
-21
lines changed

include/swift/SIL/AbstractionPattern.h

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,64 @@ class AbstractionPattern {
12551255
llvm_unreachable("bad kind");
12561256
}
12571257

1258+
/// Is the given pack type a valid substitution of this abstraction
1259+
/// pattern?
1260+
bool matchesPack(CanPackType substType);
1261+
1262+
bool isPack() const {
1263+
switch (getKind()) {
1264+
case Kind::Invalid:
1265+
llvm_unreachable("querying invalid abstraction pattern!");
1266+
case Kind::Opaque:
1267+
case Kind::PartialCurriedObjCMethodType:
1268+
case Kind::CurriedObjCMethodType:
1269+
case Kind::CFunctionAsMethodType:
1270+
case Kind::CurriedCFunctionAsMethodType:
1271+
case Kind::PartialCurriedCFunctionAsMethodType:
1272+
case Kind::ObjCMethodType:
1273+
case Kind::CXXMethodType:
1274+
case Kind::CurriedCXXMethodType:
1275+
case Kind::PartialCurriedCXXMethodType:
1276+
case Kind::OpaqueFunction:
1277+
case Kind::OpaqueDerivativeFunction:
1278+
case Kind::ObjCCompletionHandlerArgumentsType:
1279+
case Kind::Tuple:
1280+
case Kind::ClangType:
1281+
return false;
1282+
case Kind::Type:
1283+
case Kind::Discard:
1284+
return isa<PackType>(getType());
1285+
}
1286+
llvm_unreachable("bad kind");
1287+
}
1288+
1289+
size_t getNumPackElements() const {
1290+
switch (getKind()) {
1291+
case Kind::Invalid:
1292+
llvm_unreachable("querying invalid abstraction pattern!");
1293+
case Kind::Opaque:
1294+
case Kind::PartialCurriedObjCMethodType:
1295+
case Kind::CurriedObjCMethodType:
1296+
case Kind::CFunctionAsMethodType:
1297+
case Kind::CurriedCFunctionAsMethodType:
1298+
case Kind::PartialCurriedCFunctionAsMethodType:
1299+
case Kind::ObjCMethodType:
1300+
case Kind::CXXMethodType:
1301+
case Kind::CurriedCXXMethodType:
1302+
case Kind::PartialCurriedCXXMethodType:
1303+
case Kind::OpaqueFunction:
1304+
case Kind::OpaqueDerivativeFunction:
1305+
case Kind::ObjCCompletionHandlerArgumentsType:
1306+
case Kind::Tuple:
1307+
case Kind::ClangType:
1308+
llvm_unreachable("pattern is not a pack");
1309+
case Kind::Type:
1310+
case Kind::Discard:
1311+
return cast<PackType>(getType())->getNumElements();
1312+
}
1313+
llvm_unreachable("bad kind");
1314+
}
1315+
12581316
/// Given that the value being abstracted is a move only type, return the
12591317
/// abstraction pattern with the move only bit removed.
12601318
AbstractionPattern removingMoveOnlyWrapper() const;
@@ -1264,9 +1322,21 @@ class AbstractionPattern {
12641322
AbstractionPattern addingMoveOnlyWrapper() const;
12651323

12661324
/// Given that the value being abstracted is a tuple type, return
1267-
/// the abstraction pattern for its object type.
1325+
/// the abstraction pattern for an element type.
12681326
AbstractionPattern getTupleElementType(unsigned index) const;
12691327

1328+
/// Given that the value being abstracted is a pack type, return
1329+
/// the abstraction pattern for an element type.
1330+
AbstractionPattern getPackElementType(unsigned index) const;
1331+
1332+
/// Give that the value being abstracted is a pack expansion type, return the
1333+
/// underlying pattern type.
1334+
AbstractionPattern getPackExpansionPatternType() const;
1335+
1336+
/// Give that the value being abstracted is a pack expansion type, return the
1337+
/// underlying count type.
1338+
AbstractionPattern getPackExpansionCountType() const;
1339+
12701340
/// Given that the value being abstracted is a function, return the
12711341
/// abstraction pattern for its result type.
12721342
AbstractionPattern getFunctionResultType() const;

lib/AST/Type.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,20 @@ static bool isLegalSILType(CanType type) {
655655
return true;
656656
}
657657

658+
// Packs are legal if all their elements are legal.
659+
if (auto packType = dyn_cast<PackType>(type)) {
660+
for (auto eltType : packType.getElementTypes()) {
661+
if (!isLegalSILType(eltType)) return false;
662+
}
663+
return true;
664+
}
665+
666+
// Pack expansions are legal if all their pattern and count types are legal.
667+
if (auto packExpansionType = dyn_cast<PackExpansionType>(type)) {
668+
return (isLegalSILType(packExpansionType.getPatternType()) &&
669+
isLegalSILType(packExpansionType.getCountType()));
670+
}
671+
658672
// Optionals are legal if their object type is legal.
659673
if (auto objectType = type.getOptionalObjectType()) {
660674
return isLegalSILType(objectType);

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,159 @@ AbstractionPattern::getTupleElementType(unsigned index) const {
401401
llvm_unreachable("bad kind");
402402
}
403403

404+
static CanType getCanPackElementType(CanType type, unsigned index) {
405+
return cast<PackType>(type).getElementType(index);
406+
}
407+
408+
AbstractionPattern
409+
AbstractionPattern::getPackElementType(unsigned index) const {
410+
switch (getKind()) {
411+
case Kind::Invalid:
412+
llvm_unreachable("querying invalid abstraction pattern!");
413+
case Kind::PartialCurriedObjCMethodType:
414+
case Kind::CurriedObjCMethodType:
415+
case Kind::PartialCurriedCFunctionAsMethodType:
416+
case Kind::CurriedCFunctionAsMethodType:
417+
case Kind::CFunctionAsMethodType:
418+
case Kind::ObjCMethodType:
419+
case Kind::CXXMethodType:
420+
case Kind::CurriedCXXMethodType:
421+
case Kind::PartialCurriedCXXMethodType:
422+
case Kind::OpaqueFunction:
423+
case Kind::OpaqueDerivativeFunction:
424+
case Kind::ClangType:
425+
case Kind::Tuple:
426+
case Kind::ObjCCompletionHandlerArgumentsType:
427+
llvm_unreachable("not a pack type");
428+
case Kind::Opaque:
429+
return *this;
430+
case Kind::Discard:
431+
llvm_unreachable("operation not needed on discarded abstractions yet");
432+
case Kind::Type:
433+
if (isTypeParameterOrOpaqueArchetype())
434+
return AbstractionPattern::getOpaque();
435+
return AbstractionPattern(getGenericSignature(),
436+
getCanPackElementType(getType(), index));
437+
}
438+
llvm_unreachable("bad kind");
439+
}
440+
441+
bool AbstractionPattern::matchesPack(CanPackType substType) {
442+
switch (getKind()) {
443+
case Kind::Invalid:
444+
llvm_unreachable("querying invalid abstraction pattern!");
445+
case Kind::PartialCurriedObjCMethodType:
446+
case Kind::CurriedObjCMethodType:
447+
case Kind::PartialCurriedCFunctionAsMethodType:
448+
case Kind::CurriedCFunctionAsMethodType:
449+
case Kind::CFunctionAsMethodType:
450+
case Kind::ObjCMethodType:
451+
case Kind::CXXMethodType:
452+
case Kind::CurriedCXXMethodType:
453+
case Kind::PartialCurriedCXXMethodType:
454+
case Kind::OpaqueFunction:
455+
case Kind::OpaqueDerivativeFunction:
456+
case Kind::Tuple:
457+
case Kind::ObjCCompletionHandlerArgumentsType:
458+
case Kind::ClangType:
459+
return false;
460+
case Kind::Opaque:
461+
return true;
462+
case Kind::Type:
463+
case Kind::Discard: {
464+
if (isTypeParameterOrOpaqueArchetype())
465+
return true;
466+
auto type = getType();
467+
if (auto pack = dyn_cast<PackType>(type))
468+
return (pack->getNumElements() == substType->getNumElements());
469+
return false;
470+
}
471+
}
472+
llvm_unreachable("bad kind");
473+
}
474+
475+
static CanType getPackExpansionPatternType(CanType type) {
476+
return cast<PackExpansionType>(type).getPatternType();
477+
}
478+
479+
AbstractionPattern AbstractionPattern::getPackExpansionPatternType() const {
480+
switch (getKind()) {
481+
case Kind::Invalid:
482+
llvm_unreachable("querying invalid abstraction pattern!");
483+
case Kind::ObjCMethodType:
484+
case Kind::CurriedObjCMethodType:
485+
case Kind::PartialCurriedObjCMethodType:
486+
case Kind::CFunctionAsMethodType:
487+
case Kind::CurriedCFunctionAsMethodType:
488+
case Kind::PartialCurriedCFunctionAsMethodType:
489+
case Kind::CXXMethodType:
490+
case Kind::CurriedCXXMethodType:
491+
case Kind::PartialCurriedCXXMethodType:
492+
case Kind::Tuple:
493+
case Kind::OpaqueFunction:
494+
case Kind::OpaqueDerivativeFunction:
495+
case Kind::ObjCCompletionHandlerArgumentsType:
496+
case Kind::ClangType:
497+
llvm_unreachable("pattern for function or tuple cannot be for "
498+
"pack expansion type");
499+
500+
case Kind::Opaque:
501+
return *this;
502+
503+
case Kind::Type:
504+
if (isTypeParameterOrOpaqueArchetype())
505+
return AbstractionPattern::getOpaque();
506+
return AbstractionPattern(getGenericSignature(),
507+
::getPackExpansionPatternType(getType()));
508+
509+
case Kind::Discard:
510+
return AbstractionPattern::getDiscard(
511+
getGenericSignature(), ::getPackExpansionPatternType(getType()));
512+
}
513+
llvm_unreachable("bad kind");
514+
}
515+
516+
static CanType getPackExpansionCountType(CanType type) {
517+
return cast<PackExpansionType>(type).getCountType();
518+
}
519+
520+
AbstractionPattern AbstractionPattern::getPackExpansionCountType() const {
521+
switch (getKind()) {
522+
case Kind::Invalid:
523+
llvm_unreachable("querying invalid abstraction pattern!");
524+
case Kind::ObjCMethodType:
525+
case Kind::CurriedObjCMethodType:
526+
case Kind::PartialCurriedObjCMethodType:
527+
case Kind::CFunctionAsMethodType:
528+
case Kind::CurriedCFunctionAsMethodType:
529+
case Kind::PartialCurriedCFunctionAsMethodType:
530+
case Kind::CXXMethodType:
531+
case Kind::CurriedCXXMethodType:
532+
case Kind::PartialCurriedCXXMethodType:
533+
case Kind::Tuple:
534+
case Kind::OpaqueFunction:
535+
case Kind::OpaqueDerivativeFunction:
536+
case Kind::ObjCCompletionHandlerArgumentsType:
537+
case Kind::ClangType:
538+
llvm_unreachable("pattern for function or tuple cannot be for "
539+
"pack expansion type");
540+
541+
case Kind::Opaque:
542+
return *this;
543+
544+
case Kind::Type:
545+
if (isTypeParameterOrOpaqueArchetype())
546+
return AbstractionPattern::getOpaque();
547+
return AbstractionPattern(getGenericSignature(),
548+
::getPackExpansionCountType(getType()));
549+
550+
case Kind::Discard:
551+
return AbstractionPattern::getDiscard(
552+
getGenericSignature(), ::getPackExpansionCountType(getType()));
553+
}
554+
llvm_unreachable("bad kind");
555+
}
556+
404557
AbstractionPattern AbstractionPattern::removingMoveOnlyWrapper() const {
405558
switch (getKind()) {
406559
case Kind::Invalid:

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4128,7 +4128,10 @@ class SILTypeSubstituter :
41284128
}
41294129

41304130
CanType visitPackExpansionType(CanPackExpansionType origType) {
4131-
llvm_unreachable("Unimplemented!");
4131+
CanType patternType = visit(origType.getPatternType());
4132+
CanType countType = visit(origType.getCountType());
4133+
4134+
return CanType(PackExpansionType::get(patternType, countType));
41324135
}
41334136

41344137
/// Tuples need to have their component types substituted by these

0 commit comments

Comments
 (0)