[project @ 2003-10-01 10:49:07 by wolfgang]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcSimplify.lhs
index 758659a..1970ab3 100644 (file)
@@ -9,7 +9,8 @@
 module TcSimplify (
        tcSimplifyInfer, tcSimplifyInferCheck,
        tcSimplifyCheck, tcSimplifyRestricted,
-       tcSimplifyToDicts, tcSimplifyIPs, tcSimplifyTop,
+       tcSimplifyToDicts, tcSimplifyIPs, 
+       tcSimplifyTop, tcSimplifyInteractive,
        tcSimplifyBracket,
 
        tcSimplifyDeriv, tcSimplifyDefault,
@@ -19,7 +20,7 @@ module TcSimplify (
 #include "HsVersions.h"
 
 import {-# SOURCE #-} TcUnify( unifyTauTy )
-
+import TcEnv           -- temp
 import HsSyn           ( MonoBinds(..), HsExpr(..), andMonoBinds, andMonoBindList )
 import TcHsSyn         ( TcExpr, TcId,
                          TcMonoBinds, TcDictBinds
@@ -32,14 +33,14 @@ import Inst         ( lookupInst, LookupInstResult(..),
                          isStdClassTyVarDict, isMethodFor, isMethod,
                          instToId, tyVarsOfInsts,  cloneDict,
                          ipNamesOfInsts, ipNamesOfInst, dictPred,
-                         instBindingRequired, instCanBeGeneralised,
+                         instBindingRequired,
                          newDictsFromOld, tcInstClassOp,
                          getDictClassTys, isTyVarDict,
-                         instLoc, pprInst, zonkInst, tidyInsts, tidyMoreInsts,
+                         instLoc, zonkInst, tidyInsts, tidyMoreInsts,
                          Inst, pprInsts, pprInstsInFull,
                          isIPDict, isInheritableInst
                        )
-import TcEnv           ( tcGetGlobalTyVars, tcGetInstEnv, tcLookupId )
+import TcEnv           ( tcGetGlobalTyVars, tcGetInstEnv, tcLookupId, findGlobals )
 import InstEnv         ( lookupInstEnv, classInstEnv, InstLookupResult(..) )
 import TcMType         ( zonkTcTyVarsAndFV, tcInstTyVars, checkAmbiguity )
 import TcType          ( TcTyVar, TcTyVarSet, ThetaType, TyVarDetails(VanillaTv),
@@ -50,18 +51,22 @@ import Id           ( idType, mkUserLocal )
 import Var             ( TyVar )
 import Name            ( getOccName, getSrcLoc )
 import NameSet         ( NameSet, mkNameSet, elemNameSet )
-import Class           ( classBigSig )
+import Class           ( classBigSig, classKey )
 import FunDeps         ( oclose, grow, improve, pprEquationDoc )
-import PrelInfo                ( isNumericClass, isCreturnableClass, isCcallishClass ) 
-import PrelNames       ( splitName, fstName, sndName )
+import PrelInfo                ( isNumericClass ) 
+import PrelNames       ( splitName, fstName, sndName, showClassKey, eqClassKey, ordClassKey)
+import HscTypes                ( GhciMode(Interactive) )
 
 import Subst           ( mkTopTyVarSubst, substTheta, substTy )
 import TysWiredIn      ( unitTy, pairTyCon )
+import ErrUtils                ( Message )
 import VarSet
+import VarEnv          ( TidyEnv )
 import FiniteMap
 import Outputable
 import ListSetOps      ( equivClasses )
-import Util            ( zipEqual )
+import Unique          ( hasKey )
+import Util            ( zipEqual, isSingleton )
 import List            ( partition )
 import CmdLineOpts
 \end{code}
@@ -547,9 +552,6 @@ tcSimplifyInfer doc tau_tvs wanted_lie
   = inferLoop doc (varSetElems tau_tvs)
              wanted_lie                `thenM` \ (qtvs, frees, binds, irreds) ->
 
-       -- Check for non-generalisable insts
-    mappM_ addCantGenErr (filter (not . instCanBeGeneralised) irreds)  `thenM_`
-
     extendLIEs frees                                                   `thenM_`
     returnM (qtvs, binds, map instToId irreds)
 
@@ -567,6 +569,7 @@ inferLoop doc tau_tvs wanteds
          | isClassDict inst              = DontReduceUnlessConstant    -- Dicts
          | otherwise                     = ReduceMe                    -- Lits and Methods
     in
+    traceTc (text "infloop" <+> vcat [ppr tau_tvs', ppr wanteds', ppr preds, ppr (grow preds tau_tvs'), ppr qtvs])     `thenM_`
                -- Step 2
     reduceContext doc try_me [] wanteds'    `thenM` \ (no_improvement, frees, binds, irreds) ->
 
@@ -739,7 +742,7 @@ tcSimplCheck doc get_qtvs givens wanted_lie
       =                -- Step 1
        mappM zonkInst givens   `thenM` \ givens' ->
        mappM zonkInst wanteds  `thenM` \ wanteds' ->
-       get_qtvs                        `thenM` \ qtvs' ->
+       get_qtvs                `thenM` \ qtvs' ->
 
                    -- Step 2
        let
@@ -783,14 +786,13 @@ tcSimplifyRestricted doc tau_tvs wanteds
        --      foo = f (3::Int)
        -- We want to infer the polymorphic type
        --      foo :: forall b. b -> b
-    let
-       try_me inst = ReduceMe          -- Reduce as far as we can.  Don't stop at
-                                       -- dicts; the idea is to get rid of as many type
-                                       -- variables as possible, and we don't want to stop
-                                       -- at (say) Monad (ST s), because that reduces
-                                       -- immediately, with no constraint on s.
-    in
-    simpleReduceLoop doc try_me wanteds                `thenM` \ (_, _, constrained_dicts) ->
+
+       -- 'reduceMe': Reduce as far as we can.  Don't stop at
+       -- dicts; the idea is to get rid of as many type
+       -- variables as possible, and we don't want to stop
+       -- at (say) Monad (ST s), because that reduces
+       -- immediately, with no constraint on s.
+    simpleReduceLoop doc reduceMe wanteds      `thenM` \ (foo_frees, foo_binds, constrained_dicts) ->
 
        -- Next, figure out the tyvars we will quantify over
     zonkTcTyVarsAndFV (varSetElems tau_tvs)    `thenM` \ tau_tvs' ->
@@ -800,6 +802,10 @@ tcSimplifyRestricted doc tau_tvs wanteds
        qtvs = (tau_tvs' `minusVarSet` oclose (fdPredsOfInsts constrained_dicts) gbl_tvs)
                         `minusVarSet` constrained_tvs
     in
+    traceTc (text "tcSimplifyRestricted" <+> vcat [
+               pprInsts wanteds, pprInsts foo_frees, pprInsts constrained_dicts,
+               ppr foo_binds,
+               ppr constrained_tvs, ppr tau_tvs', ppr qtvs ])  `thenM_`
 
        -- The first step may have squashed more methods than
        -- necessary, so try again, this time knowing the exact
@@ -814,19 +820,28 @@ tcSimplifyRestricted doc tau_tvs wanteds
        -- Remember that we may need to do *some* simplification, to
        -- (for example) squash {Monad (ST s)} into {}.  It's not enough
        -- just to float all constraints
-    mappM zonkInst wanteds                     `thenM` \ wanteds' ->
+    restrict_loop doc qtvs wanteds
+       -- We still need a loop because improvement can take place
+       -- E.g. if we have (C (T a)) and the instance decl
+       --      instance D Int b => C (T a) where ...
+       -- and there's a functional dependency for D.   Then we may improve
+       -- the tyep variable 'b'.
+
+restrict_loop doc qtvs wanteds
+  = mappM zonkInst wanteds                     `thenM` \ wanteds' ->
+    zonkTcTyVarsAndFV (varSetElems qtvs)       `thenM` \ qtvs' ->
     let
-        try_me inst | isFreeWrtTyVars qtvs inst = Free
-                   | otherwise                 = ReduceMe
+        try_me inst | isFreeWrtTyVars qtvs' inst = Free
+                   | otherwise                  = ReduceMe
     in
     reduceContext doc try_me [] wanteds'       `thenM` \ (no_improvement, frees, binds, irreds) ->
-    ASSERT( no_improvement )
-    ASSERT( null irreds )
-       -- No need to loop because simpleReduceLoop will have
-       -- already done any improvement necessary
-
-    extendLIEs frees                           `thenM_`
-    returnM (varSetElems qtvs, binds)
+    if no_improvement then
+       ASSERT( null irreds )
+       extendLIEs frees                        `thenM_`
+       returnM (varSetElems qtvs', binds)
+    else
+       restrict_loop doc qtvs' (irreds ++ frees)       `thenM` \ (qtvs1, binds1) ->
+       returnM (qtvs1, binds `AndMonoBinds` binds1)
 \end{code}
 
 
@@ -905,12 +920,10 @@ this bracket again at its usage site.
 \begin{code}
 tcSimplifyBracket :: [Inst] -> TcM ()
 tcSimplifyBracket wanteds
-  = simpleReduceLoop doc try_me wanteds                `thenM_`
+  = simpleReduceLoop doc reduceMe wanteds      `thenM_`
     returnM ()
-
   where
-    doc     = text "tcSimplifyBracket"
-    try_me inst        = ReduceMe
+    doc = text "tcSimplifyBracket"
 \end{code}
 
 
@@ -1065,6 +1078,7 @@ data Avail
 
   | NoRhs              -- Used for Insts like (CCallable f)
                        -- where no witness is required.
+                       -- ToDo: remove?
 
   | Rhs                -- Used when there is a RHS
        TcExpr          -- The RHS
@@ -1414,8 +1428,13 @@ reduce stack try_me wanted state
     ; ReduceMe ->              -- It should be reduced
        lookupInst wanted             `thenM` \ lookup_result ->
        case lookup_result of
-           GenInst wanteds' rhs -> reduceList stack try_me wanteds' state      `thenM` \ state' ->
-                                   addWanted state' wanted rhs wanteds'
+           GenInst wanteds' rhs -> addWanted state wanted rhs wanteds'         `thenM` \ state' ->
+                                   reduceList stack try_me wanteds' state'
+               -- Experiment with doing addWanted *before* the reduceList, 
+               -- which has the effect of adding the thing we are trying
+               -- to prove to the database before trying to prove the things it
+               -- needs.  See note [RECURSIVE DICTIONARIES]
+
            SimpleInst rhs       -> addWanted state wanted rhs []
 
            NoInstance ->    -- No such instance!
@@ -1583,6 +1602,42 @@ Now we implement the Right Solution, which is to check for loops directly
 when adding superclasses.  It's a bit like the occurs check in unification.
 
 
+Note [RECURSIVE DICTIONARIES]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider 
+    data D r = ZeroD | SuccD (r (D r));
+    
+    instance (Eq (r (D r))) => Eq (D r) where
+        ZeroD     == ZeroD     = True
+        (SuccD a) == (SuccD b) = a == b
+        _         == _         = False;
+    
+    equalDC :: D [] -> D [] -> Bool;
+    equalDC = (==);
+
+We need to prove (Eq (D [])).  Here's how we go:
+
+       d1 : Eq (D [])
+
+by instance decl, holds if
+       d2 : Eq [D []]
+       where   d1 = dfEqD d2
+
+by instance decl of Eq, holds if
+       d3 : D []
+       where   d2 = dfEqList d2
+               d1 = dfEqD d2
+
+But now we can "tie the knot" to give
+
+       d3 = d1
+       d2 = dfEqList d2
+       d1 = dfEqD d2
+
+and it'll even run!  The trick is to put the thing we are trying to prove
+(in this case Eq (D []) into the database before trying to prove its
+contributing clauses.
+       
 
 %************************************************************************
 %*                                                                     *
@@ -1605,9 +1660,17 @@ It's OK: the final zonking stage should zap y to (), which is fine.
 
 
 \begin{code}
-tcSimplifyTop :: [Inst] -> TcM TcDictBinds
-tcSimplifyTop wanteds
-  = simpleReduceLoop (text "tcSimplTop") reduceMe wanteds      `thenM` \ (frees, binds, irreds) ->
+tcSimplifyTop, tcSimplifyInteractive :: [Inst] -> TcM TcDictBinds
+tcSimplifyTop         wanteds = tc_simplify_top False {- Not interactive loop -} wanteds
+tcSimplifyInteractive wanteds = tc_simplify_top True  {- Interactive loop -}     wanteds
+
+
+-- The TcLclEnv should be valid here, solely to improve
+-- error message generation for the monomorphism restriction
+tc_simplify_top is_interactive wanteds
+  = getLclEnv                                                  `thenM` \ lcl_env ->
+    traceTc (text "tcSimplifyTop" <+> ppr (lclEnvElts lcl_env))        `thenM_`
+    simpleReduceLoop (text "tcSimplTop") reduceMe wanteds      `thenM` \ (frees, binds, irreds) ->
     ASSERT( null frees )
 
     let
@@ -1629,13 +1692,17 @@ tcSimplifyTop wanteds
        (tidy_env, tidy_dicts) = tidyInsts bad_guys
        (bad_ips, non_ips)     = partition isIPDict tidy_dicts
        (no_insts, ambigs)     = partition no_inst non_ips
-       no_inst d = not (isTyVarDict d) || tyVarsOfInst d `subVarSet` fixed_tvs
-       fixed_tvs = oclose (fdPredsOfInsts tidy_dicts) emptyVarSet
+       no_inst d              = not (isTyVarDict d) 
+       -- Previously, there was a more elaborate no_inst definition:
+       --      no_inst d = not (isTyVarDict d) || tyVarsOfInst d `subVarSet` fixed_tvs
+       --      fixed_tvs = oclose (fdPredsOfInsts tidy_dicts) emptyVarSet
+       -- But that seems over-elaborate to me; it only bites for class decls with
+       -- fundeps like this:           class C a b | -> b where ...
     in
 
        -- Report definite errors
-    mappM (addTopInstanceErrs tidy_env) (groupInsts no_insts)  `thenM_`
-    mappM (addTopIPErrs tidy_env)       (groupInsts bad_ips)           `thenM_`
+    addTopInstanceErrs tidy_env no_insts       `thenM_`
+    addTopIPErrs tidy_env bad_ips              `thenM_`
 
        -- Deal with ambiguity errors, but only if
        -- if there has not been an error so far; errors often
@@ -1648,10 +1715,10 @@ tcSimplifyTop wanteds
        --      e.g. Num (IO a) and Eq (Int -> Int)
        -- and ambiguous dictionaries
        --      e.g. Num a
-       mappM (addAmbigErr tidy_env)    ambigs  `thenM_`
+       addTopAmbigErrs (tidy_env, ambigs)      `thenM_`
 
        -- Disambiguate the ones that look feasible
-        mappM disambigGroup std_oks
+        mappM (disambigGroup is_interactive) std_oks
     )                                  `thenM` \ binds_ambig ->
 
     returnM (binds `andMonoBinds` andMonoBindList binds_ambig)
@@ -1698,15 +1765,12 @@ Since we're not using the result of @foo@, the result if (presumably)
 @void@.
 
 \begin{code}
-disambigGroup :: [Inst]        -- All standard classes of form (C a)
+disambigGroup :: Bool  -- True <=> simplifying at top-level interactive loop
+             -> [Inst] -- All standard classes of form (C a)
              -> TcM TcDictBinds
 
-disambigGroup dicts
-  |   any isNumericClass classes       -- Guaranteed all standard classes
-         -- see comment at the end of function for reasons as to
-         -- why the defaulting mechanism doesn't apply to groups that
-         -- include CCallable or CReturnable dicts.
-   && not (any isCcallishClass classes)
+disambigGroup is_interactive dicts
+  |   any std_default_class classes    -- Guaranteed all standard classes
   =    -- THE DICTS OBEY THE DEFAULTABLE CONSTRAINT
        -- SO, TRY DEFAULT TYPES IN ORDER
 
@@ -1729,35 +1793,36 @@ disambigGroup dicts
     in
        -- See if any default works
     tryM (try_default default_tys)     `thenM` \ mb_ty ->
-    case mb_ty of {
-       Left _ ->       -- If not, add an AmbigErr
-                 addAmbigErrs dicts    `thenM_`
-                 returnM EmptyMonoBinds ;
+    case mb_ty of
+       Left  _                 -> bomb_out
+       Right chosen_default_ty -> choose_default chosen_default_ty
 
-       Right chosen_default_ty ->
+  | otherwise                          -- No defaults
+  = bomb_out
 
-       -- If so, bind the type variable 
+  where
+    tyvar   = get_tv (head dicts)      -- Should be non-empty
+    classes = map get_clas dicts
+
+    std_default_class cls
+      =  isNumericClass cls
+      || (is_interactive && 
+         classKey cls `elem` [showClassKey, eqClassKey, ordClassKey])
+               -- In interactive mode, we default Show a to Show ()
+               -- to avoid graututious errors on "show []"
+
+    choose_default default_ty  -- Commit to tyvar = default_ty
+      =        -- Bind the type variable 
+       unifyTauTy default_ty (mkTyVarTy tyvar) `thenM_`
        -- and reduce the context, for real this time
-    unifyTauTy chosen_default_ty (mkTyVarTy tyvar)     `thenM_`
-    simpleReduceLoop (text "disambig" <+> ppr dicts)
+       simpleReduceLoop (text "disambig" <+> ppr dicts)
                     reduceMe dicts                     `thenM` \ (frees, binds, ambigs) ->
-    WARN( not (null frees && null ambigs), ppr frees $$ ppr ambigs )
-    warnDefault dicts chosen_default_ty                        `thenM_`
-    returnM binds }
-
-  | all isCreturnableClass classes
-  =    -- Default CCall stuff to (); we don't even both to check that () is an
-       -- instance of CReturnable, because we know it is.
-    unifyTauTy (mkTyVarTy tyvar) unitTy    `thenM_`
-    returnM EmptyMonoBinds
+       WARN( not (null frees && null ambigs), ppr frees $$ ppr ambigs )
+       warnDefault dicts default_ty                    `thenM_`
+       returnM binds
 
-  | otherwise -- No defaults
-  = addAmbigErrs dicts `thenM_`
-    returnM EmptyMonoBinds
-
-  where
-    tyvar       = get_tv (head dicts)          -- Should be non-empty
-    classes     = map get_clas dicts
+    bomb_out = addTopAmbigErrs (tidyInsts dicts)       `thenM_`
+              returnM EmptyMonoBinds
 \end{code}
 
 [Aside - why the defaulting mechanism is turned off when
@@ -1901,61 +1966,109 @@ from the insts, or just whatever seems to be around in the monad just
 now?
 
 \begin{code}
-groupInsts :: [Inst] -> [[Inst]]
+groupErrs :: ([Inst] -> TcM ())        -- Deal with one group
+         -> [Inst]             -- The offending Insts
+          -> TcM ()
 -- Group together insts with the same origin
 -- We want to report them together in error messages
-groupInsts []          = []
-groupInsts (inst:insts) = (inst:friends) : groupInsts others
-                       where
-                               -- (It may seem a bit crude to compare the error messages,
-                               --  but it makes sure that we combine just what the user sees,
-                               --  and it avoids need equality on InstLocs.)
-                         (friends, others) = partition is_friend insts
-                         loc_msg           = showSDoc (pprInstLoc (instLoc inst))
-                         is_friend friend  = showSDoc (pprInstLoc (instLoc friend)) == loc_msg
+
+groupErrs report_err [] 
+  = returnM ()
+groupErrs report_err (inst:insts) 
+  = do_one (inst:friends)              `thenM_`
+    groupErrs report_err others
+
+  where
+       -- (It may seem a bit crude to compare the error messages,
+       --  but it makes sure that we combine just what the user sees,
+       --  and it avoids need equality on InstLocs.)
+   (friends, others) = partition is_friend insts
+   loc_msg          = showSDoc (pprInstLoc (instLoc inst))
+   is_friend friend  = showSDoc (pprInstLoc (instLoc friend)) == loc_msg
+   do_one insts = addInstCtxt (instLoc (head insts)) (report_err insts)
+               -- Add location and context information derived from the Insts
+
+-- Add the "arising from..." part to a message about bunch of dicts
+addInstLoc :: [Inst] -> Message -> Message
+addInstLoc insts msg = msg $$ nest 2 (pprInstLoc (instLoc (head insts)))
 
 plural [x] = empty
 plural xs  = char 's'
 
+
 addTopIPErrs tidy_env tidy_dicts
-  = addInstErrTcM (instLoc (head tidy_dicts))
-       (tidy_env,
-        ptext SLIT("Unbound implicit parameter") <> plural tidy_dicts <+> pprInsts tidy_dicts)
+  = groupErrs report tidy_dicts
+  where
+    report dicts = addErrTcM (tidy_env, mk_msg dicts)
+    mk_msg dicts = addInstLoc dicts (ptext SLIT("Unbound implicit parameter") <> 
+                                    plural tidy_dicts <+> pprInsts tidy_dicts)
 
 -- Used for top-level irreducibles
 addTopInstanceErrs tidy_env tidy_dicts
-  = addInstErrTcM (instLoc (head tidy_dicts))
-       (tidy_env,
-        ptext SLIT("No instance") <> plural tidy_dicts <+> 
-               ptext SLIT("for") <+> pprInsts tidy_dicts)
-
-addAmbigErrs dicts
-  = mappM (addAmbigErr tidy_env) tidy_dicts
+  = groupErrs report tidy_dicts
   where
-    (tidy_env, tidy_dicts) = tidyInsts dicts
-
-addAmbigErr tidy_env tidy_dict
-  = addInstErrTcM (instLoc tidy_dict)
-       (tidy_env,
-        sep [text "Ambiguous type variable(s)" <+> pprQuotedList ambig_tvs,
-             nest 4 (text "in the constraint" <+> quotes (pprInst tidy_dict))])
+    report dicts = mkMonomorphismMsg tidy_env dicts    `thenM` \ (tidy_env, mono_msg) ->
+                  addErrTcM (tidy_env, mk_msg dicts $$ mono_msg)
+    mk_msg dicts = addInstLoc dicts (ptext SLIT("No instance") <> plural tidy_dicts <+> 
+                                    ptext SLIT("for") <+> pprInsts tidy_dicts)
+                  
+
+addTopAmbigErrs (tidy_env, tidy_dicts)
+-- Divide into groups that share a common set of ambiguous tyvars
+  = mapM report (equivClasses cmp [(d, tvs_of d) | d <- tidy_dicts])
   where
-    ambig_tvs = varSetElems (tyVarsOfInst tidy_dict)
+    tvs_of :: Inst -> [TcTyVar]
+    tvs_of d = varSetElems (tyVarsOfInst d)
+    cmp (_,tvs1) (_,tvs2) = tvs1 `compare` tvs2
+    
+    report :: [(Inst,[TcTyVar])] -> TcM ()
+    report pairs@((_,tvs) : _) -- The pairs share a common set of ambiguous tyvars
+       = mkMonomorphismMsg tidy_env dicts      `thenM` \ (tidy_env, mono_msg) ->
+         addErrTcM (tidy_env, msg $$ mono_msg)
+       where
+         dicts = map fst pairs
+         msg = sep [text "Ambiguous type variable" <> plural tvs <+> 
+                            pprQuotedList tvs <+> in_msg,
+                    nest 2 (pprInstsInFull dicts)]
+         in_msg | isSingleton dicts = text "in the top-level constraint:"
+                | otherwise         = text "in these top-level constraints:"
+
+
+mkMonomorphismMsg :: TidyEnv -> [Inst] -> TcM (TidyEnv, Message)
+-- There's an error with these Insts; if they have free type variables
+-- it's probably caused by the monomorphism restriction. 
+-- Try to identify the offending variable
+-- ASSUMPTION: the Insts are fully zonked
+mkMonomorphismMsg tidy_env insts
+  | isEmptyVarSet inst_tvs
+  = returnM (tidy_env, empty)
+  | otherwise
+  = findGlobals inst_tvs tidy_env      `thenM` \ (tidy_env, docs) ->
+    returnM (tidy_env, mk_msg docs)
 
+  where
+    inst_tvs = tyVarsOfInsts insts
+
+    mk_msg []   = empty                -- This happens in things like
+                               --      f x = show (read "foo")
+                               -- whre monomorphism doesn't play any role
+    mk_msg docs = vcat [ptext SLIT("Possible cause: the monomorphism restriction applied to the following:"),
+                       nest 2 (vcat docs),
+                       ptext SLIT("Probable fix: give these definition(s) an explicit type signature")]
+    
 warnDefault dicts default_ty
   = doptM Opt_WarnTypeDefaults  `thenM` \ warn_flag ->
-    addSrcLoc (get_loc (head dicts)) (warnTc warn_flag warn_msg)
+    addInstCtxt (instLoc (head dicts)) (warnTc warn_flag warn_msg)
   where
        -- Tidy them first
     (_, tidy_dicts) = tidyInsts dicts
-    get_loc i = case instLoc i of { (_,loc,_) -> loc }
     warn_msg  = vcat [ptext SLIT("Defaulting the following constraint(s) to type") <+>
                                quotes (ppr default_ty),
                      pprInstsInFull tidy_dicts]
 
 complainCheck doc givens irreds
-  = mappM zonkInst given_dicts_and_ips                   `thenM` \ givens' ->
-    mappM (addNoInstanceErrs doc givens') (groupInsts irreds)  `thenM_`
+  = mappM zonkInst given_dicts_and_ips                 `thenM` \ givens' ->
+    groupErrs (addNoInstanceErrs doc givens') irreds   `thenM_`
     returnM ()
   where
     given_dicts_and_ips = filter (not . isMethod) givens
@@ -1969,7 +2082,8 @@ addNoInstanceErrs what_doc givens dicts
        (tidy_env1, tidy_givens) = tidyInsts givens
        (tidy_env2, tidy_dicts)  = tidyMoreInsts tidy_env1 dicts
 
-       doc = vcat [sep [herald <+> pprInsts tidy_dicts,
+       doc = vcat [addInstLoc dicts $
+                   sep [herald <+> pprInsts tidy_dicts,
                         nest 4 $ ptext SLIT("from the context") <+> pprInsts tidy_givens],
                    ambig_doc,
                    ptext SLIT("Probable fix:"),
@@ -2016,7 +2130,7 @@ addNoInstanceErrs what_doc givens dicts
                where
                  (clas,tys) = getDictClassTys dict
     in
-    addInstErrTcM (instLoc (head dicts)) (tidy_env2, doc)
+    addErrTcM (tidy_env2, doc)
 
 -- Used for the ...Thetas variants; all top level
 noInstErr pred = ptext SLIT("No instance for") <+> quotes (ppr pred)
@@ -2032,9 +2146,4 @@ reduceDepthErr n stack
          nest 4 (pprInstsInFull stack)]
 
 reduceDepthMsg n stack = nest 4 (pprInstsInFull stack)
-
------------------------------------------------
-addCantGenErr inst
-  = addErrTc (sep [ptext SLIT("Cannot generalise these overloadings (in a _ccall_):"),
-                  nest 4 (ppr inst <+> pprInstLoc (instLoc inst))])
 \end{code}