Simon Hengel pushed to branch wip/sol/interactive-package-error-hints at Glasgow Haskell Compiler / GHC
Commits:
-
26d9f72d
by Simon Hengel at 2026-06-25T16:00:46+07:00
7 changed files:
- compiler/GHC/Iface/Errors/Ppr.hs
- ghc/GHCi/UI/Exception.hs
- + testsuite/tests/package/ImportReexport_cabal.hs
- + testsuite/tests/package/ImportReexport_cabal.stderr
- + testsuite/tests/package/ImportReexport_ghci.hs
- + testsuite/tests/package/ImportReexport_ghci.stderr
- testsuite/tests/package/all.T
Changes:
| ... | ... | @@ -13,11 +13,6 @@ module GHC.Iface.Errors.Ppr |
| 13 | 13 | , missingInterfaceErrorReason
|
| 14 | 14 | , missingInterfaceErrorDiagnostic
|
| 15 | 15 | , readInterfaceErrorDiagnostic
|
| 16 | - |
|
| 17 | - , lookingForHerald
|
|
| 18 | - , cantFindErrorX
|
|
| 19 | - , mayShowLocations
|
|
| 20 | - , pkgHiddenHint
|
|
| 21 | 16 | )
|
| 22 | 17 | where
|
| 23 | 18 | |
| ... | ... | @@ -124,38 +119,14 @@ data FindOrLoad = Find | Load |
| 124 | 119 | |
| 125 | 120 | data AmbiguousOrMissing = AoM_Ambiguous | AoM_Missing
|
| 126 | 121 | |
| 127 | -cantFindError :: IfaceMessageOpts
|
|
| 128 | - -> FindingModuleOrInterface
|
|
| 129 | - -> CantFindInstalled
|
|
| 130 | - -> SDoc
|
|
| 131 | -cantFindError opts =
|
|
| 132 | - cantFindErrorX
|
|
| 133 | - (pkgHiddenHint (const empty) (ifaceBuildingCabalPackage opts))
|
|
| 134 | - (mayShowLocations "-v" (ifaceShowTriedFiles opts))
|
|
| 135 | - |
|
| 136 | - |
|
| 137 | -pkgHiddenHint :: (UnitInfo -> SDoc) -> BuildingCabalPackage
|
|
| 138 | - -> UnitInfo -> SDoc
|
|
| 139 | -pkgHiddenHint _hint YesBuildingCabalPackage pkg
|
|
| 140 | - = text "Perhaps you need to add" <+>
|
|
| 141 | - quotes (ppr (unitPackageName pkg)) <+>
|
|
| 142 | - text "to the build-depends in your .cabal file."
|
|
| 143 | -pkgHiddenHint hint _not_cabal pkg
|
|
| 144 | - = hint pkg
|
|
| 145 | - |
|
| 146 | -mayShowLocations :: String -> Bool -> [FilePath] -> SDoc
|
|
| 147 | -mayShowLocations option verbose files
|
|
| 148 | - | null files = empty
|
|
| 149 | - | not verbose =
|
|
| 150 | - text "Use" <+> text option <+>
|
|
| 151 | - text "to see a list of the files searched for."
|
|
| 152 | - | otherwise =
|
|
| 153 | - hang (text "Locations searched:") 2 $ vcat (map text files)
|
|
| 122 | +data ErrorMode = NormalMode | InteractiveMode | BuildingCabalPackage
|
|
| 123 | + |
|
| 124 | +cantFindError :: IfaceMessageOpts -> FindingModuleOrInterface -> CantFindInstalled -> SDoc
|
|
| 125 | +cantFindError opts mod_or_interface cantFindInstalled =
|
|
| 126 | + sdocOption sdocInteractiveErrorHints $ cantFindErrorWith opts mod_or_interface cantFindInstalled
|
|
| 154 | 127 | |
| 155 | --- | General version of cantFindError which has some holes which allow GHC/GHCi to display slightly different
|
|
| 156 | --- error messages.
|
|
| 157 | -cantFindErrorX :: (UnitInfo -> SDoc) -> ([FilePath] -> SDoc) -> FindingModuleOrInterface -> CantFindInstalled -> SDoc
|
|
| 158 | -cantFindErrorX pkg_hidden_hint may_show_locations mod_or_interface (CantFindInstalled mod_name cfir) =
|
|
| 128 | +cantFindErrorWith :: IfaceMessageOpts -> FindingModuleOrInterface -> CantFindInstalled -> Bool -> SDoc
|
|
| 129 | +cantFindErrorWith opts mod_or_interface (CantFindInstalled mod_name cfir) interactiveErrorHints =
|
|
| 159 | 130 | let ambig = isAmbiguousInstalledReason cfir
|
| 160 | 131 | find_or_load = isLoadOrFindReason cfir
|
| 161 | 132 | ppr_what = prettyCantFindWhat find_or_load mod_or_interface ambig
|
| ... | ... | @@ -279,6 +250,40 @@ cantFindErrorX pkg_hidden_hint may_show_locations mod_or_interface (CantFindInst |
| 279 | 250 | <+> quotes (ppr unit)
|
| 280 | 251 | $$ pprReason (text "which is") reason
|
| 281 | 252 | |
| 253 | + mode :: ErrorMode
|
|
| 254 | + mode
|
|
| 255 | + | interactiveErrorHints = InteractiveMode
|
|
| 256 | + | otherwise = case ifaceBuildingCabalPackage opts of
|
|
| 257 | + NoBuildingCabalPackage -> NormalMode
|
|
| 258 | + YesBuildingCabalPackage -> BuildingCabalPackage
|
|
| 259 | + |
|
| 260 | + pkg_hidden_hint :: UnitInfo -> SDoc
|
|
| 261 | + pkg_hidden_hint pkg = case mode of
|
|
| 262 | + NormalMode ->
|
|
| 263 | + empty
|
|
| 264 | + InteractiveMode ->
|
|
| 265 | + text "You can run" <+>
|
|
| 266 | + quotes (text ":set -package " <> ppr (unitPackageName pkg)) <+>
|
|
| 267 | + text "to expose it." $$
|
|
| 268 | + text "(Note: this unloads all the modules in the current scope.)"
|
|
| 269 | + BuildingCabalPackage ->
|
|
| 270 | + text "Perhaps you need to add" <+>
|
|
| 271 | + quotes (ppr (unitPackageName pkg)) <+>
|
|
| 272 | + text "to the build-depends in your .cabal file."
|
|
| 273 | + |
|
| 274 | + may_show_locations :: [FilePath] -> SDoc
|
|
| 275 | + may_show_locations files
|
|
| 276 | + | null files =
|
|
| 277 | + empty
|
|
| 278 | + | ifaceShowTriedFiles opts =
|
|
| 279 | + hang (text "Locations searched:") 2 $ vcat (map text files)
|
|
| 280 | + | otherwise =
|
|
| 281 | + text "Use" <+> text option <+> text "to see a list of the files searched for."
|
|
| 282 | + where
|
|
| 283 | + option :: String
|
|
| 284 | + option = case mode of
|
|
| 285 | + InteractiveMode -> ":set -v"
|
|
| 286 | + _ -> "-v"
|
|
| 282 | 287 | |
| 283 | 288 | interfaceErrorDiagnostic :: IfaceMessageOpts -> IfaceMessage -> SDoc
|
| 284 | 289 | interfaceErrorDiagnostic opts = \ case
|
| ... | ... | @@ -20,9 +20,6 @@ import GHC.Prelude |
| 20 | 20 | |
| 21 | 21 | import GHC.Driver.Errors.Types
|
| 22 | 22 | |
| 23 | -import GHC.Iface.Errors.Ppr
|
|
| 24 | -import GHC.Iface.Errors.Types
|
|
| 25 | - |
|
| 26 | 23 | import GHC.Tc.Errors.Ppr
|
| 27 | 24 | import GHC.Tc.Errors.Types
|
| 28 | 25 | |
| ... | ... | @@ -30,8 +27,6 @@ import GHC.Types.Error.Codes |
| 30 | 27 | import GHC.Types.SrcLoc (interactiveSrcSpan)
|
| 31 | 28 | import GHC.TypeLits
|
| 32 | 29 | |
| 33 | -import GHC.Unit.State
|
|
| 34 | - |
|
| 35 | 30 | import GHC.Utils.Outputable
|
| 36 | 31 | import GHC.Utils.Error
|
| 37 | 32 | |
| ... | ... | @@ -152,18 +147,11 @@ ghciDiagnosticMessage ghc_opts msg = |
| 152 | 147 | case tcRnMessage (tcMessageOpts ghc_opts) tc_msg of
|
| 153 | 148 | Nothing -> diagnosticMessage ghc_opts msg
|
| 154 | 149 | Just sdoc -> sdoc
|
| 155 | - GhcDriverMessage (DriverInterfaceError err) ->
|
|
| 156 | - case ghciInterfaceError err of
|
|
| 157 | - Just sdoc -> mkSimpleDecorated sdoc
|
|
| 158 | - Nothing -> diagnosticMessage ghc_opts msg
|
|
| 159 | - GhcDriverMessage {} -> diagnosticMessage ghc_opts msg
|
|
| 160 | - GhcPsMessage {} -> diagnosticMessage ghc_opts msg
|
|
| 161 | - GhcDsMessage {} -> diagnosticMessage ghc_opts msg
|
|
| 162 | - GhcUnknownMessage {} -> diagnosticMessage ghc_opts msg
|
|
| 150 | + _ -> diagnosticMessage ghc_opts msg
|
|
| 163 | 151 | where
|
| 152 | + tcRnMessage :: TcRnMessageOpts -> TcRnMessage -> Maybe DecoratedSDoc
|
|
| 164 | 153 | tcRnMessage tc_opts tc_msg =
|
| 165 | 154 | case tc_msg of
|
| 166 | - TcRnInterfaceError err -> mkSimpleDecorated <$> (ghciInterfaceError err)
|
|
| 167 | 155 | TcRnMessageWithInfo unit_state msg_with_info ->
|
| 168 | 156 | case msg_with_info of
|
| 169 | 157 | TcRnMessageDetailed err_info wrapped_msg
|
| ... | ... | @@ -174,32 +162,6 @@ ghciDiagnosticMessage ghc_opts msg = |
| 174 | 162 | messageWithHsDocContext tc_opts ctxt <$> tcRnMessage tc_opts wrapped_msg
|
| 175 | 163 | _ -> Nothing
|
| 176 | 164 | |
| 177 | - opts = tcOptsIfaceOpts (tcMessageOpts ghc_opts)
|
|
| 178 | - |
|
| 179 | - ghciInterfaceError (Can'tFindInterface err looking_for) =
|
|
| 180 | - hangNotEmpty (lookingForHerald looking_for) 2 <$> ghciMissingInterfaceErrorDiagnostic err
|
|
| 181 | - ghciInterfaceError _ = Nothing
|
|
| 182 | - |
|
| 183 | - ghciMissingInterfaceErrorDiagnostic reason =
|
|
| 184 | - case reason of
|
|
| 185 | - CantFindErr us module_or_interface cfi ->
|
|
| 186 | - Just (pprWithUnitState us $ cantFindErrorX pkg_hidden_hint may_show_locations module_or_interface cfi)
|
|
| 187 | - _ -> Nothing
|
|
| 188 | - where
|
|
| 189 | - may_show_locations :: [String] -> SDoc
|
|
| 190 | - may_show_locations = mayShowLocations ":set -v" (ifaceShowTriedFiles opts)
|
|
| 191 | - |
|
| 192 | - pkg_hidden_hint :: UnitInfo -> SDoc
|
|
| 193 | - pkg_hidden_hint = pkgHiddenHint hidden_msg (ifaceBuildingCabalPackage opts)
|
|
| 194 | - where
|
|
| 195 | - hidden_msg :: UnitInfo -> SDoc
|
|
| 196 | - hidden_msg pkg =
|
|
| 197 | - text "You can run" <+>
|
|
| 198 | - quotes (text ":set -package " <> ppr (unitPackageName pkg)) <+>
|
|
| 199 | - text "to expose it." $$
|
|
| 200 | - text "(Note: this unloads all the modules in the current scope.)"
|
|
| 201 | - |
|
| 202 | - |
|
| 203 | 165 | data InvalidMacroStart = Colon | ExclamationMark
|
| 204 | 166 | |
| 205 | 167 | instance Outputable InvalidMacroStart where
|
| 1 | +module ImportReexport where
|
|
| 2 | +import GHC.Types -- reexported and renamed by ghc-prim from ghc-internal
|
|
| 3 | +import GHC.Platform.ArchOS -- reexported by by ghc and ghc-boot + provided by ghc-platform |
| 1 | +ImportReexport_cabal.hs:2:1: error: [GHC-87110]
|
|
| 2 | + Could not load module ‘GHC.Types’.
|
|
| 3 | + It is a member of the hidden package ‘ghc-prim-0.14.0’.
|
|
| 4 | + Perhaps you need to add ‘ghc-prim’ to the build-depends in your .cabal file.
|
|
| 5 | + Use -v to see a list of the files searched for.
|
|
| 6 | + |
|
| 7 | +ImportReexport_cabal.hs:3:1: error: [GHC-87110]
|
|
| 8 | + Could not load module ‘GHC.Platform.ArchOS’.
|
|
| 9 | + It is a member of the hidden package ‘ghc-10.1’.
|
|
| 10 | + Perhaps you need to add ‘ghc’ to the build-depends in your .cabal file.
|
|
| 11 | + It is a member of the hidden package ‘ghc-boot-10.1’.
|
|
| 12 | + Perhaps you need to add ‘ghc-boot’ to the build-depends in your .cabal file.
|
|
| 13 | + It is a member of the hidden package ‘ghc-platform-0.1.0.0’.
|
|
| 14 | + Perhaps you need to add ‘ghc-platform’ to the build-depends in your .cabal file.
|
|
| 15 | + Use -v to see a list of the files searched for.
|
|
| 16 | + |
| 1 | +module ImportReexport where
|
|
| 2 | +import GHC.Types -- reexported and renamed by ghc-prim from ghc-internal
|
|
| 3 | +import GHC.Platform.ArchOS -- reexported by by ghc and ghc-boot + provided by ghc-platform |
| 1 | +ImportReexport_ghci.hs:2:1: error: [GHC-87110]
|
|
| 2 | + Could not load module ‘GHC.Types’.
|
|
| 3 | + It is a member of the hidden package ‘ghc-prim-0.14.0’.
|
|
| 4 | + You can run ‘:set -package ghc-prim’ to expose it.
|
|
| 5 | + (Note: this unloads all the modules in the current scope.)
|
|
| 6 | + Use :set -v to see a list of the files searched for.
|
|
| 7 | + |
|
| 8 | +ImportReexport_ghci.hs:3:1: error: [GHC-87110]
|
|
| 9 | + Could not load module ‘GHC.Platform.ArchOS’.
|
|
| 10 | + It is a member of the hidden package ‘ghc-10.1’.
|
|
| 11 | + You can run ‘:set -package ghc’ to expose it.
|
|
| 12 | + (Note: this unloads all the modules in the current scope.)
|
|
| 13 | + It is a member of the hidden package ‘ghc-boot-10.1’.
|
|
| 14 | + You can run ‘:set -package ghc-boot’ to expose it.
|
|
| 15 | + (Note: this unloads all the modules in the current scope.)
|
|
| 16 | + It is a member of the hidden package ‘ghc-platform-0.1.0.0’.
|
|
| 17 | + You can run ‘:set -package ghc-platform’ to expose it.
|
|
| 18 | + (Note: this unloads all the modules in the current scope.)
|
|
| 19 | + Use :set -v to see a list of the files searched for.
|
|
| 20 | + |
| ... | ... | @@ -13,12 +13,16 @@ test('package04', normal, compile, [incr_containers]) |
| 13 | 13 | test('package05', normal, compile, [incr_ghc + inc_ghc])
|
| 14 | 14 | test('package06', normal, compile, [incr_ghc])
|
| 15 | 15 | test('package06e', normalise_version('ghc'), compile_fail, [incr_ghc])
|
| 16 | -test('ImportReexport', normalise_version('ghc'), compile_fail, ['-hide-all-packages -XNoImplicitPrelude'])
|
|
| 17 | 16 | test('package07e', normalise_version('ghc'), compile_fail, [incr_ghc + inc_ghc + hide_ghc])
|
| 18 | 17 | test('package08e', normalise_version('ghc'), compile_fail, [incr_ghc + hide_ghc])
|
| 19 | 18 | test('package09e', normal, compile_fail, ['-package "containers (Data.Map as M, Data.Set as M)"'])
|
| 20 | 19 | test('package10', normal, compile, ['-hide-all-packages -package "ghc (GHC.Types.Unique.FM as Prelude)" '])
|
| 21 | 20 | |
| 21 | +import_reexport_args = '-hide-all-packages -XNoImplicitPrelude '
|
|
| 22 | +test('ImportReexport', normal, compile_fail, [import_reexport_args])
|
|
| 23 | +test('ImportReexport_cabal', normal, compile_fail, [import_reexport_args + '-fbuilding-cabal-package'])
|
|
| 24 | +test('ImportReexport_ghci', normal, compile_fail, [import_reexport_args + '-finteractive-error-hints'])
|
|
| 25 | + |
|
| 22 | 26 | test('T4806', normalise_version('containers'), compile_fail, ['-ignore-package containers'])
|
| 23 | 27 | test('T4806a', normalise_version('deepseq', 'containers', 'template-haskell'), compile_fail, ['-ignore-package deepseq'])
|
| 24 | 28 | test('T22884', normalise_version('text'), compile_fail, ['-hide-package text'])
|