
#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