X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Frename%2FRnNames.lhs;h=a7b84ebdefe86f4b7d7d38fe9432d86d2420f720;hb=389cca214f33a29646e08d57e3dca862140007b2;hp=e79bfba2b0c040462328f6de0cdb1f60694dc91d;hpb=0f5e104c36b1dc3d8deeec5fef3d65e7b3a1b5ad;p=ghc-hetmet.git diff --git a/compiler/rename/RnNames.lhs b/compiler/rename/RnNames.lhs index e79bfba..a7b84eb 100644 --- a/compiler/rename/RnNames.lhs +++ b/compiler/rename/RnNames.lhs @@ -7,13 +7,14 @@ module RnNames ( rnImports, getLocalNonValBinders, rnExports, extendGlobalRdrEnvRn, - reportUnusedNames, finishDeprecations, + reportUnusedNames, finishWarnings, ) where #include "HsVersions.h" import DynFlags import HsSyn +import TcEnv ( isBrackStage ) import RnEnv import RnHsDoc ( rnHsDoc ) import IfaceEnv ( ifaceExportNames ) @@ -33,7 +34,7 @@ import Maybes import SrcLoc import FiniteMap import ErrUtils -import BasicTypes ( DeprecTxt ) +import BasicTypes ( WarningTxt(..) ) import DriverPhases ( isHsBoot ) import Util import FastString @@ -63,7 +64,7 @@ rnImports imports implicit_prelude <- doptM Opt_ImplicitPrelude let prel_imports = mkPrelImports this_mod implicit_prelude imports (source, ordinary) = partition is_source_import imports - is_source_import (L _ (ImportDecl _ is_boot _ _ _)) = is_boot + is_source_import (L _ (ImportDecl _ _ is_boot _ _ _)) = is_boot ifOptM Opt_WarnImplicitPrelude ( when (notNull prel_imports) $ addWarn (implicitPreludeWarn) @@ -99,13 +100,14 @@ mkPrelImports this_mod implicit_prelude import_decls | otherwise = [preludeImportDecl] where explicit_prelude_import - = notNull [ () | L _ (ImportDecl mod _ _ _ _) <- import_decls, + = notNull [ () | L _ (ImportDecl mod Nothing _ _ _ _) <- import_decls, unLoc mod == pRELUDE_NAME ] preludeImportDecl :: LImportDecl RdrName preludeImportDecl = L loc $ ImportDecl (L loc pRELUDE_NAME) + Nothing {- no specific package -} False {- Not a boot interface -} False {- Not qualified -} Nothing {- No "as" -} @@ -118,18 +120,22 @@ rnImportDecl :: Module -> LImportDecl RdrName -> RnM (LImportDecl Name, GlobalRdrEnv, ImportAvails,AnyHpcUsage) -rnImportDecl this_mod (L loc (ImportDecl loc_imp_mod_name want_boot +rnImportDecl this_mod (L loc (ImportDecl loc_imp_mod_name mb_pkg want_boot qual_only as_mod imp_details)) = setSrcSpan loc $ do + when (isJust mb_pkg) $ do + pkg_imports <- doptM Opt_PackageImports + when (not pkg_imports) $ addErr packageImportErr + -- If there's an error in loadInterface, (e.g. interface -- file not found) we get lots of spurious errors from 'filterImports' let imp_mod_name = unLoc loc_imp_mod_name doc = ppr imp_mod_name <+> ptext (sLit "is directly imported") - iface <- loadSrcInterface doc imp_mod_name want_boot + iface <- loadSrcInterface doc imp_mod_name want_boot mb_pkg -- Compiler sanity check: if the import didn't say -- {-# SOURCE #-} we should not get a hi-boot file @@ -137,13 +143,19 @@ rnImportDecl this_mod (L loc (ImportDecl loc_imp_mod_name want_boot -- Issue a user warning for a redundant {- SOURCE -} import -- NB that we arrange to read all the ordinary imports before - -- any of the {- SOURCE -} imports - warnIf (want_boot && not (mi_boot iface)) + -- any of the {- SOURCE -} imports. + -- + -- in --make and GHCi, the compilation manager checks for this, + -- and indeed we shouldn't do it here because the existence of + -- the non-boot module depends on the compilation order, which + -- is not deterministic. The hs-boot test can show this up. + dflags <- getDOpts + warnIf (want_boot && not (mi_boot iface) && isOneShot (ghcMode dflags)) (warnRedundantSourceImport imp_mod_name) let imp_mod = mi_module iface - deprecs = mi_deprecs iface + warns = mi_warns iface orph_iface = mi_orphan iface has_finsts = mi_finsts iface deps = mi_deps iface @@ -233,13 +245,13 @@ rnImportDecl this_mod (L loc (ImportDecl loc_imp_mod_name want_boot } -- Complain if we import a deprecated module - ifOptM Opt_WarnDeprecations ( - case deprecs of - DeprecAll txt -> addWarn (moduleDeprec imp_mod_name txt) - _ -> return () + ifOptM Opt_WarnWarningsDeprecations ( + case warns of + WarnAll txt -> addWarn (moduleWarn imp_mod_name txt) + _ -> return () ) - let new_imp_decl = L loc (ImportDecl loc_imp_mod_name want_boot + let new_imp_decl = L loc (ImportDecl loc_imp_mod_name mb_pkg want_boot qual_only as_mod new_imp_details) return (new_imp_decl, gbl_env, imports, mi_hpc iface) @@ -263,44 +275,57 @@ From the top-level declarations of this module produce * the ImportAvails created by its bindings. -Note [Shadowing in extendGlobalRdrEnvRn] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Usually when etending the GlobalRdrEnv we complain if a new binding -duplicates an existing one. By adding the bindings one at a time, -this check also complains if we add two new bindings for the same name. -(Remember that in Template Haskell the duplicates might *already be* -in the GlobalRdrEnv from higher up the module.) - -But with a Template Haskell quotation we want to *shadow*: +Note [Top-level Names in Template Haskell decl quotes] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider a Template Haskell declaration quotation like this: + module M where f x = h [d| f = 3 |] -Here the inner binding for 'f' simply shadows the outer one. -And that applies even if the binding for 'f' is in a where-clause, -and hence is in the *local* RdrEnv not the *global* RdrEnv. +When renaming the declarations inside [d| ...|], we treat the +top level binders specially in two ways + +1. We give them an Internal name, not (as usual) an External one. + Otherwise the NameCache gets confused by a second allocation of + M.f. (We used to invent a fake module ThFake to avoid this, but + that had other problems, notably in getting the correct answer for + nameIsLocalOrFrom in lookupFixity. So we now leave tcg_module + unaffected.) + +2. We make them *shadow* the outer bindings. If we don't do that, + we'll get a complaint when extending the GlobalRdrEnv, saying that + there are two bindings for 'f'. -Hence the shadowP boolean passed in. + This shadowing applies even if the binding for 'f' is in a + where-clause, and hence is in the *local* RdrEnv not the *global* + RdrEnv. + +We find out whether we are inside a [d| ... |] by testing the TH +stage. This is a slight hack, because the stage field was really meant for +the type checker, and here we are not interested in the fields of Brack, +hence the error thunks in thRnBrack. \begin{code} -extendGlobalRdrEnvRn :: Bool -- Note [Shadowing in extendGlobalRdrEnvRn] - -> [AvailInfo] +extendGlobalRdrEnvRn :: [AvailInfo] -> MiniFixityEnv -> RnM (TcGblEnv, TcLclEnv) -- Updates both the GlobalRdrEnv and the FixityEnv -- We return a new TcLclEnv only becuase we might have to - -- delete some bindings from it; see Note [Shadowing in extendGlobalRdrEnvRn] + -- delete some bindings from it; + -- see Note [Top-level Names in Template Haskell decl quotes] -extendGlobalRdrEnvRn shadowP avails new_fixities +extendGlobalRdrEnvRn avails new_fixities = do { (gbl_env, lcl_env) <- getEnvs + ; stage <- getStage ; let rdr_env = tcg_rdr_env gbl_env fix_env = tcg_fix_env gbl_env -- Delete new_occs from global and local envs - -- We are going to shadow them - -- See Note [Shadowing in extendGlobalRdrEnvRn] + -- If we are in a TemplateHaskell decl bracket, + -- we are going to shadow them + -- See Note [Top-level Names in Template Haskell decl quotes] + shadowP = isBrackStage stage new_occs = map (nameOccName . gre_name) gres rdr_env1 = hideSomeUnquals rdr_env new_occs lcl_env1 = lcl_env { tcl_rdr = delListFromOccEnv (tcl_rdr lcl_env) new_occs } - - -- Note [Shadowing in extendGlobalRdrEnvRn] (rdr_env2, lcl_env2) | shadowP = (rdr_env1, lcl_env1) | otherwise = (rdr_env, lcl_env) @@ -372,13 +397,16 @@ get_local_binders gbl_env (HsGroup {hs_valds = ValBindsIn _ val_sigs, mod = tcg_mod gbl_env is_hs_boot = isHsBoot (tcg_src gbl_env) ; + for_hs_bndrs :: [Located RdrName] for_hs_bndrs = [nm | L _ (ForeignImport nm _ _) <- foreign_decls] -- In a hs-boot file, the value binders come from the -- *signatures*, and there should be no foreign binders + val_bndrs :: [Located RdrName] val_bndrs | is_hs_boot = [nm | L _ (TypeSig nm _) <- val_sigs] | otherwise = for_hs_bndrs + new_simple :: Located RdrName -> RnM (GenAvailInfo Name) new_simple rdr_name = do nm <- newTopSrcBinder mod rdr_name return (Avail nm) @@ -633,7 +661,7 @@ filterAvail keep ie rest = let left = filter keep ns in if null left then rest else AvailTC tc left : rest --- | Given an import/export spec, construct the appropriate 'GlobalRdrElt's. +-- | Given an import\/export spec, construct the appropriate 'GlobalRdrElt's. gresFromIE :: ImpDeclSpec -> (LIE Name, AvailInfo) -> [GlobalRdrElt] gresFromIE decl_spec (L loc ie, avail) = gresFromAvail prov_fn avail @@ -933,7 +961,9 @@ isModuleExported implicit_prelude mod (GRE { gre_name = name, gre_prov = prov }) -- every module that imports the Prelude | otherwise = case prov of - LocalDef -> moduleName (nameModule name) == mod + LocalDef | Just name_mod <- nameModule_maybe name + -> moduleName name_mod == mod + | otherwise -> False Imported is -> any unQualSpecOK is && any (qualSpecOK mod) is ------------------------------- @@ -966,23 +996,23 @@ check_occs ie occs names %********************************************************* \begin{code} -finishDeprecations :: DynFlags -> Maybe DeprecTxt - -> TcGblEnv -> RnM TcGblEnv --- (a) Report usasge of deprecated imports --- (b) If the whole module is deprecated, update tcg_deprecs --- All this happens only once per module -finishDeprecations dflags mod_deprec tcg_env +finishWarnings :: DynFlags -> Maybe WarningTxt + -> TcGblEnv -> RnM TcGblEnv +-- (a) Report usage of imports that are deprecated or have other warnings +-- (b) If the whole module is warned about or deprecated, update tcg_warns +-- All this happens only once per module +finishWarnings dflags mod_warn tcg_env = do { (eps,hpt) <- getEpsAndHpt - ; ifOptM Opt_WarnDeprecations $ + ; ifOptM Opt_WarnWarningsDeprecations $ mapM_ (check hpt (eps_PIT eps)) all_gres -- By this time, typechecking is complete, -- so the PIT is fully populated - -- Deal with a module deprecation; it overrides all existing deprecs - ; let new_deprecs = case mod_deprec of - Just txt -> DeprecAll txt - Nothing -> tcg_deprecs tcg_env - ; return (tcg_env { tcg_deprecs = new_deprecs }) } + -- Deal with a module deprecation; it overrides all existing warns + ; let new_warns = case mod_warn of + Just txt -> WarnAll txt + Nothing -> tcg_warns tcg_env + ; return (tcg_env { tcg_warns = new_warns }) } where used_names = allUses (tcg_dus tcg_env) -- Report on all deprecated uses; hence allUses @@ -992,13 +1022,13 @@ finishDeprecations dflags mod_deprec tcg_env | name `elemNameSet` used_names , Just deprec_txt <- lookupImpDeprec dflags hpt pit gre = addWarnAt (importSpecLoc imp_spec) - (sep [ptext (sLit "Deprecated use of") <+> + (sep [ptext (sLit "In the use of") <+> pprNonVarNameSpace (occNameSpace (nameOccName name)) <+> quotes (ppr name), (parens imp_msg) <> colon, (ppr deprec_txt) ]) where - name_mod = nameModule name + name_mod = ASSERT2( isExternalName name, ppr name ) nameModule name imp_mod = importSpecModule imp_spec imp_msg = ptext (sLit "imported from") <+> ppr imp_mod <> extra extra | imp_mod == moduleName name_mod = empty @@ -1013,18 +1043,19 @@ finishDeprecations dflags mod_deprec tcg_env -- interface lookupImpDeprec :: DynFlags -> HomePackageTable -> PackageIfaceTable - -> GlobalRdrElt -> Maybe DeprecTxt + -> GlobalRdrElt -> Maybe WarningTxt -- The name is definitely imported, so look in HPT, PIT lookupImpDeprec dflags hpt pit gre - = case lookupIfaceByModule dflags hpt pit (nameModule name) of - Just iface -> mi_dep_fn iface name `mplus` -- Bleat if the thing, *or + = case lookupIfaceByModule dflags hpt pit mod of + Just iface -> mi_warn_fn iface name `mplus` -- Bleat if the thing, *or case gre_par gre of - ParentIs p -> mi_dep_fn iface p -- its parent*, is deprec'd + ParentIs p -> mi_warn_fn iface p -- its parent*, is warn'd NoParent -> Nothing Nothing -> Nothing -- See Note [Used names with interface not loaded] where - name = gre_name gre + name = gre_name gre + mod = ASSERT2( isExternalName name, ppr name ) nameModule name \end{code} Note [Used names with interface not loaded] @@ -1190,7 +1221,10 @@ reportUnusedNames export_decls gbl_env (_, no_imp, loc) <- xs, let mod_name = moduleName mod, not (mod_name `elemFM` minimal_imports1), - mod /= pRELUDE, + moduleName mod /= pRELUDE_NAME, + -- XXX not really correct, but we don't want + -- to generate warnings when compiling against + -- a compat version of base. not no_imp] -- The not no_imp part is not to complain about -- import M (), which is an idiom for importing @@ -1332,7 +1366,7 @@ printMinimalImports imps where all_used avail_occs = all (`elem` map nameOccName ns) avail_occs doc = text "Compute minimal imports from" <+> ppr n - n_mod = nameModule n + n_mod = ASSERT( isExternalName n ) nameModule n \end{code} @@ -1361,8 +1395,9 @@ dodgyExportWarn item = dodgyMsg (ptext (sLit "export")) item dodgyMsg :: OutputableBndr n => SDoc -> n -> SDoc dodgyMsg kind tc - = sep [ ptext (sLit "The") <+> kind <+> ptext (sLit "item") <+> quotes (ppr (IEThingAll tc)), - ptext (sLit "suggests that") <+> quotes (ppr tc) <+> ptext (sLit "has constructors or class methods,"), + = sep [ ptext (sLit "The") <+> kind <+> ptext (sLit "item") <+> quotes (ppr (IEThingAll tc)) + <+> ptext (sLit "suggests that"), + quotes (ppr tc) <+> ptext (sLit "has (in-scope) constructors or class methods,"), ptext (sLit "but it has none") ] exportItemErr :: IE RdrName -> SDoc @@ -1428,12 +1463,20 @@ nullModuleExport :: ModuleName -> SDoc nullModuleExport mod = ptext (sLit "The export item `module") <+> ppr mod <> ptext (sLit "' exports nothing") -moduleDeprec :: ModuleName -> DeprecTxt -> SDoc -moduleDeprec mod txt - = sep [ ptext (sLit "Module") <+> quotes (ppr mod) <+> ptext (sLit "is deprecated:"), - nest 4 (ppr txt) ] +moduleWarn :: ModuleName -> WarningTxt -> SDoc +moduleWarn mod (WarningTxt txt) + = sep [ ptext (sLit "Module") <+> quotes (ppr mod) <> ptext (sLit ":"), + nest 4 (ppr txt) ] +moduleWarn mod (DeprecatedTxt txt) + = sep [ ptext (sLit "Module") <+> quotes (ppr mod) + <+> ptext (sLit "is deprecated:"), + nest 4 (ppr txt) ] implicitPreludeWarn :: SDoc implicitPreludeWarn = ptext (sLit "Module `Prelude' implicitly imported") + +packageImportErr :: SDoc +packageImportErr + = ptext (sLit "Package-qualified imports are not enabled; use -XPackageImports") \end{code}