\section[Rename]{Renaming and dependency analysis passes}
\begin{code}
-module Rename ( renameModule, closeIfaceDecls, checkOldIface ) where
+module Rename ( renameModule, renameExpr, closeIfaceDecls, checkOldIface ) where
#include "HsVersions.h"
import HsSyn
-import RdrHsSyn ( RdrNameHsModule, RdrNameHsDecl, RdrNameDeprecation,
+import RdrHsSyn ( RdrNameHsModule, RdrNameHsDecl, RdrNameDeprecation, RdrNameHsExpr,
RdrNameTyClDecl, RdrNameRuleDecl, RdrNameInstDecl, RdrNameImportDecl
)
import RnHsSyn ( RenamedHsDecl, RenamedTyClDecl, RenamedRuleDecl, RenamedInstDecl,
- extractHsTyNames,
+ extractHsTyNames, RenamedHsExpr,
instDeclFVs, tyClDeclFVs, ruleDeclFVs
)
import CmdLineOpts ( DynFlags, DynFlag(..) )
import RnMonad
-import RnNames ( getGlobalNames )
+import RnExpr ( rnExpr )
+import RnNames ( getGlobalNames, exportsFromAvail )
import RnSource ( rnSourceDecls, rnTyClDecl, rnIfaceRuleDecl, rnInstDecl )
-import RnIfaces ( slurpImpDecls, mkImportInfo,
+import RnIfaces ( slurpImpDecls, mkImportInfo, recordLocalSlurps,
getInterfaceExports, closeDecls,
RecompileRequired, outOfDate, recompileRequired
)
import RnHiFiles ( readIface, removeContext, loadInterface,
- loadExports, loadFixDecls, loadDeprecs )
-import RnEnv ( availsToNameSet, availName,
- emptyAvailEnv, unitAvailEnv, availEnvElts, plusAvailEnv, groupAvails,
- warnUnusedImports, warnUnusedLocalBinds, warnUnusedModules,
- lookupOrigNames, lookupSrcName, newGlobalName, unQualInScope
+ loadExports, loadFixDecls, loadDeprecs,
+ tryLoadInterface )
+import RnEnv ( availsToNameSet, availName, mkIfaceGlobalRdrEnv,
+ emptyAvailEnv, unitAvailEnv, availEnvElts,
+ plusAvailEnv, groupAvails, warnUnusedImports,
+ warnUnusedLocalBinds, warnUnusedModules,
+ lookupOrigNames, lookupSrcName,
+ newGlobalName, unQualInScope
)
import Module ( Module, ModuleName, WhereFrom(..),
moduleNameUserString, moduleName,
)
import PrelInfo ( derivingOccurrences )
import Type ( funTyCon )
-import ErrUtils ( dumpIfSet, showPass, printErrorsAndWarnings, errorsFound )
+import ErrUtils ( dumpIfSet, dumpIfSet_dyn, showPass,
+ printErrorsAndWarnings, errorsFound )
import Bag ( bagToList )
import FiniteMap ( FiniteMap, fmToList, emptyFM, lookupFM,
addToFM_C, elemFM, addToFM
import IO ( openFile, IOMode(..) )
import HscTypes ( PersistentCompilerState, HomeIfaceTable, HomeSymbolTable,
ModIface(..), WhatsImported(..),
- VersionInfo(..), ImportVersion,
+ VersionInfo(..), ImportVersion, IsExported,
IfaceDecls, mkIfaceDecls, dcl_tycl, dcl_rules, dcl_insts,
GlobalRdrEnv, pprGlobalRdrEnv,
AvailEnv, GenAvailInfo(..), AvailInfo, Avails,
+
%*********************************************************
%* *
-\subsection{The main function: rename}
+\subsection{The two main wrappers}
%* *
%*********************************************************
-> HomeIfaceTable -> HomeSymbolTable
-> PersistentCompilerState
-> Module -> RdrNameHsModule
- -> IO (PersistentCompilerState, Maybe (PrintUnqualified, ModIface, [RenamedHsDecl]))
+ -> IO (PersistentCompilerState, Maybe (PrintUnqualified, (IsExported, ModIface, [RenamedHsDecl])))
-- Nothing => some error occurred in the renamer
-renameModule dflags hit hst old_pcs this_module rdr_module
- = do { showPass dflags "Renamer"
+renameModule dflags hit hst pcs this_module rdr_module
+ = renameSource dflags hit hst pcs this_module $
+ rename this_module rdr_module
+\end{code}
+
+
+\begin{code}
+renameExpr :: DynFlags
+ -> HomeIfaceTable -> HomeSymbolTable
+ -> PersistentCompilerState
+ -> Module -> RdrNameHsExpr
+ -> IO ( PersistentCompilerState,
+ Maybe (PrintUnqualified, (RenamedHsExpr, [RenamedHsDecl]))
+ )
+
+renameExpr dflags hit hst pcs this_module expr
+ = do { renameSource dflags hit hst pcs this_module $
+ tryLoadInterface doc (moduleName this_module) ImportByUser
+ `thenRn` \ (iface, maybe_err) ->
+ case maybe_err of {
+ Just msg -> ioToRnM (printErrs alwaysQualify
+ (ptext SLIT("failed to load interface for")
+ <+> quotes (ppr this_module)
+ <> char ':' <+> msg)) `thenRn_`
+ returnRn Nothing;
+ Nothing ->
+
+ let rdr_env = mi_globals iface
+ print_unqual = unQualInScope rdr_env
+ in
+
+ initRnMS rdr_env emptyLocalFixityEnv SourceMode (rnExpr expr)
+ `thenRn` \ (e,fvs) ->
+
+ checkErrsRn `thenRn` \ no_errs_so_far ->
+ if not no_errs_so_far then
+ -- Found errors already, so exit now
+ doDump e [] `thenRn_`
+ returnRn Nothing
+ else
+
+ lookupOrigNames implicit_occs `thenRn` \ implicit_names ->
+ slurpImpDecls (fvs `plusFV` implicit_names) `thenRn` \ decls ->
+
+ doDump e decls `thenRn_`
+ returnRn (Just (print_unqual, (e, decls)))
+ }}
+ where
+ implicit_occs = string_occs
+ doc = text "context for compiling expression"
+
+ doDump :: RenamedHsExpr -> [RenamedHsDecl] -> RnMG (Either IOError ())
+ doDump e decls =
+ getDOptsRn `thenRn` \ dflags ->
+ ioToRnM (dumpIfSet_dyn dflags Opt_D_dump_rn "Renamer:"
+ (vcat (ppr e : map ppr decls)))
+\end{code}
- -- Initialise the renamer monad
- ; (new_pcs, msgs, maybe_rn_stuff) <- initRn dflags hit hst old_pcs this_module
- (rename this_module rdr_module)
- ; let print_unqualified :: Name -> Bool -- Is this chap in scope unqualified?
- print_unqualified = case maybe_rn_stuff of
- Just (unqual, _, _) -> unqual
- Nothing -> alwaysQualify
+%*********************************************************
+%* *
+\subsection{The main function: rename}
+%* *
+%*********************************************************
+\begin{code}
+renameSource :: DynFlags
+ -> HomeIfaceTable -> HomeSymbolTable
+ -> PersistentCompilerState
+ -> Module
+ -> RnMG (Maybe (PrintUnqualified, r))
+ -> IO (PersistentCompilerState, Maybe (PrintUnqualified, r))
+ -- Nothing => some error occurred in the renamer
+
+renameSource dflags hit hst old_pcs this_module thing_inside
+ = do { showPass dflags "Renamer"
+
+ -- Initialise the renamer monad
+ ; (new_pcs, msgs, maybe_rn_stuff) <- initRn dflags hit hst old_pcs this_module thing_inside
-- Print errors from renaming
- ; printErrorsAndWarnings print_unqualified msgs ;
+ ; let print_unqual = case maybe_rn_stuff of
+ Just (unqual, _) -> unqual
+ Nothing -> alwaysQualify
+
+ ; printErrorsAndWarnings print_unqual msgs ;
-- Return results. No harm in updating the PCS
; if errorsFound msgs then
\end{code}
\begin{code}
-rename :: Module -> RdrNameHsModule -> RnMG (Maybe (PrintUnqualified, IsExported, ModIface, [RenamedHsDecl]))
-rename this_module contents@(HsModule _ _ _ imports local_decls mod_deprec loc)
+rename :: Module -> RdrNameHsModule -> RnMG (Maybe (PrintUnqualified, (IsExported, ModIface, [RenamedHsDecl])))
+rename this_module contents@(HsModule _ _ exports imports local_decls mod_deprec loc)
= pushSrcLocRn loc $
-- FIND THE GLOBAL NAME ENVIRONMENT
returnRn Nothing
else
- -- PROCESS EXPORT LIST (but not if we've had errors already)
+ -- PROCESS EXPORT LIST
exportsFromAvail mod_name exports all_avails gbl_env `thenRn` \ export_avails ->
traceRn (text "Local top-level environment" $$
-- CHECK THAT main IS DEFINED, IF REQUIRED
checkMain this_module local_gbl_env `thenRn_`
+ -- EXIT IF ERRORS FOUND
+ -- We exit here if there are any errors in the source, *before*
+ -- we attempt to slurp the decls from the interfaces, otherwise
+ -- the slurped decls may get lost when we return up the stack
+ -- to hscMain/hscExpr.
+ checkErrsRn `thenRn` \ no_errs_so_far ->
+ if not no_errs_so_far then
+ -- Found errors already, so exit now
+ rnDump [] rn_local_decls `thenRn_`
+ returnRn Nothing
+ else
+
-- SLURP IN ALL THE NEEDED DECLARATIONS
implicitFVs mod_name rn_local_decls `thenRn` \ implicit_fvs ->
let
traceRn (text "Source FVs:" <+> fsep (map ppr (nameSetToList slurp_fvs))) `thenRn_`
slurpImpDecls slurp_fvs `thenRn` \ rn_imp_decls ->
- -- EXIT IF ERRORS FOUND
rnDump rn_imp_decls rn_local_decls `thenRn_`
- checkErrsRn `thenRn` \ no_errs_so_far ->
- if not no_errs_so_far then
- -- Found errors already, so exit now
- returnRn Nothing
- else
-- GENERATE THE VERSION/USAGE INFO
mkImportInfo mod_name imports `thenRn` \ my_usages ->
imports global_avail_env
source_fvs export_avails rn_imp_decls `thenRn_`
- returnRn (Just (print_unqualified, is_exported, mod_iface, final_decls))
+ returnRn (Just (print_unqualified, (is_exported, mod_iface, final_decls)))
where
mod_name = moduleName this_module
\end{code}
-- generate code
implicit_occs = string_occs ++ foldr ((++) . get) implicit_main decls
- -- Virtually every program has error messages in it somewhere
- string_occs = [unpackCString_RDR, unpackCStringFoldr_RDR,
- unpackCStringUtf8_RDR, eqString_RDR]
- get (TyClD (TyData _ _ _ _ _ _ (Just deriv_classes) _ _ _))
- = concat (map get_deriv deriv_classes)
- get other = []
+ get (TyClD (TyData {tcdDerivs = Just deriv_classes})) = concat (map get_deriv deriv_classes)
+ get other = []
get_deriv cls = case lookupUFM derivingOccurrences cls of
Nothing -> []
Just occs -> occs
+
+-- Virtually every program has error messages in it somewhere
+string_occs = [unpackCString_RDR, unpackCStringFoldr_RDR,
+ unpackCStringUtf8_RDR, eqString_RDR]
\end{code}
\begin{code}
getFixities acc (FixD fix)
= fix_decl acc fix
- getFixities acc (TyClD (ClassDecl _ _ _ _ sigs _ _ _ ))
+ getFixities acc (TyClD (ClassDecl { tcdSigs = sigs}))
= foldlRn fix_decl acc [sig | FixSig sig <- sigs]
-- Get fixities from class decl sigs too.
getFixities acc other_decl
mi_boot = False, mi_orphan = pi_orphan iface,
mi_fixities = fix_env, mi_deprecs = deprec_env,
mi_decls = decls,
- mi_globals = panic "No mi_globals in old interface"
+ mi_globals = mkIfaceGlobalRdrEnv avails
}
in
returnRn mod_iface
needed = unionManyNameSets (map ruleDeclFVs rule_decls) `unionNameSets`
unionManyNameSets (map instDeclFVs inst_decls) `unionNameSets`
unionManyNameSets (map tyClDeclFVs tycl_decls)
+ local_names = foldl add emptyNameSet tycl_decls
+ add names decl = addListToNameSet names (map fst (tyClDeclSysNames decl ++ tyClDeclNames decl))
in
- closeDecls decls needed
+ -- Record that we have now got declarations for local_names
+ recordLocalSlurps local_names `thenRn_`
+
+ -- Do the transitive closure
+ lookupOrigNames implicit_occs `thenRn` \ implicit_names ->
+ closeDecls decls (needed `plusFV` implicit_names) `thenRn` \closed_decls ->
+ rnDump [] closed_decls `thenRn_`
+ returnRn closed_decls
+ where
+ implicit_occs = string_occs -- Data type decls with record selectors,
+ -- which may appear in the decls, need unpackCString
+ -- and friends. It's easier to just grab them right now.
\end{code}
%*********************************************************