1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
-----------------------------------------------------------------------------
--
-- Pretty-printing TyThings
--
-- (c) The GHC Team 2005
--
-----------------------------------------------------------------------------
{-# LANGUAGE CPP #-}
module PprTyThing (
pprTyThing,
pprTyThingInContext,
pprTyThingLoc,
pprTyThingInContextLoc,
pprTyThingHdr,
pprTypeForUser,
pprFamInst
) where
#include "HsVersions.h"
import GhcPrelude
import Type ( Type, ArgFlag(..), TyThing(..), mkTyVarBinders, tidyOpenType )
import IfaceSyn ( ShowSub(..), ShowHowMuch(..), AltPpr(..)
, showToHeader, pprIfaceDecl )
import CoAxiom ( coAxiomTyCon )
import HscTypes( tyThingParent_maybe )
import MkIface ( tyThingToIfaceDecl )
import FamInstEnv( FamInst(..), FamFlavor(..) )
import TyCoPpr ( pprUserForAll, pprTypeApp, pprSigmaType )
import Name
import VarEnv( emptyTidyEnv )
import Outputable
-- -----------------------------------------------------------------------------
-- Pretty-printing entities that we get from the GHC API
{- 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
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 -}
--------------------
-- | Pretty-prints a 'FamInst' (type/data family instance) with its defining location.
pprFamInst :: FamInst -> SDoc
-- * For data instances we go via pprTyThing of the representational TyCon,
-- because there is already much cleverness associated with printing
-- data type declarations that I don't want to duplicate
-- * For type instances we print directly here; there is no TyCon
-- to give to pprTyThing
--
-- FamInstEnv.pprFamInst does a more quick-and-dirty job for internal purposes
pprFamInst (FamInst { fi_flavor = DataFamilyInst rep_tc })
= pprTyThingInContextLoc (ATyCon rep_tc)
pprFamInst (FamInst { fi_flavor = SynFamilyInst, fi_axiom = axiom
, fi_tvs = tvs, fi_tys = lhs_tys, fi_rhs = rhs })
= showWithLoc (pprDefinedAt (getName axiom)) $
hang (text "type instance"
<+> pprUserForAll (mkTyVarBinders Specified tvs)
-- See Note [Printing foralls in type family instances]
-- in IfaceType
<+> pprTypeApp (coAxiomTyCon axiom) lhs_tys)
2 (equals <+> ppr rhs)
----------------------------
-- | Pretty-prints a 'TyThing' with its defining location.
pprTyThingLoc :: TyThing -> SDoc
pprTyThingLoc tyThing
= showWithLoc (pprDefinedAt (getName tyThing))
(pprTyThing showToHeader tyThing)
-- | Pretty-prints the 'TyThing' header. For functions and data constructors
-- the function is equivalent to 'pprTyThing' but for type constructors
-- and classes it prints only the header part of the declaration.
pprTyThingHdr :: TyThing -> SDoc
pprTyThingHdr = pprTyThing showToHeader
-- | Pretty-prints a 'TyThing' in context: that is, if the entity
-- is a data constructor, record selector, or class method, then
-- the entity's parent declaration is pretty-printed with irrelevant
-- parts omitted.
pprTyThingInContext :: ShowSub -> TyThing -> SDoc
pprTyThingInContext show_sub thing
= go [] thing
where
go ss thing
= case tyThingParent_maybe thing of
Just parent ->
go (getOccName thing : ss) parent
Nothing ->
pprTyThing
(show_sub { ss_how_much = ShowSome ss (AltPpr Nothing) })
thing
-- | Like 'pprTyThingInContext', but adds the defining location.
pprTyThingInContextLoc :: TyThing -> SDoc
pprTyThingInContextLoc tyThing
= showWithLoc (pprDefinedAt (getName tyThing))
(pprTyThingInContext showToHeader tyThing)
-- | Pretty-prints a 'TyThing'.
pprTyThing :: ShowSub -> TyThing -> SDoc
-- We pretty-print 'TyThing' via 'IfaceDecl'
-- See Note [Pretty-printing TyThings]
pprTyThing ss ty_thing
= pprIfaceDecl ss' (tyThingToIfaceDecl ty_thing)
where
ss' = case ss_how_much ss of
ShowHeader (AltPpr Nothing) -> ss { ss_how_much = ShowHeader ppr' }
ShowSome xs (AltPpr Nothing) -> ss { ss_how_much = ShowSome xs ppr' }
_ -> ss
ppr' = AltPpr $ ppr_bndr $ getName ty_thing
ppr_bndr :: Name -> Maybe (OccName -> SDoc)
ppr_bndr name
| isBuiltInSyntax name
= Nothing
| otherwise
= case nameModule_maybe name of
Just mod -> Just $ \occ -> getPprStyle $ \sty ->
pprModulePrefix sty mod occ <> ppr occ
Nothing -> WARN( True, ppr name ) Nothing
-- Nothing is unexpected here; TyThings have External names
pprTypeForUser :: Type -> SDoc
-- The type is tidied
pprTypeForUser ty
= pprSigmaType tidy_ty
where
(_, tidy_ty) = tidyOpenType emptyTidyEnv ty
-- Often the types/kinds we print in ghci are fully generalised
-- and have no free variables, but it turns out that we sometimes
-- print un-generalised kinds (eg when doing :k T), so it's
-- better to use tidyOpenType here
showWithLoc :: SDoc -> SDoc -> SDoc
showWithLoc loc doc
= hang doc 2 (char '\t' <> comment <+> loc)
-- The tab tries to make them line up a bit
where
comment = text "--"
|