@@ -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
@@ -5578,7 +5611,13 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5578
5611
}
5579
5612
5580
5613
printQualifiedType (T);
5581
- printGenericArgs (T->getDirectGenericArgs ());
5614
+
5615
+ auto *typeAliasDecl = T->getDecl ();
5616
+ if (typeAliasDecl->isGeneric ()) {
5617
+ auto genericSig = typeAliasDecl->getGenericSignature ();
5618
+ printGenericArgs (genericSig.getInnermostGenericParams (),
5619
+ T->getDirectGenericArgs ());
5620
+ }
5582
5621
}
5583
5622
5584
5623
void visitParenType (ParenType *T) {
@@ -5663,7 +5702,16 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
5663
5702
}
5664
5703
}
5665
5704
printQualifiedType (T);
5666
- printGenericArgs (T->getGenericArgs ());
5705
+
5706
+ // It would be nicer to use genericSig.getInnermostGenericParams() here,
5707
+ // but that triggers a request cycle if we're in the middle of computing
5708
+ // the generic signature already.
5709
+ SmallVector<Type, 2 > paramTypes;
5710
+ for (auto *paramDecl : T->getDecl ()->getGenericParams ()->getParams ()) {
5711
+ paramTypes.push_back (paramDecl->getDeclaredInterfaceType ());
5712
+ }
5713
+ printGenericArgs (TypeArrayView<GenericTypeParamType>(paramTypes),
5714
+ T->getGenericArgs ());
5667
5715
}
5668
5716
5669
5717
void visitParentType (Type T) {
@@ -6477,6 +6525,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6477
6525
return false ;
6478
6526
};
6479
6527
6528
+ auto *namingDecl = T->getDecl ()->getNamingDecl ();
6529
+ auto genericSig = namingDecl->getInnermostDeclContext ()
6530
+ ->getGenericSignatureOfContext ();
6531
+
6480
6532
switch (Options.OpaqueReturnTypePrinting ) {
6481
6533
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
6482
6534
if (printNamedOpaque ())
@@ -6494,8 +6546,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6494
6546
6495
6547
// Opaque archetype substitutions are always canonical, so re-sugar the
6496
6548
// constraint type using the owning declaration's generic parameter names.
6497
- auto genericSig = T->getDecl ()->getNamingDecl ()->getInnermostDeclContext ()
6498
- ->getGenericSignatureOfContext ();
6499
6549
if (genericSig)
6500
6550
constraint = genericSig->getSugaredType (constraint);
6501
6551
@@ -6522,22 +6572,22 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
6522
6572
// attribute to apply to, but the attribute alone references the opaque
6523
6573
// type.
6524
6574
Printer << " ) __" ;
6525
- printGenericArgs (T->getSubstitutions ().getReplacementTypes ());
6575
+
6576
+ if (genericSig) {
6577
+ printGenericArgs (genericSig.getGenericParams (),
6578
+ T->getSubstitutions ().getReplacementTypes ());
6579
+ }
6526
6580
return ;
6527
6581
}
6528
6582
case PrintOptions::OpaqueReturnTypePrintingMode::Description: {
6529
6583
// TODO(opaque): present opaque types with user-facing syntax. we should
6530
6584
// probably print this as `some P` and record the fact that we printed that
6531
6585
// so that diagnostics can add followup notes.
6532
- Printer << " (return type of " << T-> getDecl ()-> getNamingDecl () ->printRef ();
6586
+ Printer << " (return type of " << namingDecl ->printRef ();
6533
6587
Printer << ' )' ;
6534
- if (!T->getSubstitutions ().empty ()) {
6535
- Printer << ' <' ;
6536
- auto replacements = T->getSubstitutions ().getReplacementTypes ();
6537
- llvm::interleave (
6538
- replacements.begin (), replacements.end (), [&](Type t) { visit (t); },
6539
- [&] { Printer << " , " ; });
6540
- Printer << ' >' ;
6588
+ if (genericSig) {
6589
+ printGenericArgs (genericSig.getGenericParams (),
6590
+ T->getSubstitutions ().getReplacementTypes ());
6541
6591
}
6542
6592
return ;
6543
6593
}
0 commit comments