More refactoring of instance declarations (fixes Trac #2572)
authorsimonpj@microsoft.com <unknown>
Wed, 10 Sep 2008 08:51:21 +0000 (08:51 +0000)
committersimonpj@microsoft.com <unknown>
Wed, 10 Sep 2008 08:51:21 +0000 (08:51 +0000)
commitaaed05e88978688e37dc74177dd4eba51a6ab4d0
treeef8581b58862b24d7770c16f1dcc8c5cff88ae70
parent112ad1978f8c03d26a7df9ac892915dc93724b66
More refactoring of instance declarations (fixes Trac #2572)

In refactoring instance declarations I'd taken a short cut over
scoped type variables, but it wasn't right as #2572 shows.

Fixing it required a significant chunk of further refactoring,
alas. But it's done!  Quite tidily as it turns out.

The main issue is that when typechecking a default method, we
need two sets of type variables in scope
class C a where
      op :: forall b. ...
  op = e
In 'e', *both* 'a' and 'b' are in scope.  But the type of the
default method has a nested flavour
op :: forall a. C a => forall b. ....
and our normal scoping mechanisms don't bring 'b' into scope.
(And probably shouldn't.)

Solution (which is done for instance methods too) is to use
a local defintion, like this:

  $dmop :: forall a. C a => forall b. ....
  $dmop a d = let
                 op :: forall b. ...
                 op = e
              in op

and now the scoping works out.  I hope I have now see the
last of this code for a bit!
compiler/typecheck/TcClassDcl.lhs
compiler/typecheck/TcExpr.lhs
compiler/typecheck/TcInstDcls.lhs
compiler/typecheck/TcUnify.lhs