Skip to content

Commit 2ebddf5

Browse files
authored
Merge pull request #62180 from slavapestov/printing-variadic-types
Fixes for printing variadic generic types
2 parents 70a148d + 1020b70 commit 2ebddf5

17 files changed

+405
-270
lines changed

include/swift/AST/PackExpansionMatcher.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ namespace swift {
2727

2828
class ASTContext;
2929

30-
/// The result of a match. If one of lhs or rhs is a pack expansion type,
31-
/// the other one is a pack type.
30+
/// The result of a match. An important invariant is that either both types
31+
/// are PackExpansionTypes, or both types are scalars. In particular, any
32+
/// PackTypes are always wrapped in a PackExpansionType.
3233
struct MatchedPair {
3334
Type lhs;
3435
Type rhs;
3536

36-
// An index into the original left-hand side.
37-
unsigned idx;
37+
unsigned lhsIdx;
38+
unsigned rhsIdx;
3839

39-
MatchedPair(Type lhs, Type rhs, unsigned idx)
40-
: lhs(lhs), rhs(rhs), idx(idx) {}
40+
MatchedPair(Type lhs, Type rhs, unsigned lhsIdx, unsigned rhsIdx)
41+
: lhs(lhs), rhs(rhs), lhsIdx(lhsIdx), rhsIdx(rhsIdx) {}
4142
};
4243

4344
/// Performs a structural match of two lists of tuple elements. The invariant

include/swift/AST/TypeRepr.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ class GenericIdentTypeRepr final : public ComponentIdentTypeRepr,
366366
: ComponentIdentTypeRepr(TypeReprKind::GenericIdent, Loc, Id),
367367
AngleBrackets(AngleBrackets) {
368368
Bits.GenericIdentTypeRepr.NumGenericArgs = GenericArgs.size();
369-
assert(!GenericArgs.empty());
370369
#ifndef NDEBUG
371370
for (auto arg : GenericArgs)
372371
assert(arg != nullptr);

include/swift/AST/Types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Identifier;
7171
class InOutType;
7272
class OpaqueTypeDecl;
7373
class OpenedArchetypeType;
74+
class PackType;
7475
class PlaceholderTypeRepr;
7576
enum class ReferenceCounting : uint8_t;
7677
enum class ResilienceExpansion : unsigned;
@@ -2002,6 +2003,8 @@ class TypeAliasType final
20022003
/// this type references.
20032004
ArrayRef<Type> getDirectGenericArgs() const;
20042005

2006+
PackType *getExpandedGenericArgsPack();
2007+
20052008
// Support for FoldingSet.
20062009
void Profile(llvm::FoldingSetNodeID &id) const;
20072010

@@ -2420,6 +2423,8 @@ class BoundGenericType : public NominalOrBoundGenericNominalType,
24202423
return {getTrailingObjectsPointer(), Bits.BoundGenericType.GenericArgCount};
24212424
}
24222425

2426+
PackType *getExpandedGenericArgsPack();
2427+
24232428
void Profile(llvm::FoldingSetNodeID &ID) {
24242429
Profile(ID, getDecl(), getParent(), getGenericArgs());
24252430
}
@@ -6478,6 +6483,10 @@ class PackType final : public TypeBase, public llvm::FoldingSetNode,
64786483
/// Creates a pack from the types in \p elements.
64796484
static PackType *get(const ASTContext &C, ArrayRef<Type> elements);
64806485

6486+
static PackType *get(const ASTContext &C,
6487+
TypeArrayView<GenericTypeParamType> params,
6488+
ArrayRef<Type> args);
6489+
64816490
public:
64826491
/// Retrieves the number of elements in this pack.
64836492
unsigned getNumElements() const { return Bits.PackType.Count; }

lib/AST/ASTContext.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3259,11 +3259,6 @@ PackType *PackType::get(const ASTContext &C, ArrayRef<Type> elements) {
32593259
RecursiveTypeProperties properties;
32603260
bool isCanonical = true;
32613261
for (Type eltTy : elements) {
3262-
assert(!eltTy->isTypeParameter() ||
3263-
!eltTy->getRootGenericParam()->isParameterPack() &&
3264-
"Pack type parameter outside of a pack expansion");
3265-
assert(!eltTy->is<PackArchetypeType>() &&
3266-
"Pack type archetype outside of a pack expansion");
32673262
assert(!eltTy->is<PackType>() &&
32683263
"Cannot have pack directly inside another pack");
32693264

lib/AST/ASTPrinter.cpp

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5294,15 +5294,20 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
52945294
Optional<llvm::DenseMap<const clang::Module *, ModuleDecl *>>
52955295
VisibleClangModules;
52965296

5297-
void printGenericArgs(ArrayRef<Type> Args) {
5298-
if (Args.empty())
5299-
return;
5300-
5297+
void printGenericArgs(PackType *flatArgs) {
53015298
Printer << "<";
5302-
interleave(Args, [&](Type Arg) { visit(Arg); }, [&] { Printer << ", "; });
5299+
interleave(flatArgs->getElementTypes(),
5300+
[&](Type arg) { visit(arg); },
5301+
[&] { Printer << ", "; });
53035302
Printer << ">";
53045303
}
53055304

5305+
void printGenericArgs(ASTContext &ctx,
5306+
TypeArrayView<GenericTypeParamType> params,
5307+
ArrayRef<Type> args) {
5308+
printGenericArgs(PackType::get(ctx, params, args));
5309+
}
5310+
53065311
/// Helper function for printing a type that is embedded within a larger type.
53075312
///
53085313
/// This is necessary whenever the inner type may not normally be represented
@@ -5638,7 +5643,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
56385643
}
56395644

56405645
printQualifiedType(T);
5641-
printGenericArgs(T->getDirectGenericArgs());
5646+
5647+
auto *typeAliasDecl = T->getDecl();
5648+
if (typeAliasDecl->isGeneric()) {
5649+
printGenericArgs(T->getExpandedGenericArgsPack());
5650+
}
56425651
}
56435652

56445653
void visitParenType(ParenType *T) {
@@ -5723,7 +5732,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
57235732
}
57245733
}
57255734
printQualifiedType(T);
5726-
printGenericArgs(T->getGenericArgs());
5735+
5736+
printGenericArgs(T->getExpandedGenericArgsPack());
57275737
}
57285738

57295739
void visitParentType(Type T) {
@@ -6537,6 +6547,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
65376547
return false;
65386548
};
65396549

6550+
OpaqueTypeDecl *decl = T->getDecl();
6551+
auto *namingDecl = decl->getNamingDecl();
6552+
auto genericSig = namingDecl->getInnermostDeclContext()
6553+
->getGenericSignatureOfContext();
6554+
65406555
switch (Options.OpaqueReturnTypePrinting) {
65416556
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
65426557
if (printNamedOpaque())
@@ -6554,8 +6569,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
65546569

65556570
// Opaque archetype substitutions are always canonical, so re-sugar the
65566571
// constraint type using the owning declaration's generic parameter names.
6557-
auto genericSig = T->getDecl()->getNamingDecl()->getInnermostDeclContext()
6558-
->getGenericSignatureOfContext();
65596572
if (genericSig)
65606573
constraint = genericSig->getSugaredType(constraint);
65616574

@@ -6568,7 +6581,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
65686581
// turn this back into a reference to the naming decl for the opaque
65696582
// type.
65706583
Printer << "@_opaqueReturnTypeOf(";
6571-
OpaqueTypeDecl *decl = T->getDecl();
65726584

65736585
Printer.printEscapedStringLiteral(
65746586
decl->getOpaqueReturnTypeIdentifier().str());
@@ -6582,22 +6594,24 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
65826594
// attribute to apply to, but the attribute alone references the opaque
65836595
// type.
65846596
Printer << ") __";
6585-
printGenericArgs(T->getSubstitutions().getReplacementTypes());
6597+
6598+
if (genericSig) {
6599+
printGenericArgs(decl->getASTContext(),
6600+
genericSig.getGenericParams(),
6601+
T->getSubstitutions().getReplacementTypes());
6602+
}
65866603
return;
65876604
}
65886605
case PrintOptions::OpaqueReturnTypePrintingMode::Description: {
65896606
// TODO(opaque): present opaque types with user-facing syntax. we should
65906607
// probably print this as `some P` and record the fact that we printed that
65916608
// so that diagnostics can add followup notes.
6592-
Printer << "(return type of " << T->getDecl()->getNamingDecl()->printRef();
6609+
Printer << "(return type of " << namingDecl->printRef();
65936610
Printer << ')';
6594-
if (!T->getSubstitutions().empty()) {
6595-
Printer << '<';
6596-
auto replacements = T->getSubstitutions().getReplacementTypes();
6597-
llvm::interleave(
6598-
replacements.begin(), replacements.end(), [&](Type t) { visit(t); },
6599-
[&] { Printer << ", "; });
6600-
Printer << '>';
6611+
if (genericSig) {
6612+
printGenericArgs(decl->getASTContext(),
6613+
genericSig.getGenericParams(),
6614+
T->getSubstitutions().getReplacementTypes());
66016615
}
66026616
return;
66036617
}

0 commit comments

Comments
 (0)