summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2014-12-16 17:46:06 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2014-12-17 14:45:45 +0000
commit67a0cab6b501e2d6280b51655af66ad448b3deef (patch)
treeba4dad04d275df9d26ea8ff24a821c9863669e29
parentc43653722ed89f30dae29e7a2117afbc2f269b76 (diff)
downloadhaskell-67a0cab6b501e2d6280b51655af66ad448b3deef.tar.gz
Fix GHCi/GHC-API tidying and modules (Trac #9424, #9426)
There were two related bugs here Trac #9426 We must increment the ic_mod_index field of the InteractiveContext if we have new instances, because we maek DFunIds that should be distinct from previous ones. Previously we were only incrementing when defining new user-visible Ids. The main change is in HscTypes.extendInteractiveContext, which now alwyas bumps the ic_mod_index. I also added a specialised extendInteractiveContextWithIds for the case where we are *only* adding new user-visible Ids. Trac #9424 In HscMain.hscDeclsWithLocations we were failing to use the *tidied* ClsInsts; but the un-tidied ones are LocalIds which causes a later ASSERT error. On the way I realised that, to behave consistently, the tcg_insts and tcg_fam_insts field of TcGblEnv should really only contain instances from the current GHCi command, not all the ones to date. That in turn meant I had to move the code for deleting replacement instances from addLocalInst, addLocalFamInst to HscTypes.extendInteractiveContext
-rw-r--r--compiler/ghci/Debugger.hs6
-rw-r--r--compiler/main/HscMain.hs18
-rw-r--r--compiler/main/HscTypes.hs84
-rw-r--r--compiler/main/InteractiveEval.hs12
-rw-r--r--compiler/main/TidyPgm.hs8
-rw-r--r--compiler/typecheck/FamInst.hs11
-rw-r--r--compiler/typecheck/Inst.hs17
-rw-r--r--compiler/typecheck/TcRnDriver.hs2
-rw-r--r--compiler/typecheck/TcRnTypes.hs5
-rw-r--r--compiler/types/FamInstEnv.hs10
-rw-r--r--compiler/types/InstEnv.hs13
-rw-r--r--docs/users_guide/ghci.xml7
12 files changed, 117 insertions, 76 deletions
diff --git a/compiler/ghci/Debugger.hs b/compiler/ghci/Debugger.hs
index 26aad6f975..e5d021d30d 100644
--- a/compiler/ghci/Debugger.hs
+++ b/compiler/ghci/Debugger.hs
@@ -116,7 +116,7 @@ bindSuspensions t = do
let (names, tys, hvals) = unzip3 stuff
let ids = [ mkVanillaGlobal name ty
| (name,ty) <- zip names tys]
- new_ic = extendInteractiveContext ictxt (map AnId ids)
+ new_ic = extendInteractiveContextWithIds ictxt ids
liftIO $ extendLinkEnv (zip names hvals)
modifySession $ \_ -> hsc_env {hsc_IC = new_ic }
return t'
@@ -193,8 +193,8 @@ showTerm term = do
bindToFreshName hsc_env ty userName = do
name <- newGrimName userName
- let id = AnId $ mkVanillaGlobal name ty
- new_ic = extendInteractiveContext (hsc_IC hsc_env) [id]
+ let id = mkVanillaGlobal name ty
+ new_ic = extendInteractiveContextWithIds (hsc_IC hsc_env) [id]
return (hsc_env {hsc_IC = new_ic }, name)
-- Create new uniques and give them sequentially numbered names
diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs
index 7b3712de78..c5cb9a182b 100644
--- a/compiler/main/HscMain.hs
+++ b/compiler/main/HscMain.hs
@@ -1465,9 +1465,6 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
-- We grab the whole environment because of the overlapping that may have
-- been done. See the notes at the definition of InteractiveContext
-- (ic_instances) for more details.
- let finsts = tcg_fam_insts tc_gblenv
- insts = tcg_insts tc_gblenv
-
let defaults = tcg_default tc_gblenv
{- Desugar it -}
@@ -1481,13 +1478,18 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
simpl_mg <- liftIO $ hscSimplify hsc_env ds_result
{- Tidy -}
- (tidy_cg, _mod_details) <- liftIO $ tidyProgram hsc_env simpl_mg
+ (tidy_cg, mod_details) <- liftIO $ tidyProgram hsc_env simpl_mg
let dflags = hsc_dflags hsc_env
!CgGuts{ cg_module = this_mod,
cg_binds = core_binds,
cg_tycons = tycons,
cg_modBreaks = mod_breaks } = tidy_cg
+
+ !ModDetails { md_insts = cls_insts
+ , md_fam_insts = fam_insts } = mod_details
+ -- Get the *tidied* cls_insts and fam_insts
+
data_tycons = filter isDataTyCon tycons
{- Prepare For Code Generation -}
@@ -1510,16 +1512,14 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
-- We only need to keep around the external bindings
-- (as decided by TidyPgm), since those are the only ones
-- that might be referenced elsewhere.
- -- The DFunIds are in 'insts' (see Note [ic_tythings] in HscTypes
+ -- The DFunIds are in 'cls_insts' (see Note [ic_tythings] in HscTypes
-- Implicit Ids are implicit in tcs
tythings = map AnId ext_ids ++ map ATyCon tcs
let icontext = hsc_IC hsc_env
- ictxt1 = extendInteractiveContext icontext tythings
- ictxt = ictxt1 { ic_instances = (insts, finsts)
- , ic_default = defaults }
-
+ ictxt = extendInteractiveContext icontext ext_ids tcs
+ cls_insts fam_insts defaults
return (tythings, ictxt)
hscImport :: HscEnv -> String -> IO (ImportDecl RdrName)
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index d3666f52e8..c3879b6d58 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -52,7 +52,8 @@ module HscTypes (
-- * Interactive context
InteractiveContext(..), emptyInteractiveContext,
icPrintUnqual, icInScopeTTs, icExtendGblRdrEnv,
- extendInteractiveContext, substInteractiveContext,
+ extendInteractiveContext, extendInteractiveContextWithIds,
+ substInteractiveContext,
setInteractivePrintName, icInteractiveModule,
InteractiveImport(..), setInteractivePackage,
mkPrintUnqualified, pprModulePrefix,
@@ -131,7 +132,7 @@ import HsSyn
import RdrName
import Avail
import Module
-import InstEnv ( InstEnv, ClsInst )
+import InstEnv ( InstEnv, ClsInst, identicalClsInstHead )
import FamInstEnv
import Rules ( RuleBase )
import CoreSyn ( CoreProgram )
@@ -1160,13 +1161,22 @@ The details are a bit tricky though:
The 'thisPackage' field stays as 'main' (or whatever -this-package-key says.
- * The main trickiness is that the type environment (tcg_type_env and
- fixity envt (tcg_fix_env), and instances (tcg_insts, tcg_fam_insts)
- now contains entities from all the interactive-package modules
- (Ghci1, Ghci2, ...) together, rather than just a single module as
- is usually the case. So you can't use "nameIsLocalOrFrom" to
- decide whether to look in the TcGblEnv vs the HPT/PTE. This is a
- change, but not a problem provided you know.
+ * The main trickiness is that the type environment (tcg_type_env) and
+ fixity envt (tcg_fix_env), now contain entities from all the
+ interactive-package modules (Ghci1, Ghci2, ...) together, rather
+ than just a single module as is usually the case. So you can't use
+ "nameIsLocalOrFrom" to decide whether to look in the TcGblEnv vs
+ the HPT/PTE. This is a change, but not a problem provided you
+ know.
+
+* However, the tcg_binds, tcg_sigs, tcg_insts, tcg_fam_insts, etc fields
+ of the TcGblEnv, which collect "things defined in this module", all
+ refer to stuff define in a single GHCi command, *not* all the commands
+ so far.
+
+ In contrast, tcg_inst_env, tcg_fam_inst_env, have instances from
+ all GhciN modules, which makes sense -- they are all "home package"
+ modules.
Note [Interactively-bound Ids in GHCi]
@@ -1214,6 +1224,16 @@ It does *not* contain
* CoAxioms (ditto)
See also Note [Interactively-bound Ids in GHCi]
+
+Note [Override identical instances in GHCi]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If you declare a new instance in GHCi that is identical to a previous one,
+we simply override the previous one; we don't regard it as overlapping.
+e.g. Prelude> data T = A | B
+ Prelude> instance Eq T where ...
+ Prelude> instance Eq T where ... -- This one overrides
+
+It's exactly the same for type-family instances. See Trac #7102
-}
-- | Interactive context, recording information about the state of the
@@ -1325,28 +1345,50 @@ icPrintUnqual :: DynFlags -> InteractiveContext -> PrintUnqualified
icPrintUnqual dflags InteractiveContext{ ic_rn_gbl_env = grenv } =
mkPrintUnqualified dflags grenv
--- | This function is called with new TyThings recently defined to update the
+-- | extendInteractiveContext is called with new TyThings recently defined to update the
-- InteractiveContext to include them. Ids are easily removed when shadowed,
-- but Classes and TyCons are not. Some work could be done to determine
-- whether they are entirely shadowed, but as you could still have references
-- to them (e.g. instances for classes or values of the type for TyCons), it's
-- not clear whether removing them is even the appropriate behavior.
-extendInteractiveContext :: InteractiveContext -> [TyThing] -> InteractiveContext
-extendInteractiveContext ictxt new_tythings
- | null new_tythings
- = ictxt
- | otherwise
+extendInteractiveContext :: InteractiveContext
+ -> [Id] -> [TyCon]
+ -> [ClsInst] -> [FamInst]
+ -> Maybe [Type]
+ -> InteractiveContext
+extendInteractiveContext ictxt ids tcs new_cls_insts new_fam_insts defaults
= ictxt { ic_mod_index = ic_mod_index ictxt + 1
+ -- Always bump this; even instances should create
+ -- a new mod_index (Trac #9426)
, ic_tythings = new_tythings ++ old_tythings
, ic_rn_gbl_env = ic_rn_gbl_env ictxt `icExtendGblRdrEnv` new_tythings
- }
+ , ic_instances = (new_cls_insts ++ old_cls_insts, new_fam_insts ++ old_fam_insts)
+ , ic_default = defaults }
where
- old_tythings = filter (not . shadowed) (ic_tythings ictxt)
-
- shadowed (AnId id) = ((`elem` new_names) . nameOccName . idName) id
- shadowed _ = False
+ new_tythings = map AnId ids ++ map ATyCon tcs
+ old_tythings = filterOut (shadowed_by ids) (ic_tythings ictxt)
+
+ -- Discard old instances that have been fully overrridden
+ -- See Note [Override identical instances in GHCi]
+ (cls_insts, fam_insts) = ic_instances ictxt
+ old_cls_insts = filterOut (\i -> any (identicalClsInstHead i) new_cls_insts) cls_insts
+ old_fam_insts = filterOut (\i -> any (identicalFamInstHead i) new_fam_insts) fam_insts
+
+extendInteractiveContextWithIds :: InteractiveContext -> [Id] -> InteractiveContext
+extendInteractiveContextWithIds ictxt ids
+ | null ids = ictxt
+ | otherwise = ictxt { ic_mod_index = ic_mod_index ictxt + 1
+ , ic_tythings = new_tythings ++ old_tythings
+ , ic_rn_gbl_env = ic_rn_gbl_env ictxt `icExtendGblRdrEnv` new_tythings }
+ where
+ new_tythings = map AnId ids
+ old_tythings = filterOut (shadowed_by ids) (ic_tythings ictxt)
- new_names = [ nameOccName (getName id) | AnId id <- new_tythings ]
+shadowed_by :: [Id] -> TyThing -> Bool
+shadowed_by ids = shadowed
+ where
+ shadowed id = getOccName id `elemOccSet` new_occs
+ new_occs = mkOccSet (map getOccName ids)
setInteractivePackage :: HscEnv -> HscEnv
-- Set the 'thisPackage' DynFlag to 'interactive'
diff --git a/compiler/main/InteractiveEval.hs b/compiler/main/InteractiveEval.hs
index bbd5213b54..6f60efe8b9 100644
--- a/compiler/main/InteractiveEval.hs
+++ b/compiler/main/InteractiveEval.hs
@@ -306,8 +306,7 @@ handleRunStatus step expr bindings final_ids
-- Completed successfully
| Complete (Right hvals) <- status
= do hsc_env <- getSession
- let final_ic = extendInteractiveContext (hsc_IC hsc_env)
- (map AnId final_ids)
+ let final_ic = extendInteractiveContextWithIds (hsc_IC hsc_env) final_ids
final_names = map getName final_ids
liftIO $ Linker.extendLinkEnv (zip final_names hvals)
hsc_env' <- liftIO $ rttiEnvironment hsc_env{hsc_IC=final_ic}
@@ -580,10 +579,10 @@ bindLocalsAtBreakpoint hsc_env apStack Nothing = do
e_fs = fsLit "e"
e_name = mkInternalName (getUnique e_fs) (mkTyVarOccFS e_fs) span
e_tyvar = mkRuntimeUnkTyVar e_name liftedTypeKind
- exn_id = AnId $ Id.mkVanillaGlobal exn_name (mkTyVarTy e_tyvar)
+ exn_id = Id.mkVanillaGlobal exn_name (mkTyVarTy e_tyvar)
ictxt0 = hsc_IC hsc_env
- ictxt1 = extendInteractiveContext ictxt0 [exn_id]
+ ictxt1 = extendInteractiveContextWithIds ictxt0 [exn_id]
span = mkGeneralSrcSpan (fsLit "<exception thrown>")
--
@@ -652,7 +651,7 @@ bindLocalsAtBreakpoint hsc_env apStack (Just info) = do
(_,tidy_tys) = tidyOpenTypes emptyTidyEnv id_tys
final_ids = zipWith setIdType all_ids tidy_tys
ictxt0 = hsc_IC hsc_env
- ictxt1 = extendInteractiveContext ictxt0 (map AnId final_ids)
+ ictxt1 = extendInteractiveContextWithIds ictxt0 final_ids
Linker.extendLinkEnv [ (name,hval) | (name, Just hval) <- zip names mb_hValues ]
when result_ok $ Linker.extendLinkEnv [(result_name, unsafeCoerce# apStack)]
@@ -711,8 +710,7 @@ rttiEnvironment hsc_env@HscEnv{hsc_IC=ic} = do
printInfoForUser dflags alwaysQualify $
fsep [text "RTTI Improvement for", ppr id, equals, ppr subst]
- let ic' = extendInteractiveContext
- (substInteractiveContext ic subst) []
+ let ic' = substInteractiveContext ic subst
return hsc_env{hsc_IC=ic'}
getIdValFromApStack :: HValue -> Int -> IO (Maybe HValue)
diff --git a/compiler/main/TidyPgm.hs b/compiler/main/TidyPgm.hs
index a32f206273..579d979cd6 100644
--- a/compiler/main/TidyPgm.hs
+++ b/compiler/main/TidyPgm.hs
@@ -303,7 +303,7 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
, mg_exports = exports
, mg_rdr_env = rdr_env
, mg_tcs = tcs
- , mg_insts = insts
+ , mg_insts = cls_insts
, mg_fam_insts = fam_insts
, mg_binds = binds
, mg_patsyns = patsyns
@@ -343,11 +343,11 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
isExternalName (idName id)]
; type_env1 = extendTypeEnvWithIds type_env final_ids
- ; tidy_insts = map (tidyClsInstDFun (lookup_aux_id tidy_type_env)) insts
+ ; tidy_cls_insts = map (tidyClsInstDFun (lookup_aux_id tidy_type_env)) cls_insts
-- A DFunId will have a binding in tidy_binds, and so will now be in
-- tidy_type_env, replete with IdInfo. Its name will be unchanged since
-- it was born, but we want Global, IdInfo-rich (or not) DFunId in the
- -- tidy_insts. Similarly the Ids inside a PatSyn.
+ -- tidy_cls_insts. Similarly the Ids inside a PatSyn.
; tidy_rules = tidyRules tidy_env trimmed_rules
-- You might worry that the tidy_env contains IdInfo-rich stuff
@@ -408,7 +408,7 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
ModDetails { md_types = tidy_type_env,
md_rules = tidy_rules,
- md_insts = tidy_insts,
+ md_insts = tidy_cls_insts,
md_vect_info = tidy_vect_info,
md_fam_insts = fam_insts,
md_exports = exports,
diff --git a/compiler/typecheck/FamInst.hs b/compiler/typecheck/FamInst.hs
index b3e7525856..117ef7b364 100644
--- a/compiler/typecheck/FamInst.hs
+++ b/compiler/typecheck/FamInst.hs
@@ -328,11 +328,10 @@ addLocalFamInst (home_fie, my_fis) fam_inst
-- In GHCi, we *override* any identical instances
-- that are also defined in the interactive context
- -- Trac #7102
- ; let (home_fie', my_fis')
- | isGHCi = ( deleteFromFamInstEnv home_fie fam_inst
- , filterOut (identicalFamInst fam_inst) my_fis)
- | otherwise = (home_fie, my_fis)
+ -- See Note [Override identical instances in GHCi] in HscTypes
+ ; let home_fie'
+ | isGHCi = deleteFromFamInstEnv home_fie fam_inst
+ | otherwise = home_fie
-- Load imported instances, so that we report
-- overlaps correctly
@@ -343,7 +342,7 @@ addLocalFamInst (home_fie, my_fis) fam_inst
-- Check for conflicting instance decls
; no_conflict <- checkForConflicts inst_envs fam_inst
; if no_conflict then
- return (home_fie'', fam_inst : my_fis')
+ return (home_fie'', fam_inst : my_fis)
else
return (home_fie, my_fis) }
diff --git a/compiler/typecheck/Inst.hs b/compiler/typecheck/Inst.hs
index 79f8c6b295..b91498f0d0 100644
--- a/compiler/typecheck/Inst.hs
+++ b/compiler/typecheck/Inst.hs
@@ -464,12 +464,13 @@ addLocalInst (home_ie, my_insts) ispec
; isGHCi <- getIsGHCi
; eps <- getEps
; tcg_env <- getGblEnv
- ; let (home_ie', my_insts')
- | isGHCi = ( deleteFromInstEnv home_ie ispec
- , filterOut (identicalInstHead ispec) my_insts)
- | otherwise = (home_ie, my_insts)
- -- If there is a home-package duplicate instance,
- -- silently delete it
+
+ -- In GHCi, we *override* any identical instances
+ -- that are also defined in the interactive context
+ -- See Note [Override identical instances in GHCi]
+ ; let home_ie'
+ | isGHCi = deleteFromInstEnv home_ie ispec
+ | otherwise = home_ie
(_tvs, cls, tys) = instanceHead ispec
-- If we're compiling sig-of and there's an external duplicate
@@ -484,7 +485,7 @@ addLocalInst (home_ie, my_insts) ispec
, ie_local = home_ie'
, ie_visible = tcg_visible_orphan_mods tcg_env }
(matches, _, _) = lookupInstEnv inst_envs cls tys
- dups = filter (identicalInstHead ispec) (map fst matches)
+ dups = filter (identicalClsInstHead ispec) (map fst matches)
-- Check functional dependencies
; case checkFunDeps inst_envs ispec of
@@ -495,7 +496,7 @@ addLocalInst (home_ie, my_insts) ispec
; unless (null dups) $
dupInstErr ispec (head dups)
- ; return (extendInstEnv home_ie' ispec, ispec:my_insts') }
+ ; return (extendInstEnv home_ie' ispec, ispec : my_insts) }
{-
Note [Signature files and type class instances]
diff --git a/compiler/typecheck/TcRnDriver.hs b/compiler/typecheck/TcRnDriver.hs
index 8ad52ba069..47fdd3a8a3 100644
--- a/compiler/typecheck/TcRnDriver.hs
+++ b/compiler/typecheck/TcRnDriver.hs
@@ -1413,8 +1413,6 @@ runTcInteractive hsc_env thing_inside
; let gbl_env' = gbl_env {
tcg_rdr_env = ic_rn_gbl_env icxt
, tcg_type_env = type_env
- , tcg_insts = ic_insts
- , tcg_fam_insts = ic_finsts
, tcg_inst_env = extendInstEnvList
(extendInstEnvList (tcg_inst_env gbl_env) ic_insts)
home_insts
diff --git a/compiler/typecheck/TcRnTypes.hs b/compiler/typecheck/TcRnTypes.hs
index 260a636ac8..1f06ae31cb 100644
--- a/compiler/typecheck/TcRnTypes.hs
+++ b/compiler/typecheck/TcRnTypes.hs
@@ -456,8 +456,9 @@ data TcGblEnv
tcg_ev_binds :: Bag EvBind, -- Top-level evidence bindings
- -- Things defined in this module, or (in GHCi) in the interactive package
- -- For the latter, see Note [The interactive package] in HscTypes
+ -- Things defined in this module, or (in GHCi)
+ -- in the declarations for a single GHCi command.
+ -- For the latter, see Note [The interactive package] in HscTypes
tcg_binds :: LHsBinds Id, -- Value bindings in this module
tcg_sigs :: NameSet, -- ...Top-level names that *lack* a signature
tcg_imp_specs :: [LTcSpecPrag], -- ...SPECIALISE prags for imported Ids
diff --git a/compiler/types/FamInstEnv.hs b/compiler/types/FamInstEnv.hs
index 7fd2ef6040..a8ddda3ca0 100644
--- a/compiler/types/FamInstEnv.hs
+++ b/compiler/types/FamInstEnv.hs
@@ -12,7 +12,7 @@ module FamInstEnv (
FamInstEnvs, FamInstEnv, emptyFamInstEnv, emptyFamInstEnvs,
extendFamInstEnv, deleteFromFamInstEnv, extendFamInstEnvList,
- identicalFamInst, famInstEnvElts, familyInstances, orphNamesOfFamInst,
+ identicalFamInstHead, famInstEnvElts, familyInstances, orphNamesOfFamInst,
-- * CoAxioms
mkCoAxBranch, mkBranchedCoAxiom, mkUnbranchedCoAxiom, mkSingleCoAxiom,
@@ -369,12 +369,12 @@ deleteFromFamInstEnv inst_env fam_inst@(FamInst {fi_fam = fam_nm})
where
adjust :: FamilyInstEnv -> FamilyInstEnv
adjust (FamIE items)
- = FamIE (filterOut (identicalFamInst fam_inst) items)
+ = FamIE (filterOut (identicalFamInstHead fam_inst) items)
-identicalFamInst :: FamInst -> FamInst -> Bool
--- Same LHS, *and* both instances are on the interactive command line
+identicalFamInstHead :: FamInst -> FamInst -> Bool
+-- ^ True when the LHSs are identical
-- Used for overriding in GHCi
-identicalFamInst (FamInst { fi_axiom = ax1 }) (FamInst { fi_axiom = ax2 })
+identicalFamInstHead (FamInst { fi_axiom = ax1 }) (FamInst { fi_axiom = ax2 })
= coAxiomTyCon ax1 == coAxiomTyCon ax2
&& brListLength brs1 == brListLength brs2
&& and (brListZipWith identical_branch brs1 brs2)
diff --git a/compiler/types/InstEnv.hs b/compiler/types/InstEnv.hs
index e9eb1dd001..ba49ba304b 100644
--- a/compiler/types/InstEnv.hs
+++ b/compiler/types/InstEnv.hs
@@ -20,7 +20,7 @@ module InstEnv (
IsOrphan(..), isOrphan, notOrphan,
InstEnvs(..), VisibleOrphanModules, InstEnv,
- emptyInstEnv, extendInstEnv, deleteFromInstEnv, identicalInstHead,
+ emptyInstEnv, extendInstEnv, deleteFromInstEnv, identicalClsInstHead,
extendInstEnvList, lookupUniqueInstEnv, lookupInstEnv', lookupInstEnv, instEnvElts,
memberInstEnv, instIsVisible,
classInstances, orphNamesOfClsInst, instanceBindFun,
@@ -490,7 +490,7 @@ orphNamesOfClsInst = orphNamesOfDFunHead . idType . instanceDFunId
-- We use this when we do signature checking in TcRnDriver
memberInstEnv :: InstEnv -> ClsInst -> Bool
memberInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm } ) =
- maybe False (\(ClsIE items) -> any (identicalInstHead ins_item) items)
+ maybe False (\(ClsIE items) -> any (identicalClsInstHead ins_item) items)
(lookupUFM inst_env cls_nm)
extendInstEnvList :: InstEnv -> [ClsInst] -> InstEnv
@@ -506,14 +506,15 @@ deleteFromInstEnv :: InstEnv -> ClsInst -> InstEnv
deleteFromInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm })
= adjustUFM adjust inst_env cls_nm
where
- adjust (ClsIE items) = ClsIE (filterOut (identicalInstHead ins_item) items)
+ adjust (ClsIE items) = ClsIE (filterOut (identicalClsInstHead ins_item) items)
-identicalInstHead :: ClsInst -> ClsInst -> Bool
+identicalClsInstHead :: ClsInst -> ClsInst -> Bool
-- ^ True when when the instance heads are the same
-- e.g. both are Eq [(a,b)]
+-- Used for overriding in GHCi
-- Obviously should be insenstive to alpha-renaming
-identicalInstHead (ClsInst { is_cls_nm = cls_nm1, is_tcs = rough1, is_tvs = tvs1, is_tys = tys1 })
- (ClsInst { is_cls_nm = cls_nm2, is_tcs = rough2, is_tvs = tvs2, is_tys = tys2 })
+identicalClsInstHead (ClsInst { is_cls_nm = cls_nm1, is_tcs = rough1, is_tvs = tvs1, is_tys = tys1 })
+ (ClsInst { is_cls_nm = cls_nm2, is_tcs = rough2, is_tvs = tvs2, is_tys = tys2 })
= cls_nm1 == cls_nm2
&& not (instanceCantMatch rough1 rough2) -- Fast check for no match, uses the "rough match" fields
&& isJust (tcMatchTys (mkVarSet tvs1) tys1 tys2)
diff --git a/docs/users_guide/ghci.xml b/docs/users_guide/ghci.xml
index 4ea1f92f61..6e09f3a16e 100644
--- a/docs/users_guide/ghci.xml
+++ b/docs/users_guide/ghci.xml
@@ -667,9 +667,10 @@ Prelude>
an attempt to distinguish it from the new <literal>T</literal>,
which is displayed as simply <literal>T</literal>.</para>
- <para>Class and type-family instance declarations are simply added to the list of available instances, with one
- exception. Since type-family instances are not permitted to overlap, but you might want to re-define one,
- a type-family instance <emphasis>replaces</emphasis> any earlier type instance with an identical left hand side.
+ <para>Class and type-family instance declarations are simply added to the list of available instances,
+ with one exception. Since you might want to re-define one,
+ a class or type-family instance <emphasis>replaces</emphasis> any earlier instance with
+ an identical head or left hand side (respectively).
(See <xref linkend="type-families"/>.)</para>
</sect2>