
#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