diff options
Diffstat (limited to 'compiler/main/PprTyThing.hs')
-rw-r--r-- | compiler/main/PprTyThing.hs | 85 |
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 -} |