Bug in GHC.Stack.callStack when used with sections
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
-- 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
-- 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
-- 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
.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |