
#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): -------------------------------------+------------------------------------- Comment (by simonpj): There are several things going on here. First, let's just note that none of this arises if we have `MonoLocalBinds`, which is what happens if you have GADTs etc. Second, we have this magic rule that `CallStack` constraints can be spontaneously solved by the solver. This is an ad-hoc rule that means we don't gratuitously infer top-level types like `f :: (?x :: CallStack) => blah`. **But it should really only apply at top level.** For nested let- bindings I think it'd be fine to abstract. So in the "spontaneous solve" code in `TcInteract.interactDict` we can make it conditional on the `tc_lvl` being 3. (Sorry about the 3; I'm committing a new `Note [TcLevel assignment]` in `TcType` to explain. There should be a definition `topImplicationTcLevel = 3` alongside `topTcLevel = 1`.) Third, I think that if `MonoLocalBinds` is off, then we do want to generalise over `CallStack` constraints, just like any other implicit parameter. Consider {{{ f :: (?loc :: CallStack) => blah f x = let g y = ...error "foo".... in ...(g x) ... (g v) ... }}} Now, if `g` fails, calling `error`, surely you'd like to see which of `g`'s call sites was implicated? So we'd expect `g` to get an inferred type {{{ g :: (?loc :: CallStack) => something }}} Does it make a difference if `g` has no arguments? Well, the monomorphism restriction says we won't quantify over any constraints, so yes, it makes a difference. Fourth you seems to want to treat `getCallStack` specially, which I am doubtful about. In the above example `g`'s RHS has a call to `error`, but it should not behave any differently if it had a call to `getCallStack` instead. The latter is just another ordinary function with a `(?x :: CallStack)` constraint. Bottom line: I think that all we need do is suppress the spontaneous-solve code for `CallStack` if we are not at top level. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10845#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler