[GHC] #10845: Incorrect behavior when let binding implicit CallStack object
GHC
ghc-devs at haskell.org
Tue Oct 6 11:32:56 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):
-------------------------------------+-------------------------------------
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
More information about the ghc-tickets
mailing list