
#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