@@ -5234,12 +5234,45 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5234
5234
Optional<llvm::DenseMap<const clang::Module *, ModuleDecl *>>
5235
5235
VisibleClangModules;
5236
5236
5237
- void printGenericArgs (ArrayRef<Type> Args) {
5238
- if (Args.empty ())
5237
+ void printGenericArgs (TypeArrayView<GenericTypeParamType> params,
5238
+ ArrayRef<Type> args) {
5239
+ assert (params.size () == args.size ());
5240
+
5241
+ if (args.empty ())
5239
5242
return ;
5240
5243
5244
+ // Unlike tuple elements and function type parameter lists, packs are not
5245
+ // flattened in the arguments of a generic type, so we need to perform a
5246
+ // transformation to print them in a form that will resolve back to the
5247
+ // same type:
5248
+ //
5249
+ // VariadicType<Pack{T1, T2}> => VariadicType<T1, T2>
5250
+ // VariadicType<T> => VariadicType<T...> where T is a type parameter pack
5251
+ //
5252
+ SmallVector<Type, 2 > flatArgs;
5253
+ for (unsigned i : indices (params)) {
5254
+ auto param = params[i];
5255
+ auto arg = args[i];
5256
+ if (param->isParameterPack ()) {
5257
+ if (auto *packType = arg->getAs <PackType>()) {
5258
+ flatArgs.append (packType->getElementTypes ().begin (),
5259
+ packType->getElementTypes ().end ());
5260
+ } else {
5261
+ assert (arg->is <PackArchetypeType>() ||
5262
+ arg->is <TypeVariableType>() ||
5263
+ arg->isParameterPack ());
5264
+ flatArgs.push_back (PackExpansionType::get (arg, arg));
5265
+ }
5266
+ } else {
5267
+ assert (!arg->is <PackType>());
5268
+ flatArgs.push_back (arg);
5269
+ }
5270
+ }
5271
+
5241
5272
Printer << " <" ;
5242
- interleave (Args, [&](Type Arg) { visit (Arg); }, [&] { Printer << " , " ; });
5273
+ interleave (flatArgs,
5274
+ [&](Type arg) { visit (arg); },
5275
+ [&] { Printer << " , " ; });
5243
5276
Printer << " >" ;
5244
5277
}
5245
5278
@@ -5572,7 +5605,13 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5572
5605
}
5573
5606
5574
5607
printQualifiedType (T);
5575
- printGenericArgs (T->getDirectGenericArgs ());
5608
+
5609
+ auto *typeAliasDecl = T->getDecl ();
5610
+ if (typeAliasDecl->isGeneric ()) {
5611
+ auto genericSig = typeAliasDecl->getGenericSignature ();
5612
+ printGenericArgs (genericSig.getInnermostGenericParams (),
5613
+ T->getDirectGenericArgs ());
5614
+ }
5576
5615
}
5577
5616
5578
5617
void visitParenType (ParenType *T) {
@@ -5657,7 +5696,16 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5657
5696
}
5658
5697
}
5659
5698
printQualifiedType (T);
5660
- printGenericArgs (T->getGenericArgs ());
5699
+
5700
+ // It would be nicer to use genericSig.getInnermostGenericParams() here,
5701
+ // but that triggers a request cycle if we're in the middle of computing
5702
+ // the generic signature already.
5703
+ SmallVector<Type, 2 > paramTypes;
5704
+ for (auto *paramDecl : T->getDecl ()->getGenericParams ()->getParams ()) {
5705
+ paramTypes.push_back (paramDecl->getDeclaredInterfaceType ());
5706
+ }
5707
+ printGenericArgs (TypeArrayView<GenericTypeParamType>(paramTypes),
5708
+ T->getGenericArgs ());
5661
5709
}
5662
5710
5663
5711
void visitParentType (Type T) {
@@ -6472,6 +6520,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6472
6520
return false ;
6473
6521
};
6474
6522
6523
+ auto *namingDecl = T->getDecl ()->getNamingDecl ();
6524
+ auto genericSig = namingDecl->getInnermostDeclContext ()
6525
+ ->getGenericSignatureOfContext ();
6526
+
6475
6527
switch (Options.OpaqueReturnTypePrinting ) {
6476
6528
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
6477
6529
if (printNamedOpaque ())
@@ -6489,8 +6541,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6489
6541
6490
6542
// Opaque archetype substitutions are always canonical, so re-sugar the
6491
6543
// constraint type using the owning declaration's generic parameter names.
6492
- auto genericSig = T->getDecl ()->getNamingDecl ()->getInnermostDeclContext ()
6493
- ->getGenericSignatureOfContext ();
6494
6544
if (genericSig)
6495
6545
constraint = genericSig->getSugaredType (constraint);
6496
6546
@@ -6517,22 +6567,22 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6517
6567
// attribute to apply to, but the attribute alone references the opaque
6518
6568
// type.
6519
6569
Printer << " ) __" ;
6520
- printGenericArgs (T->getSubstitutions ().getReplacementTypes ());
6570
+
6571
+ if (genericSig) {
6572
+ printGenericArgs (genericSig.getGenericParams (),
6573
+ T->getSubstitutions ().getReplacementTypes ());
6574
+ }
6521
6575
return ;
6522
6576
}
6523
6577
case PrintOptions::OpaqueReturnTypePrintingMode::Description: {
6524
6578
// TODO(opaque): present opaque types with user-facing syntax. we should
6525
6579
// probably print this as `some P` and record the fact that we printed that
6526
6580
// so that diagnostics can add followup notes.
6527
- Printer << " (return type of " << T-> getDecl ()-> getNamingDecl () ->printRef ();
6581
+ Printer << " (return type of " << namingDecl ->printRef ();
6528
6582
Printer << ' )' ;
6529
- if (!T->getSubstitutions ().empty ()) {
6530
- Printer << ' <' ;
6531
- auto replacements = T->getSubstitutions ().getReplacementTypes ();
6532
- llvm::interleave (
6533
- replacements.begin (), replacements.end (), [&](Type t) { visit (t); },
6534
- [&] { Printer << " , " ; });
6535
- Printer << ' >' ;
6583
+ if (genericSig) {
6584
+ printGenericArgs (genericSig.getGenericParams (),
6585
+ T->getSubstitutions ().getReplacementTypes ());
6536
6586
}
6537
6587
return ;
6538
6588
}
0 commit comments