I've compiled GHC from HEAD this morning, and it once again broke my OpenGL 
binding. After boiling down the example (see attached Foo.hs), it seems that 
either Storable itself, constant folding or the strictness analysis is buggy:

   [EMAIL PROTECTED]:~> ./Foo
   *** main 1
   *** main 2
   Foo: Prelude.undefined

I suspect that the "undefined" is the one in the default instance of 
peekElemOff, but that is just guessing. GHC even goes so far to optimize away 
the last putStrLn (see Foo.simpl). :-(

Cheers,
   S.
import Foreign

-- Strangely enough, this works if newtype is used...
data Elem a = Elem a

instance Storable a => Storable (Elem a) where
   sizeOf ~(Elem r) = 3 * sizeOf r
   alignment ~(Elem r) = alignment r
   peek ptr = do r <- peekElemOff (castPtr ptr) 0; return (Elem r)
   poke ptr (Elem r) = poke (castPtr ptr) r

main :: IO ()
main = do
   putStrLn "*** main 1"
   allocaBytes 100 $ \buf -> do
      poke buf (Elem 12345)
      putStrLn "*** main 2"
      Elem x <- peekElemOff buf 0
      print (x :: Int)
      putStrLn "*** main 3"
==================== Tidy Core ====================
Main.lvl :: [GHC.Base.Char]
[GlobalId]
[]
Main.lvl = GHC.Base.unpackCString# "*** main 2"

Main.lvl1 :: [GHC.Base.Char]
[GlobalId]
[]
Main.lvl1 = GHC.Base.unpackCString# "*** main 1"

Main.a :: GHC.Prim.State# GHC.Prim.RealWorld
          -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
[GlobalId]
[Arity 1
 Str: DmdType L]
Main.a =
  \ (eta_aJN :: GHC.Prim.State# GHC.Prim.RealWorld) ->
    case ((GHC.IO.hPutStr GHC.Handle.stdout Main.lvl1)
          `cast` ((GHC.IOBase.:CoIO) ()
                  :: GHC.IOBase.IO ()
                       :=:
                     GHC.Prim.State# GHC.Prim.RealWorld
                     -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)))
           eta_aJN
    of wild_aFw { (# new_s_aFy, a98_aFz #) ->
    case GHC.IO.$whPutChar GHC.Handle.stdout '\n' new_s_aFy
    of wild1_aID { (# new_s1_aIF, a981_aIG #) ->
    case GHC.Prim.newPinnedByteArray# @ GHC.Prim.RealWorld 100 new_s1_aIF
    of wild2_aSC { (# s_aSE, mbarr#_aSF #) ->
    case GHC.Prim.unsafeFreezeByteArray# @ GHC.Prim.RealWorld mbarr#_aSF s_aSE
    of wild11_aSH { (# s1_aSJ, barr#_aSK #) ->
    case GHC.Prim.writeIntOffAddr#
           @ GHC.Prim.RealWorld (GHC.Prim.byteArrayContents# barr#_aSK) 0 12345 
s1_aSJ
    of s2_aJd { __DEFAULT ->
    case ((GHC.IO.hPutStr GHC.Handle.stdout Main.lvl)
          `cast` ((GHC.IOBase.:CoIO) ()
                  :: GHC.IOBase.IO ()
                       :=:
                     GHC.Prim.State# GHC.Prim.RealWorld
                     -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)))
           s2_aJd
    of wild3_XGu { (# new_s2_XGx, a982_XGz #) ->
    case GHC.IO.$whPutChar GHC.Handle.stdout '\n' new_s2_XGx
    of wild4_XKC { (# new_s3_XKF, a983_XKH #) ->
    GHC.Err.undefined
    `cast` (CoUnsafe (forall a_az9. a_az9)
                     (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
            :: forall a_az9. a_az9 :=: (# GHC.Prim.State# GHC.Prim.RealWorld, 
() #))
    }
    }
    }
    }
    }
    }
    }

Main.poke :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int)
             -> Main.Elem GHC.Base.Int
             -> GHC.IOBase.IO ()
[GlobalId]
[Arity 3
 NoCafRefs
 Str: DmdType U(L)U(U(L))L]
Main.poke =
  \ (ptr_abO :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int))
    (ds_dxP :: Main.Elem GHC.Base.Int) ->
    (\ (eta_sJg :: GHC.Prim.State# GHC.Prim.RealWorld) ->
       case ds_dxP of wild_B1 { Main.Elem r_abP ->
       case ptr_abO of wild1_ay0 { GHC.Ptr.Ptr addr_ay2 ->
       case r_abP of wild2_aJ9 { GHC.Base.I# x_aJb ->
       case GHC.Prim.writeIntOffAddr# @ GHC.Prim.RealWorld addr_ay2 0 x_aJb 
eta_sJg
       of s2_aJd { __DEFAULT ->
       (# s2_aJd, GHC.Base.() #)
       }
       }
       }
       })
    `cast` (sym ((GHC.IOBase.:CoIO) ())
            :: GHC.Prim.State# GHC.Prim.RealWorld
               -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
                 :=:
               GHC.IOBase.IO ())

Main.peek :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int)
             -> GHC.IOBase.IO (Main.Elem GHC.Base.Int)
[GlobalId]
[Arity 2
 NoCafRefs
 Str: DmdType U(L)L]
Main.peek =
  \ (ptr_abK :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int)) ->
    (\ (s_aIC :: GHC.Prim.State# GHC.Prim.RealWorld) ->
       case ptr_abK of wild_ay0 { GHC.Ptr.Ptr addr_ay2 ->
       case GHC.Prim.readIntOffAddr# @ GHC.Prim.RealWorld addr_ay2 0 s_aIC
       of wild2_aIT { (# s2_aIV, x_aIW #) ->
       (# s2_aIV, (Main.Elem @ GHC.Base.Int (GHC.Base.I# x_aIW)) #)
       }
       })
    `cast` (sym ((GHC.IOBase.:CoIO) (Main.Elem GHC.Base.Int))
            :: GHC.Prim.State# GHC.Prim.RealWorld
               -> (# GHC.Prim.State# GHC.Prim.RealWorld, Main.Elem GHC.Base.Int 
#)
                 :=:
               GHC.IOBase.IO (Main.Elem GHC.Base.Int))

Main.alignment :: Main.Elem GHC.Base.Int -> GHC.Base.Int
[GlobalId]
[Arity 1
 NoCafRefs
 Str: DmdType U(A)m]
Main.alignment =
  \ (ds_dxK :: Main.Elem GHC.Base.Int) ->
    case ds_dxK of wild_B1 { Main.Elem r_abI -> Foreign.Storable.lvl }

Main.lvl2 :: GHC.Base.Int
[GlobalId]
[NoCafRefs]
Main.lvl2 = GHC.Base.I# 24

Main.sizeOf :: Main.Elem GHC.Base.Int -> GHC.Base.Int
[GlobalId]
[Arity 1
 NoCafRefs
 Str: DmdType U(A)m]
Main.sizeOf =
  \ (ds_dxC :: Main.Elem GHC.Base.Int) ->
    case ds_dxC of wild_B1 { Main.Elem r_aa8 -> Main.lvl2 }

Main.peekByteOff :: forall b_avX.
                    GHC.Ptr.Ptr b_avX -> GHC.Base.Int -> GHC.IOBase.IO 
(Main.Elem GHC.Base.Int)
[GlobalId]
[Arity 3
 NoCafRefs
 Str: DmdType U(L)U(L)L]
Main.peekByteOff =
  \ (@ b_awy) (ptr_azz :: GHC.Ptr.Ptr b_awy) (off_azA :: GHC.Base.Int) ->
    (\ (s_aIC :: GHC.Prim.State# GHC.Prim.RealWorld) ->
       case ptr_azz of wild_aJl { GHC.Ptr.Ptr addr_aJn ->
       case off_azA of wild1_aJp { GHC.Base.I# d_aJr ->
       case GHC.Prim.readIntOffAddr#
              @ GHC.Prim.RealWorld (GHC.Prim.plusAddr# addr_aJn d_aJr) 0 s_aIC
       of wild2_aIT { (# s2_aIV, x_aIW #) ->
       (# s2_aIV, (Main.Elem @ GHC.Base.Int (GHC.Base.I# x_aIW)) #)
       }
       }
       })
    `cast` (sym ((GHC.IOBase.:CoIO) (Main.Elem GHC.Base.Int))
            :: GHC.Prim.State# GHC.Prim.RealWorld
               -> (# GHC.Prim.State# GHC.Prim.RealWorld, Main.Elem GHC.Base.Int 
#)
                 :=:
               GHC.IOBase.IO (Main.Elem GHC.Base.Int))

Main.pokeByteOff :: forall b_avZ.
                    GHC.Ptr.Ptr b_avZ -> GHC.Base.Int -> Main.Elem GHC.Base.Int 
-> GHC.IOBase.IO ()
[GlobalId]
[Arity 2
 NoCafRefs
 Str: DmdType LL]
Main.pokeByteOff =
  \ (@ b_awE) (ptr_azh :: GHC.Ptr.Ptr b_awE) (off_azi :: GHC.Base.Int) ->
    let {
      ptr1_sW1 [Just D(L)] :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int)
      [Str: DmdType]
      ptr1_sW1 = GHC.Ptr.plusPtr @ b_awE @ (Main.Elem GHC.Base.Int) ptr_azh 
off_azi
    } in 
      \ (ds_dxP :: Main.Elem GHC.Base.Int) ->
        (\ (eta_sJg :: GHC.Prim.State# GHC.Prim.RealWorld) ->
           case ds_dxP of wild_B1 { Main.Elem r_abP ->
           case ptr1_sW1 of wild1_ay0 { GHC.Ptr.Ptr addr_ay2 ->
           case r_abP of wild2_aJ9 { GHC.Base.I# x_aJb ->
           case GHC.Prim.writeIntOffAddr# @ GHC.Prim.RealWorld addr_ay2 0 x_aJb 
eta_sJg
           of s2_aJd { __DEFAULT ->
           (# s2_aJd, GHC.Base.() #)
           }
           }
           }
           })
        `cast` (sym ((GHC.IOBase.:CoIO) ())
                :: GHC.Prim.State# GHC.Prim.RealWorld
                   -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
                     :=:
                   GHC.IOBase.IO ())

Main.$dmpeekElemOff :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int)
                       -> GHC.Base.Int
                       -> GHC.IOBase.IO (Main.Elem GHC.Base.Int)
[GlobalId]
[Arity 3
 Str: DmdType U(A)U(A)Ab]
Main.$dmpeekElemOff =
  \ (ptr_ayD :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int)) (off_ayE :: GHC.Base.Int) 
->
    (\ (eta_sJB :: GHC.Prim.State# GHC.Prim.RealWorld) ->
       case ptr_ayD of wild_aJl { GHC.Ptr.Ptr addr_aJn ->
       case off_ayE of wild1_ayQ { GHC.Base.I# x_ayS ->
       GHC.Err.undefined
       `cast` (CoUnsafe (forall a_az9. a_az9)
                        (# GHC.Prim.State# GHC.Prim.RealWorld, Main.Elem 
GHC.Base.Int #)
               :: forall a_az9. a_az9
                    :=:
                  (# GHC.Prim.State# GHC.Prim.RealWorld, Main.Elem GHC.Base.Int 
#))
       }
       })
    `cast` (sym ((GHC.IOBase.:CoIO) (Main.Elem GHC.Base.Int))
            :: GHC.Prim.State# GHC.Prim.RealWorld
               -> (# GHC.Prim.State# GHC.Prim.RealWorld, Main.Elem GHC.Base.Int 
#)
                 :=:
               GHC.IOBase.IO (Main.Elem GHC.Base.Int))

Main.$dmpokeElemOff :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int)
                       -> GHC.Base.Int
                       -> Main.Elem GHC.Base.Int
                       -> GHC.IOBase.IO ()
[GlobalId]
[Arity 4
 NoCafRefs
 Str: DmdType U(L)U(L)U(U(L))L]
Main.$dmpokeElemOff =
  \ (ptr_ayf :: GHC.Ptr.Ptr (Main.Elem GHC.Base.Int))
    (off_ayg :: GHC.Base.Int)
    (val_ayh :: Main.Elem GHC.Base.Int) ->
    (\ (eta_sTo :: GHC.Prim.State# GHC.Prim.RealWorld) ->
       case val_ayh of wild_B1 { Main.Elem r_abP ->
       case ptr_ayf of wild1_aJl { GHC.Ptr.Ptr addr_aJn ->
       case off_ayg of wild2_ayt { GHC.Base.I# x_ayv ->
       case r_abP of wild21_aJ9 { GHC.Base.I# x1_aJb ->
       case GHC.Prim.writeIntOffAddr#
              @ GHC.Prim.RealWorld
              (GHC.Prim.plusAddr# addr_aJn (GHC.Prim.*# x_ayv 24))
              0
              x1_aJb
              eta_sTo
       of s2_aJd { __DEFAULT ->
       (# s2_aJd, GHC.Base.() #)
       }
       }
       }
       }
       })
    `cast` (sym ((GHC.IOBase.:CoIO) ())
            :: GHC.Prim.State# GHC.Prim.RealWorld
               -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
                 :=:
               GHC.IOBase.IO ())

Main.$dStorable :: Foreign.Storable.Storable (Main.Elem GHC.Base.Int)
[GlobalId]
[Str: DmdType m]
Main.$dStorable =
  Foreign.Storable.:DStorable
    @ (Main.Elem GHC.Base.Int)
    Main.sizeOf
    Main.alignment
    Main.$dmpeekElemOff
    Main.$dmpokeElemOff
    Main.peekByteOff
    Main.pokeByteOff
    Main.peek
    Main.poke

Main.main :: GHC.IOBase.IO ()
[GlobalId]
[Arity 1
 Str: DmdType L]
Main.main =
  Main.a
  `cast` (sym ((GHC.IOBase.:CoIO) ())
          :: GHC.Prim.State# GHC.Prim.RealWorld
             -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
               :=:
             GHC.IOBase.IO ())

Main.$f1 :: forall a_aa6.
            (Foreign.Storable.Storable a_aa6) =>
            Foreign.Storable.Storable (Main.Elem a_aa6)
[GlobalId]
[Arity 1
 Str: DmdType Lm]
Main.$f1 =
  __inline_me (\ (@ a_aa6) ($dStorable1_avR :: Foreign.Storable.Storable a_aa6) 
->
                 let {
                   sizeOf1_sHj :: Main.Elem a_aa6 -> GHC.Base.Int
                   [Arity 1
                    Str: DmdType U(L)]
                   sizeOf1_sHj =
                     \ (ds_dxC :: Main.Elem a_aa6) ->
                       case ds_dxC of wild_B1 { Main.Elem r_aa8 ->
                       GHC.Num.*
                         @ GHC.Base.Int
                         GHC.Num.$f6
                         (GHC.Base.I# 3)
                         (Foreign.Storable.sizeOf @ a_aa6 $dStorable1_avR r_aa8)
                       } } in
                 let {
                   alignment1_sHk :: Main.Elem a_aa6 -> GHC.Base.Int
                   [Arity 1
                    Str: DmdType U(L) {avR->U(ASAAAAAA)}]
                   alignment1_sHk =
                     \ (ds_dxK :: Main.Elem a_aa6) ->
                       case ds_dxK of wild_B1 { Main.Elem r_abI ->
                       Foreign.Storable.alignment @ a_aa6 $dStorable1_avR r_abI
                       } } in
                 let {
                   peek1_sHl :: GHC.Ptr.Ptr (Main.Elem a_aa6) -> GHC.IOBase.IO 
(Main.Elem a_aa6)
                   [Arity 1
                    Str: DmdType L]
                   peek1_sHl =
                     \ (ptr_abK :: GHC.Ptr.Ptr (Main.Elem a_aa6)) ->
                       GHC.Base.>>=
                         @ GHC.IOBase.IO
                         GHC.IOBase.$f16
                         @ a_aa6
                         @ (Main.Elem a_aa6)
                         (Foreign.Storable.peekElemOff
                            @ a_aa6
                            $dStorable1_avR
                            (GHC.Ptr.castPtr @ (Main.Elem a_aa6) @ a_aa6 
ptr_abK)
                            (GHC.Base.I# 0))
                         (\ (r_abM :: a_aa6) ->
                            GHC.Base.return
                              @ GHC.IOBase.IO
                              GHC.IOBase.$f16
                              @ (Main.Elem a_aa6)
                              (Main.Elem @ a_aa6 r_abM)) } in
                 let {
                   poke1_sHm :: GHC.Ptr.Ptr (Main.Elem a_aa6)
                                -> Main.Elem a_aa6
                                -> GHC.IOBase.IO ()
                   [Arity 2
                    Str: DmdType LU(L) {avR->U(AAAAAAAS)}]
                   poke1_sHm =
                     \ (ptr_abO :: GHC.Ptr.Ptr (Main.Elem a_aa6)) (ds_dxP :: 
Main.Elem a_aa6) ->
                       case ds_dxP of wild_B1 { Main.Elem r_abP ->
                       Foreign.Storable.poke
                         @ a_aa6
                         $dStorable1_avR
                         (GHC.Ptr.castPtr @ (Main.Elem a_aa6) @ a_aa6 ptr_abO)
                         r_abP
                       } } in
                 __letrec {
                   $dStorable2_sHe :: Foreign.Storable.Storable (Main.Elem 
a_aa6)
                   [Str: DmdType m]
                   $dStorable2_sHe =
                     Foreign.Storable.:DStorable
                       @ (Main.Elem a_aa6)
                       sizeOf1_sHj
                       alignment1_sHk
                       $dmpeekElemOff1_sHg
                       $dmpokeElemOff1_sHf
                       peekByteOff1_sHi
                       pokeByteOff1_sHh
                       peek1_sHl
                       poke1_sHm;
                   peekByteOff1_sHi :: forall b_avX.
                                       GHC.Ptr.Ptr b_avX -> GHC.Base.Int -> 
GHC.IOBase.IO (Main.Elem a_aa6)
                   [Arity 2
                    Str: DmdType LL {sHe->U(AAAAAAC(S)A)}]
                   peekByteOff1_sHi =
                     \ (@ b_awy) ->
                       Foreign.Storable.$dmpeekByteOff @ (Main.Elem a_aa6) 
$dStorable2_sHe @ b_awy;
                   pokeByteOff1_sHh :: forall b_avZ.
                                       GHC.Ptr.Ptr b_avZ -> GHC.Base.Int -> 
Main.Elem a_aa6 -> GHC.IOBase.IO ()
                   [Arity 2
                    Str: DmdType LL {sHe->U(AAAAAAAC(S))}]
                   pokeByteOff1_sHh =
                     \ (@ b_awE) ->
                       Foreign.Storable.$dmpokeByteOff @ (Main.Elem a_aa6) 
$dStorable2_sHe @ b_awE;
                   $dmpeekElemOff1_sHg :: GHC.Ptr.Ptr (Main.Elem a_aa6)
                                          -> GHC.Base.Int
                                          -> GHC.IOBase.IO (Main.Elem a_aa6)
                   [Arity 2
                    Str: DmdType LL {sHe->U(LAAAC(C(S))AAA)}]
                   $dmpeekElemOff1_sHg =
                     Foreign.Storable.$dmpeekElemOff @ (Main.Elem a_aa6) 
$dStorable2_sHe;
                   $dmpokeElemOff1_sHf :: GHC.Ptr.Ptr (Main.Elem a_aa6)
                                          -> GHC.Base.Int
                                          -> Main.Elem a_aa6
                                          -> GHC.IOBase.IO ()
                   [Arity 3
                    Str: DmdType LLL {sHe->U(LAAAAC(C(C(S)))AA)}]
                   $dmpokeElemOff1_sHf =
                     Foreign.Storable.$dmpokeElemOff @ (Main.Elem a_aa6) 
$dStorable2_sHe;
                 } in  $dStorable2_sHe)

:Main.main :: GHC.IOBase.IO ()
[GlobalId]
[Arity 1
 Str: DmdType L]
:Main.main =
  GHC.TopHandler.runMainIO
    @ ()
    (Main.a
     `cast` (sym ((GHC.IOBase.:CoIO) ())
             :: GHC.Prim.State# GHC.Prim.RealWorld
                -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
                  :=:
                GHC.IOBase.IO ()))




==================== Tidy Core Rules ====================
"SPEC Main.$f1"
    __forall {$dStorable1_XIk :: Foreign.Storable.Storable GHC.Base.Int}
      Main.$f1 @ GHC.Base.Int $dStorable1_XIk
      = Main.$dStorable


Reply via email to