Skip to content
  • Simon Peyton Jones's avatar
    [project @ 2006-01-05 13:10:55 by simonpj] · dd45134b
    Simon Peyton Jones authored
    MERGE TO STABLE
    
    This commit fixes a nasty problem discovered by Volker Stolz.
    The problem is described in Note [Multiple instantiation] in
    TcExpr, which is reproduced below.
    
    (Core Lint identifies the problem, incidentally.)
    
    tc200 is a test case.
    
    
    Note [Multiple instantiation]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    We are careful never to make a MethodInst that has, as its meth_id, another MethodInst.
    For example, consider
    	f :: forall a. Eq a => forall b. Ord b => a -> b
    At a call to f, at say [Int, Bool], it's tempting to translate the call to
    
    	f_m1
      where
    	f_m1 :: forall b. Ord b => Int -> b
    	f_m1 = f Int dEqInt
    
    	f_m2 :: Int -> Bool
    	f_m2 = f_m1 Bool dOrdBool
    
    But notice that f_m2 has f_m1 as its meth_id.  Now the danger is that if we do
    a tcSimplCheck with a Given f_mx :: f Int dEqInt, we may make a binding
    	f_m1 = f_mx
    But it's entirely possible that f_m2 will continue to float out, because it
    mentions no type variables.  Result, f_m1 isn't in scope.
    
    Here's a concrete example that does this (test tc200):
    
        class C a where
          f :: Eq b => b -> a -> Int
          baz :: Eq a => Int -> a -> Int
    
        instance C Int where
          baz = f
    
    Current solution: only do the "method sharing" thing for the first type/dict
    application, not for the iterated ones.  A horribly subtle point.
    dd45134b