Simon Hengel pushed to branch wip/sol/interactive-error-hints at Glasgow Haskell Compiler / GHC Commits: a350548f by Simon Hengel at 2026-06-21T21:23:29+07:00 Add a flag to control GHCi specific error hints (close #27409) - - - - - 10 changed files: - + changelog.d/interactive-error-hints - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/GHC/Utils/Outputable.hs - docs/users_guide/ghci.rst - ghc/GHCi/UI/Exception.hs - ghc/Main.hs - testsuite/tests/ghci/scripts/ghci024.stdout Changes: ===================================== changelog.d/interactive-error-hints ===================================== @@ -0,0 +1,6 @@ +section: compiler +synopsis: + Add flags `-finteractive-error-hints` / `-fno-interactive-error-hints` that + control whether GHCi specific error hints are printed. +issues: #27409 +mrs: !16225 ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1570,6 +1570,7 @@ initSDocContext dflags style = SDC , sdocLineLength = pprCols dflags , sdocCanUseUnicode = useUnicode dflags , sdocPrintErrIndexLinks = overrideWith (canUseErrorLinks dflags) (useErrorLinks dflags) + , sdocInteractiveErrorHints = gopt Opt_InteractiveErrorHints dflags , sdocHexWordLiterals = gopt Opt_HexWordLiterals dflags , sdocPprDebug = dopt Opt_D_ppr_debug dflags , sdocPrintUnicodeSyntax = gopt Opt_PrintUnicodeSyntax dflags ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -861,6 +861,7 @@ data GeneralFlag -- Error message suppression | Opt_ShowErrorContext + | Opt_InteractiveErrorHints -- Object code determinism | Opt_ObjectDeterminism ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2665,6 +2665,7 @@ fFlagsDeps = [ (addWarn "-compact-unwind is only implemented by the darwin platform. Ignoring.") return dflags)), flagSpec "show-error-context" Opt_ShowErrorContext, + flagSpec "interactive-error-hints" Opt_InteractiveErrorHints, flagSpec "cmm-thread-sanitizer" Opt_CmmThreadSanitizer, flagSpec "split-sections" Opt_SplitSections, flagSpec "break-points" Opt_InsertBreakpoints, ===================================== compiler/GHC/Types/Hint/Ppr.hs ===================================== @@ -43,19 +43,44 @@ instance Outputable GhcHint where -> case extHint of SuggestSingleExtension extraUserInfo ext -> ("Perhaps you intended to use" <+> extension_with_implied ext) - $$ extraUserInfo + $$ interactiveErrorHints [ext] extraUserInfo False SuggestAnyExtension extraUserInfo exts -> (enable "any" <+> unquotedListWith "or" (map implied exts)) - $$ extraUserInfo + $$ interactiveErrorHints exts extraUserInfo True SuggestExtensions extraUserInfo exts -> (enable "all" <+> unquotedListWith "and" (map implied exts)) - $$ extraUserInfo + $$ interactiveErrorHints exts extraUserInfo False SuggestExtensionInOrderTo extraUserInfo ext -> ("Use" <+> extension_with_implied ext) - $$ extraUserInfo + $$ interactiveErrorHints [ext] extraUserInfo False where extension_with_implied ext = "the" <+> quotes (ppr ext) <+> "extension" <+> pprImpliedExtensions ext implied ext = quotes (ppr ext) <+> pprImpliedExtensions ext enable any_or_all = "Enable" <+> any_or_all <+> "of the following extensions" <> colon + + interactiveErrorHints :: [LangExt.Extension] -> SDoc -> Bool -> SDoc + interactiveErrorHints exts doc enable_any = sdocOption sdocInteractiveErrorHints $ \ case + True -> suggestSetExt exts doc enable_any + False -> doc + + -- Suggest enabling extension with :set -X<ext> + -- SuggestAnyExtension will be on multiple lines so the user can select which to enable without editing + suggestSetExt :: [LangExt.Extension] -> SDoc -> Bool -> SDoc + suggestSetExt exts doc enable_any = doc $$ hang header 2 exts_cmds + where + header = text "You may enable" <+> which <+> text "language extension" <> plural exts <+> text "in GHCi with:" + which + | [ _ext ] <- exts + = text "this" + | otherwise + = if enable_any + then text "these" + else text "all of these" + exts_cmds + | enable_any + = vcat $ map (\ext -> text ":set -X" <> ppr ext) exts + | otherwise + = text ":set" <> hcat (map (\ext -> text " -X" <> ppr ext) exts) + SuggestCorrectPragmaName suggestions -> text "Perhaps you meant" <+> quotedListWithOr (map text suggestions) SuggestMissingDo ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -398,6 +398,7 @@ data SDocContext = SDC -- ^ True if Unicode encoding is supported -- and not disabled by GHC_NO_UNICODE environment variable , sdocPrintErrIndexLinks :: !Bool + , sdocInteractiveErrorHints :: !Bool , sdocHexWordLiterals :: !Bool , sdocPprDebug :: !Bool , sdocPrintUnicodeSyntax :: !Bool @@ -466,6 +467,7 @@ defaultSDocContext = SDC , sdocLineLength = defaultSDocCols , sdocCanUseUnicode = False , sdocPrintErrIndexLinks = False + , sdocInteractiveErrorHints = False , sdocHexWordLiterals = False , sdocPprDebug = False , sdocPrintUnicodeSyntax = False ===================================== docs/users_guide/ghci.rst ===================================== @@ -2114,6 +2114,27 @@ mostly obvious. If disabled, only the target given last on the command line interface will be added to interactive context of the GHCi session. +.. ghc-flag:: -finteractive-error-hints + :shortdesc: Print GHCi specific error hints. + :type: dynamic + :reverse: -fno-interactive-error-hints + :category: + + :default: on + :since: XXX + + By default, GHCi extends error hints with GHCi specific instructions. + + Example: + + .. code-block:: none + + Perhaps you intended to use the ‘BlockArguments’ extension + You may enable this language extension in GHCi with: + :set -XBlockArguments + + This can be disabled with `-fno-interactive-error-hints`. + Packages ~~~~~~~~ ===================================== ghc/GHCi/UI/Exception.hs ===================================== @@ -23,8 +23,6 @@ import GHC.Driver.Errors.Types import GHC.Iface.Errors.Ppr import GHC.Iface.Errors.Types -import qualified GHC.LanguageExtensions as LangExt - import GHC.Tc.Errors.Ppr import GHC.Tc.Errors.Types @@ -137,7 +135,7 @@ instance Diagnostic GhciMessage where GhciUnknownMessage m -> diagnosticReason m diagnosticHints = \case - GhciGhcMessage m -> map GhciGhcHint (ghciDiagnosticHints m) + GhciGhcMessage m -> map GhciGhcHint (diagnosticHints m) GhciCommandMessage m -> map GhciCommandHint (diagnosticHints m) GhciUnknownMessage m -> diagnosticHints m @@ -146,40 +144,6 @@ instance Diagnostic GhciMessage where GhciCommandMessage m -> diagnosticCode m GhciUnknownMessage m -> diagnosticCode m - --- | Modifications to hint messages which we want to display in GHCi. -ghciDiagnosticHints :: GhcMessage -> [GhcHint] -ghciDiagnosticHints msg = map modifyHintForGHCi (diagnosticHints msg) - where - modifyHintForGHCi :: GhcHint -> GhcHint - modifyHintForGHCi = \case - SuggestExtension extHint -> SuggestExtension $ modifyExtHintForGHCi extHint - hint -> hint - modifyExtHintForGHCi :: LanguageExtensionHint -> LanguageExtensionHint - modifyExtHintForGHCi = \case - SuggestSingleExtension doc ext -> SuggestSingleExtension (suggestSetExt [ext] doc False) ext - SuggestExtensionInOrderTo doc ext -> SuggestExtensionInOrderTo (suggestSetExt [ext] doc False) ext - SuggestAnyExtension doc exts -> SuggestAnyExtension (suggestSetExt exts doc True ) exts - SuggestExtensions doc exts -> SuggestExtensions (suggestSetExt exts doc False) exts - -- Suggest enabling extension with :set -X<ext> - -- SuggestAnyExtension will be on multiple lines so the user can select which to enable without editing - suggestSetExt :: [LangExt.Extension] -> SDoc -> Bool -> SDoc - suggestSetExt exts doc enable_any = doc $$ hang header 2 exts_cmds - where - header = text "You may enable" <+> which <+> text "language extension" <> plural exts <+> text "in GHCi with:" - which - | [ _ext ] <- exts - = text "this" - | otherwise - = if enable_any - then text "these" - else text "all of these" - exts_cmds - | enable_any - = vcat $ map (\ext -> text ":set -X" <> ppr ext) exts - | otherwise - = text ":set" <> hcat (map (\ext -> text " -X" <> ppr ext) exts) - -- | Modifications to error messages which we want to display in GHCi ghciDiagnosticMessage :: GhcMessageOpts -> GhcMessage -> DecoratedSDoc ghciDiagnosticMessage ghc_opts msg = ===================================== ghc/Main.hs ===================================== @@ -199,6 +199,7 @@ main' postLoadMode units dflags0 args flagWarnings = do | DoRun <- postLoadMode = def_ghci_flags | otherwise = dflags1 where def_ghci_flags = dflags1 `gopt_set` Opt_ImplicitImportQualified + `gopt_set` Opt_InteractiveErrorHints `gopt_set` Opt_IgnoreOptimChanges `gopt_set` Opt_IgnoreHpcChanges -- Setting this by default has the nice effect that ===================================== testsuite/tests/ghci/scripts/ghci024.stdout ===================================== @@ -12,6 +12,7 @@ other dynamic, non-language, flag settings: -fimplicit-import-qualified -fshow-warning-groups -fprefer-byte-code + -finteractive-error-hints -fbreak-points warning settings: -Wpattern-namespace-specifier View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a350548f23f793f4244e76d5a606d574... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a350548f23f793f4244e76d5a606d574... You're receiving this email because of your account on gitlab.haskell.org.