summaryrefslogtreecommitdiff
path: root/compiler/main/PprTyThing.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/main/PprTyThing.hs')
-rw-r--r--compiler/main/PprTyThing.hs85
1 files changed, 58 insertions, 27 deletions
diff --git a/compiler/main/PprTyThing.hs b/compiler/main/PprTyThing.hs
index 86098a5e7f..b0a72cf499 100644
--- a/compiler/main/PprTyThing.hs
+++ b/compiler/main/PprTyThing.hs
@@ -19,6 +19,8 @@ module PprTyThing (
#include "HsVersions.h"
+import GhcPrelude
+
import Type ( TyThing(..) )
import IfaceSyn ( ShowSub(..), ShowHowMuch(..), AltPpr(..)
, showToHeader, pprIfaceDecl )
@@ -35,39 +37,68 @@ import Outputable
-- -----------------------------------------------------------------------------
-- Pretty-printing entities that we get from the GHC API
-{- Note [Pretty-printing TyThings]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We pretty-print a TyThing by converting it to an IfaceDecl,
-and pretty-printing that (see ppr_ty_thing below).
-Here is why:
+{- Note [Pretty printing via IfaceSyn]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+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
-* When pretty-printing (a type, say), the idiomatic solution is not to
- "rename type variables on the fly", but rather to "tidy" the type
- (which gives each variable a distinct print-name), and then
- pretty-print it (without renaming). Separate the two
- concerns. Functions like tidyType do this.
+Why do this?
-* Alas, for type constructors, TyCon, tidying does not work well,
+* 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.
-* One alternative would be 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.
-
-* One place the non-pretty names can show up is in GHCi. But another
- is in interface files. Look at MkIface.tyThingToIfaceDecl which
- converts a TyThing (i.e. TyCon, Class etc) to an IfaceDecl. And it
- already does tidying as part of that conversion! Why? Because
- interface files contains fast-strings, not uniques, so the names
- must at least be distinct.
-
-So if we convert to IfaceDecl, we get a nice tidy IfaceDecl, and can
-print that. Of course, that means that pretty-printing IfaceDecls
-must be careful to display nice user-friendly results, but that's ok.
+* 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 -}