Opened 20 months ago
Last modified 7 months ago
#14828 new bug
panic! when using :print on some functions with class constraints?
Reported by:  jol  Owned by:  

Priority:  normal  Milestone:  
Component:  GHCi  Version:  8.2.2 
Keywords:  debugger  Cc:  
Operating System:  Linux  Architecture:  x86_64 (amd64) 
Type of failure:  Compiletime crash or panic  Test Case:  
Blocked By:  Blocking:  
Related Tickets:  Differential Rev(s):  
Wiki Page: 
Description
These are the problematic ones I've found:
> :t foldl foldl :: Foldable t => (b > a > b) > b > t a > b > :print foldl ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t1_a1H7[rt] :: TYPE t_a1H6[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug > :t fmap fmap :: Functor f => (a > b) > f a > f b > :print fmap ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t1_a1Hu[rt] :: TYPE t_a1Ht[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug > :t return return :: Monad m => a > m a > :print return ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t1_a1Wt[rt] :: TYPE t_a1Ws[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug > :t pure pure :: Applicative f => a > f a > :print pure ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t1_a1WP[rt] :: TYPE t_a1WO[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
These that don't have constraints are fine:
> :print id id = (_t1::a > a) > :print map map = (_t2::(a1 > b) > [a1] > [b]) > :print const const = (_t3::a2 > b1 > a2)
This value and function created in the session are fine:
> let x :: Monad m => m (); x = return () Prelude > :p x x = (_t5::Monad m1 => m1 ()) > let f :: Monad m => Int > m Int; f n = return (n + 1) Prelude > :p f f = (_t6::Monad m2 => Int > m2 Int)
mempty and mappend imported from Data.Monoid are fine:
> :m + Data.Monoid > :p mempty mempty = (_t7::Monoid a4 => a4) > :p mappend mappend = (_t8::Monoid a4 => a4 > a4 > a4)
foldl' and foldr imported from Data.List are not fine:
> :m + Data.List > :p foldl' ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t1_a6Qy[rt] :: TYPE t_a6Qx[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug > :p Data.List.foldr ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t2_a6RG[rt] :: TYPE t1_a6RF[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
but all
and init
from that same module are fine:
> :p Data.List.all all = (_t13::Foldable t1 => (a22 > Bool) > t1 a22 > Bool) > :p Data.List.init init = (_t14::[a29] > [a29])
So, in a given module, among functions with class constraints, some have the error and others don't. I haven't found a value that's not a function with the error, and I haven't found a function with no class constraints exhibit the error.
Change History (7)
comment:1 Changed 20 months ago by
Keywords:  debugger added 

comment:2 Changed 10 months ago by
comment:4 Changed 8 months ago by
I spent some time today digging into why exactly this panic happens. The immediate issue appears to be a hiccup in how the interactive debugger handles higherrank types, which is surprising, considering that none of the types in the original description appear to be higherrank. For the time being, just take my word for it that this is true—I'll return to this point later.
Here is an example showing that :print
chokes on a term with a higherrank type:
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/rgscott/.ghci λ> f :: (forall a. a > a) > b > b; f g x = g x λ> :print f ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t1_a1tY[rt] :: TYPE t_a1tX[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type
The fact that the panic mentions t1_a1tY
is a bit curious... I wonder what happens if we try an older version of GHC?
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/rgscott/.ghci λ> f :: (forall a. a > a) > b > b; f g x = g x λ> :print f f = (_t1::t1)
Ah, this doesn't panic on GHC 8.0, so this must be a regression introduced between 8.0 and 8.2. Moreover, note that even in 8.0, :print f
's behavior is strange: it prints out a thunk of type t1
instead of, say, (forall a. a > a) > b > b
. This must explain where the t1_a1tY
in the 8.2 panic comes from, since that is the type of _t1
(with its unique explicitly printed).
What changed between GHC 8.0 and 8.2 that would trigger this panic? As it turns out, it's commit e7985ed23ddc68b6a2e4af753578dc1d9e8ab4c9 (Update levity polymorphism
). Specifically, this change:

compiler/ghci/Debugger.hs
diff git a/compiler/ghci/Debugger.hs b/compiler/ghci/Debugger.hs index 64ac1540aa..4d7f8e3ef0 100644
a b import Var hiding ( varName ) 28 28 import VarSet 29 29 import UniqFM 30 30 import Type 31 import Kind32 31 import GHC 33 32 import Outputable 34 33 import PprTyThing … … pprintClosureCommand bindThings force str = do 78 77 term_ < GHC.obtainTermFromId maxBound force id' 79 78 term < tidyTermTyVars term_ 80 79 term' < if bindThings && 81 False == isUnliftedTypeKind (termType term)80 (not (isUnliftedType (termType term))) 82 81 then bindSuspensions term 83 82 else return term 84 83  Before leaving, we compare the type obtained to see if it's more specific
I'm not sure if this was Richard's intention, but this patch actually changes the behavior of :print
. Unlike isUnlifedTypeKind
, isUnliftedType
is a partial function. If isUnliftedType
cannot ascertain with 100% confidence that a type is unlifted, then it throws the isUnliftedType
panic we saw above. Evidently, GHC isn't 100% confident that t1_a1tY
is unlifted.
This proposes one possible patch. Instead of checking if not (isUnliftedType (termType term))
returns True
, we could check is isLiftedType_maybe (termType term)
returns Just True
. This "inverts" the check by querying if GHC is 100% certain that termType term
is lifted, and moreover, isLiftedType_maybe
won't panic if that isn't the case.
So why are functions like fmap
, which appear not to be higherrank, triggering this panic? ddumprtti
reveals the answer:
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/rgscott/.ghci λ> :set ddumprtti λ> :print fmap Term reconstruction started with initial type forall (f :: * > *). GHC.Base.Functor f => forall a b. (a > b) > f a > f b Unknown closure: Fun check2 passed add constraint: t1_a1sK[tau:1] = GHC.Base.Functor f0_a1sI[tau:1] => forall a b. (a > b) > f0_a1sI[tau:1] a > f0_a1sI[tau:1] b Term reconstruction completed. Term obtained: _ Type obtained: t1_a1sK[rt] ghc: panic! (the 'impossible' happened) (GHC version 8.2.2 for x86_64unknownlinux): isUnliftedType t1_a1sK[rt] :: TYPE t_a1sJ[rt] Call stack: CallStack (from HasCallStack): prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable pprPanic, called at compiler/types/Type.hs:1952:10 in ghc:Type
In particular, take special notice of these parts:
Term reconstruction started with initial type forall (f :: * > *). GHC.Base.Functor f => forall a b. (a > b) > f a > f b
add constraint: t1_a1sK[tau:1] = GHC.Base.Functor f0_a1sI[tau:1] => forall a b. (a > b) > f0_a1sI[tau:1] a > f0_a1sI[tau:1] b
:print
starts with the type forall f. Functor f => forall a b. (a > b) > f a > f b
which, strictly speaking, is higherrank, as there is a nested use of forall a b
. Normally, we don't think of forall
s to the right of =>
as higherrank, since we can "float" them out to the front of the type, but :print
doesn't appear to be doing this, since the add constraint
logging message says that t1_a1sK
is equal to Functor f0 => forall a b. (a > b) > f0 a > f0 b
, where f0
is a metavariable. Note that :print
seems to have instantiated f
with a metavariable, but not a
or b
! If :print
had done that, then t1_a1sK
would not be higherrank at all, avoiding this panic in the first place.
Of course, even if we did this smarter metavariable instantiation, the problem of higherrank types crashing :print
would still linger. This suggests that we should fix the isUnliftedType
panic first, and then we can worry about future steps like making the type of fmap
render correctly with :print
.
Note this is still an issue in 8.6.2