import TcRnMonad
import FiniteMap
-import PrelNames ( pRELUDE_Name, isBuiltInSyntaxName, isUnboundName,
+import PrelNames ( pRELUDE_Name, isUnboundName,
main_RDR_Unqual )
import Module ( Module, ModuleName, moduleName, mkPackageModule,
moduleNameUserString, isHomeModule,
unitModuleEnvByName, unitModuleEnv,
lookupModuleEnvByName, moduleEnvElts )
-import Name ( Name, nameSrcLoc, nameOccName, nameModuleName,
- nameParent, nameParent_maybe, isExternalName, nameModule )
+import Name ( Name, nameSrcLoc, nameOccName, nameModuleName, isWiredInName,
+ nameParent, nameParent_maybe, isExternalName, nameModule,
+ isBuiltInSyntax )
import NameSet
-import NameEnv
import OccName ( srcDataName, isTcOcc, occNameFlavour, OccEnv,
mkOccEnv, lookupOccEnv, emptyOccEnv, extendOccEnv )
import HscTypes ( GenAvailInfo(..), AvailInfo, Avails, GhciMode(..),
Provenance(..), ImportSpec(..),
isLocalGRE, pprNameProvenance )
import Outputable
-import Maybes ( isJust, isNothing, catMaybes, mapCatMaybes, seqMaybe )
+import Maybes ( isNothing, catMaybes, mapCatMaybes, seqMaybe )
import SrcLoc ( noSrcLoc, Located(..), mkGeneralSrcSpan,
- unLoc, noLoc )
+ unLoc, noLoc, srcLocSpan, SrcSpan )
import BasicTypes ( DeprecTxt )
import ListSetOps ( removeDups )
-import Util ( sortLt, notNull, isSingleton )
+import Util ( sortLe, notNull, isSingleton )
import List ( partition )
import IO ( openFile, IOMode(..) )
\end{code}
-> RnM (GlobalRdrEnv, ImportAvails)
rnImports imports
- = -- PROCESS IMPORT DECLS
+ = do { -- PROCESS IMPORT DECLS
-- Do the non {- SOURCE -} ones first, so that we get a helpful
-- warning for {- SOURCE -} ones that are unnecessary
- getModule `thenM` \ this_mod ->
- doptM Opt_NoImplicitPrelude `thenM` \ opt_no_prelude ->
- let
- all_imports = mk_prel_imports this_mod opt_no_prelude ++ imports
- (source, ordinary) = partition is_source_import all_imports
- is_source_import (L _ (ImportDecl _ is_boot _ _ _)) = is_boot
-
- get_imports = importsFromImportDecl this_mod
- in
- mappM get_imports ordinary `thenM` \ stuff1 ->
- mappM get_imports source `thenM` \ stuff2 ->
+ this_mod <- getModule
+ ; opt_no_prelude <- doptM Opt_NoImplicitPrelude
+ ; let
+ all_imports = mk_prel_imports this_mod opt_no_prelude ++ imports
+ (source, ordinary) = partition is_source_import all_imports
+ is_source_import (L _ (ImportDecl _ is_boot _ _ _)) = is_boot
+
+ get_imports = importsFromImportDecl this_mod
+
+ ; stuff1 <- mappM get_imports ordinary
+ ; stuff2 <- mappM get_imports source
-- COMBINE RESULTS
- let
+ ; let
(imp_gbl_envs, imp_avails) = unzip (stuff1 ++ stuff2)
gbl_env :: GlobalRdrEnv
gbl_env = foldr plusGlobalRdrEnv emptyGlobalRdrEnv imp_gbl_envs
all_avails :: ImportAvails
all_avails = foldr plusImportAvails emptyImportAvails imp_avails
- in
+
-- ALL DONE
- returnM (gbl_env, all_avails)
+ ; return (gbl_env, all_avails) }
where
-- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
-- because the former doesn't even look at Prelude.hi for instance
importsFromImportDecl this_mod
(L loc (ImportDecl loc_imp_mod_name want_boot qual_only as_mod imp_details))
=
- addSrcSpan loc $
+ setSrcSpan loc $
-- If there's an error in loadInterface, (e.g. interface
-- file not found) we get lots of spurious errors from 'filterImports'
-- (a) remove this_mod (might be there as a hi-boot)
-- (b) add imp_mod itself
-- Take its dependent packages unchanged
- ((imp_mod_name, want_boot) : filter not_self (dep_mods deps), dep_pkgs deps)
+ ((imp_mod_name, want_boot) : dep_mods deps, dep_pkgs deps)
| otherwise
= -- Imported module is from another package
ASSERT( not (mi_package iface `elem` dep_pkgs deps) )
([], mi_package iface : dep_pkgs deps)
- not_self (m, _) = m /= this_mod_name
-
import_all = case imp_details of
Just (is_hiding, ls) -- Imports are spec'd explicitly
| not is_hiding -> Just (not (null ls))
imports = ImportAvails {
imp_qual = unitModuleEnvByName qual_mod_name avail_env,
imp_env = avail_env,
- imp_mods = unitModuleEnv imp_mod (imp_mod, import_all),
+ imp_mods = unitModuleEnv imp_mod (imp_mod, import_all, loc),
imp_orphs = orphans,
imp_dep_mods = mkModDeps dependent_mods,
imp_dep_pkgs = dependent_pkgs }
-- The complaint will come out as "Multiple declarations of Foo.f" because
-- since 'f' is in the env twice, the unQualInScope used by the error-msg
-- printer returns False. It seems awkward to fix, unfortunately.
- mappM_ (addErr . dupDeclErr) dups `thenM_`
+ mappM_ addDupDeclErr dups `thenM_`
doptM Opt_NoImplicitPrelude `thenM` \ implicit_prelude ->
let
avails' | implicit_prelude = filter not_built_in_syntax avails
| otherwise = avails
- not_built_in_syntax a = not (all isBuiltInSyntaxName (availNames a))
+ not_built_in_syntax a = not (all isBuiltInSyntax (availNames a))
-- Only filter it if all the names of the avail are built-in
-- In particular, lists have (:) which is not built in syntax
- -- so we don't filter it out. [Sept 03: wrong: see isBuiltInSyntaxName]
+ -- so we don't filter it out. [Sept 03: wrong: see isBuiltInSyntax]
avail_env = mkAvailEnv avails'
imports = emptyImportAvails {
Just avail@(AvailTC _ [n]) -> -- This occurs when you import T(..), but
-- only export T abstractly. The single [n]
-- in the AvailTC is the type or class itself
- ifOptM Opt_WarnMisc (addWarn (dodgyImportWarn tc)) `thenM_`
+ ifOptM Opt_WarnDodgyImports (addWarn (dodgyImportWarn tc)) `thenM_`
succeed_with False avail
Just avail -> succeed_with False avail
reportDeprecations :: TcGblEnv -> RnM ()
reportDeprecations tcg_env
= ifOptM Opt_WarnDeprecations $
- do { hpt <- getHpt
- ; eps <- getEps
+ do { (eps,hpt) <- getEpsAndHpt
; mapM_ (check hpt (eps_PIT eps)) all_gres }
where
used_names = findUses (tcg_dus tcg_env) emptyNameSet
check hpt pit (GRE {gre_name = name, gre_prov = Imported (imp_spec:_) _})
| name `elemNameSet` used_names
, Just deprec_txt <- lookupDeprec hpt pit name
- = addSrcSpan (is_loc imp_spec) $
+ = setSrcSpan (is_loc imp_spec) $
addWarn (sep [ptext SLIT("Deprecated use of") <+>
- text (occNameFlavour (nameOccName name)) <+>
+ occNameFlavour (nameOccName name) <+>
quotes (ppr name),
(parens imp_msg),
(ppr deprec_txt) ])
= case lookupIface hpt pit (nameModule n) of
Just iface -> mi_dep_fn iface n `seqMaybe` -- Bleat if the thing, *or
mi_dep_fn iface (nameParent n) -- its parent*, is deprec'd
- Nothing -> pprPanic "lookupDeprec" (ppr n)
+ Nothing
+ | isWiredInName n -> Nothing
+ -- We have not necessarily loaded the .hi file for a
+ -- wired-in name (yet), although we *could*.
+ -- And we never deprecate them
+
+ | otherwise -> pprPanic "lookupDeprec" (ppr n)
-- By now all the interfaces should have been loaded
gre_is_used :: NameSet -> GlobalRdrElt -> Bool
-- 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 (GRE {gre_name = n,
- gre_prov = Imported imp_specs _}) acc
+ add_name (GRE {gre_name = n, gre_prov = Imported imp_specs _}) acc
= addToFM_C plusAvailEnv acc (is_mod (head imp_specs))
(unitAvailEnv (mk_avail n (nameParent_maybe n)))
add_name other acc
mk_avail n Nothing | isTcOcc (nameOccName n) = AvailTC n [n]
| otherwise = Avail n
- add_inst_mod m acc
- | m `elemFM` acc = acc -- We import something already
- | otherwise = addToFM acc m emptyAvailEnv
+ add_inst_mod (mod,_,_) acc
+ | mod_name `elemFM` acc = acc -- We import something already
+ | otherwise = addToFM acc mod_name emptyAvailEnv
+ where
+ mod_name = moduleName mod
-- Add an empty collection of imports for a module
-- from which we have sucked only instance decls
imports = tcg_imports gbl_env
- direct_import_mods :: [ModuleName]
- direct_import_mods = map (moduleName . fst)
- (moduleEnvElts (imp_mods imports))
-
- hasEmptyImpList :: ModuleName -> Bool
- hasEmptyImpList m =
- case lookupModuleEnvByName (imp_mods imports) m of
- Just (_,Just x) -> not x
- _ -> False
+ direct_import_mods :: [(Module, Maybe Bool, SrcSpan)]
+ -- See the type of the imp_mods for this triple
+ direct_import_mods = moduleEnvElts (imp_mods imports)
-- unused_imp_mods are the directly-imported modules
-- that are not mentioned in minimal_imports1
-- [Note: not 'minimal_imports', because that includes directly-imported
-- modules even if we use nothing from them; see notes above]
- unused_imp_mods = [m | m <- direct_import_mods,
- isNothing (lookupFM minimal_imports1 m),
- m /= pRELUDE_Name,
- not (hasEmptyImpList m)]
- -- hasEmptyImpList arranges not to complain about
+ unused_imp_mods = [(mod_name,loc) | (mod,imp,loc) <- direct_import_mods,
+ let mod_name = moduleName mod,
+ not (mod_name `elemFM` minimal_imports1),
+ mod_name /= pRELUDE_Name,
+ imp /= Just False]
+ -- The Just False part is not to complain about
-- import M (), which is an idiom for importing
-- instance declarations
module_unused :: ModuleName -> Bool
- module_unused mod = mod `elem` unused_imp_mods
+ module_unused mod = any (((==) mod) . fst) unused_imp_mods
---------------------
warnDuplicateImports :: [GlobalRdrElt] -> RnM ()
(gre:_) -> gre
[] -> pprPanic "exportClashErr" (ppr name)
-dupDeclErr (n:ns)
- = vcat [ptext SLIT("Multiple declarations of") <+> quotes (ppr n),
+addDupDeclErr :: [Name] -> TcRn ()
+addDupDeclErr (n:ns)
+ = addErrAt (srcLocSpan (nameSrcLoc n)) $
+ vcat [ptext SLIT("Multiple declarations of") <+> quotes (ppr n),
+ nest 2 (ptext SLIT("other declarations at:")),
nest 4 (vcat (map ppr sorted_locs))]
where
- sorted_locs = sortLt occ'ed_before (map nameSrcLoc (n:ns))
- occ'ed_before a b = LT == compare a b
+ sorted_locs = sortLe occ'ed_before (map nameSrcLoc ns)
+ occ'ed_before a b = case compare a b of
+ LT -> True
+ EQ -> True
+ GT -> False
dupExportWarn occ_name ie1 ie2
= hsep [quotes (ppr occ_name),