import {-# SOURCE #-} TcUnify( unifyTauTy )
import TcEnv -- temp
-import HsSyn ( HsBind(..), LHsBinds, HsExpr(..), LHsExpr, pprLHsBinds )
+import HsSyn ( HsBind(..), HsExpr(..), LHsExpr, emptyLHsBinds )
import TcHsSyn ( TcId, TcDictBinds, mkHsApp, mkHsTyApp, mkHsDictApp )
import TcRnMonad
getDictClassTys, isTyVarDict,
instLoc, zonkInst, tidyInsts, tidyMoreInsts,
Inst, pprInsts, pprDictsInFull, pprInstInFull, tcGetInstEnvs,
- isIPDict, isInheritableInst, pprDFuns, pprDictsTheta
+ isInheritableInst, pprDFuns, pprDictsTheta
)
import TcEnv ( tcGetGlobalTyVars, tcLookupId, findGlobals )
import InstEnv ( lookupInstEnv, classInstances )
import TcMType ( zonkTcTyVarsAndFV, tcInstTyVars, checkAmbiguity )
-import TcType ( TcTyVar, TcTyVarSet, ThetaType, TyVarDetails(VanillaTv),
- mkClassPred, isOverloadedTy, mkTyConApp,
+import TcType ( TcTyVar, TcTyVarSet, ThetaType,
+ mkClassPred, isOverloadedTy, mkTyConApp,
mkTyVarTy, tcGetTyVar, isTyVarClassPred, mkTyVarTys,
tyVarsOfPred, tcEqType, pprPred )
import Id ( idType, mkUserLocal )
import PrelInfo ( isNumericClass )
import PrelNames ( splitName, fstName, sndName, integerTyConName,
showClassKey, eqClassKey, ordClassKey )
-import Subst ( mkTopTyVarSubst, substTheta, substTy )
+import Type ( zipTopTvSubst, substTheta, substTy )
import TysWiredIn ( pairTyCon, doubleTy )
import ErrUtils ( Message )
import VarSet
| 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_`
+ 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) ->
givens wanted_lie `thenM` \ (qtvs', binds) ->
returnM binds
where
- get_qtvs = zonkTcTyVarsAndFV qtvs
+-- get_qtvs = zonkTcTyVarsAndFV qtvs
+ get_qtvs = return (mkVarSet qtvs)
-- tcSimplifyInferCheck is used when we know the constraints we are to simplify
@LIE@), as well as the @HsBinds@ generated.
\begin{code}
-bindInstsOfLocalFuns :: [Inst] -> [TcId] -> TcM (LHsBinds TcId)
+bindInstsOfLocalFuns :: [Inst] -> [TcId] -> TcM TcDictBinds
+-- Simlifies only MethodInsts, and generate only bindings of form
+-- fm = f tys dicts
+-- We're careful not to even generate bindings of the form
+-- d1 = d2
+-- You'd think that'd be fine, but it interacts with what is
+-- arguably a bug in Match.tidyEqnInfo (see notes there)
bindInstsOfLocalFuns wanteds local_ids
| null overloaded_ids
-- Common case
= extendLIEs wanteds `thenM_`
- returnM emptyBag
+ returnM emptyLHsBinds
| otherwise
- = simpleReduceLoop doc try_me wanteds `thenM` \ (frees, binds, irreds) ->
+ = simpleReduceLoop doc try_me for_me `thenM` \ (frees, binds, irreds) ->
ASSERT( null irreds )
+ extendLIEs not_for_me `thenM_`
extendLIEs frees `thenM_`
returnM binds
where
doc = text "bindInsts" <+> ppr local_ids
overloaded_ids = filter is_overloaded local_ids
is_overloaded id = isOverloadedTy (idType id)
+ (for_me, not_for_me) = partition (isMethodFor overloaded_set) wanteds
overloaded_set = mkVarSet overloaded_ids -- There can occasionally be a lot of them
-- so it's worth building a set, so that
-- lookup (in isMethodFor) is faster
-
- try_me inst | isMethodFor overloaded_set inst = ReduceMe
- | otherwise = Free
+ try_me inst | isMethod inst = ReduceMe
+ | otherwise = Free
\end{code}
returnM False
where
unify ((qtvs, pairs), doc)
- = addErrCtxt doc $
- tcInstTyVars VanillaTv (varSetElems qtvs) `thenM` \ (_, _, tenv) ->
+ = addErrCtxt doc $
+ tcInstTyVars (varSetElems qtvs) `thenM` \ (_, _, tenv) ->
mapM_ (unif_pr tenv) pairs
unif_pr tenv (ty1,ty2) = unifyTauTy (substTy tenv ty1) (substTy tenv ty2)
\end{code}
avails1 = addToFM avails inst avail
is_loop inst = any (`tcEqType` idType (instToId inst)) dep_tys
-- Note: this compares by *type*, not by Unique
- deps = findAllDeps emptyVarSet avail
+ deps = findAllDeps (unitVarSet (instToId inst)) avail
dep_tys = map idType (varSetElems deps)
findAllDeps :: IdSet -> Avail -> IdSet
-- See Note [SUPERCLASS-LOOP]
-- Watch out, though. Since the avails may contain loops
-- (see Note [RECURSIVE DICTIONARIES]), so we need to track the ones we've seen so far
- findAllDeps so_far (Rhs _ kids)
- = foldl findAllDeps
- (extendVarSetList so_far (map instToId kids)) -- Add the kids to so_far
- [a | Just a <- map (lookupFM avails) kids] -- Find the kids' Avail
- findAllDeps so_far other = so_far
-
+ findAllDeps so_far (Rhs _ kids) = foldl find_all so_far kids
+ findAllDeps so_far other = so_far
+
+ find_all :: IdSet -> Inst -> IdSet
+ find_all so_far kid
+ | kid_id `elemVarSet` so_far = so_far
+ | Just avail <- lookupFM avails kid = findAllDeps so_far' avail
+ | otherwise = so_far'
+ where
+ so_far' = extendVarSet so_far kid_id -- Add the new kid to so_far
+ kid_id = instToId kid
addSCs :: (Inst -> Bool) -> Avails -> Inst -> TcM Avails
-- Add all the superclasses of the Inst to Avails
where
(clas, tys) = getDictClassTys dict
(tyvars, sc_theta, sc_sels, _) = classBigSig clas
- sc_theta' = substTheta (mkTopTyVarSubst tyvars tys) sc_theta
+ sc_theta' = substTheta (zipTopTvSubst tyvars tys) sc_theta
add_sc avails (sc_dict, sc_sel) -- Add it, and its superclasses
| add_me sc_dict = addSCs is_loop avails' sc_dict
non_std_tyvars = unionVarSets (map tyVarsOfInst non_stds)
-- Collect together all the bad guys
- bad_guys = non_stds ++ concat std_bads
- (bad_ips, non_ips) = partition isIPDict bad_guys
- (no_insts, ambigs) = partition no_inst non_ips
- 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 ...
+ bad_guys = non_stds ++ concat std_bads
+ (non_ips, bad_ips) = partition isClassDict bad_guys
+ (ambigs, no_insts) = partition is_ambig non_ips
+ is_ambig d = not (tyVarsOfInst d `subVarSet` fixed_tvs)
+ fixed_tvs = oclose (fdPredsOfInsts irreds) emptyVarSet
+ -- If the dict has free type variables, it's almost certainly ambiguous,
+ -- and that's the first thing to fix.
+ -- Otherwise, addNoInstanceErrs does the right thing
+ -- I say "almost certain" because we might have
+ -- class C a b | a -> B where ...
+ -- plus an Inst (C Int x). Then the 'x' isn't ambiguous; it's just that
+ -- there's no instance decl for (C Int ...). Hence the oclose.
in
-- Report definite errors
-> TcM ThetaType -- Needed
tcSimplifyDeriv tyvars theta
- = tcInstTyVars VanillaTv tyvars `thenM` \ (tvs, _, tenv) ->
+ = tcInstTyVars tyvars `thenM` \ (tvs, _, tenv) ->
-- The main loop may do unification, and that may crash if
-- it doesn't see a TcTyVar, so we have to instantiate. Sigh
-- ToDo: what if two of them do get unified?
- newDicts DataDeclOrigin (substTheta tenv theta) `thenM` \ wanteds ->
+ newDicts DerivOrigin (substTheta tenv theta) `thenM` \ wanteds ->
simpleReduceLoop doc reduceMe wanteds `thenM` \ (frees, _, irreds) ->
ASSERT( null frees ) -- reduceMe never returns Free
-- of problems; in particular, it's hard to compare solutions for
-- equality when finding the fixpoint. So I just rule it out for now.
- rev_env = mkTopTyVarSubst tvs (mkTyVarTys tyvars)
+ rev_env = zipTopTvSubst tvs (mkTyVarTys tyvars)
-- This reverse-mapping is a Royal Pain,
-- but the result should mention TyVars not TcTyVars
in
-> TcM ()
tcSimplifyDefault theta
- = newDicts DataDeclOrigin theta `thenM` \ wanteds ->
+ = newDicts DefaultOrigin theta `thenM` \ wanteds ->
simpleReduceLoop doc reduceMe wanteds `thenM` \ (frees, _, irreds) ->
ASSERT( null frees ) -- try_me never returns Free
addNoInstanceErrs Nothing [] irreds `thenM_`
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
| otherwise
= case lookupInstEnv dflags inst_envs clas tys of
-- The case of exactly one match and no unifiers means
- -- a successful lookup. That can't happen here.
+ -- a successful lookup. That can't happen here, becuase
+ -- dicts only end up here if they didn't match in Inst.lookupInst
#ifdef DEBUG
([m],[]) -> pprPanic "addNoInstanceErrs" (ppr dict)
#endif
in
-- Now generate a good message for the no-instance bunch
- mk_probable_fix tidy_env2 mb_what no_inst_dicts `thenM` \ (tidy_env3, probable_fix) ->
+ mk_probable_fix tidy_env2 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]
= vcat [ addInstLoc [dict] ((ptext SLIT("Overlapping instances for")
<+> pprPred (dictPred dict))),
sep [ptext SLIT("Matching instances") <> colon,
- nest 2 (pprDFuns (dfuns ++ unifiers))],
+ nest 2 (vcat [pprDFuns dfuns, pprDFuns unifiers])],
ASSERT( not (null matches) )
if not (isSingleton matches)
then -- Two or more matches
where
dfuns = [df | (_, (_,_,df)) <- matches]
- 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])
+ mk_probable_fix tidy_env dicts
+ = returnM (tidy_env, sep [ptext SLIT("Probable fix:"), nest 2 (vcat fixes)])
where
- fix1 = sep [ptext SLIT("Add") <+> pprDictsTheta dicts,
- ptext SLIT("to the") <+> what]
+ fixes = add_ors (fix1 ++ fix2)
- fix2 | null instance_dicts = empty
- | otherwise = ptext SLIT("Or add an instance declaration for")
- <+> pprDictsTheta instance_dicts
+ fix1 = case mb_what of
+ Nothing -> [] -- Top level
+ Just what -> -- Nested (type signatures, instance decls)
+ [ sep [ ptext SLIT("add") <+> pprDictsTheta dicts,
+ ptext SLIT("to the") <+> what] ]
+
+ fix2 | null instance_dicts = []
+ | otherwise = [ ptext SLIT("add an instance declaration for")
+ <+> pprDictsTheta 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
+ add_ors :: [SDoc] -> [SDoc]
+ add_ors (f1:fs) = f1 : map (ptext SLIT("or") <+>) fs
addTopAmbigErrs dicts
-- Divide into groups that share a common set of ambiguous tyvars
report :: [(Inst,[TcTyVar])] -> TcM ()
report pairs@((inst,tvs) : _) -- The pairs share a common set of ambiguous tyvars
- = mkMonomorphismMsg tidy_env dicts `thenM` \ (tidy_env, mono_msg) ->
- addSrcSpan (instLocSrcSpan (instLoc inst)) $
+ = mkMonomorphismMsg tidy_env tvs `thenM` \ (tidy_env, mono_msg) ->
+ setSrcSpan (instLocSrcSpan (instLoc inst)) $
-- the location of the first one will do for the err message
addErrTcM (tidy_env, msg $$ mono_msg)
where
dicts = map fst pairs
msg = sep [text "Ambiguous type variable" <> plural tvs <+>
- pprQuotedList tvs <+> in_msg,
+ pprQuotedList tvs <+> in_msg,
nest 2 (pprDictsInFull dicts)]
- in_msg | isSingleton dicts = text "in the top-level constraint:"
- | otherwise = text "in these top-level constraints:"
+ in_msg = text "in the constraint" <> plural dicts <> colon
-mkMonomorphismMsg :: TidyEnv -> [Inst] -> TcM (TidyEnv, Message)
+mkMonomorphismMsg :: TidyEnv -> [TcTyVar] -> 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) ->
+mkMonomorphismMsg tidy_env inst_tvs
+ = findGlobals (mkVarSet 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 [] = ptext SLIT("Probable fix: add a type signature that fixes these type variable(s)")
+ -- 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")]