In GHCi, filter instances by what is in scope, not just by what is in scope unqualified
authorsimonpj@microsoft.com <unknown>
Sat, 4 Aug 2007 17:35:39 +0000 (17:35 +0000)
committersimonpj@microsoft.com <unknown>
Sat, 4 Aug 2007 17:35:39 +0000 (17:35 +0000)
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
compiler/typecheck/TcRnDriver.lhs
docs/users_guide/ghci.xml

index 3de25ce..42b787a 100644 (file)
@@ -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]
index 17bd303..4a3cb5e 100644 (file)
@@ -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
index 86bfa8f..7a3c77a 100644 (file)
@@ -1923,6 +1923,12 @@ Prelude> :. cmds.ghci
          will be printed.  If <replaceable>name</replaceable> has
          been loaded from a source file, then GHCi will also display
          the location of its definition in the source.</para>
+         <para>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 <relaceable>name</replaceable>, 
+         and (b) all the other things mentioned in the instance
+         are in scope (either qualified or otherwise) as a result of 
+         a <literal>:load</literal> or <literal>:module</literal> commands. </para>
        </listitem>
       </varlistentry>