[GHC] #13233: typePrimRep panic while compiling GHC with profiling
GHC
ghc-devs at haskell.org
Sun Apr 23 17:20:21 UTC 2017
#13233: typePrimRep panic while compiling GHC with profiling
-------------------------------------+-------------------------------------
Reporter: bgamari | Owner: goldfire
Type: bug | Status: new
Priority: highest | Milestone: 8.2.1
Component: Compiler | Version: 8.0.1
Resolution: | Keywords:
| LevityPolymorphism
Operating System: Unknown/Multiple | Architecture:
Type of failure: Compile-time | Unknown/Multiple
crash or panic | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by goldfire):
tl;dr: Implementing this efficiently is non-obvious. But I think I found a
way in the process of writing this comment.
So I finally sat down this morning to fix this. But I can't think of a way
to do so reasonably efficiently.
The challenge is:
Figure out when an Id which `hasNoBinding` is used with levity
polymorphic arguments.
The problem is that, in both the zonker and the desugarer (really, the
only places to detect levity polymorphism problems), by the time we're
looking at an Id, it's too late. We've lost all the context, including any
type arguments (that is, `HsWrapper`s) that will instantiate the Id's
levity polymorphic polytype. We could do the usual thing and accumulate
arguments as we descend, but that seems fragile within the complexity of
`HsSyn`, needing to deal with `HsWrap`, sections, and other horrors. We
could check the desugared expression, but when? And how to do so without
unwrapping all the `App`s that have accumulated? To solve that last
question, we could add an extra return value to `dsExpr` stating when
we're desugaring an applied `hasNoBinding` Id... but it's still unclear
when to run the check.
My most promising idea was to check whenever desugaring an `HsWrap`,
figuring that a use of a polymorphic `hasNoBinding` Id would always be
directly within an `HsWrap`. If we cleverly use composition to avoid
`HsWrap foo (HsWrap bar ...)`, we can quickly detect when an `HsWrap`
surrounds a `hasNoBinding` Id -- but only if the typechecker always puts
such an Id in an `HsWrap`. Alas, since we have the lazy instantiation of
`TypeApplications`, that's no longer true. If a polymorphic `hasNoBinding`
Id is used as the argument to a higher-rank function, it's possible there
will be no `HsWrap`. And insisting on instantiating `hasNoBinding` Ids
right away means that these will no longer be usable with
`TypeApplications`, which would be a shame.
Perhaps a small tweak on the above idea will work: `dsExpr` gets an
additional parameter saying whether or not the expr being desugared is
immediately wrapped in an `HsWrap`. If we find a `HsVar` with a levity-
polymorphic `hasNoBinding` Id inside and we're ''not'' in an `HsWrap`,
issue an error. Additionally, every time we desugar an `HsWrap`, check if
it's immediately wrapping a `hasNoBinding` id; if so, so the levity
polymorphism check, using the type of the desugared expression to do the
check. This might just work. It's heavier than I'd like, but not
unreasonably so.
I like it enough to implement. Thanks for listening. :)
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13233#comment:31>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list