From b0d80aa3d908a6b9991920a5ac7fd1b437ecafd3 Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Sat, 4 Aug 2007 17:35:39 +0000 Subject: [PATCH] In GHCi, filter instances by what is in scope, not just by what is in scope unqualified Trac #1581 was doing too much filtering; it even filtered out intances defined in this very module! The new rule shows more instances, but hopefully not to many. Furthermore I have moved the filtering out of TcRnDriver (where it does not belong) to InteractiveEval. And I've added a note to the documentation. --- compiler/main/InteractiveEval.hs | 23 ++++++++++++++++++++++- compiler/typecheck/TcRnDriver.lhs | 30 ++++++++---------------------- docs/users_guide/ghci.xml | 6 ++++++ 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/compiler/main/InteractiveEval.hs b/compiler/main/InteractiveEval.hs index 3de25ce..42b787a 100644 --- a/compiler/main/InteractiveEval.hs +++ b/compiler/main/InteractiveEval.hs @@ -711,8 +711,29 @@ moduleIsInterpreted s modl = withSession s $ \h -> _not_a_home_module -> return False -- | Looks up an identifier in the current interactive context (for :info) +-- Filter the instances by the ones whose tycons (or clases resp) +-- are in scope (qualified or otherwise). Otherwise we list a whole lot too many! +-- The exact choice of which ones to show, and which to hide, is a judgement call. +-- (see Trac #1581) getInfo :: Session -> Name -> IO (Maybe (TyThing,Fixity,[Instance])) -getInfo s name = withSession s $ \hsc_env -> tcRnGetInfo hsc_env name +getInfo s name + = withSession s $ \hsc_env -> + do { mb_stuff <- tcRnGetInfo hsc_env name + ; case mb_stuff of + Nothing -> return Nothing + Just (thing, fixity, ispecs) -> do + { let rdr_env = ic_rn_gbl_env (hsc_IC hsc_env) + ; return (Just (thing, fixity, filter (plausible rdr_env) ispecs)) } } + where + plausible rdr_env ispec -- Dfun involving only names that are in ic_rn_glb_env + = all ok $ nameSetToList $ tyClsNamesOfType $ idType $ instanceDFunId ispec + where -- A name is ok if it's in the rdr_env, + -- whether qualified or not + ok n | n == name = True -- The one we looked for in the first place! + | isBuiltInSyntax n = True + | isExternalName n = any ((== n) . gre_name) + (lookupGRE_Name rdr_env n) + | otherwise = True -- | Returns all names in scope in the current interactive context getNamesInScope :: Session -> IO [Name] diff --git a/compiler/typecheck/TcRnDriver.lhs b/compiler/typecheck/TcRnDriver.lhs index 17bd303..4a3cb5e 100644 --- a/compiler/typecheck/TcRnDriver.lhs +++ b/compiler/typecheck/TcRnDriver.lhs @@ -1246,21 +1246,17 @@ tcRnGetInfo hsc_env name -- in the home package all relevant modules are loaded.) loadUnqualIfaces ictxt - thing <- tcRnLookupName' name + thing <- tcRnLookupName' name fixity <- lookupFixityRn name - ispecs <- lookupInsts (icPrintUnqual ictxt) thing + ispecs <- lookupInsts thing return (thing, fixity, ispecs) -lookupInsts :: PrintUnqualified -> TyThing -> TcM [Instance] --- Filter the instances by the ones whose tycons (or clases resp) --- are in scope unqualified. Otherwise we list a whole lot too many! -lookupInsts print_unqual (AClass cls) +lookupInsts :: TyThing -> TcM [Instance] +lookupInsts (AClass cls) = do { inst_envs <- tcGetInstEnvs - ; return [ ispec - | ispec <- classInstances inst_envs cls - , plausibleDFun print_unqual (instanceDFunId ispec) ] } + ; return (classInstances inst_envs cls) } -lookupInsts print_unqual (ATyCon tc) +lookupInsts (ATyCon tc) = do { eps <- getEps -- Load all instances for all classes that are -- in the type environment (which are all the ones -- we've seen in any interface file so far) @@ -1268,22 +1264,12 @@ lookupInsts print_unqual (ATyCon tc) ; return [ ispec | ispec <- instEnvElts home_ie ++ instEnvElts pkg_ie , let dfun = instanceDFunId ispec - , relevant dfun - , plausibleDFun print_unqual dfun ] } + , relevant dfun ] } where relevant df = tc_name `elemNameSet` tyClsNamesOfDFunHead (idType df) tc_name = tyConName tc -lookupInsts print_unqual other = return [] - -plausibleDFun print_unqual dfun -- Dfun involving only names that print unqualified - = all ok (nameSetToList (tyClsNamesOfType (idType dfun))) - where - ok name | isBuiltInSyntax name = True - | isExternalName name = - isNothing $ fst print_unqual (nameModule name) - (nameOccName name) - | otherwise = True +lookupInsts other = return [] loadUnqualIfaces :: InteractiveContext -> TcM () -- Load the home module for everything that is in scope unqualified diff --git a/docs/users_guide/ghci.xml b/docs/users_guide/ghci.xml index 86bfa8f..7a3c77a 100644 --- a/docs/users_guide/ghci.xml +++ b/docs/users_guide/ghci.xml @@ -1923,6 +1923,12 @@ Prelude> :. cmds.ghci will be printed. If name has been loaded from a source file, then GHCi will also display the location of its definition in the source. + For types and classes, GHCi also summarises instances that + mention them. To avoid showing irrelevant information, an instance + is shown only if (a) its head mentions name, + and (b) all the other things mentioned in the instance + are in scope (either qualified or otherwise) as a result of + a :load or :module commands. -- 1.7.10.4