[GHC] #13285: Bug in GHC.Stack.callStack when used with sections

GHC ghc-devs at haskell.org
Thu Feb 16 03:37:13 UTC 2017


#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


More information about the ghc-tickets mailing list