Commit b0d80aa3 authored by simonpj@microsoft.com's avatar simonpj@microsoft.com
Browse files

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.
parent 7df91d49
......@@ -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]
......
......@@ -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
......
......@@ -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>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment