+\begin{code}
+lookupBndrRn rdr_name
+ = getLocalNameEnv `thenRn` \ local_env ->
+ case lookupRdrEnv local_env rdr_name of
+ Just name -> returnRn name
+ Nothing -> lookupTopBndrRn rdr_name
+
+lookupTopBndrRn rdr_name
+-- Look up a top-level local binder. We may be looking up an unqualified 'f',
+-- and there may be several imported 'f's too, which must not confuse us.
+-- So we have to filter out the non-local ones.
+-- A separate function (importsFromLocalDecls) reports duplicate top level
+-- decls, so here it's safe just to choose an arbitrary one.
+
+ | isOrig rdr_name
+ -- This is here just to catch the PrelBase defn of (say) [] and similar
+ -- The parser reads the special syntax and returns an Orig RdrName
+ -- But the global_env contains only Qual RdrNames, so we won't
+ -- find it there; instead just get the name via the Orig route
+ = lookupOrigName rdr_name
+
+ | otherwise
+ = getModeRn `thenRn` \ mode ->
+ if isInterfaceMode mode
+ then lookupIfaceName rdr_name
+ else
+ getModuleRn `thenRn` \ mod ->
+ getGlobalNameEnv `thenRn` \ global_env ->
+ case lookup_local mod global_env rdr_name of
+ Just name -> returnRn name
+ Nothing -> failWithRn (mkUnboundName rdr_name)
+ (unknownNameErr rdr_name)
+ where
+ lookup_local mod global_env rdr_name
+ = case lookupRdrEnv global_env rdr_name of
+ Nothing -> Nothing
+ Just gres -> case [n | GRE n _ _ <- gres, nameIsLocalOrFrom mod n] of
+ [] -> Nothing
+ (n:ns) -> Just n
+
+
+-- lookupSigOccRn is used for type signatures and pragmas
+-- Is this valid?
+-- module A
+-- import M( f )
+-- f :: Int -> Int
+-- f x = x
+-- It's clear that the 'f' in the signature must refer to A.f
+-- The Haskell98 report does not stipulate this, but it will!
+-- So we must treat the 'f' in the signature in the same way
+-- as the binding occurrence of 'f', using lookupBndrRn
+lookupSigOccRn :: RdrName -> RnMS Name
+lookupSigOccRn = lookupBndrRn
+
+-- lookupInstDeclBndr is used for the binders in an
+-- instance declaration. Here we use the class name to
+-- disambiguate.
+
+lookupInstDeclBndr :: Name -> RdrName -> RnMS Name
+ -- We use the selector name as the binder
+lookupInstDeclBndr cls_name rdr_name
+ | isOrig rdr_name -- Occurs in derived instances, where we just
+ -- refer diectly to the right method
+ = lookupOrigName rdr_name
+
+ | otherwise
+ = getGlobalAvails `thenRn` \ avail_env ->
+ case lookupNameEnv avail_env cls_name of
+ -- The class itself isn't in scope, so cls_name is unboundName
+ -- e.g. import Prelude hiding( Ord )
+ -- instance Ord T where ...
+ -- The program is wrong, but that should not cause a crash.
+ Nothing -> returnRn (mkUnboundName rdr_name)
+ Just (AvailTC _ ns) -> case [n | n <- ns, nameOccName n == occ] of
+ (n:ns)-> ASSERT( null ns ) returnRn n
+ [] -> failWithRn (mkUnboundName rdr_name)
+ (unknownNameErr rdr_name)
+ other -> pprPanic "lookupInstDeclBndr" (ppr cls_name)
+ where
+ occ = rdrNameOcc rdr_name
+
+-- lookupOccRn looks up an occurrence of a RdrName
+lookupOccRn :: RdrName -> RnMS Name
+lookupOccRn rdr_name
+ = getLocalNameEnv `thenRn` \ local_env ->
+ case lookupRdrEnv local_env rdr_name of
+ Just name -> returnRn name
+ Nothing -> lookupGlobalOccRn rdr_name
+
+-- lookupGlobalOccRn is like lookupOccRn, except that it looks in the global
+-- environment. It's used only for
+-- record field names
+-- class op names in class and instance decls
+
+lookupGlobalOccRn rdr_name
+ = getModeRn `thenRn` \ mode ->
+ if (isInterfaceMode mode)
+ then lookupIfaceName rdr_name
+ else
+
+ getGlobalNameEnv `thenRn` \ global_env ->
+ case mode of
+ SourceMode -> lookupSrcName global_env rdr_name
+
+ CmdLineMode
+ | not (isQual rdr_name) ->
+ lookupSrcName global_env rdr_name
+
+ -- We allow qualified names on the command line to refer to
+ -- *any* name exported by any module in scope, just as if
+ -- there was an "import qualified M" declaration for every
+ -- module.
+ --
+ -- First look up the name in the normal environment. If
+ -- it isn't there, we manufacture a new occurrence of an
+ -- original name.
+ | otherwise ->
+ case lookupRdrEnv global_env rdr_name of
+ Just _ -> lookupSrcName global_env rdr_name
+ Nothing -> lookupQualifiedName rdr_name
+
+-- a qualified name on the command line can refer to any module at all: we
+-- try to load the interface if we don't already have it.
+lookupQualifiedName :: RdrName -> RnM d Name
+lookupQualifiedName rdr_name
+ = let
+ mod = rdrNameModule rdr_name
+ occ = rdrNameOcc rdr_name
+ in
+ loadInterface (ppr rdr_name) mod ImportByUser `thenRn` \ iface ->
+ case [ name | (_,avails) <- mi_exports iface,
+ avail <- avails,
+ name <- availNames avail,
+ nameOccName name == occ ] of
+ (n:ns) -> ASSERT (null ns) returnRn n
+ _ -> failWithRn (mkUnboundName rdr_name) (unknownNameErr rdr_name)
+
+lookupSrcName :: GlobalRdrEnv -> RdrName -> RnM d Name
+-- NB: passed GlobalEnv explicitly, not necessarily in RnMS monad
+lookupSrcName global_env rdr_name
+ | isOrig rdr_name -- Can occur in source code too
+ = lookupOrigName rdr_name