diff options
Diffstat (limited to 'compiler/GHC/Rename/Names.hs')
-rw-r--r-- | compiler/GHC/Rename/Names.hs | 180 |
1 files changed, 41 insertions, 139 deletions
diff --git a/compiler/GHC/Rename/Names.hs b/compiler/GHC/Rename/Names.hs index 92cab86d05..ba45769034 100644 --- a/compiler/GHC/Rename/Names.hs +++ b/compiler/GHC/Rename/Names.hs @@ -72,7 +72,6 @@ import GHC.Types.Basic ( TopLevelFlag(..) ) import GHC.Types.SourceText import GHC.Types.Id import GHC.Types.HpcInfo -import GHC.Types.Error import GHC.Types.PkgQual import GHC.Types.GREInfo (ConInfo(..)) @@ -90,7 +89,7 @@ import GHC.Data.Maybe import GHC.Data.List.SetOps ( removeDups ) import Control.Monad -import Data.Foldable ( for_, toList ) +import Data.Foldable ( for_ ) import Data.IntMap ( IntMap ) import qualified Data.IntMap as IntMap import Data.Map ( Map ) @@ -323,7 +322,7 @@ rnImportDecl this_mod NoRawPkgQual -> pure () RawPkgQual _ -> do pkg_imports <- xoptM LangExt.PackageImports - when (not pkg_imports) $ addErr packageImportErr + when (not pkg_imports) $ addErr TcRnPackageImportsDisabled let qual_only = isImportDeclQualified qual_style @@ -356,8 +355,7 @@ rnImportDecl this_mod NoPkgQual -> True ThisPkg uid -> uid == homeUnitId_ (hsc_dflags hsc_env) OtherPkg _ -> False)) - (addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $ - (text "A module cannot import itself:" <+> ppr imp_mod_name)) + (addErr (TcRnSelfImport imp_mod_name)) -- Check for a missing import list (Opt_WarnMissingImportList also -- checks for T(..) items but that is done in checkDodgyImport below) @@ -365,12 +363,7 @@ rnImportDecl this_mod Just (Exactly, _) -> return () -- Explicit import list _ | implicit -> return () -- Do not bleat for implicit imports | qual_only -> return () - | otherwise -> whenWOptM Opt_WarnMissingImportList $ do - let msg = mkTcRnUnknownMessage $ - mkPlainDiagnostic (WarningWithFlag Opt_WarnMissingImportList) - noHints - (missingImportListWarn imp_mod_name) - addDiagnostic msg + | otherwise -> addDiagnostic (TcRnNoExplicitImportList imp_mod_name) iface <- loadSrcInterface doc imp_mod_name want_boot pkg_qual @@ -389,11 +382,9 @@ rnImportDecl this_mod -- is not deterministic. The hs-boot test can show this up. dflags <- getDynFlags warnIf ((want_boot == IsBoot) && (mi_boot iface == NotBoot) && isOneShot (ghcMode dflags)) - (warnRedundantSourceImport imp_mod_name) + (TcRnRedundantSourceImport imp_mod_name) when (mod_safe && not (safeImportsOn dflags)) $ - addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $ - (text "safe import can't be used as Safe Haskell isn't on!" - $+$ text ("please enable Safe Haskell through either Safe, Trustworthy or Unsafe")) + addErr (TcRnSafeImportsDisabled imp_mod_name) let qual_mod_name = fmap unLoc as_mod `orElse` imp_mod_name @@ -432,12 +423,7 @@ rnImportDecl this_mod -- Complain if we import a deprecated module case mi_warns iface of - WarnAll txt -> do - let msg = mkTcRnUnknownMessage $ - mkPlainDiagnostic (WarningWithCategory (warningTxtCategory txt)) - noHints - (moduleWarn imp_mod_name txt) - addDiagnostic msg + WarnAll txt -> addDiagnostic (TcRnDeprecatedModule imp_mod_name txt) _ -> return () -- Complain about -Wcompat-unqualified-imports violations. @@ -614,11 +600,7 @@ calculateAvails home_unit other_home_units iface mod_safe' want_boot imported_by warnUnqualifiedImport :: ImportDecl GhcPs -> ModIface -> RnM () warnUnqualifiedImport decl iface = when bad_import $ do - let msg = mkTcRnUnknownMessage $ - mkPlainDiagnostic (WarningWithFlag Opt_WarnCompatUnqualifiedImports) - noHints - warning - addDiagnosticAt loc msg + addDiagnosticAt loc (TcRnCompatUnqualifiedImport decl) where mod = mi_module iface loc = getLocA $ ideclName decl @@ -635,21 +617,10 @@ warnUnqualifiedImport decl iface = && not has_import_list && mod `elemModuleSet` qualifiedMods - warning = vcat - [ text "To ensure compatibility with future core libraries changes" - , text "imports to" <+> ppr (ideclName decl) <+> text "should be" - , text "either qualified or have an explicit import list." - ] - -- Modules for which we warn if we see unqualified imports qualifiedMods = mkModuleSet [ dATA_LIST ] -warnRedundantSourceImport :: ModuleName -> TcRnMessage -warnRedundantSourceImport mod_name - = mkTcRnUnknownMessage $ mkPlainDiagnostic WarningWithoutFlag noHints $ - text "Unnecessary {-# SOURCE #-} in the import of module" <+> quotes (ppr mod_name) - {- ************************************************************************ * * @@ -1252,32 +1223,35 @@ filterImports hsc_env iface decl_spec (Just (want_hiding, L l import_items)) = setSrcSpanA loc $ do (stuff, warns) <- liftM (fromMaybe ([],[])) $ run_lookup (lookup_ie ieRdr) - mapM_ emit_warning warns + mapM_ (addTcRnDiagnostic <=< warning_msg) warns return [ (L loc ie, gres) | (ie,gres) <- stuff ] where + -- Warn when importing T(..) and no children are brought in scope - emit_warning (DodgyImport n) = whenWOptM Opt_WarnDodgyImports $ - addTcRnDiagnostic (TcRnDodgyImports n) - emit_warning MissingImportList = whenWOptM Opt_WarnMissingImportList $ - addTcRnDiagnostic (TcRnMissingImportList ieRdr) - emit_warning (BadImportW ie) = whenWOptM Opt_WarnDodgyImports $ do + warning_msg (DodgyImport n) = + pure (TcRnDodgyImports (DodgyImportsEmptyParent n)) + warning_msg MissingImportList = + pure (TcRnMissingImportList ieRdr) + warning_msg (BadImportW ie) = do -- 'BadImportW' is only constructed below in 'handle_bad_import', in -- the 'EverythingBut' case, so that's what we pass to -- 'badImportItemErr'. - badImportItemErr iface decl_spec ie BadImportIsParent all_avails EverythingBut + reason <- badImportItemErr iface decl_spec ie BadImportIsParent all_avails + pure (TcRnDodgyImports (DodgyImportsHiding reason)) run_lookup :: IELookupM a -> TcRn (Maybe a) run_lookup m = case m of Failed err -> do - lookup_err_msg err + msg <- lookup_err_msg err + addErr (TcRnImportLookup msg) return Nothing Succeeded a -> return (Just a) lookup_err_msg err = case err of - BadImport ie sub -> badImportItemErr iface decl_spec ie sub all_avails Exactly - IllegalImport -> illegalImportItemErr - QualImportError rdr -> qualImportItemErr rdr - AmbiguousImport rdr xs -> ambiguousImportItemErr rdr xs + BadImport ie sub -> badImportItemErr iface decl_spec ie sub all_avails + IllegalImport -> pure ImportLookupIllegal + QualImportError rdr -> pure (ImportLookupQualified rdr) + AmbiguousImport rdr xs -> pure (ImportLookupAmbiguous rdr xs) -- For each import item, we convert its RdrNames to Names, -- and at the same time compute all the GlobalRdrElt corresponding @@ -1756,8 +1730,7 @@ warnUnusedImportDecls gbl_env hsc_src (vcat [ text "Uses:" <+> ppr uses , text "Import usage" <+> ppr usage]) - ; whenWOptM Opt_WarnUnusedImports $ - mapM_ (warnUnusedImport Opt_WarnUnusedImports rdr_env) usage + ; mapM_ (warnUnusedImport rdr_env) usage ; whenGOptM Opt_D_dump_minimal_imports $ printMinimalImports hsc_src usage } @@ -1862,9 +1835,8 @@ mkImportMap gres is:iss -> bestImport (is NE.:| iss) add _ gres = gre : gres -warnUnusedImport :: WarningFlag -> GlobalRdrEnv - -> ImportDeclUsage -> RnM () -warnUnusedImport flag rdr_env (L loc decl, used, unused) +warnUnusedImport :: GlobalRdrEnv -> ImportDeclUsage -> RnM () +warnUnusedImport rdr_env (L loc decl, used, unused) -- Do not warn for 'import M()' | Just (Exactly, L _ []) <- ideclImportList decl @@ -1878,9 +1850,7 @@ warnUnusedImport flag rdr_env (L loc decl, used, unused) -- Nothing used; drop entire declaration | null used - = let dia = mkTcRnUnknownMessage $ - mkPlainDiagnostic (WarningWithFlag flag) noHints msg1 - in addDiagnosticAt (locA loc) dia + = addDiagnosticAt (locA loc) (TcRnUnusedImport decl UnusedImportNone) -- Everything imported is used; nop | null unused @@ -1891,45 +1861,27 @@ warnUnusedImport flag rdr_env (L loc decl, used, unused) | Just (_, L _ imports) <- ideclImportList decl , length unused == 1 , Just (L loc _) <- find (\(L _ ie) -> ((ieName ie) :: Name) `elem` unused) imports - = let dia = mkTcRnUnknownMessage $ mkPlainDiagnostic (WarningWithFlag flag) noHints msg2 - in addDiagnosticAt (locA loc) dia + = addDiagnosticAt (locA loc) (TcRnUnusedImport decl (UnusedImportSome sort_unused)) -- Some imports are unused | otherwise - = let dia = mkTcRnUnknownMessage $ mkPlainDiagnostic (WarningWithFlag flag) noHints msg2 - in addDiagnosticAt (locA loc) dia + = addDiagnosticAt (locA loc) (TcRnUnusedImport decl (UnusedImportSome sort_unused)) where - msg1 = vcat [ pp_herald <+> quotes pp_mod <+> is_redundant - , nest 2 (text "except perhaps to import instances from" - <+> quotes pp_mod) - , text "To import instances alone, use:" - <+> text "import" <+> pp_mod <> parens Outputable.empty ] - msg2 = sep [ pp_herald <+> quotes sort_unused - , text "from module" <+> quotes pp_mod <+> is_redundant] - pp_herald = text "The" <+> pp_qual <+> text "import of" - pp_qual - | isImportDeclQualified (ideclQualified decl)= text "qualified" - | otherwise = Outputable.empty - pp_mod = ppr (unLoc (ideclName decl)) - is_redundant = text "is redundant" - -- In warning message, pretty-print identifiers unqualified unconditionally -- to improve the consistent for ambiguous/unambiguous identifiers. -- See trac#14881. - ppr_possible_field n = + possible_field n = case lookupGRE_Name rdr_env n of Just (GRE { gre_par = par, gre_info = IAmRecField info }) -> let fld_occ :: OccName fld_occ = nameOccName $ flSelector $ recFieldLabel info - in case par of - ParentIs p -> pprNameUnqualified p <> parens (ppr fld_occ) - NoParent -> ppr fld_occ - _ -> pprNameUnqualified n + in UnusedImportNameRecField par fld_occ + _ -> UnusedImportNameRegular n -- Print unused names in a deterministic (lexicographic) order - sort_unused :: SDoc - sort_unused = pprWithCommas ppr_possible_field $ + sort_unused :: [UnusedImportName] + sort_unused = fmap possible_field $ sortBy (comparing nameOccName) unused {- @@ -2137,30 +2089,13 @@ DRFPatSynExport for a test of this. ************************************************************************ -} -qualImportItemErr :: RdrName -> TcRn () -qualImportItemErr rdr - = addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $ - hang (text "Illegal qualified name in import item:") - 2 (ppr rdr) - -ambiguousImportItemErr :: RdrName -> [GlobalRdrElt] -> TcRn () -ambiguousImportItemErr rdr gres - = addErr $ mkTcRnUnknownMessage $ mkPlainError noHints err - where - err = hang (text "Ambiguous name" <+> quotes (ppr rdr) <+> text "in import item. It could refer to:") - 2 (vcat (map (ppr . greOccName) gres)) - badImportItemErr :: ModIface -> ImpDeclSpec -> IE GhcPs -> BadImportIsSubordinate -> [AvailInfo] - -> ImportListInterpretation - -> TcRn () -badImportItemErr iface decl_spec ie sub avails ili - = do { patsyns_enabled <- xoptM LangExt.PatternSynonyms - ; let err = TcRnBadImport importErrorKind iface decl_spec ie patsyns_enabled ili - ; case ili of - EverythingBut -> addTcRnDiagnostic err - Exactly -> addErr err } + -> TcRn ImportLookupReason +badImportItemErr iface decl_spec ie sub avails = do + patsyns_enabled <- xoptM LangExt.PatternSynonyms + pure (ImportLookupBad importErrorKind iface decl_spec ie patsyns_enabled) where importErrorKind | any checkIfTyCon avails = case sub of @@ -2189,43 +2124,15 @@ badImportItemErr iface decl_spec ie sub avails ili IEThingWith _ _ _ ns -> map (ieWrappedName . unLoc) ns _ -> panic "importedChildren failed pattern match: no children" -illegalImportItemErr :: TcRn () -illegalImportItemErr = addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $ text "Illegal import item" - addDupDeclErr :: NonEmpty GlobalRdrElt -> TcRn () addDupDeclErr gres@(gre :| _) - = addErrAt (getSrcSpan (NE.last sorted_names)) $ mkTcRnUnknownMessage $ mkPlainError noHints $ - -- Report the error at the later location - vcat [text "Multiple declarations of" <+> - quotes (ppr (greOccName gre)), - -- NB. print the OccName, not the Name, because the - -- latter might not be in scope in the RdrEnv and so will - -- be printed qualified. - text "Declared at:" <+> - vcat (toList $ ppr . nameSrcLoc <$> sorted_names)] + -- Report the error at the later location + = addErrAt (getSrcSpan (NE.last sorted_names)) $ (TcRnDuplicateDecls (greOccName gre) sorted_names) where sorted_names = NE.sortBy (SrcLoc.leftmost_smallest `on` nameSrcSpan) (fmap greName gres) -missingImportListWarn :: ModuleName -> SDoc -missingImportListWarn mod - = text "The module" <+> quotes (ppr mod) <+> text "does not have an explicit import list" - -moduleWarn :: ModuleName -> WarningTxt GhcRn -> SDoc -moduleWarn mod (WarningTxt _ _ txt) - = sep [ text "Module" <+> quotes (ppr mod) <> colon, - nest 2 (vcat (map (ppr . hsDocString . unLoc) txt)) ] -moduleWarn mod (DeprecatedTxt _ txt) - = sep [ text "Module" <+> quotes (ppr mod) - <+> text "is deprecated:", - nest 2 (vcat (map (ppr . hsDocString . unLoc) txt)) ] - -packageImportErr :: TcRnMessage -packageImportErr - = mkTcRnUnknownMessage $ mkPlainError noHints $ - text "Package-qualified imports are not enabled; use PackageImports" - -- This data decl will parse OK -- data T = a Int -- treating "a" as the constructor. @@ -2241,9 +2148,4 @@ packageImportErr checkConName :: RdrName -> TcRn () checkConName name - = checkErr (isRdrDataCon name || isRdrTc name) (badDataCon name) - -badDataCon :: RdrName -> TcRnMessage -badDataCon name - = mkTcRnUnknownMessage $ mkPlainError noHints $ - hsep [text "Illegal data constructor name", quotes (ppr name)] + = checkErr (isRdrDataCon name || isRdrTc name) (TcRnIllegalDataCon name) |