[GHC] #13594: Typechecker behavior w.r.t. BangPatterns and nested foralls has changed in 8.2

GHC ghc-devs at haskell.org
Thu Apr 20 09:41:17 UTC 2017


#13594: Typechecker behavior w.r.t. BangPatterns and nested foralls has changed in
8.2
-------------------------------------+-------------------------------------
        Reporter:  RyanGlScott       |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler (Type    |              Version:  8.2.1-rc2
  checker)                           |
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  GHC rejects       |  Unknown/Multiple
  valid program                      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Gah!

 GHC has two sorts of bindings: `FunBind` and `PatBind`:

 * `FunBind` is used for function bindings, obviously, but also for
 bindings of form `x = e`.  As the comments in `HsBinds.hs` say:
 {{{
     -- FunBind is used for both functions     @f x = e@
     -- and variables                          @f = \x -> e@
     --
     -- Reason 1: Special case for type inference: see
 'TcBinds.tcMonoBinds'.
     --
     -- Reason 2: Instance decls can only have FunBinds, which is
 convenient.
     --           If you change this, you'll need to change e.g.
 rnMethodBinds
 }}}

 * `PatBind` is used for all other pattern bindings

 So `!x = e` is treated as a `PatBind`.  And that means that it will take
 the `InferGen` patch (see `TcBinds.decideGeneralisationPlan`); and that
 means that it will behave differently type-inference-wise than `x = e; x
 :: sig`.  And that is bad: bangs aren't supposed to affect typing.

 Best solution (I think): add a bang-flag to `FunRhs` (c.f. the
 `LexicalFixity` flag) in `HsExpr.HsMatchContext`.  Then

 * `!x = e` would be a "simple" pattern binding
 * `FunBind` would handle all simple pattern bindings (as well as true
 function binding)

 NB:  `(x) = e` would not be a "simple" pattern binding, and would still go
 via `PatBind`.  Maybe that's even a feature.

 We could instead put the flag in `FunBind` itself, but I'm influenced by
 that `LexicalFixity` flag, which Alan migraed from `FunBind` to the
 `HsMatchContext` place (I forget why).

 I'm too swamped work on this, but I'll happily offer guidance.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13594#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list