[GHC] #14231: Core lint error "in result of Static argument"

GHC ghc-devs at haskell.org
Tue Jul 10 09:13:23 UTC 2018


#14231: Core lint error "in result of Static argument"
-------------------------------------+-------------------------------------
        Reporter:  mpickering        |                Owner:  (none)
            Type:  bug               |               Status:  patch
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.5
      Resolution:                    |             Keywords:
                                     |  StaticArgumentTransformation
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D4945
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Crumbs -- code in `SAT.hs` is extremely impenetrable.  But it is mainly
 doing the right thing; the "weird cloning" is nearly right.

 Here's an example
 {{{
    f :: forall a b. (a,b) -> b -> Int
    f = /\a b. \(x:(a,b)) (y:b). <body>
 where
    <body> is an expression
        mentioning a, b, x, y
        and with recursive calls like (f <ty> b <e> y)
            where presumably <e> :: (<ty>,b)

 Here the second type argument `b`, and the second value argument `y::b`,
 are static.  The first type arg `a` and value arg `x::(a,b)` are dynamic.
 The body of `f` may mention any or all of `a`, `b`, `x`, `y`.

 We want to generate this:
 {{{
    f :: forall a b. (a,b) -> b -> Int
    f = /\a b. \(x:(a,b)) (y:b).
        letrec fwrk = /\a \(x:(a,b).
                         REPLACE (f <ty> b <e> y) WITH (fwrk <ty> <e>)
                         IN  <body>
        in fwrk a x
 }}}
 Here `fwrk` is the local, recursive worker, which has free variables `b`'
 and `y::b`.
 Notice that the binders of `fwrk`, namely `a` and `x::(a,b)` must be
 identical (same
 unique) as the originals, because they are mentioned in `<body>`.

 What is this "REPLACE" business?  We want to replace a recusive call to
 `f` with
 a call to `fwrk`.  The easy way to do this is with a non-recursive let,
 later inlined:
 {{{
     f = /\a b \(x::(a,b) (y::b). fwrk a x
 }}}
 We must use the ''same'' unique for `f`: we are deliberately shadowing its
 outer binding.
 Contrary to the claims in `Note [Binder type capture]` I don't think it
 matters
 whether or not we clone the lambda binders; we are free to alpha-rename
 the lambda as
 we please, including re-using existing binders.

 So the bugs seem to be:

 * In `bindWith` (comment:8) we are abstracting over the type variable,
 ''but it is static''. This is the real source of the problem.  In my
 example above, note that `b` was static but `a` was not.

 * Once we fix this we don't need to clone those binders at all; `Note
 [Binder type capture]` is moot.

 I also commented on a bug in the Phab.

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


More information about the ghc-tickets mailing list