@@ -5282,12 +5282,45 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5282
5282
Optional<llvm::DenseMap<const clang::Module *, ModuleDecl *>>
5283
5283
VisibleClangModules;
5284
5284
5285
- void printGenericArgs (ArrayRef<Type> Args) {
5286
- if (Args.empty ())
5285
+ void printGenericArgs (TypeArrayView<GenericTypeParamType> params,
5286
+ ArrayRef<Type> args) {
5287
+ assert (params.size () == args.size ());
5288
+
5289
+ if (args.empty ())
5287
5290
return ;
5288
5291
5292
+ // Unlike tuple elements and function type parameter lists, packs are not
5293
+ // flattened in the arguments of a generic type, so we need to perform a
5294
+ // transformation to print them in a form that will resolve back to the
5295
+ // same type:
5296
+ //
5297
+ // VariadicType<Pack{T1, T2}> => VariadicType<T1, T2>
5298
+ // VariadicType<T> => VariadicType<T...> where T is a type parameter pack
5299
+ //
5300
+ SmallVector<Type, 2 > flatArgs;
5301
+ for (unsigned i : indices (params)) {
5302
+ auto param = params[i];
5303
+ auto arg = args[i];
5304
+ if (param->isParameterPack ()) {
5305
+ if (auto *packType = arg->getAs <PackType>()) {
5306
+ flatArgs.append (packType->getElementTypes ().begin (),
5307
+ packType->getElementTypes ().end ());
5308
+ } else {
5309
+ assert (arg->is <PackArchetypeType>() ||
5310
+ arg->is <TypeVariableType>() ||
5311
+ arg->isParameterPack ());
5312
+ flatArgs.push_back (PackExpansionType::get (arg, arg));
5313
+ }
5314
+ } else {
5315
+ assert (!arg->is <PackType>());
5316
+ flatArgs.push_back (arg);
5317
+ }
5318
+ }
5319
+
5289
5320
Printer << " <" ;
5290
- interleave (Args, [&](Type Arg) { visit (Arg); }, [&] { Printer << " , " ; });
5321
+ interleave (flatArgs,
5322
+ [&](Type arg) { visit (arg); },
5323
+ [&] { Printer << " , " ; });
5291
5324
Printer << " >" ;
5292
5325
}
5293
5326
@@ -5626,7 +5659,13 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5626
5659
}
5627
5660
5628
5661
printQualifiedType (T);
5629
- printGenericArgs (T->getDirectGenericArgs ());
5662
+
5663
+ auto *typeAliasDecl = T->getDecl ();
5664
+ if (typeAliasDecl->isGeneric ()) {
5665
+ auto genericSig = typeAliasDecl->getGenericSignature ();
5666
+ printGenericArgs (genericSig.getInnermostGenericParams (),
5667
+ T->getDirectGenericArgs ());
5668
+ }
5630
5669
}
5631
5670
5632
5671
void visitParenType (ParenType *T) {
@@ -5711,7 +5750,16 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5711
5750
}
5712
5751
}
5713
5752
printQualifiedType (T);
5714
- printGenericArgs (T->getGenericArgs ());
5753
+
5754
+ // It would be nicer to use genericSig.getInnermostGenericParams() here,
5755
+ // but that triggers a request cycle if we're in the middle of computing
5756
+ // the generic signature already.
5757
+ SmallVector<Type, 2 > paramTypes;
5758
+ for (auto *paramDecl : T->getDecl ()->getGenericParams ()->getParams ()) {
5759
+ paramTypes.push_back (paramDecl->getDeclaredInterfaceType ());
5760
+ }
5761
+ printGenericArgs (TypeArrayView<GenericTypeParamType>(paramTypes),
5762
+ T->getGenericArgs ());
5715
5763
}
5716
5764
5717
5765
void visitParentType (Type T) {
@@ -6525,6 +6573,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6525
6573
return false ;
6526
6574
};
6527
6575
6576
+ auto *namingDecl = T->getDecl ()->getNamingDecl ();
6577
+ auto genericSig = namingDecl->getInnermostDeclContext ()
6578
+ ->getGenericSignatureOfContext ();
6579
+
6528
6580
switch (Options.OpaqueReturnTypePrinting ) {
6529
6581
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
6530
6582
if (printNamedOpaque ())
@@ -6542,8 +6594,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6542
6594
6543
6595
// Opaque archetype substitutions are always canonical, so re-sugar the
6544
6596
// constraint type using the owning declaration's generic parameter names.
6545
- auto genericSig = T->getDecl ()->getNamingDecl ()->getInnermostDeclContext ()
6546
- ->getGenericSignatureOfContext ();
6547
6597
if (genericSig)
6548
6598
constraint = genericSig->getSugaredType (constraint);
6549
6599
@@ -6570,22 +6620,22 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6570
6620
// attribute to apply to, but the attribute alone references the opaque
6571
6621
// type.
6572
6622
Printer << " ) __" ;
6573
- printGenericArgs (T->getSubstitutions ().getReplacementTypes ());
6623
+
6624
+ if (genericSig) {
6625
+ printGenericArgs (genericSig.getGenericParams (),
6626
+ T->getSubstitutions ().getReplacementTypes ());
6627
+ }
6574
6628
return ;
6575
6629
}
6576
6630
case PrintOptions::OpaqueReturnTypePrintingMode::Description: {
6577
6631
// TODO(opaque): present opaque types with user-facing syntax. we should
6578
6632
// probably print this as `some P` and record the fact that we printed that
6579
6633
// so that diagnostics can add followup notes.
6580
- Printer << " (return type of " << T-> getDecl ()-> getNamingDecl () ->printRef ();
6634
+ Printer << " (return type of " << namingDecl ->printRef ();
6581
6635
Printer << ' )' ;
6582
- if (!T->getSubstitutions ().empty ()) {
6583
- Printer << ' <' ;
6584
- auto replacements = T->getSubstitutions ().getReplacementTypes ();
6585
- llvm::interleave (
6586
- replacements.begin (), replacements.end (), [&](Type t) { visit (t); },
6587
- [&] { Printer << " , " ; });
6588
- Printer << ' >' ;
6636
+ if (genericSig) {
6637
+ printGenericArgs (genericSig.getGenericParams (),
6638
+ T->getSubstitutions ().getReplacementTypes ());
6589
6639
}
6590
6640
return ;
6591
6641
}
0 commit comments