Fix #14875 by introducing PprPrec, and using it
authorRyan Scott <ryan.gl.scott@gmail.com>
Sun, 13 May 2018 22:36:23 +0000 (18:36 -0400)
committerBen Gamari <ben@smart-cactus.org>
Mon, 14 May 2018 02:22:43 +0000 (22:22 -0400)
commit21e1a00c0ccf3072ccc04cd1acfc541c141189d2
tree6730896263197984b0466c22b84ab007401d775a
parentbf6cad8b86ee34ed5aa5fa0e295304b51f2a2324
Fix #14875 by introducing PprPrec, and using it

Trying to determine when to insert parentheses during TH
conversion is a bit of a mess. There is an assortment of functions
that try to detect this, such as:

* `hsExprNeedsParens`
* `isCompoundHsType`
* `hsPatNeedsParens`
* `isCompoundPat`
* etc.

To make things worse, each of them have slightly different semantics.
Plus, they don't work well in the presence of explicit type
signatures, as #14875 demonstrates.

All of these problems can be alleviated with the use of an explicit
precedence argument (much like what `showsPrec` currently does). To
accomplish this, I introduce a new `PprPrec` data type, and define
standard predences for things like function application, infix
operators, function arrows, and explicit type signatures (that last
one is new). I then added `PprPrec` arguments to the various
`-NeedsParens` functions, and use them to make smarter decisions
about when things need to be parenthesized.

A nice side effect is that functions like `isCompoundHsType` are
now completely unneeded, since they're simply aliases for
`hsTypeNeedsParens appPrec`. As a result, I did a bit of refactoring
to remove these sorts of functions. I also did a pass over various
utility functions in GHC for constructing AST forms and used more
appropriate precedences where convenient.

Along the way, I also ripped out the existing `TyPrec`
data type (which was tailor-made for pretty-printing `Type`s) and
replaced it with `PprPrec` for consistency.

Test Plan: make test TEST=T14875

Reviewers: alanz, goldfire, bgamari

Reviewed By: bgamari

Subscribers: rwbarton, thomie, carter

GHC Trac Issues: #14875

Differential Revision: https://phabricator.haskell.org/D4688
18 files changed:
compiler/basicTypes/BasicTypes.hs
compiler/hsSyn/Convert.hs
compiler/hsSyn/HsDecls.hs
compiler/hsSyn/HsExpr.hs
compiler/hsSyn/HsLit.hs
compiler/hsSyn/HsPat.hs
compiler/hsSyn/HsTypes.hs
compiler/hsSyn/HsUtils.hs
compiler/iface/IfaceSyn.hs
compiler/iface/IfaceType.hs
compiler/typecheck/TcGenDeriv.hs
compiler/types/TyCoRep.hs
compiler/types/Type.hs
libraries/template-haskell/Language/Haskell/TH/Ppr.hs
testsuite/tests/deriving/should_compile/T14682.stderr
testsuite/tests/th/T14875.hs [new file with mode: 0644]
testsuite/tests/th/T14875.stderr [new file with mode: 0644]
testsuite/tests/th/all.T