module TcSimplify (
tcSimplifyInfer, tcSimplifyInferCheck,
tcSimplifyCheck, tcSimplifyRestricted,
- tcSimplifyToDicts, tcSimplifyIPs, tcSimplifyTop,
+ tcSimplifyToDicts, tcSimplifyIPs,
+ tcSimplifyTop, tcSimplifyInteractive,
tcSimplifyBracket,
tcSimplifyDeriv, tcSimplifyDefault,
isStdClassTyVarDict, isMethodFor, isMethod,
instToId, tyVarsOfInsts, cloneDict,
ipNamesOfInsts, ipNamesOfInst, dictPred,
- instBindingRequired, instCanBeGeneralised,
+ instBindingRequired,
newDictsFromOld, tcInstClassOp,
getDictClassTys, isTyVarDict,
- instLoc, pprInst, zonkInst, tidyInsts, tidyMoreInsts,
- Inst, pprInsts, pprInstsInFull,
- isIPDict, isInheritableInst
+ instLoc, zonkInst, tidyInsts, tidyMoreInsts,
+ Inst, pprInsts, pprInstsInFull, tcGetInstEnvs,
+ isIPDict, isInheritableInst, pprDFuns
)
-import TcEnv ( tcGetGlobalTyVars, tcGetInstEnv, tcLookupId, findGlobals )
-import InstEnv ( lookupInstEnv, classInstEnv, InstLookupResult(..) )
+import TcEnv ( tcGetGlobalTyVars, tcLookupId, findGlobals )
+import InstEnv ( lookupInstEnv, classInstEnv )
import TcMType ( zonkTcTyVarsAndFV, tcInstTyVars, checkAmbiguity )
import TcType ( TcTyVar, TcTyVarSet, ThetaType, TyVarDetails(VanillaTv),
mkClassPred, isOverloadedTy, mkTyConApp,
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, integerTyConName,
+ showClassKey, eqClassKey, ordClassKey )
import Subst ( mkTopTyVarSubst, substTheta, substTy )
-import TysWiredIn ( unitTy, pairTyCon )
+import TysWiredIn ( pairTyCon, doubleTy )
import ErrUtils ( Message )
import VarSet
import VarEnv ( TidyEnv )
import FiniteMap
import Outputable
import ListSetOps ( equivClasses )
-import Util ( zipEqual )
+import Util ( zipEqual, isSingleton )
import List ( partition )
import CmdLineOpts
\end{code}
= 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)
| 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) ->
= check_loop givens wanted_lie `thenM` \ (qtvs, frees, binds, irreds) ->
-- Complain about any irreducible ones
- complainCheck doc givens irreds `thenM_`
+ mappM zonkInst given_dicts_and_ips `thenM` \ givens' ->
+ groupErrs (addNoInstanceErrs (Just doc) givens') irreds `thenM_`
-- Done
- extendLIEs frees `thenM_`
+ extendLIEs frees `thenM_`
returnM (qtvs, binds)
where
+ given_dicts_and_ips = filter (not . isMethod) givens
+ -- For error reporting, filter out methods, which are
+ -- only added to the given set as an optimisation
+
ip_set = mkNameSet (ipNamesOfInsts givens)
check_loop givens wanteds
= -- Step 1
mappM zonkInst givens `thenM` \ givens' ->
mappM zonkInst wanteds `thenM` \ wanteds' ->
- get_qtvs `thenM` \ qtvs' ->
+ get_qtvs `thenM` \ qtvs' ->
-- Step 2
let
-- 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' ->
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
-- 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}
\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}
| NoRhs -- Used for Insts like (CCallable f)
-- where no witness is required.
+ -- ToDo: remove?
| Rhs -- Used when there is a RHS
TcExpr -- The RHS
returnM (no_improvement, frees, binds, irreds)
+tcImprove :: Avails -> TcM Bool -- False <=> no change
+-- Perform improvement using all the predicates in Avails
tcImprove avails
- = tcGetInstEnv `thenM` \ inst_env ->
+ = tcGetInstEnvs `thenM` \ (home_ie, pkg_ie) ->
let
preds = [ (pred, pp_loc)
| inst <- keysFM avails,
-- It does not have duplicates (good)
-- NB that (?x::t1) and (?x::t2) will be held separately in avails
-- so that improve will see them separate
- eqns = improve (classInstEnv inst_env) preds
+ eqns = improve get_insts preds
+ get_insts clas = classInstEnv home_ie clas ++ classInstEnv pkg_ie clas
in
if null eqns then
returnM True
; 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!
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.
+
%************************************************************************
%* *
\begin{code}
-tcSimplifyTop :: [Inst] -> TcM TcDictBinds
-tcSimplifyTop wanteds
+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) ->
-- Collect together all the bad guys
bad_guys = non_stds ++ concat std_bads
- (tidy_env, tidy_dicts) = tidyInsts bad_guys
- (bad_ips, non_ips) = partition isIPDict tidy_dicts
+ (bad_ips, non_ips) = partition isIPDict bad_guys
(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
- addTopInstanceErrs tidy_env no_insts `thenM_`
- addTopIPErrs tidy_env bad_ips `thenM_`
+ groupErrs (addNoInstanceErrs Nothing []) no_insts `thenM_`
+ addTopIPErrs bad_ips `thenM_`
-- Deal with ambiguity errors, but only if
-- if there has not been an error so far; errors often
-- e.g. Num (IO a) and Eq (Int -> Int)
-- and ambiguous dictionaries
-- e.g. Num a
- addTopAmbigErrs (tidy_env, ambigs) `thenM_`
+ addTopAmbigErrs 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)
@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
-- default list which can satisfy all the ambiguous classes.
-- For example, if Real a is reqd, but the only type in the
-- default list is Int.
- getDefaultTys `thenM` \ default_tys ->
+ get_default_tys `thenM` \ default_tys ->
let
try_default [] -- No defaults work, so fail
= failM
in
-- See if any default works
tryM (try_default default_tys) `thenM` \ mb_ty ->
- case mb_ty of {
- Left _ -> -- If not, add an AmbigErr
- addTopAmbigErrs (tidyInsts 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
-
- | otherwise -- No defaults
- = addTopAmbigErrs (tidyInsts dicts) `thenM_`
- returnM EmptyMonoBinds
-
- where
- tyvar = get_tv (head dicts) -- Should be non-empty
- classes = map get_clas dicts
+ WARN( not (null frees && null ambigs), ppr frees $$ ppr ambigs )
+ warnDefault dicts default_ty `thenM_`
+ returnM binds
+
+ bomb_out = addTopAmbigErrs dicts `thenM_`
+ returnM EmptyMonoBinds
+
+get_default_tys
+ = do { mb_defaults <- getDefaultTys
+ ; case mb_defaults of
+ Just tys -> return tys
+ Nothing -> -- No use-supplied default;
+ -- use [Integer, Double]
+ do { integer_ty <- tcMetaTy integerTyConName
+ ; return [integer_ty, doubleTy] } }
\end{code}
[Aside - why the defaulting mechanism is turned off when
plural [x] = empty
plural xs = char 's'
-
-addTopIPErrs tidy_env tidy_dicts
+addTopIPErrs dicts
= groupErrs report tidy_dicts
where
+ (tidy_env, tidy_dicts) = tidyInsts dicts
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
- = groupErrs report tidy_dicts
+addNoInstanceErrs :: Maybe SDoc -- Nothing => top level
+ -- Just d => d describes the construct
+ -> [Inst] -- What is given by the context or type sig
+ -> [Inst] -- What is wanted
+ -> TcM ()
+addNoInstanceErrs mb_what givens []
+ = returnM ()
+addNoInstanceErrs mb_what givens dicts
+ = -- Some of the dicts are here because there is no instances
+ -- and some because there are too many instances (overlap)
+ -- The first thing we do is separate them
+ getDOpts `thenM` \ dflags ->
+ tcGetInstEnvs `thenM` \ inst_envs ->
+ let
+ (tidy_env1, tidy_givens) = tidyInsts givens
+ (tidy_env2, tidy_dicts) = tidyMoreInsts tidy_env1 dicts
+
+ -- Run through the dicts, generating a message for each
+ -- overlapping one, but simply accumulating all the
+ -- no-instance ones so they can be reported as a group
+ (overlap_doc, no_inst_dicts) = foldl check_overlap (empty, []) tidy_dicts
+ check_overlap (overlap_doc, no_inst_dicts) dict
+ | not (isClassDict dict) = (overlap_doc, dict : no_inst_dicts)
+ | otherwise
+ = case lookupInstEnv dflags inst_envs clas tys of
+ ([], _) -> (overlap_doc, dict : no_inst_dicts) -- No matches
+ inst_res -> (mk_overlap_msg dict inst_res $$ overlap_doc, no_inst_dicts)
+ where
+ (clas,tys) = getDictClassTys dict
+ in
+ mk_probable_fix tidy_env2 mb_what no_inst_dicts `thenM` \ (tidy_env3, probable_fix) ->
+ let
+ no_inst_doc | null no_inst_dicts = empty
+ | otherwise = vcat [addInstLoc no_inst_dicts heading, probable_fix]
+ heading | null givens = ptext SLIT("No instance") <> plural no_inst_dicts <+>
+ ptext SLIT("for") <+> pprInsts no_inst_dicts
+ | otherwise = sep [ptext SLIT("Could not deduce") <+> pprInsts no_inst_dicts,
+ nest 2 $ ptext SLIT("from the context") <+> pprInsts tidy_givens]
+ in
+ addErrTcM (tidy_env3, no_inst_doc $$ overlap_doc)
+
where
- 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)
-
+ mk_overlap_msg dict (matches, unifiers)
+ = vcat [ addInstLoc [dict] ((ptext SLIT("Overlapping instances for") <+> ppr dict)),
+ sep [ptext SLIT("Matching instances") <> colon,
+ nest 2 (pprDFuns (dfuns ++ unifiers))],
+ if null unifiers
+ then empty
+ else parens (ptext SLIT("The choice depends on the instantiation of") <+>
+ quotes (pprWithCommas ppr (varSetElems (tyVarsOfInst dict))))]
+ where
+ dfuns = [df | (_, (_,_,df)) <- matches]
-addTopAmbigErrs (tidy_env, tidy_dicts)
- = groupErrs report tidy_dicts
+ mk_probable_fix tidy_env Nothing dicts -- Top level
+ = mkMonomorphismMsg tidy_env dicts
+ mk_probable_fix tidy_env (Just what) dicts -- Nested (type signatures, instance decls)
+ = returnM (tidy_env, sep [ptext SLIT("Probable fix:"), nest 2 fix1, nest 2 fix2])
+ where
+ fix1 = sep [ptext SLIT("Add") <+> pprInsts dicts,
+ ptext SLIT("to the") <+> what]
+
+ fix2 | null instance_dicts = empty
+ | otherwise = ptext SLIT("Or add an instance declaration for")
+ <+> pprInsts instance_dicts
+ instance_dicts = [d | d <- dicts, isClassDict d, not (isTyVarDict d)]
+ -- Insts for which it is worth suggesting an adding an instance declaration
+ -- Exclude implicit parameters, and tyvar dicts
+
+
+addTopAmbigErrs dicts
+-- Divide into groups that share a common set of ambiguous tyvars
+ = mapM report (equivClasses cmp [(d, tvs_of d) | d <- tidy_dicts])
where
- report dicts = mkMonomorphismMsg tidy_env dicts `thenM` \ (tidy_env, mono_msg) ->
- addErrTcM (tidy_env, mk_msg dicts $$ mono_msg)
- mk_msg dicts = addInstLoc dicts $
- sep [text "Ambiguous type variable(s)" <+> pprQuotedList ambig_tvs,
- nest 2 (text "in the constraint" <> plural dicts <+> pprInsts dicts)]
- where
- ambig_tvs = varSetElems (tyVarsOfInsts dicts)
+ (tidy_env, tidy_dicts) = tidyInsts dicts
+
+ 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
-- 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)]
+ 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 ->
quotes (ppr default_ty),
pprInstsInFull tidy_dicts]
-complainCheck doc givens irreds
- = mappM zonkInst given_dicts_and_ips `thenM` \ givens' ->
- groupErrs (addNoInstanceErrs doc givens') irreds `thenM_`
- returnM ()
- where
- given_dicts_and_ips = filter (not . isMethod) givens
- -- Filter out methods, which are only added to
- -- the given set as an optimisation
-
-addNoInstanceErrs what_doc givens dicts
- = getDOpts `thenM` \ dflags ->
- tcGetInstEnv `thenM` \ inst_env ->
- let
- (tidy_env1, tidy_givens) = tidyInsts givens
- (tidy_env2, tidy_dicts) = tidyMoreInsts tidy_env1 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:"),
- nest 4 fix1,
- nest 4 fix2]
-
- herald = ptext SLIT("Could not") <+> unambig_doc <+> ptext SLIT("deduce")
- unambig_doc | ambig_overlap = ptext SLIT("unambiguously")
- | otherwise = empty
-
- -- The error message when we don't find a suitable instance
- -- is complicated by the fact that sometimes this is because
- -- there is no instance, and sometimes it's because there are
- -- too many instances (overlap). See the comments in TcEnv.lhs
- -- with the InstEnv stuff.
-
- ambig_doc
- | not ambig_overlap = empty
- | otherwise
- = vcat [ptext SLIT("The choice of (overlapping) instance declaration"),
- nest 4 (ptext SLIT("depends on the instantiation of") <+>
- quotes (pprWithCommas ppr (varSetElems (tyVarsOfInsts tidy_dicts))))]
-
- fix1 = sep [ptext SLIT("Add") <+> pprInsts tidy_dicts,
- ptext SLIT("to the") <+> what_doc]
-
- fix2 | null instance_dicts
- = empty
- | otherwise
- = ptext SLIT("Or add an instance declaration for") <+> pprInsts instance_dicts
-
- instance_dicts = [d | d <- tidy_dicts, isClassDict d, not (isTyVarDict d)]
- -- Insts for which it is worth suggesting an adding an instance declaration
- -- Exclude implicit parameters, and tyvar dicts
-
- -- Checks for the ambiguous case when we have overlapping instances
- ambig_overlap = any ambig_overlap1 dicts
- ambig_overlap1 dict
- | isClassDict dict
- = case lookupInstEnv dflags inst_env clas tys of
- NoMatch ambig -> ambig
- other -> False
- | otherwise = False
- where
- (clas,tys) = getDictClassTys dict
- in
- addErrTcM (tidy_env2, doc)
-
-- Used for the ...Thetas variants; all top level
noInstErr pred = ptext SLIT("No instance for") <+> quotes (ppr pred)
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}