[GHC] #10845: Incorrect behavior when let binding implicit CallStack object
GHC
ghc-devs at haskell.org
Tue Nov 3 13:30:30 UTC 2015
#10845: Incorrect behavior when let binding implicit CallStack object
-------------------------------------+-------------------------------------
Reporter: nitromaster101 | Owner: gridaphobe
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.11
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: #10846 | Differential Rev(s): Phab:D1422
Wiki Page: |
-------------------------------------+-------------------------------------
Changes (by simonpj):
* differential: => Phab:D1422
Comment:
On [Phab:D1422] you say:
Sadly, it turns out we can't remove the no-given solver entirely. Consider
{{{
main = do putStrLn $ showCallStack ?loc
putStrLn $ showCallStack ?loc
}}}
GHC treats the constraints arising from the two occurrences of ?loc as
interchangeable (after all, they have the same type), and solves one from
the other, giving us the incorrect output
{{{
% ./T10845
CallStack:
?loc, called at T10845.hs:33:36 in main:Main
CallStack:
?loc, called at T10845.hs:33:36 in main:Main
}}}
(note that both CallStacks refer to the same location).
Good point! But there is a better way to solve this particular issue:
* In `Inst.instCallConstraints`, add a special case for `CallStack`
constraints, where you push on the call site (i.e. do what the
solver currently does, in `isCallStackIP`
* Now any Wanted call-stack constraints encountered by the solver
can be solved by equality from each other, or directly from a given.
In fact this makes call-stack constraints behave even more like
implicit-parameter constraints.
* Defaulting solves a `CallStack` constraint with `EmptyStack`
This is much simpler and more direct.
There is a wrinkle: what if the function being called had a type
like `f :: c => T c -> Int`, and `c` was subsequently inferred to
be `IP "foo" CallStack`? So the fact that it's a call-stack constraint
isn't immediately obvious.
It's a pretty obscure problem but could be solved by NOT solving in
`instCallConstraints`, but intead
* Have two kind of call-stack constraints, with origin
`OccurrenceOf`, and `IPOccOrigin` (this is actually true already;
see `IPCallStackIP`.
* The only way to solve an `OccurrenceOf` call-stack constraint is by
pushing on the call item, and producing a new wanted `IPOccOrigin`
call-stack constraint
* Solve wanted `IPOccOrigin` call-stack constraints as above, from each
other,
from givens, or by defaulting.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10845#comment:13>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list