X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Frename%2FRnNames.lhs;h=4cba23b9bf743b77d9f2943a6ec223aa4d188145;hp=55fcea2054fc68270add9cba520deb43d19be282;hb=d2ce0f52d42edf32bb9f13796e6ba6edba8bd516;hpb=65277a1c9ff86c28c656849d6f6cbb392f1eb3e7 diff --git a/compiler/rename/RnNames.lhs b/compiler/rename/RnNames.lhs index 55fcea2..4cba23b 100644 --- a/compiler/rename/RnNames.lhs +++ b/compiler/rename/RnNames.lhs @@ -6,7 +6,8 @@ \begin{code} module RnNames ( rnImports, getLocalNonValBinders, - rnExports, extendGlobalRdrEnvRn, + rnExports, extendGlobalRdrEnvRn, + gresFromAvails, reportUnusedNames, finishWarnings, ) where @@ -19,8 +20,9 @@ import RnEnv import RnHsDoc ( rnHsDoc ) import IfaceEnv ( ifaceExportNames ) import LoadIface ( loadSrcInterface, loadSysInterface ) -import TcRnMonad hiding (LIE) +import TcRnMonad +import HeaderInfo ( mkPrelImports ) import PrelNames import Module import Name @@ -60,7 +62,7 @@ rnImports imports -- warning for {- SOURCE -} ones that are unnecessary = do this_mod <- getModule implicit_prelude <- doptM Opt_ImplicitPrelude - let prel_imports = mkPrelImports this_mod implicit_prelude imports + let prel_imports = mkPrelImports (moduleName this_mod) implicit_prelude imports (source, ordinary) = partition is_source_import imports is_source_import (L _ (ImportDecl _ _ is_boot _ _ _)) = is_boot @@ -68,10 +70,11 @@ rnImports imports when (notNull prel_imports) $ addWarn (implicitPreludeWarn) ) - stuff1 <- mapM (rnImportDecl this_mod) (prel_imports ++ ordinary) - stuff2 <- mapM (rnImportDecl this_mod) source - let (decls, rdr_env, imp_avails,hpc_usage) = combine (stuff1 ++ stuff2) - return (decls, rdr_env, imp_avails,hpc_usage) + stuff1 <- mapM (rnImportDecl this_mod True) prel_imports + stuff2 <- mapM (rnImportDecl this_mod False) ordinary + stuff3 <- mapM (rnImportDecl this_mod False) source + let (decls, rdr_env, imp_avails, hpc_usage) = combine (stuff1 ++ stuff2 ++ stuff3) + return (decls, rdr_env, imp_avails, hpc_usage) where combine :: [(LImportDecl Name, GlobalRdrEnv, ImportAvails,AnyHpcUsage)] @@ -84,41 +87,11 @@ rnImports imports imp_avails1 `plusImportAvails` imp_avails2, hpc_usage1 || hpc_usage2) -mkPrelImports :: Module -> Bool -> [LImportDecl RdrName] -> [LImportDecl RdrName] --- Consruct the implicit declaration "import Prelude" (or not) --- --- NB: opt_NoImplicitPrelude is slightly different to import Prelude (); --- because the former doesn't even look at Prelude.hi for instance --- declarations, whereas the latter does. -mkPrelImports this_mod implicit_prelude import_decls - | this_mod == pRELUDE - || explicit_prelude_import - || not implicit_prelude - = [] - | otherwise = [preludeImportDecl] - where - explicit_prelude_import - = 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" -} - Nothing {- No import list -} - - loc = mkGeneralSrcSpan (fsLit "Implicit import declaration") - - -rnImportDecl :: Module +rnImportDecl :: Module -> Bool -> LImportDecl RdrName -> RnM (LImportDecl Name, GlobalRdrEnv, ImportAvails,AnyHpcUsage) -rnImportDecl this_mod (L loc (ImportDecl loc_imp_mod_name mb_pkg want_boot +rnImportDecl this_mod implicit_prelude (L loc (ImportDecl loc_imp_mod_name mb_pkg want_boot qual_only as_mod imp_details)) = setSrcSpan loc $ do @@ -132,6 +105,17 @@ rnImportDecl this_mod (L loc (ImportDecl loc_imp_mod_name mb_pkg want_boot imp_mod_name = unLoc loc_imp_mod_name doc = ppr imp_mod_name <+> ptext (sLit "is directly imported") + let isExplicit lie = case unLoc lie of + IEThingAll _ -> False + _ -> True + case imp_details of + Just (False, lies) + | all isExplicit lies -> + return () + _ -> + unless implicit_prelude $ + ifOptM Opt_WarnMissingImportList (addWarn (missingImportListWarn imp_mod_name)) + iface <- loadSrcInterface doc imp_mod_name want_boot mb_pkg -- Compiler sanity check: if the import didn't say @@ -289,23 +273,34 @@ top level binders specially in two ways 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'. - - 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. + there are two bindings for 'f'. There are several tricky points: + + * 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. + + * The *qualified* name M.f from the enclosing module must certainly + still be available. So we don't nuke it entirely; we just make + it seem like qualified import. + + * We only shadow *External* names (which come from the main module) + Do not shadow *Inernal* names because in the bracket + [d| class C a where f :: a + f = 4 |] + rnSrcDecls will first call extendGlobalRdrEnvRn with C[f] from the + class decl, and *separately* extend the envt with the value binding. + +3. 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 :: [AvailInfo] -> MiniFixityEnv -> RnM (TcGblEnv, TcLclEnv) -- Updates both the GlobalRdrEnv and the FixityEnv - -- We return a new TcLclEnv only becuase we might have to + -- We return a new TcLclEnv only because we might have to -- delete some bindings from it; -- see Note [Top-level Names in Template Haskell decl quotes] @@ -321,7 +316,7 @@ extendGlobalRdrEnvRn avails new_fixities -- 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 + rdr_env1 = transformGREs qual_gre new_occs rdr_env lcl_env1 = lcl_env { tcl_rdr = delListFromOccEnv (tcl_rdr lcl_env) new_occs } (rdr_env2, lcl_env2) | shadowP = (rdr_env1, lcl_env1) | otherwise = (rdr_env, lcl_env) @@ -348,6 +343,35 @@ extendGlobalRdrEnvRn avails new_fixities where name = gre_name gre occ = nameOccName name + + qual_gre :: GlobalRdrElt -> GlobalRdrElt + -- Transform top-level GREs from the module being compiled + -- so that they are out of the way of new definitions in a Template + -- Haskell bracket + -- See Note [Top-level Names in Template Haskell decl quotes] + -- Seems like 5 times as much work as it deserves! + -- + -- For a LocalDef we make a (fake) qualified imported GRE for a + -- local GRE so that the original *qualified* name is still in scope + -- but the *unqualified* one no longer is. What a hack! + + qual_gre gre@(GRE { gre_prov = LocalDef, gre_name = name }) + | isExternalName name = gre { gre_prov = Imported [imp_spec] } + | otherwise = gre + -- Do not shadow Internal (ie Template Haskell) Names + -- See Note [Top-level Names in Template Haskell decl quotes] + where + mod = ASSERT2( isExternalName name, ppr name) moduleName (nameModule name) + imp_spec = ImpSpec { is_item = ImpAll, is_decl = decl_spec } + decl_spec = ImpDeclSpec { is_mod = mod, is_as = mod, + is_qual = True, -- Qualified only! + is_dloc = srcLocSpan (nameSrcLoc name) } + + qual_gre gre@(GRE { gre_prov = Imported specs }) + = gre { gre_prov = Imported (map qual_spec specs) } + + qual_spec spec@(ImpSpec { is_decl = decl_spec }) + = spec { is_decl = decl_spec { is_qual = True } } \end{code} @getLocalDeclBinders@ returns the names for an @HsDecl@. It's @@ -405,8 +429,8 @@ getLocalNonValBinders :: HsGroup RdrName -> RnM [AvailInfo] -- Get all the top-level binders bound the group *except* -- for value bindings, which are treated separately -- Specificaly we return AvailInfo for --- type decls --- class decls +-- type decls (incl constructors and record selectors) +-- class decls (including class ops) -- associated types -- foreign imports -- (in hs-boot files) value signatures @@ -423,8 +447,7 @@ get_local_binders gbl_env (HsGroup {hs_valds = ValBindsIn _ val_sigs, = do { -- separate out the family instance declarations let (tyinst_decls1, tycl_decls_noinsts) = partition (isFamInstDecl . unLoc) tycl_decls - tyinst_decls = tyinst_decls1 ++ - concatMap (instDeclATs . unLoc) inst_decls + tyinst_decls = tyinst_decls1 ++ instDeclATs inst_decls -- process all type/class decls except family instances ; tc_names <- mapM new_tc tycl_decls_noinsts @@ -440,7 +463,6 @@ get_local_binders gbl_env (HsGroup {hs_valds = ValBindsIn _ val_sigs, ; val_names <- mapM new_simple val_bndrs ; return (val_names ++ tc_names ++ ti_names) } where - mod = tcg_mod gbl_env is_hs_boot = isHsBoot (tcg_src gbl_env) ; for_hs_bndrs :: [Located RdrName] @@ -454,23 +476,23 @@ get_local_binders gbl_env (HsGroup {hs_valds = ValBindsIn _ val_sigs, new_simple :: Located RdrName -> RnM (GenAvailInfo Name) new_simple rdr_name = do - nm <- newTopSrcBinder mod rdr_name + nm <- newTopSrcBinder rdr_name return (Avail nm) new_tc tc_decl -- NOT for type/data instances - = do { main_name <- newTopSrcBinder mod main_rdr - ; sub_names <- mapM (newTopSrcBinder mod) sub_rdrs + = do { main_name <- newTopSrcBinder main_rdr + ; sub_names <- mapM newTopSrcBinder sub_rdrs ; return (AvailTC main_name (main_name : sub_names)) } where - (main_rdr : sub_rdrs) = tyClDeclNames (unLoc tc_decl) + (main_rdr : sub_rdrs) = hsTyClDeclBinders tc_decl new_ti tc_name_env ti_decl -- ONLY for type/data instances = do { main_name <- lookupFamInstDeclBndr tc_name_env main_rdr - ; sub_names <- mapM (newTopSrcBinder mod) sub_rdrs + ; sub_names <- mapM newTopSrcBinder sub_rdrs ; return (AvailTC main_name sub_names) } -- main_name is not bound here! where - (main_rdr : sub_rdrs) = tyClDeclNames (unLoc ti_decl) + (main_rdr : sub_rdrs) = hsTyClDeclBinders ti_decl get_local_binders _ g = pprPanic "get_local_binders" (ppr g) \end{code} @@ -578,12 +600,13 @@ filterImports iface decl_spec (Just (want_hiding, import_items)) all_avails -- different parents). See the discussion at occ_env. lookup_ie :: Bool -> IE RdrName -> MaybeErr Message [(IE Name,AvailInfo)] lookup_ie opt_typeFamilies ie - = let bad_ie = Failed (badImportItemErr iface decl_spec ie) + = let bad_ie :: MaybeErr Message a + bad_ie = Failed (badImportItemErr iface decl_spec ie) - lookup_name rdrName = - case lookupOccEnv occ_env (rdrNameOcc rdrName) of - Nothing -> bad_ie - Just n -> return n + lookup_name rdr + | isQual rdr = Failed (qualImportItemErr rdr) + | Just nm <- lookupOccEnv occ_env (rdrNameOcc rdr) = return nm + | otherwise = bad_ie in case ie of IEVar n -> do @@ -1304,20 +1327,20 @@ isImpAll _other = False \begin{code} warnUnusedImport :: ImportDeclUsage -> RnM () -warnUnusedImport (L loc decl, used, unused) - | Just (False,[]) <- ideclHiding decl - = return () -- Do not warn for 'import M()' +warnUnusedImport (L loc decl, used, unused) + | Just (False,[]) <- ideclHiding decl + = return () -- Do not warn for 'import M()' | null used = addWarnAt loc msg1 -- Nothing used; drop entire decl - | null unused = return () -- Everything imported is used; nop + | null unused = return () -- Everything imported is used; nop | otherwise = addWarnAt loc msg2 -- Some imports are unused where msg1 = vcat [pp_herald <+> quotes pp_mod <+> pp_not_used, - nest 2 (ptext (sLit "except perhaps to import instances from") - <+> quotes pp_mod), - ptext (sLit "To import instances alone, use:") - <+> ptext (sLit "import") <+> pp_mod <> parens empty ] + nest 2 (ptext (sLit "except perhaps to import instances from") + <+> quotes pp_mod), + ptext (sLit "To import instances alone, use:") + <+> ptext (sLit "import") <+> pp_mod <> parens empty ] msg2 = sep [pp_herald <+> quotes (pprWithCommas ppr unused), - text "from module" <+> quotes pp_mod <+> pp_not_used] + text "from module" <+> quotes pp_mod <+> pp_not_used] pp_herald = text "The import of" pp_mod = ppr (unLoc (ideclName decl)) pp_not_used = text "is redundant" @@ -1386,6 +1409,11 @@ printMinimalImports imports_w_usage %************************************************************************ \begin{code} +qualImportItemErr :: RdrName -> SDoc +qualImportItemErr rdr + = hang (ptext (sLit "Illegal qualified name in import item:")) + 2 (ppr rdr) + badImportItemErr :: ModIface -> ImpDeclSpec -> IE RdrName -> SDoc badImportItemErr iface decl_spec ie = sep [ptext (sLit "Module"), quotes (ppr (is_mod decl_spec)), source_import, @@ -1472,6 +1500,10 @@ nullModuleExport :: ModuleName -> SDoc nullModuleExport mod = ptext (sLit "The export item `module") <+> ppr mod <> ptext (sLit "' exports nothing") +missingImportListWarn :: ModuleName -> SDoc +missingImportListWarn mod + = ptext (sLit "The module") <+> quotes (ppr mod) <+> ptext (sLit "does not have an explicit import list") + moduleWarn :: ModuleName -> WarningTxt -> SDoc moduleWarn mod (WarningTxt txt) = sep [ ptext (sLit "Module") <+> quotes (ppr mod) <> ptext (sLit ":"),