%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-2006
%
\section[RnEnv]{Environment manipulation for the renamer monad}
\begin{code}
module RnEnv (
- newTopSrcBinder,
+ newTopSrcBinder, lookupFamInstDeclBndr,
lookupLocatedBndrRn, lookupBndrRn,
lookupLocatedTopBndrRn, lookupTopBndrRn,
lookupLocatedOccRn, lookupOccRn,
lookupFixityRn, lookupTyFixityRn, lookupLocatedSigOccRn,
lookupLocatedInstDeclBndr,
lookupSyntaxName, lookupSyntaxTable, lookupImportedName,
+ lookupGreRn, lookupGreRn_maybe,
newLocalsRn, newIPNameRn,
bindLocalNames, bindLocalNamesFV,
mkRdrUnqual, setRdrNameSpace, rdrNameOcc,
pprGlobalRdrEnv, lookupGRE_RdrName,
isExact_maybe, isSrcRdrName,
+ Parent(..),
GlobalRdrElt(..), GlobalRdrEnv, lookupGlobalRdrEnv,
isLocalGRE, extendLocalRdrEnv, elemLocalRdrEnv, lookupLocalRdrEnv,
Provenance(..), pprNameProvenance,
import HscTypes ( availNames, ModIface(..), FixItem(..), lookupFixity )
import TcRnMonad
import Name ( Name, nameIsLocalOrFrom, mkInternalName, isWiredInName,
- nameSrcLoc, nameOccName, nameModule, nameParent, isExternalName )
+ nameSrcLoc, nameOccName, nameModule, isExternalName )
import NameSet
import OccName ( tcName, isDataOcc, pprNonVarNameSpace, occNameSpace,
reportIfUnused )
%*********************************************************
\begin{code}
-newTopSrcBinder :: Module -> Maybe Name -> Located RdrName -> RnM Name
-newTopSrcBinder this_mod mb_parent (L loc rdr_name)
+newTopSrcBinder :: Module -> Located RdrName -> RnM Name
+newTopSrcBinder this_mod (L loc rdr_name)
| Just name <- isExact_maybe rdr_name
= -- This is here to catch
-- (a) Exact-name binders created by Template Haskell
-- the RdrName, not from the environment. In principle, it'd be fine to
-- have an arbitrary mixture of external core definitions in a single module,
-- (apart from module-initialisation issues, perhaps).
- ; newGlobalBinder rdr_mod rdr_occ mb_parent (srcSpanStart loc) }
+ ; newGlobalBinder rdr_mod rdr_occ (srcSpanStart loc) }
--TODO, should pass the whole span
| otherwise
(addErrAt loc (badQualBndrErr rdr_name))
-- Binders should not be qualified; if they are, and with a different
-- module name, we we get a confusing "M.T is not in scope" error later
- ; newGlobalBinder this_mod (rdrNameOcc rdr_name) mb_parent (srcSpanStart loc) }
+ ; newGlobalBinder this_mod (rdrNameOcc rdr_name) (srcSpanStart loc) }
\end{code}
%*********************************************************
-- we don't bother to call newTopSrcBinder first
-- We assume there is no "parent" name
= do { loc <- getSrcSpanM
- ; newGlobalBinder rdr_mod rdr_occ Nothing (srcSpanStart loc) }
+ ; newGlobalBinder rdr_mod rdr_occ (srcSpanStart loc) }
| otherwise
= do { mb_gre <- lookupGreLocalRn rdr_name
-- disambiguate.
lookupLocatedInstDeclBndr :: Name -> Located RdrName -> RnM (Located Name)
-lookupLocatedInstDeclBndr cls = wrapLocM (lookupInstDeclBndr cls)
+lookupLocatedInstDeclBndr cls rdr = wrapLocM (lookupInstDeclBndr cls) rdr
lookupInstDeclBndr :: Name -> RdrName -> RnM Name
+-- This is called on the method name on the left-hand side of an
+-- instance declaration binding. eg. instance Functor T where
+-- fmap = ...
+-- ^^^^ called on this
+-- Regardless of how many unqualified fmaps are in scope, we want
+-- the one that comes from the Functor class.
lookupInstDeclBndr cls_name rdr_name
| isUnqual rdr_name -- Find all the things the rdr-name maps to
= do { -- and pick the one with the right parent name
- let { is_op gre = cls_name == nameParent (gre_name gre)
+ let { is_op gre@(GRE {gre_par = ParentIs n}) = cls_name == n
+ ; is_op other = False
; occ = rdrNameOcc rdr_name
; lookup_fn env = filter is_op (lookupGlobalRdrEnv env occ) }
; mb_gre <- lookupGreRn_help rdr_name lookup_fn
; case mb_gre of
Just gre -> return (gre_name gre)
Nothing -> do { addErr (unknownInstBndrErr cls_name rdr_name)
+ ; traceRn (text "lookupInstDeclBndr" <+> ppr rdr_name)
; return (mkUnboundName rdr_name) } }
| otherwise -- Occurs in derived instances, where we just
newIPNameRn :: IPName RdrName -> TcRnIf m n (IPName Name)
newIPNameRn ip_rdr = newIPName (mapIPName rdrNameOcc ip_rdr)
+-- Looking up family names in type instances is a subtle affair. The family
+-- may be imported, in which case we need to lookup the occurence of a global
+-- name. Alternatively, the family may be in the same binding group (and in
+-- fact in a declaration processed later), and we need to create a new top
+-- source binder.
+--
+-- So, also this is strictly speaking an occurence, we cannot raise an error
+-- message yet for instances without a family declaration. This will happen
+-- during renaming the type instance declaration in RnSource.rnTyClDecl.
+--
+lookupFamInstDeclBndr :: Module -> Located RdrName -> RnM Name
+lookupFamInstDeclBndr mod lrdr_name@(L _ rdr_name)
+ | not (isSrcRdrName rdr_name)
+ = lookupImportedName rdr_name
+
+ | otherwise
+ = -- First look up the name in the normal environment.
+ lookupGreRn_maybe rdr_name `thenM` \ mb_gre ->
+ case mb_gre of {
+ Just gre -> returnM (gre_name gre) ;
+ Nothing -> newTopSrcBinder mod lrdr_name }
+
--------------------------------------------------
-- Occurrences
--------------------------------------------------
| otherwise
= -- First look up the name in the normal environment.
- lookupGreRn rdr_name `thenM` \ mb_gre ->
+ lookupGreRn_maybe rdr_name `thenM` \ mb_gre ->
case mb_gre of {
Just gre -> returnM (gre_name gre) ;
Nothing ->
lookupSrcOcc_maybe :: RdrName -> RnM (Maybe Name)
-- No filter function; does not report an error on failure
lookupSrcOcc_maybe rdr_name
- = do { mb_gre <- lookupGreRn rdr_name
+ = do { mb_gre <- lookupGreRn_maybe rdr_name
; case mb_gre of
Nothing -> returnM Nothing
Just gre -> returnM (Just (gre_name gre)) }
-------------------------
-lookupGreRn :: RdrName -> RnM (Maybe GlobalRdrElt)
+lookupGreRn_maybe :: RdrName -> RnM (Maybe GlobalRdrElt)
-- Just look up the RdrName in the GlobalRdrEnv
-lookupGreRn rdr_name
+lookupGreRn_maybe rdr_name
= lookupGreRn_help rdr_name (lookupGRE_RdrName rdr_name)
+lookupGreRn :: RdrName -> RnM GlobalRdrElt
+-- If not found, add error message, and return a fake GRE
+lookupGreRn rdr_name
+ = do { mb_gre <- lookupGreRn_maybe rdr_name
+ ; case mb_gre of {
+ Just gre -> return gre ;
+ Nothing -> do
+ { name <- unboundName rdr_name
+ ; return (GRE { gre_name = name, gre_par = NoParent,
+ gre_prov = LocalDef }) }}}
+
lookupGreLocalRn :: RdrName -> RnM (Maybe GlobalRdrElt)
-- Similar, but restricted to locally-defined things
lookupGreLocalRn rdr_name