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,
- moduleEnvElts, lookupModuleEnv
+ moduleEnvElts
)
import Name ( Name, NamedThing(..), getSrcLoc,
nameIsLocalOrFrom, nameOccName, nameModule,
)
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
Provenance(..), ImportReason(..), initialVersionInfo,
Deprecations(..), lookupDeprec, lookupIface
)
+import CmStaticInfo ( GhciMode(..) )
import List ( partition, nub )
\end{code}
-> HomeIfaceTable -> HomeSymbolTable
-> PersistentCompilerState
-> Module -> RdrNameHsExpr
- -> IO (PersistentCompilerState, Maybe (PrintUnqualified, (RenamedHsExpr, [RenamedHsDecl])))
+ -> IO ( PersistentCompilerState,
+ Maybe (PrintUnqualified, (RenamedHsExpr, [RenamedHsDecl]))
+ )
renameExpr dflags hit hst pcs this_module expr
- | Just iface <- lookupModuleEnv hit this_module
- = do { let rdr_env = mi_globals iface
- ; let print_unqual = unQualInScope rdr_env
-
- ; renameSource dflags hit hst pcs this_module $
- initRnMS rdr_env emptyLocalFixityEnv SourceMode (rnExpr expr) `thenRn` \ (e,fvs) ->
- closeDecls [] fvs `thenRn` \ decls ->
- doptRn Opt_D_dump_rn `thenRn` \ dump_rn ->
- ioToRnM (dumpIfSet dump_rn "Renamer:" (ppr e)) `thenRn_`
+ = 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 CmdLineMode (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)))
- }
-
- | otherwise
- = do { printErrs alwaysQualify (ptext SLIT("renameExpr: Bad module context") <+> ppr this_module)
- ; return (pcs, Nothing)
- }
+ }}
+ 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}
-- 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 ->
-- 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
%************************************************************************
\begin{code}
-checkOldIface :: DynFlags
+checkOldIface :: GhciMode
+ -> DynFlags
-> HomeIfaceTable -> HomeSymbolTable
-> PersistentCompilerState
-> FilePath
-> IO (PersistentCompilerState, Bool, (RecompileRequired, Maybe ModIface))
-- True <=> errors happened
-checkOldIface dflags hit hst pcs iface_path source_unchanged maybe_iface
+checkOldIface ghci_mode dflags hit hst pcs iface_path source_unchanged maybe_iface
+
+ -- If the source has changed and we're in interactive mode, avoid reading
+ -- an interface; just return the one we might have been supplied with.
+ | ghci_mode == Interactive && not source_unchanged
+ = return (pcs, False, (outOfDate, maybe_iface))
+
+ | otherwise
= runRn dflags hit hst pcs (panic "Bogus module") $
case maybe_iface of
Just old_iface -> -- Use the one we already have
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}
%*********************************************************
minimal_imports1 = foldr add_name minimal_imports0 defined_and_used
minimal_imports = foldr add_inst_mod minimal_imports1 inst_mods
- add_name (n,NonLocalDef (UserImport m _ _)) acc = addToFM_C plusAvailEnv acc (moduleName (nameModule n))
+ -- We've carefully preserved the provenance so that we can
+ -- construct minimal imports that import the name by (one of)
+ -- the same route(s) as the programmer originally did.
+ add_name (n,NonLocalDef (UserImport m _ _)) acc = addToFM_C plusAvailEnv acc (moduleName m)
(unitAvailEnv (mk_avail n))
add_name (n,other_prov) acc = acc
pit = iPIT ifaces
deprecs = [ (n,txt)
| n <- nameSetToList used_names,
+ not (nameIsLocalOrFrom this_mod n),
Just txt <- [lookup_deprec hit pit n] ]
+ -- nameIsLocalOrFrom: don't complain about locally defined names
+ -- For a start, we may be exporting a deprecated thing
+ -- Also we may use a deprecated thing in the defn of another
+ -- deprecated things. We may even use a deprecated thing in
+ -- the defn of a non-deprecated thing, when changing a module's
+ -- interface
in
mapRn_ warnDeprec deprecs
where
- export_mods = nub [ moduleName (nameModule name)
+ export_mods = nub [ moduleName mod
| avail <- export_avails,
- let name = availName avail,
- not (nameIsLocalOrFrom this_mod name) ]
+ let mod = nameModule (availName avail),
+ mod /= this_mod ]
load_home m = loadInterface (text "Check deprecations for" <+> ppr m) m ImportBySystem
lookup_deprec hit pit n
- | nameIsLocalOrFrom this_mod n
- = lookupDeprec my_deprecs n
- | otherwise
= case lookupIface hit pit n of
Just iface -> lookupDeprec (mi_deprecs iface) n
Nothing -> pprPanic "warnDeprecations:" (ppr n)