summaryrefslogtreecommitdiff
path: root/compiler/GHC/Utils/Outputable.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Utils/Outputable.hs')
-rw-r--r--compiler/GHC/Utils/Outputable.hs49
1 files changed, 34 insertions, 15 deletions
diff --git a/compiler/GHC/Utils/Outputable.hs b/compiler/GHC/Utils/Outputable.hs
index b4a21a314e..6bd48605d9 100644
--- a/compiler/GHC/Utils/Outputable.hs
+++ b/compiler/GHC/Utils/Outputable.hs
@@ -126,6 +126,7 @@ import GHC.Data.FastString
import qualified GHC.Utils.Ppr as Pretty
import qualified GHC.Utils.Ppr.Colour as Col
import GHC.Utils.Ppr ( Doc, Mode(..) )
+import GHC.Utils.Panic.Plain (assert)
import GHC.Serialized
import GHC.LanguageExtensions (Extension)
import GHC.Utils.GlobalVars( unsafeHasPprDebug )
@@ -855,9 +856,10 @@ ppWhenOption f doc = sdocOption f $ \case
False -> empty
{-# INLINE CONLIKE ppUnlessOption #-}
-ppUnlessOption :: IsLine doc => (SDocContext -> Bool) -> doc -> doc
-ppUnlessOption f doc = docWithContext $
- \ctx -> if f ctx then empty else doc
+ppUnlessOption :: (SDocContext -> Bool) -> SDoc -> SDoc
+ppUnlessOption f doc = sdocOption f $ \case
+ True -> empty
+ False -> doc
-- | Apply the given colour\/style for the argument.
--
@@ -1040,10 +1042,7 @@ instance Outputable ModuleName where
pprModuleName :: IsLine doc => ModuleName -> doc
pprModuleName (ModuleName nm) =
- docWithContext $ \ctx ->
- if codeStyle (sdocStyle ctx)
- then ztext (zEncodeFS nm)
- else ftext nm
+ docWithStyle (ztext (zEncodeFS nm)) (\_ -> ftext nm)
{-# SPECIALIZE pprModuleName :: ModuleName -> SDoc #-}
{-# SPECIALIZE pprModuleName :: ModuleName -> HLine #-} -- see Note [SPECIALIZE to HDoc]
@@ -1633,6 +1632,7 @@ IsOutput, that allows these combinators to be generic over both variants:
class IsOutput doc where
empty :: doc
docWithContext :: (SDocContext -> doc) -> doc
+ docWithStyle :: doc -> (PprStyle -> SDoc) -> doc
class IsOutput doc => IsLine doc
class (IsOutput doc, IsLine (Line doc)) => IsDoc doc
@@ -1669,13 +1669,22 @@ arguments depending on the type they are instantiated at. They serve as a
difficult to make completely equivalent under both printer implementations.
These operations should generally be avoided, as they can result in surprising
-changes in behavior when the printer implementation is changed. However, in
-certain cases, the alternative is even worse. For example, we use dualLine in
-the implementation of pprUnitId, as the hack we use for printing unit ids
-(see Note [Pretty-printing UnitId] in GHC.Unit) is difficult to adapt to HLine
-and is not necessary for code paths that use it, anyway.
-
-Use these operations wisely. -}
+changes in behavior when the printer implementation is changed.
+Right now, they are used only when outputting debugging comments in
+codegen, as it is difficult to adapt that code to use HLine and not necessary.
+
+Use these operations wisely.
+
+Note [docWithStyle]
+~~~~~~~~~~~~~~~~~~~
+Sometimes when printing, we consult the printing style. This can be done
+with 'docWithStyle c f'. This is similar to 'docWithContext (f . sdocStyle)',
+but:
+* For code style, 'docWithStyle c f' will return 'c'.
+* For other styles, 'docWithStyle c f', will call 'f style', but expect
+ an SDoc rather than doc. This removes the need to write code polymorphic
+ in SDoc and HDoc, since the latter is used only for code style.
+-}
-- | Represents a single line of output that can be efficiently printed directly
-- to a 'System.IO.Handle' (actually a 'BufHandle').
@@ -1700,7 +1709,7 @@ pattern HDoc f <- HDoc' f
{-# COMPLETE HDoc #-}
bPutHDoc :: BufHandle -> SDocContext -> HDoc -> IO ()
-bPutHDoc h ctx (HDoc f) = f ctx h
+bPutHDoc h ctx (HDoc f) = assert (codeStyle (sdocStyle ctx)) (f ctx h)
-- | A superclass for 'IsLine' and 'IsDoc' that provides an identity, 'empty',
-- as well as access to the shared 'SDocContext'.
@@ -1709,6 +1718,7 @@ bPutHDoc h ctx (HDoc f) = f ctx h
class IsOutput doc where
empty :: doc
docWithContext :: (SDocContext -> doc) -> doc
+ docWithStyle :: doc -> (PprStyle -> SDoc) -> doc -- see Note [docWithStyle]
-- | A class of types that represent a single logical line of text, with support
-- for horizontal composition.
@@ -1779,6 +1789,11 @@ instance IsOutput SDoc where
{-# INLINE CONLIKE empty #-}
docWithContext = sdocWithContext
{-# INLINE docWithContext #-}
+ docWithStyle c f = sdocWithContext (\ctx -> let sty = sdocStyle ctx
+ in if codeStyle sty then c
+ else f sty)
+ -- see Note [docWithStyle]
+ {-# INLINE CONLIKE docWithStyle #-}
instance IsLine SDoc where
char c = docToSDoc $ Pretty.char c
@@ -1823,12 +1838,16 @@ instance IsOutput HLine where
{-# INLINE empty #-}
docWithContext f = HLine $ \ctx h -> runHLine (f ctx) ctx h
{-# INLINE CONLIKE docWithContext #-}
+ docWithStyle c _ = HLine $ \ctx h -> assert (codeStyle (sdocStyle ctx)) (runHLine c ctx h) -- see Note [docWithStyle]
+ {-# INLINE CONLIKE docWithStyle #-}
instance IsOutput HDoc where
empty = HDoc (\_ _ -> pure ())
{-# INLINE empty #-}
docWithContext f = HDoc $ \ctx h -> runHDoc (f ctx) ctx h
{-# INLINE CONLIKE docWithContext #-}
+ docWithStyle c _ = HDoc $ \ctx h -> assert (codeStyle (sdocStyle ctx)) (runHDoc c ctx h) -- see Note [docWithStyle]
+ {-# INLINE CONLIKE docWithStyle #-}
instance IsLine HLine where
char c = HLine (\_ h -> bPutChar h c)