
#13285: Bug in GHC.Stack.callStack when used with sections -------------------------------------+------------------------------------- Reporter: SimonHengel | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: Incorrect result Unknown/Multiple | at runtime Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Since GHC {{{8.0.1}}} call stacks are not constructed consistently anymore. Specifically, no stack frames are added for call sites that use section syntax. This used to work with GHC {{{7.10.2}}}. I haven't tried with {{{7.10.3}}}. Call stacks are used in {{{hspec}}} and {{{HUnit}}} to attach location information to failing test cases. Moreover, it is somewhat common to use section syntax with {{{hspec}}}. This is why I describe the bug in the context of {{{hspec}}}. But first, I give minimal steps on how to reproduce without the need of any additional dependencies. = TL;DR Minimal steps to reproduce {{{ #!haskell -- Main.hs import GHC.Stack main :: IO () main = do foo 23 42 (`foo` 23) 42 foo :: HasCallStack => Int -> Int -> IO () foo _ _ = print (length . getCallStack $ callStack) }}} {{{ $ runhaskell Main.hs }}} expected output: {{{ 1 1 }}} actual output: {{{ 1 0 }}} = Description of the bug from a users perspective (in the context of Hspec) This section describes the bug in the context of {{{hspec}}}. If you already understand how this bug affects users and why this is problematic you may choose to skip this section. == A working example Looking at the following example {{{ #!haskell -- Spec.hs import Test.Hspec main :: IO () main = hspec $ do it "works for my use case" $ do 23 `shouldBe` 42 }}} call stacks work as expected: {{{ $ runhaskell Spec.hs ... Failures: Spec.hs:6: 1) works for my use case expected: 42 but got: 23 ... }}} The users sees a source locations that points him to the failing test case. == A slightly modified and broken example If we rephrase the above example using section syntax we get {{{ #!haskell -- Spec.hs import Test.Hspec main :: IO () main = hspec $ do it "works for my use case" $ do (`shouldBe` 42) 23 }}} and things suddenly go bad: {{{ $ runhaskell Spec.hs ... Failures: src/Test/Hspec/Expectations.hs:91: 1) works for my use case expected: 42 but got: 23 ... }}} The user expects to see the call site of {{{shouldBe}}}, that points him to the failing test case. But instead he gets an unhelpful location that points somewhere at the implementation of {{{hspec-expectations}}}. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13285 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler