Hannes Siebenhandl pushed to branch wip/romes/27461 at Glasgow Haskell Compiler / GHC Commits: b6011958 by fendor at 2026-08-03T16:02:02+02:00 Fixup: handle file targets gracefully that have a difference module name We reject imports of modules that have a file name different to their module name. Such files are only valid if they are not imported by the rest of the module graph. - - - - - 10 changed files: - compiler/GHC/Driver/Downsweep.hs - + testsuite/tests/driver/T27461/Main1.hs - + testsuite/tests/driver/T27461/Main2.hs - + testsuite/tests/driver/T27461/Makefile - + testsuite/tests/driver/T27461/T27461a.stderr - + testsuite/tests/driver/T27461/T27461b.script - + testsuite/tests/driver/T27461/T27461b.stderr - + testsuite/tests/driver/T27461/T27461b.stdout - + testsuite/tests/driver/T27461/all.T - + testsuite/tests/driver/T27461/src/Bar.hs Changes: ===================================== compiler/GHC/Driver/Downsweep.hs ===================================== @@ -1555,7 +1555,23 @@ summariseModuleWithSource home_unit summ_cache_ref is_boot maybe_buf hsc_env loc -- hi file, object file, when is_boot says so let src_fn = expectJust (ml_hs_file location) summ_cache <- readIORef summ_cache_ref - case ml_hs_file_ospath location >>= \p -> M.lookup (moduleUnitId mod, p) summ_cache of + -- Reject the cache result if the module name doesn't match the inferred + -- module name based on the file name. + -- This happens if we `summariseFile` for a root file target (which has a different module name) + -- and then we try to import it. + -- + -- Fall through to `new_summary` if this happens to reject this module. + let cached = do + p <- ml_hs_file_ospath location + res <- M.lookup (moduleUnitId mod, p) summ_cache + case res of + Right (ms, _) | msKey ms /= moduleToMnk mod is_boot -> + -- Module name doesn't match the file path name. + -- We fall through to @new_summary@, where this will be + -- discovered and the correct error message will be thrown. + Nothing + _ -> Just res + case cached of Just (Right (chd_summary, SummFresh)) -> -- Fresh! just return it pure $ FoundHome (ModuleNodeCompile chd_summary) @@ -1858,6 +1874,15 @@ twice). Note that (2) can't guarantee this alone: Two ModuleName imports in separate units can (and likely do) map to the same `Module`. + Note: + There is a special case where the module name doesn't have to match the file name. + For example, the `Main` module is sometimes not defined in a file + named `Main.hs`. We still want to compile such file targets, but reject the module + if it is used as a module target. + Thus, we accept this difference while `summariseFile`, but reject if we encounter expand + this module node during `summariseModuleWithSource`. + See tests T27461a and T27461b. + See also Note [Downsweep: building and maintaining the module graph] and Note [The ModuleGraph]. -} ===================================== testsuite/tests/driver/T27461/Main1.hs ===================================== @@ -0,0 +1,6 @@ +module Main where + +import Bar () -- resolves to src/Bar.hs, which declares module Foo + +main :: IO () +main = return () ===================================== testsuite/tests/driver/T27461/Main2.hs ===================================== @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = return () ===================================== testsuite/tests/driver/T27461/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# src/Bar.hs declares module Foo, which is fine for a file target, but Main's +# `import Bar` resolves to that same file and must be rejected. +T27461a : + cp Main1.hs src/Main.hs + ! '$(TEST_HC)' $(TEST_HC_OPTS) --make -fno-code -v0 -isrc src/Main.hs src/Bar.hs ===================================== testsuite/tests/driver/T27461/T27461a.stderr ===================================== @@ -0,0 +1,4 @@ +src/Bar.hs:1:8: error: [GHC-28623] + File name does not match module name: + Saw : ‘Foo’ + Expected: ‘Bar’ ===================================== testsuite/tests/driver/T27461/T27461b.script ===================================== @@ -0,0 +1,7 @@ +"-- Successfully load modules if file target is not imported" +:! cp Main2.hs src/Main.hs +:load src/Main.hs src/Bar.hs +main +:! cp Main1.hs src/Main.hs +"-- Crash on reload as we import a file target that has the wrong module name" +:reload ===================================== testsuite/tests/driver/T27461/T27461b.stderr ===================================== @@ -0,0 +1,5 @@ +src/Bar.hs:1:8: error: [GHC-28623] + File name does not match module name: + Saw : ‘Foo’ + Expected: ‘Bar’ + ===================================== testsuite/tests/driver/T27461/T27461b.stdout ===================================== @@ -0,0 +1,2 @@ +"-- Successfully load modules if file target is not imported" +"-- Crash on reload as we import a file target that has the wrong module name" ===================================== testsuite/tests/driver/T27461/all.T ===================================== @@ -0,0 +1,3 @@ +test('T27461a', extra_files(['src/', 'Main1.hs']), makefile_test, []) +test('T27461b', [extra_files(['src/', 'Main1.hs', 'Main2.hs']), extra_hc_opts('-isrc')], + ghci_script, ['T27461b.script']) ===================================== testsuite/tests/driver/T27461/src/Bar.hs ===================================== @@ -0,0 +1,5 @@ +module Foo where +-- Named Bar.hs but declares module Foo: allowed for a file target. + +foo :: Int +foo = 1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b6011958007aa6388f2af082a61dbd3e... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b6011958007aa6388f2af082a61dbd3e... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help