[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