[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / compiler / main / ErrsTc.lhs
diff --git a/ghc/compiler/main/ErrsTc.lhs b/ghc/compiler/main/ErrsTc.lhs
new file mode 100644 (file)
index 0000000..9d946e7
--- /dev/null
@@ -0,0 +1,935 @@
+%
+% (c) The AQUA Project, Glasgow University, 1994-1995
+%
+\section[ErrsTc]{Reporting errors from the typechecker}
+
+This is an internal module---access to these functions is through
+@Errors@.
+
+DPH errors are in here, too.
+
+\begin{code}
+#include "HsVersions.h"
+
+module ErrsTc (
+       UnifyErrContext(..), UnifyErrInfo(..),
+
+       ambigErr,
+       badMatchErr,
+       badSpecialisationErr,
+       classCycleErr,
+       confusedNameErr,
+       dataConArityErr,
+       defaultErr,
+       derivingEnumErr,
+       derivingIxErr,
+       derivingWhenInstanceExistsErr,
+       dupInstErr,
+       genCantGenErr,
+       instTypeErr,
+       methodTypeLacksTyVarErr,
+       naughtyCCallContextErr,
+       noInstanceErr,
+       nonBoxedPrimCCallErr,
+       notAsPolyAsSigErr,
+       preludeInstanceErr,
+       reduceErr,
+       sigContextsErr,
+       specCtxtGroundnessErr,
+       specDataNoSpecErr,
+       specDataUnboxedErr,
+       specGroundnessErr,
+       specInstUnspecInstNotFoundErr,
+       topLevelUnboxedDeclErr,
+       tyConArityErr,
+       typeCycleErr,
+       unifyErr,
+       varyingArgsErr
+    ) where
+
+import AbsSyn          -- we print a bunch of stuff in here
+import UniType         ( UniType(..) )         -- Concrete, to make some errors
+                                               -- more informative.
+import ErrUtils
+import AbsUniType      ( extractTyVarsFromTy, pprMaybeTy,
+                         TyVar, TyVarTemplate, TyCon,
+                         TauType(..), Class, ClassOp
+                         IF_ATTACK_PRAGMAS(COMMA pprUniType)
+                       )
+import Bag             ( Bag, bagToList )
+import GenSpecEtc      ( SignatureInfo(..) )
+import HsMatches       ( pprMatches, pprMatch, pprGRHS )
+import Id              ( getIdUniType, Id, isSysLocalId )
+import Inst            ( getInstOrigin, getDictClassAndType, Inst )
+import Name            ( cmpName )
+import Outputable
+import Pretty          -- to pretty-print error messages
+#ifdef DPH
+import PodizeMonad     ( PodWarning(..) )
+#endif {- Data Parallel Haskell -}
+import SrcLoc          ( mkUnknownSrcLoc, SrcLoc )
+import Util
+\end{code}
+
+\begin{code}
+ambigErr :: [Inst] -> Error
+ambigErr insts@(inst1:_)
+  = addErrLoc loc1 "Ambiguous overloading" ( \ sty ->
+    ppAboves (map (ppr_inst sty) insts) )
+  where
+    (loc1, _) = getInstOrigin inst1
+
+ppr_inst sty inst
+  = let
+       (clas, ty)  = getDictClassAndType inst
+       (locn, msg) = getInstOrigin inst
+    in
+    ppSep [ ppBesides [ppStr "class `", ppr sty clas,
+                      ppStr "', type `", ppr sty ty, ppStr "'"],
+           ppBesides [ppStr "(", msg sty, ppStr ")"] ]
+
+----------------------------------------------------------------
+badMatchErr :: UniType -> UniType -> UnifyErrContext -> SrcLoc -> Error
+badMatchErr sig_ty inferred_ty ctxt locn
+  = addErrLoc locn "Type signature mismatch" ( \ sty ->
+    let
+       thing
+         = case ctxt of 
+             SigCtxt id _     -> ppBesides [ppChar '`', ppr sty id, ppChar '\'']
+             MethodSigCtxt op _ -> ppBesides [ppStr "class method `", ppr sty op, ppStr "'"]
+             ExprSigCtxt _ _  -> ppStr "an expression"
+             Rank2ArgCtxt _ _ -> ppStr "an expression with rank-2 polymorphic type(!)"
+             ctxt             -> pprUnifyErrContext sty ctxt
+               -- the latter is ugly, but better than a patt-match failure
+    in
+    ppAboves [ppSep [
+               ppStr "Signature for", thing, ppStr "doesn't match its inferred type."
+             ],
+             ppHang (ppStr "Signature:") 4 (ppr sty sig_ty),
+             ppHang (ppStr "Inferred type:") 4 (ppr sty inferred_ty)
+    ] )
+
+----------------------------------------------------------------
+badSpecialisationErr :: String -> String -> Int -> [Maybe UniType] -> SrcLoc -> Error
+
+badSpecialisationErr flavor messg no_tyvars ty_maybes locn
+  = addErrLoc locn ("Bad "++flavor++" specialisation pragma: "++messg)  ( \ sty ->
+    ppStr "MSG NOT DONE YET"
+    )
+
+----------------------------------------------------------------
+confusedNameErr :: String
+               -> Name         -- the confused name
+               -> SrcLoc
+               -> Error
+confusedNameErr msg nm locn
+  = addErrLoc locn msg ( \ sty ->
+    ppr sty nm )
+{-
+  where
+    msg = if flag then "Type constructor used where a class is expected"
+                 else "Class used where a type constructor is expected"
+-}
+
+----------------------------------------------------------------
+typeCycleErr :: [[(Pretty, SrcLoc)]] -> Error
+typeCycleErr = cycleErr  "The following type synonyms refer to themselves:"
+
+classCycleErr :: [[(Pretty, SrcLoc)]] -> Error
+classCycleErr = cycleErr  "The following classes form a cycle:"
+
+cycleErr :: String -> [[(Pretty, SrcLoc)]] -> Error
+cycleErr msg cycles sty
+ = ppHang (ppStr msg)
+       4 (ppAboves (map pp_cycle cycles))
+ where
+   pp_cycle things     = ppAboves (map pp_thing things)
+   pp_thing (thing,loc) = ppHang (ppBesides [ppr PprForUser loc, ppStr ": "]) 4 thing
+
+----------------------------------------------------------------
+defaultErr :: [Inst]{-dicts-} -> [UniType] -> Error
+       -- when default-resolution fails...
+
+defaultErr dicts defaulting_tys sty
+  = ppHang (ppStr "Ambiguously-overloaded types could not be resolved:")
+        4 (ppAboves [
+            ppHang (ppStr "Conflicting:")
+                 4 (ppInterleave ppSemi (map (ppr_inst sty) dicts)),
+            ppHang (ppStr "Defaulting types :")
+                 4 (ppr sty defaulting_tys),
+            ppStr "([Int, Double] is the default list of defaulting types.)" ])
+
+----------------------------------------------------------------
+derivingEnumErr :: TyCon -> Error
+derivingEnumErr tycon
+  = addErrLoc (getSrcLoc tycon) "Can't derive an instance of `Enum'" ( \ sty ->
+    ppBesides [ppStr "type `", ppr sty tycon, ppStr "'"] )
+
+----------------------------------------------------------------
+derivingIxErr :: TyCon -> Error
+derivingIxErr tycon
+  = addErrLoc (getSrcLoc tycon) "Can't derive an instance of `Ix'" ( \ sty ->
+    ppBesides [ppStr "type `", ppr sty tycon, ppStr "'"] )
+
+----------------------------------------------------------------
+derivingWhenInstanceExistsErr :: Class -> TyCon -> Error
+derivingWhenInstanceExistsErr clas tycon
+  = addErrLoc (getSrcLoc tycon) "`deriving' when an instance also exists" ( \ sty ->
+    ppBesides [ppStr "class `", ppr sty clas,
+              ppStr "', type `", ppr sty tycon, ppStr "'"] )
+
+----------------------------------------------------------------
+{- UNUSED:
+derivingNoSuperClassInstanceErr :: Class -> TyCon -> Class -> Error
+derivingNoSuperClassInstanceErr clas tycon super_class
+  = addErrLoc (getSrcLoc tycon) "No instance for a superclass in a `deriving'" ( \ sty ->
+    ppSep [ppBesides [ppStr "the superclass `", ppr sty super_class, ppStr "' has no instance"],
+          ppBesides [ppStr "at the type `", ppr sty tycon, ppStr "';"],
+          ppBesides [ppStr "(the class being \"derived\" is `", ppr sty clas, ppStr "')"]
+         ])
+-}
+
+----------------------------------------------------------------
+dupInstErr :: (Class, (UniType, SrcLoc), (UniType, SrcLoc)) -> Error
+dupInstErr (clas, info1@(ty1, locn1), info2@(ty2, locn2))
+       -- Overlapping/duplicate instances for given class; msg could be more glamourous
+  = addErrLoc locn1 "Duplicate/overlapping instances" ( \ sty ->
+    ppSep [ ppBesides [ppStr "class `", ppr sty clas, ppStr "',"],
+           showOverlap sty info1 info2] )
+
+----------------------------------------------------------------
+{- UNUSED?
+extraMethodsErr :: [Id] {-dicts-} -> SrcLoc -> Error
+       -- when an instance decl has binds for methods that aren't in the class decl
+extraMethodsErr extra_methods locn
+  = addErrLoc locn "Extra methods in instance declaration" ( \ sty ->
+    interpp'SP sty extra_methods )
+-}
+
+----------------------------------------------------------------
+genCantGenErr :: [Inst] -> Error
+genCantGenErr insts@(inst1:_)
+  = addErrLoc loc1 "Cannot generalise these overloadings (in a _ccall_):" ( \ sty ->
+    ppAboves (map (ppr_inst sty) insts) )
+  where
+    (loc1, _) = getInstOrigin inst1
+
+----------------------------------------------------------------
+{- UNUSED:
+genPrimTyVarErr :: [TyVar] -> SrcLoc -> Error
+       -- Attempt to generalise over a primitive type variable
+
+genPrimTyVarErr tyvars locn
+  = addErrLoc locn "These primitive type variables can't be made more general" ( \ sty ->
+       ppAbove (interpp'SP sty tyvars)
+               (ppStr "(Solution: add a type signature.)") )
+-}
+----------------------------------------------------------------
+noInstanceErr :: Inst -> Error
+noInstanceErr inst
+  = let (clas, ty)  = getDictClassAndType inst
+       (locn, msg) = getInstOrigin inst
+    in
+    addErrLoc locn "No such instance" ( \ sty ->
+    ppSep [ ppBesides [ppStr "class `", ppr sty clas,
+                      ppStr "', type `", ppr sty ty, ppStr "'"],
+           ppBesides [ppStr "(", msg sty, ppStr ")"] ]
+    )
+
+----------------------------------------------------------------
+{- UNUSED:
+instOpErr :: Id -> Class -> TyCon -> Error
+
+instOpErr dict clas tycon
+       -- no instance of "Class" for "TyCon"
+       -- the Id is the offending dictionary; has src location
+       -- (and we could get the Class and TyCon from it, but
+       -- since we already have it at hand ...)
+  = addErrLoc (getSrcLoc dict) "Invalid instance" ( \ sty ->
+    ppBesides [ ppStr "There is no instance of `", ppr sty tycon,
+               ppStr "' for class `",
+               ppr sty clas, ppChar '\'' ] )
+-}
+
+----------------------------------------------------------------
+instTypeErr :: UniType -> SrcLoc -> Error
+instTypeErr ty locn
+  = addShortErrLocLine locn (\ sty ->
+    let
+       rest_of_msg = ppStr "' cannot be used as the instance type\n    in an instance declaration."
+    in
+    case ty of
+      UniSyn tc _ _ -> ppBesides [ppStr "The type synonym `", ppr sty tc, rest_of_msg]
+      UniTyVar tv   -> ppBesides [ppStr "The type variable `", ppr sty tv, rest_of_msg]
+      other        -> ppBesides [ppStr "The type `", ppr sty ty, rest_of_msg]
+    )
+
+----------------------------------------------------------------
+{- UNUSED:
+methodInstErr :: (ClassOp, (UniType, SrcLoc), (UniType, SrcLoc)) -> Error
+methodInstErr (class_op, info1, info2) sty
+       -- Two instances for given class op
+  = ppHang (ppBesides [ ppStr "The class method `", ppr sty class_op, ppStr "' has been given more than one definition for"])
+       4 (showOverlap sty info1 info2)
+-}
+
+showOverlap :: PprStyle -> (UniType, SrcLoc) -> (UniType, SrcLoc) -> Pretty
+showOverlap sty (ty1,loc1) (ty2,loc2)
+  = ppSep [ppBesides [ppStr "type `", ppr sty ty1, ppStr "'"],
+          ppBeside (ppStr "at ") (ppr sty loc1),
+          ppBeside (ppStr "and ") (ppr sty loc2)]
+
+----------------------------------------------------------------
+methodTypeLacksTyVarErr :: TyVarTemplate -> String -> SrcLoc -> Error
+methodTypeLacksTyVarErr tyvar method_name locn
+  = addErrLoc locn "Method's type doesn't mention the class type variable"  (\ sty ->
+    ppAboves [ppBeside (ppStr "Class type variable: ") (ppr sty tyvar),
+             ppBeside (ppStr "Method: ") (ppStr method_name)] )
+
+----------------------------------------------------------------
+{- UNUSED:
+missingClassOpErr :: Id -> [ClassOp] -> SrcLoc -> Error
+missingClassOpErr op classops locn
+  = addErrLoc locn "Undefined class method" ( \ sty ->
+    ppBesides [ ppr sty op, ppStr "; valid method(s):",
+               interpp'SP sty classops ] )
+-}
+
+----------------------------------------------------------------
+naughtyCCallContextErr :: Name -> SrcLoc -> Error
+naughtyCCallContextErr clas_name locn
+  = addErrLoc locn "Can't use this class in a context" (\ sty ->
+    ppr sty clas_name )
+
+----------------------------------------------------------------
+nonBoxedPrimCCallErr :: Class -> UniType -> SrcLoc -> Error
+nonBoxedPrimCCallErr clas inst_ty locn
+  = addErrLoc locn "Instance isn't for a `boxed-primitive' type" ( \ sty ->
+    ppBesides [ ppStr "class `", ppr sty clas, ppStr "'; type `",
+               ppr sty inst_ty, ppStr "'"] )
+
+----------------------------------------------------------------
+notAsPolyAsSigErr :: UniType -> [TyVar] -> UnifyErrContext -> SrcLoc -> Error
+notAsPolyAsSigErr sig_ty mono_tyvars ctxt locn
+  = addErrLoc locn "A type signature is more polymorphic than the inferred type" ( \ sty ->
+    ppAboves [  ppStr "(That is, one or more type variables in the inferred type can't be forall'd.)",
+               pprUnifyErrContext sty ctxt,
+               ppHang (ppStr "Monomorphic type variable(s):")
+                  4 (interpp'SP sty mono_tyvars),
+               ppStr "Possible cause: the RHS mentions something subject to the monomorphism restriction"
+       ] )
+
+----------------------------------------------------------------
+{- UNUSED:
+patMatchWithPrimErr :: Error
+patMatchWithPrimErr
+  = dontAddErrLoc
+       "Pattern-bindings may not involve primitive types." ( \ sty ->
+       ppNil )
+-}
+
+----------------------------------------------------------------
+preludeInstanceErr :: Class -> UniType -> SrcLoc -> Error
+preludeInstanceErr clas ty locn
+  = addShortErrLocLine locn ( \ sty ->
+    ppHang (ppBesides [ppStr "Illegal instance: for Prelude class `", ppr sty clas,
+                        ppStr "' and Prelude type `", ppr sty ty, ppStr "'."] )
+        4 (ppStr "(An instance decl must be in the same module as the type decl or the class decl)") )
+
+----------------------------------------------------------------
+{- UNUSED:
+purelyLocalErr :: Name -> SrcLoc -> Error
+purelyLocalErr thing locn
+  = addShortErrLocLine locn ( \ sty ->
+    ppBesides [ppStr "`", ppr sty thing,
+              ppStr "' cannot be exported -- it would refer to an unexported local entity."] )
+-}
+
+----------------------------------------------------------------
+reduceErr :: [Inst] -> UnifyErrContext -> Error
+       -- Used by tcSimplifyCheckLIE
+       -- Could not express required dictionaries in terms of the signature
+reduceErr insts ctxt
+  = dontAddErrLoc "Type signature lacks context required by inferred type" ( \ sty ->
+    ppAboves [
+       pprUnifyErrContext sty ctxt,
+       ppHang (ppStr "Context reqd: ")
+            4 (ppAboves (map (ppr_inst sty) insts))
+    ])
+  where
+    ppr_inst sty inst
+      = let (clas, ty)  = getDictClassAndType inst
+           (locn, msg) = getInstOrigin inst
+       in
+       ppSep [ ppBesides [ppr sty locn, ppStr ": ", ppr sty clas, ppSP, ppr sty ty],
+               ppBesides [ppStr "(", msg sty, ppStr ")"] ]
+
+----------------------------------------------------------------
+{-
+unexpectedPreludeThingErr :: Outputable a => String -> a -> SrcLoc -> Error
+
+unexpectedPreludeThingErr category thing locn
+  = addShortErrLocLine locn ( \ sty ->
+    ppBesides [ppStr "Prelude ", ppStr category,
+              ppStr " not expected here: ", ppr sty thing])
+-}
+
+----------------------------------------------------------------
+specGroundnessErr :: UnifyErrContext -> [UniType] -> Error
+
+specGroundnessErr (ValSpecSpecIdCtxt name spec_ty spec locn) arg_tys
+  = addShortErrLocLine locn ( \ sty ->
+    ppHang (
+        ppSep [ppBesides [ppStr "In the SPECIALIZE pragma for `", ppr sty name, ppStr "'"],
+              ppBesides [ppStr "... type of explicit id `", ppr sty spec, ppStr "'"],
+              ppStr "... not all type variables were instantiated",
+              ppStr "to type variables or ground types (nothing in between, please!):"])
+      4 (ppAboves (map (ppr sty) arg_tys))
+    )
+
+----------------------------------------------------------------
+specCtxtGroundnessErr :: UnifyErrContext -> [Inst] -> Error
+
+specCtxtGroundnessErr err_ctxt dicts
+  = addShortErrLocLine locn ( \ sty ->
+    ppHang (
+       ppSep [ppBesides [ppStr "In the SPECIALIZE pragma for `", ppr sty name, ppStr "'"],
+              ppBesides [ppStr " specialised to the type `", ppr sty spec_ty,  ppStr "'"],
+              pp_spec_id sty,
+              ppStr "... not all overloaded type variables were instantiated",
+              ppStr "to ground types:"])
+      4 (ppAboves [ppCat [ppr sty c, ppr sty t]
+                 | (c,t) <- map getDictClassAndType dicts])
+    )
+  where
+    (name, spec_ty, locn, pp_spec_id)
+      = case err_ctxt of
+         ValSpecSigCtxt    n ty loc      -> (n, ty, loc, \ x -> ppNil)
+         ValSpecSpecIdCtxt n ty spec loc ->
+           (n, ty, loc,
+            \ sty -> ppBesides [ppStr "... type of explicit id `", ppr sty spec, ppStr "'"])
+
+----------------------------------------------------------------
+specDataNoSpecErr :: Name -> [UniType] -> SrcLoc -> Error
+
+specDataNoSpecErr name arg_tys locn
+  = addShortErrLocLine locn ( \ sty ->
+    ppHang (
+       ppSep [ppBesides [ppStr "In the SPECIALIZE pragma for `", ppr sty name, ppStr "'"],
+              ppStr "... no unboxed type arguments in specialisation:"])
+     4 (ppAboves (map (ppr sty) arg_tys))
+    )
+
+----------------------------------------------------------------
+specDataUnboxedErr :: Name -> [UniType] -> SrcLoc -> Error
+
+specDataUnboxedErr name arg_tys locn
+  = addShortErrLocLine locn ( \ sty ->
+    ppHang (
+       ppSep [ppBesides [ppStr "In the SPECIALIZE pragma for `", ppr sty name, ppStr "'"],
+              ppStr "... not all type arguments were specialised to",
+              ppStr "specific unboxed types or (boxed) type variables:"])
+      4 (ppAboves (map (ppr sty) arg_tys))
+    )
+
+----------------------------------------------------------------
+specInstUnspecInstNotFoundErr :: Class -> UniType -> SrcLoc -> Error
+
+specInstUnspecInstNotFoundErr clas inst_ty locn
+  = addErrLoc locn "No local instance to specialise" ( \ sty ->
+    ppBesides [ ppStr "class `", ppr sty clas, ppStr "' at the type `",
+               ppr sty inst_ty, ppStr "'"] )
+
+----------------------------------------------------------------
+-- The type signatures on a mutually-recursive group of definitions
+-- must all have the same context (or none).  For example:
+--     f :: Eq a => ...
+--     g :: (Eq a, Text a) => ...
+-- is illegal if f and g are mutually recursive.  This also
+-- applies to variables bound in the same pattern binding.
+
+sigContextsErr :: [SignatureInfo] -> Error
+
+sigContextsErr infos
+  = dontAddErrLoc "A group of type signatures have mismatched contexts" ( \ sty ->
+    ppAboves (map (ppr_sig_info sty) infos) )
+  where
+    ppr_sig_info sty (TySigInfo val tyvars insts tau_ty _)
+      = ppHang (ppBeside (ppr sty val) (ppStr " :: "))
+            4 (ppHang (if null insts
+                       then ppNil
+                       else ppBesides [ppStr "(", ppInterleave ppComma (map (ppr_inst sty) insts), ppStr ") => "])
+                    4 (ppr sty tau_ty))
+
+    ppr_inst sty inst
+      = let (clas, ty)  = getDictClassAndType inst
+           (locn, msg) = getInstOrigin inst
+       in
+       ppCat [ppr sty clas, ppr sty ty]
+
+----------------------------------------------------------------
+topLevelUnboxedDeclErr :: Id -> SrcLoc -> Error
+       -- Top level decl of something with a primitive type
+
+topLevelUnboxedDeclErr id locn
+  = addShortErrLocLine locn ( \ sty ->
+       ppBesides [ppStr "The top-level value `", ppr sty id, ppStr "' shouldn't have an unboxed type." ])
+
+----------------------------------------------------------------
+dataConArityErr :: Id   -> Int -> Int -> SrcLoc -> Error
+tyConArityErr   :: Name -> Int -> Int -> SrcLoc -> Error
+
+tyConArityErr   = arityError "Type"
+dataConArityErr = arityError "Constructor"
+
+arityError kind name n m locn = 
+    addErrLoc locn errmsg
+    (\ sty ->
+    ppBesides [ ppStr "`", ppr sty name, ppStr "' should have ",
+               n_arguments, ppStr ", but has been given ", ppInt m, ppChar '.'])
+    where
+       errmsg = kind ++ " has too " ++ quantity ++ " arguments"
+       quantity | m < n     = "few"
+                | otherwise = "many"
+       n_arguments | n == 0 = ppStr "no arguments"
+                   | n == 1 = ppStr "1 argument"
+                   | True   = ppCat [ppInt n, ppStr "arguments"]
+
+----------------------------------------------------------------
+unifyErr :: UnifyErrInfo -> UnifyErrContext -> SrcLoc -> Error
+
+unifyErr unify_err_info unify_err_context locn
+  = addShortErrLocLine locn ( \ sty ->
+    pprUnifyErrInfo sty unify_err_info unify_err_context)
+
+----------------------------------------------------------------
+varyingArgsErr :: Name -> [RenamedMatch] -> Error
+       -- Different number of arguments in different equations
+
+varyingArgsErr name matches
+  = dontAddErrLoc "Varying number of arguments for function" ( \ sty ->
+    ppr sty name )
+{-
+varyingArgsErr name matches
+  = addErrLoc locn "Function Definition Error" ( \ sty ->
+       ppBesides [ppStr "Function `", ppr sty name, ppStr "' should have a fixed number of arguments" ])
+-}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection[UnifyErr-types]{@UnifyErrInfo@ and @UnifyErrContext@ datatypes}
+%*                                                                     *
+%************************************************************************
+
+Here are the things that can go wrong during unification:
+
+\begin{code}
+data UnifyErrInfo
+  = UnifyMisMatch      UniType UniType
+  | TypeRec            TyVar   TauType -- Occurs check failure
+
+  | UnifyListMisMatch  [TauType] [TauType]   -- Args to unifyList: diff lengths
+                                             -- produces system error
+\end{code}
+
+@UnifyErrContext@ gives some context for unification
+errors found in expressions.  Also see the @UnifyErrInfo@ type (above),
+as well as the general error-reporting type @Error@ (in @TcErrors@).
+\begin{code}
+data UnifyErrContext
+  = PredCtxt           RenamedExpr
+  | AppCtxt            RenamedExpr RenamedExpr
+
+  | TooManyArgsCtxt    RenamedExpr     -- The offending function
+                                       -- We don't want the typechecked expr here,
+                                       -- because that may be full of 
+                                       -- confusing dictionaries
+
+  | FunAppCtxt         RenamedExpr     -- The offending function
+                       (Maybe Id)      -- same info (probably) in a more convenient form
+                       RenamedExpr     -- The offending arg
+                       UniType         -- Expected type of offending arg
+                       UniType         -- Inferred type for offending arg
+                       Int             -- Which arg number (first is 1)
+
+  | OpAppCtxt          RenamedExpr RenamedExpr RenamedExpr
+  | SectionLAppCtxt    RenamedExpr RenamedExpr
+  | SectionRAppCtxt    RenamedExpr RenamedExpr
+  | CaseCtxt           RenamedExpr [RenamedMatch]
+  | BranchCtxt         RenamedExpr RenamedExpr
+  | ListCtxt           [RenamedExpr]
+  | PatCtxt            RenamedPat
+  | CaseBranchesCtxt   [RenamedMatch]
+  | FilterCtxt         RenamedExpr
+  | GeneratorCtxt      RenamedPat RenamedExpr
+  | GRHSsBranchCtxt    [RenamedGRHS]
+  | GRHSsGuardCtxt     RenamedExpr
+  | PatMonoBindsCtxt   RenamedPat RenamedGRHSsAndBinds
+  | FunMonoBindsCtxt   Name [RenamedMatch]
+  | MatchCtxt          UniType UniType
+  | ArithSeqCtxt       RenamedExpr
+  | CCallCtxt          String [RenamedExpr]
+  | AmbigDictCtxt      [Inst]  -- Occurs check when simplifying ambiguous
+                               -- dictionaries.  Should never happen!
+  | SigCtxt            Id UniType
+  | MethodSigCtxt      Name UniType
+  | ExprSigCtxt                RenamedExpr UniType
+  | ValSpecSigCtxt     Name UniType SrcLoc
+  | ValSpecSpecIdCtxt  Name UniType Name SrcLoc
+
+       -- The next two contexts are associated only with TcSimplifyAndCheck failures
+  | BindSigCtxt                [Id]            -- Signature(s) for a group of bindings
+  | SuperClassSigCtxt                  -- Superclasses for this instance decl
+
+  | CaseBranchCtxt     RenamedMatch
+  | Rank2ArgCtxt       TypecheckedExpr UniType
+#ifdef DPH
+  | PodCtxt            [RenamedExpr]
+  | ParFilterCtxt       RenamedExpr
+  | DrawnCtxt          [RenamedPat]  RenamedPat RenamedExpr
+  | IndexCtxt          [RenamedExpr] RenamedPat RenamedExpr
+  | ParPidPatCtxt      RenamedPat 
+  | ParPidExpCtxt      RenamedExpr
+  | ParZFlhsCtxt       RenamedExpr
+#endif {- Data Parallel Haskell -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection[Errors-print-unify]{Printing unification error info}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+ppUnifyErr :: Pretty -> Pretty -> Pretty
+ppUnifyErr head rest = ppSep [head, {-if you want a blank line: ppSP,-} rest]
+
+pprUnifyErrInfo sty (UnifyMisMatch mt1 mt2) err_ctxt
+ = ppUnifyErr (ppSep [ppBesides [ppStr "Couldn't match the type `", ppr sty mt1, ppStr "'"],
+                     ppBesides [ppStr "against `", ppr sty mt2, ppStr "'."]])
+             (pprUnifyErrContext sty err_ctxt)
+
+pprUnifyErrInfo sty (TypeRec tyvar ty) err_ctxt
+ = ppUnifyErr (ppBesides [ppStr "Cannot construct the infinite type `",
+                                ppr sty tyvar, 
+                                ppStr "' = `",ppr sty ty, ppStr "' (\"occurs check\")."])
+             (pprUnifyErrContext sty err_ctxt)
+
+pprUnifyErrInfo sty (UnifyListMisMatch tys1 tys2) err_ctxt
+ = panic "pprUnifyErrInfo: unifying lists of types of different lengths"
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection[Errors-print-context]{Printing unification error context}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+pp_nest_hang :: String -> Pretty -> Pretty
+pp_nest_hang label stuff = ppNest 2 (ppHang (ppStr label) 4 stuff)
+
+context = "Error detected when type-checking "
+
+ppContext s = ppStr (context ++ s)
+
+pprUnifyErrContext sty (PredCtxt e)
+  = ppHang (ppStr "In a predicate expression:") 4 (ppr sty e)
+
+pprUnifyErrContext sty (AppCtxt f a)
+  = ppHang (ppStr "In a function application:") 4 (ppr sty (App f a))
+
+pprUnifyErrContext sty (FunAppCtxt f maybe_id actual_arg expected_arg_ty actual_arg_ty n)
+  = let
+
+       (have_extra_info, f_id, f_type)
+          = case maybe_id of
+              Nothing -> (False, bottom, bottom)
+              Just id -> (True,  id, getIdUniType id)
+
+       free_tyvars = extractTyVarsFromTy f_type
+       bottom = panic "no maybe_id"
+    in
+    ppAboves [
+       ppHang (ppCat [ ppStr "In the", speakNth n, ppStr "argument of",
+                       ppBesides [ppChar '`', ppr sty f, ppStr "',"] ])
+       4 (ppBesides [ppStr " namely `", ppr sty actual_arg, ppStr "'," ]),
+
+       ppHang  (ppStr "Expected type of the argument: ")
+               4 (ppr sty expected_arg_ty),
+
+       ppHang  (ppStr "Inferred type of the argument: ")
+               4 (ppr sty actual_arg_ty),
+
+{- OMIT
+   I'm not sure this adds anything 
+
+       if have_extra_info
+       then ppHang (ppCat [ppStr "The type of",
+                           ppBesides [ppChar '`', ppr sty f_id, ppChar '\''],
+                           ppStr "is"]) 4
+                   (ppBesides [ppChar '`', ppr sty f_type, ppStr "'."])
+       else ppNil,
+-}
+       
+       if not have_extra_info || null free_tyvars || isSysLocalId f_id
+               -- SysLocals are created for the local (monomorphic) versions
+               -- of recursive functions, and the monomorphism suggestion 
+               -- below is sometimes positively misleading.  Notably,
+               -- if you give an erroneous type sig, you may well end
+               -- up with a unification error like this, and it usually ain't due
+               -- to monomorphism.
+       then ppNil
+       else
+          ppAboves [
+               ppSep [ppStr "Possible cause of error:",
+                      ppBesides [ppChar '`', ppr sty f, ppChar '\''],
+                      ppStr "is not polymorphic"],
+               ppSep [ppStr "it is monomorphic in the type variable(s):", 
+                      interpp'SP sty free_tyvars]
+          ]
+    ]
+
+pprUnifyErrContext sty (TooManyArgsCtxt f)
+  = ppHang (ppStr "Too many arguments in an application of the function")
+        4 (ppBesides [ ppChar '`', ppr sty f, ppStr "'." ])
+
+pprUnifyErrContext sty (SectionLAppCtxt expr op)
+  = ppHang (ppStr "In a left section:")  4 (ppr sty (SectionL expr op))
+
+pprUnifyErrContext sty (SectionRAppCtxt op expr)
+  = ppHang (ppStr "In a right section:") 4 (ppr sty (SectionR op expr))
+
+pprUnifyErrContext sty (OpAppCtxt a1 op a2)
+  = ppHang (ppStr "In an infix-operator application:") 4 (ppr sty (OpApp a1 op a2))
+
+pprUnifyErrContext sty (CaseCtxt e as)
+  = ppHang (ppStr "In a case expression:") 4 (ppr sty (Case e as))
+
+pprUnifyErrContext sty (BranchCtxt b1 b2)
+  = ppSep [ppStr "In the branches of a conditional:",
+          pp_nest_hang "`then' branch:" (ppr sty b1),
+          pp_nest_hang "`else' branch:" (ppr sty b2)]
+
+pprUnifyErrContext sty (ListCtxt es)
+  = ppHang (ppStr "In a list expression:") 4 (
+             ppBesides [ppLbrack, interpp'SP sty es, ppRbrack])
+
+pprUnifyErrContext sty (PatCtxt (ConPatIn name pats))
+  = ppHang (ppStr "In a constructed pattern:")
+        4 (ppCat [ppr sty name, interppSP sty pats])
+
+pprUnifyErrContext sty (PatCtxt (ConOpPatIn pat1 op pat2))
+  = ppHang (ppStr "In an infix-operator pattern:")
+        4 (ppCat [ppr sty pat1, ppr sty op, ppr sty pat2])
+
+pprUnifyErrContext sty (PatCtxt (ListPatIn ps))
+  = ppHang (ppStr "In an explicit list pattern:")
+        4 (ppBesides [ppLbrack, interpp'SP sty ps, ppRbrack])
+
+pprUnifyErrContext sty (PatCtxt pat@(AsPatIn _ _))
+  = ppHang (ppStr "In an as-pattern:") 4 (ppr sty pat)
+
+pprUnifyErrContext sty (CaseBranchesCtxt (m:ms))
+  = ppAboves [ppStr "Inside two case alternatives:",
+             ppNest 4 (ppBeside (ppStr "... ") (pprMatches sty (True,ppNil) [m])),
+             ppNest 4 (ppBeside (ppStr "... ") (pprMatches sty (True,ppNil) ms))]
+
+pprUnifyErrContext sty (FilterCtxt e)
+  = ppHang (ppStr "In a guard in a list-comprehension:") 4 (ppr sty e)
+
+pprUnifyErrContext sty (GeneratorCtxt p e)
+  = ppHang (ppStr "In a generator in a list-comprehension:")
+        4 (ppSep [ppr sty p, ppStr "<-", ppr sty e])
+
+pprUnifyErrContext sty (GRHSsBranchCtxt grhss)
+  = ppAboves [ppStr "In some guarded right-hand-sides:",
+             ppNest 4 (ppAboves (map (pprGRHS sty False) grhss))]
+
+pprUnifyErrContext sty (GRHSsGuardCtxt g)
+  = ppHang (ppStr "In a guard on an equation:") 4 (ppr sty g)
+
+pprUnifyErrContext sty (PatMonoBindsCtxt pat grhss_and_binds)
+  = ppHang (ppStr "In a pattern binding:")
+        4 (ppr sty (PatMonoBind pat grhss_and_binds mkUnknownSrcLoc))
+
+pprUnifyErrContext sty (FunMonoBindsCtxt id matches)
+  = ppHang (ppStr "When combining a function's equation(s) & type signature (if applicable):")
+        4 (ppBesides [ppr sty id, ppSP, pprMatches sty (False,ppNil) matches])
+
+pprUnifyErrContext sty (CaseBranchCtxt match)
+  = ppHang (ppStr "When combining a \"case\" branch & type signature (if applicable):")
+        4 (pprMatch sty True{-is_case-} match)
+
+pprUnifyErrContext sty (MatchCtxt ty1 ty2)
+  = ppAboves [ppStr "In a type signature:",
+             pp_nest_hang "Signature:" (ppr sty ty1),
+             pp_nest_hang "Inferred type:" (ppr sty ty2)]
+
+pprUnifyErrContext sty (ArithSeqCtxt expr)
+  = ppHang (ppStr "In an arithmetic sequence:") 4 (ppr sty expr)
+
+pprUnifyErrContext sty (CCallCtxt label args)
+  = ppAboves [ppStr "In a _ccall_ or _casm_:",
+             pp_nest_hang "C-calling magic:" (ppStr label),
+             pp_nest_hang "Arguments:" (ppInterleave ppComma (map (ppr sty) args))]
+
+-- OLD: kill
+pprUnifyErrContext sty (AmbigDictCtxt dicts)
+  = ppStr "Ambiguous dictionary occurs check: should never happen!"
+
+pprUnifyErrContext sty (SigCtxt id tau_ty)
+  = ppHang (ppBesides [ppStr "In the type signature for ",
+                  ppr sty id,
+                  ppStr ":"]
+          ) 4 (ppr sty tau_ty)
+
+pprUnifyErrContext sty (MethodSigCtxt name ty)
+  = ppHang (ppBesides [ ppStr "When matching the definition of class method `",
+               ppr sty name, ppStr "' to its signature :" ]
+          ) 4 (ppr sty ty)
+
+pprUnifyErrContext sty (ExprSigCtxt expr ty)
+  = ppHang (ppStr "In an expression with a type signature:")
+        4 (ppSep [ppBeside (ppr sty expr) (ppStr " ::"),
+                 ppr sty ty])
+
+pprUnifyErrContext sty (BindSigCtxt ids)
+  = ppHang (ppStr "When checking type signatures for: ")
+        4 (ppInterleave (ppStr ", ") (map (ppr sty) ids))
+
+pprUnifyErrContext sty SuperClassSigCtxt
+  = ppStr "When checking superclass constraints on instance declaration"
+
+pprUnifyErrContext sty (Rank2ArgCtxt expr ty)
+  = ppHang (ppStr "In an argument which has rank-2 polymorphic type:")
+        4 (ppSep [ppBeside (ppr sty expr) (ppStr " ::"),
+                 ppr sty ty])
+
+pprUnifyErrContext sty (ValSpecSigCtxt v ty src_loc)
+  = ppHang (ppStr "In a SPECIALIZE pragma for a value:")
+        4 (ppSep [ppBeside (ppr sty v) (ppStr " ::"),
+                 ppr sty ty])
+
+pprUnifyErrContext sty (ValSpecSpecIdCtxt v ty spec src_loc)
+  = ppHang (ppStr "When checking type of explicit id in SPECIALIZE pragma:")
+        4 (ppSep [ppBeside (ppr sty v) (ppStr " ::"),
+                 ppr sty ty,
+                 ppBeside (ppStr " = ") (ppr sty spec)])
+
+#ifdef DPH
+pprUnifyErrContext sty (PodCtxt es)
+  = ppAboves [ppStr "In a POD expression:",
+             ppBesides [ppStr "<<", interpp'SP sty es, ppStr ">>"]]
+
+pprUnifyErrContext sty (ParFilterCtxt e)
+  = ppHang (ppStr "In a guard of a POD comprehension:") 4 
+          (ppr sty e)
+
+pprUnifyErrContext sty (DrawnCtxt ps p e)
+  = ppHang (ppStr "In parallel drawn from generator:")
+          4 (ppSep [ppStr "(|" ,interpp'SP sty ps, ppStr ";" , 
+                    ppr sty p ,ppStr "|)", ppStr "<<-", ppr sty e])
+
+pprUnifyErrContext sty (IndexCtxt es p e)
+  = ppHang (ppStr "In parallel index from generator:")
+          4 (ppSep [ppStr "(|",interpp'SP sty es, ppStr ";" , 
+                    ppr sty p ,ppStr "|)" , ppStr "<<=", ppr sty e])
+
+pprUnifyErrContext sty (ParPidPatCtxt p)
+  = ppHang (ppStr "In pattern for processor ID has to be in class Pid:")
+          4 (ppr sty p)
+
+pprUnifyErrContext sty (ParPidExpCtxt e)
+  = ppHang (ppStr "In expression for processor ID has to be in class Pid:")
+          4 (ppr sty e)
+
+pprUnifyErrContext sty (ParZFlhsCtxt e)
+  = ppHang (ppStr "In LHS of a POD comprehension has to be in class Processor")
+          4 (ppr sty e)
+
+#endif {- Data Parallel Haskell -}
+\end{code}
+
+\begin{code}
+#ifdef DPH
+pprPodizedWarning :: PodWarning -> Error
+pprPodizedWarning (EntryNotPodized b)
+   = addWarningLoc (getSrcLoc b)                               (\ sty ->
+     ppBeside (ppStr "Unable to parallelise entry: ")
+              (ppr sty b)
+     )
+
+pprPodizedWarning (NoGoNestedPodized b)
+   = addWarningLoc (getSrcLoc b)                               (\ sty ->
+     ppBeside (ppStr "Sorry no nested parallelism yet: ")
+             (ppr sty b)
+   )
+
+pprPodizedWarning (ContextNotAvailable b c)
+   = addWarningLoc (getSrcLoc b)                               (\ sty ->
+     ppAbove (ppBesides [ppStr "No parallelisation of binding for a ",
+                        ppStr (show_context c) , ppStr ": ",ppr sty b])
+            (ppBesides [ppStr "Maybe you should re-compile this module ",
+                        ppStr "with the `",ppStr (which_flag c), 
+                        ppStr "' flag."])
+     )
+
+pprPodizedWarning (ImportNotAvailable b c)
+   = addWarningLoc (getSrcLoc b)                               (\ sty ->
+     ppAboves [ppBesides [ppStr "No parallelisation of binding for a ",
+                         ppStr (show_context c),ppStr ": ", ppr sty b],
+              ppBesides [ppStr "If you re-compile the module `",
+                         ppStr (fst (getOrigName b)), ppStr "`"],
+              ppBesides [ppStr "with the `",ppStr (which_flag c),
+                         ppStr "' flag I may do a better job :-)"]]
+     )
+
+
+pprPodizedWarning (ArgsInDifferentContexts b)
+   = addWarningLoc (getSrcLoc b)                               (\ sty ->
+     ppBesides [ppStr "Higher Order argument used in different ",
+               ppStr "parallel contexts : ",ppr sty b]
+     )
+
+pprPodizedWarning (NoPodization)
+   = addWarning                                                (\ sty ->
+     ppStr "Program not podized")
+
+pprPodizedWarning (PodizeStats ci pi vl pl)
+   = addWarning                                                (\ sty ->
+     (ppHang (ppStr "Podization Statistics:")
+            5
+             (ppAboves [ppCat [ppStr "Info collecting passes =",ppr sty ci],
+                       ppCat [ppStr "Podization passes      =",ppr sty pi],
+                       ppCat [ppStr "Vanilla's deleted      =",ppr sty vl],
+                       ppCat [ppStr "Podized   deleted      =",ppr sty pl]]))
+     )
+
+show_context :: Int -> String
+show_context 1 = "\"vector\""
+show_context 2 = "\"matrix\""
+show_context 3 = "\"cube\""
+show_context n = "\""++(show n)++"-D Pod\""
+
+which_flag :: Int -> String
+which_flag 1 = "-fpodize-vector"
+which_flag 2 = "-fpodize-matrix"
+which_flag 3 = "-fpodize-cube"
+#endif {- Data Parallel Haskell -}
+\end{code}
+
+
+@speakNth@ converts an integer to a verbal index; eg 1 maps to ``first'' etc.
+\begin{code}
+speakNth :: Int -> Pretty
+speakNth 1 = ppStr "first"
+speakNth 2 = ppStr "second"
+speakNth 3 = ppStr "third"
+speakNth 4 = ppStr "fourth"
+speakNth 5 = ppStr "fifth"
+speakNth 6 = ppStr "sixth"
+speakNth n = ppBesides [ ppInt n, ppStr "th" ]         -- Wrong for eg "31th"
+                                                       -- but who cares?
+\end{code}