Opened 6 months ago

Last modified 6 months ago

#15598 new bug

RebindableSyntax with RankNTypes and type class method call yields panic.

Reported by: romanb Owned by:
Priority: normal Milestone:
Component: Compiler Version: 8.4.3
Keywords: RebindableSyntax, RankNTypes Cc:
Operating System: Linux Architecture: Unknown/Multiple
Type of failure: Compile-time crash or panic Test Case:
Blocked By: Blocking:
Related Tickets: 14963 Differential Rev(s):
Wiki Page:

Description (last modified by romanb)

The following program in a file ghc-panic.hs

{-# LANGUAGE
    GADTSyntax
  , RankNTypes
  , RebindableSyntax
#-}

import Prelude hiding ((>>=))

data InfDo where
    InfDo :: String -> (forall a. a -> InfDo) -> InfDo

prog :: InfDo
prog = do
    _ <- show (42 :: Int)
    prog
  where
    (>>=) = InfDo

main :: IO ()
main = let x = prog in x `seq` return ()

when loaded into GHCi yields

λ> main
ghc: panic! (the 'impossible' happened)
  (GHC version 8.4.3 for x86_64-unknown-linux):
	nameModule
  system $dShow_abfY
  Call stack:
      CallStack (from HasCallStack):
        callStackDoc, called at compiler/utils/Outputable.hs:1150:37 in ghc:Outputable
        pprPanic, called at compiler/basicTypes/Name.hs:241:3 in ghc:Name

and separate compilation yields

$ ghc ghc-panic.hs 
[1 of 1] Compiling Main             ( ghc-panic.hs, ghc-panic.o )
ghc: panic! (the 'impossible' happened)
  (GHC version 8.4.3 for x86_64-unknown-linux):
	StgCmmEnv: variable not found
  $dShow_a1qI
  local binds for:
  $tcInfDo
  $trModule
  $tcInfDo1_r1th
  $tcInfDo2_r1tH
  $trModule1_r1tI
  $trModule2_r1tJ
  $trModule3_r1tK
  $trModule4_r1tL
  sat_s1E4
  Call stack:
      CallStack (from HasCallStack):
        callStackDoc, called at compiler/utils/Outputable.hs:1150:37 in ghc:Outputable
        pprPanic, called at compiler/codeGen/StgCmmEnv.hs:149:9 in ghc:StgCmmEnv

The problem disappears when either the rank-2 type is removed from InfDo or when the call to show is replaced by a static string.

Besides 8.4.3, also reproduced with 8.6.0.20180714.

I believe it is somewhat related to https://ghc.haskell.org/trac/ghc/ticket/14963

Change History (4)

comment:1 Changed 6 months ago by romanb

Description: modified (diff)

comment:2 Changed 6 months ago by romanb

comment:3 Changed 6 months ago by romanb

Description: modified (diff)

comment:4 Changed 6 months ago by simonpj

I think you are right in connecting it with #14963. But your example here is nothing to do with GHCi, nor with -fdefer-type-errors, so it's helpful.

Lint complains immediately

*** Core Lint errors : in result of Desugar (before optimization) ***
<no location info>: warning:
    In the expression: show @ Int $dShow_a1rx (I# 42#)
    $dShow_a1rx :: Show Int
    [LclId] is out of scope
*** Offending Program ***
Rec {
$dMonad_a1rX :: Monad IO
[LclId]
$dMonad_a1rX = $fMonadIO

$tcInfDo :: TyCon
[LclIdX]
$tcInfDo
  = TyCon
      14827517540190131426##
      17869035366104385648##
      $trModule
      (TrNameS "InfDo"#)
      0#
      krep$*

$trModule :: Module
[LclIdX]
$trModule = Module (TrNameS "main"#) (TrNameS "T15598"#)

prog :: InfDo
[LclIdX]
prog
  = letrec {
      >>=_aW0 :: String -> (forall a. a -> InfDo) -> InfDo
      [LclId]
      >>=_aW0
        = letrec {
            >>=_a1ri :: String -> (forall a. a -> InfDo) -> InfDo
            [LclId]
            >>=_a1ri = InfDo; } in
          >>=_a1ri; } in
    >>=_aW0
      (show @ Int $dShow_a1rx (I# 42#))
      (\ (@ a_a1rp) ->
         let {
           $dShow_a1rx :: Show Int
           [LclId]
           $dShow_a1rx = $fShowInt } in
         \ (ds_d1De :: a_a1rp) -> prog)

main :: IO ()
[LclIdX]
main
  = letrec {
      x_a1ca :: InfDo
      [LclId]
      x_a1ca
        = letrec {
            x_a1rI :: InfDo
            [LclId]
            x_a1rI = prog; } in
          x_a1rI; } in
    case x_a1ca of x_a1ca { __DEFAULT ->
    return @ IO $dMonad_a1rX @ () ()
    }
end Rec }

*** End of Offense ***

This is pretty bad. It's all in tcSyntaxOp, I believe.

Note: See TracTickets for help on using tickets.