[source]

compiler/main/PprTyThing.hs

Note [Pretty printing via IfaceSyn]

[note link]

Our general plan for prett-printing
  • Types
  • TyCons
  • Classes
  • Pattern synonyms

…etc…

is to convert them to IfaceSyn, and pretty-print that. For example
  • pprType converts a Type to an IfaceType, and pretty prints that.
  • pprTyThing converts the TyThing to an IfaceDecl, and pretty prints that.
So IfaceSyn play a dual role:
  • it’s the internal version of an interface files
  • it’s used for pretty-printing

Why do this?

  • A significant reason is that we need to be able to pretty-print IfaceSyn (to display Foo.hi), and it was a pain to duplicate masses of pretty-printing goop, esp for Type and IfaceType.

  • When pretty-printing (a type, say), we want to tidy (with tidyType) to avoids having (forall a a. blah) where the two a’s have different uniques.

    Alas, for type constructors, TyCon, tidying does not work well, because a TyCon includes DataCons which include Types, which mention TyCons. And tidying can’t tidy a mutually recursive data structure graph, only trees.

  • Interface files contains fast-strings, not uniques, so the very same tidying must take place when we convert to IfaceDecl. E.g. MkIface.tyThingToIfaceDecl which converts a TyThing (i.e. TyCon, Class etc) to an IfaceDecl.

    Bottom line: IfaceDecls are already ‘tidy’, so it’s straightforward to print them.

  • An alternative I once explored was to ensure that TyCons get type variables with distinct print-names. That’s ok for type variables but less easy for kind variables. Processing data type declarations is already so complicated that I don’t think it’s sensible to add the extra requirement that it generates only “pretty” types and kinds.

Consequences:

  • IfaceSyn (and IfaceType) must contain enough information to print nicely. Hence, for example, the IfaceAppArgs type, which allows us to suppress invisible kind arguments in types (see Note [Suppressing invisible arguments] in IfaceType)
  • In a few places we have info that is used only for pretty-printing, and is totally ignored when turning IfaceSyn back into TyCons etc (in TcIface). For example, IfaceClosedSynFamilyTyCon stores a [IfaceAxBranch] that is used only for pretty-printing.
  • See Note [Free tyvars in IfaceType] in IfaceType

See #7730, #8776 for details