diff options
-rw-r--r-- | compiler/GHC/Rename/Env.hs | 3 | ||||
-rw-r--r-- | compiler/typecheck/TcRnExports.hs | 15 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T17832.stderr | 2 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T17832M1.hs | 3 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T17832M2.hs | 4 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/all.T | 1 |
6 files changed, 23 insertions, 5 deletions
diff --git a/compiler/GHC/Rename/Env.hs b/compiler/GHC/Rename/Env.hs index 964b49412a..d300761a68 100644 --- a/compiler/GHC/Rename/Env.hs +++ b/compiler/GHC/Rename/Env.hs @@ -1062,6 +1062,9 @@ lookupInfoOccRn :: RdrName -> RnM [Name] -- It finds all the GREs that RdrName could mean, not complaining -- about ambiguity, but rather returning them all -- C.f. #9881 +-- lookupInfoOccRn is also used in situations where we check for +-- at least one definition of the RdrName, not complaining about +-- multiple definitions. (See #17832) lookupInfoOccRn rdr_name = lookupExactOrOrig rdr_name (:[]) $ do { rdr_env <- getGlobalRdrEnv diff --git a/compiler/typecheck/TcRnExports.hs b/compiler/typecheck/TcRnExports.hs index 950b8572e8..5a4e21d5c1 100644 --- a/compiler/typecheck/TcRnExports.hs +++ b/compiler/typecheck/TcRnExports.hs @@ -176,9 +176,10 @@ tcRnExports explicit_mod exports Just main_fun | is_main_mod -> mkUnqual varName (fsLit main_fun) _ -> main_RDR_Unqual - ; has_main <- lookupGlobalOccRn_maybe default_main >>= return . isJust - -- If the module has no explicit header, and it has a main function, - -- then we add a header like "module Main(main) where ..." (#13839) + ; has_main <- (not . null) <$> lookupInfoOccRn default_main -- #17832 + -- If a module has no explicit header, and it has one or more main + -- functions in scope, then add a header like + -- "module Main(main) where ..." #13839 -- See Note [Modules without a module header] ; let real_exports | explicit_mod = exports @@ -451,12 +452,16 @@ The Haskell 2010 report says in section 5.1: For modules without a module header, this is implemented the following way: -If the module has a main function: - Then create a module header and export the main function. +If the module has a main function in scope: + Then create a module header and export the main function, + as if a module header like ‘module Main(main) where...’ would exist. This has the effect to mark the main function and all top level functions called directly or indirectly via main as 'used', and later on, unused top-level functions can be reported correctly. There is no distinction between GHC and GHCi. +If the module has several main functions in scope: + Then generate a header as above. The ambiguity is reported later in + module `TcRnDriver.hs` function `check_main`. If the module has NO main function: Then export all top-level functions. This marks all top level functions as 'used'. diff --git a/testsuite/tests/rename/should_compile/T17832.stderr b/testsuite/tests/rename/should_compile/T17832.stderr new file mode 100644 index 0000000000..ecb2d5f33d --- /dev/null +++ b/testsuite/tests/rename/should_compile/T17832.stderr @@ -0,0 +1,2 @@ +[1 of 2] Compiling T17832M1 ( T17832M1.hs, T17832M1.o ) +[2 of 2] Compiling T17832M2 ( T17832M2.hs, T17832M2.o ) diff --git a/testsuite/tests/rename/should_compile/T17832M1.hs b/testsuite/tests/rename/should_compile/T17832M1.hs new file mode 100644 index 0000000000..6c864893c1 --- /dev/null +++ b/testsuite/tests/rename/should_compile/T17832M1.hs @@ -0,0 +1,3 @@ +module T17832M1 (main) where +main :: IO () +main = return () diff --git a/testsuite/tests/rename/should_compile/T17832M2.hs b/testsuite/tests/rename/should_compile/T17832M2.hs new file mode 100644 index 0000000000..9fe7efef53 --- /dev/null +++ b/testsuite/tests/rename/should_compile/T17832M2.hs @@ -0,0 +1,4 @@ +module T17832M2 (T17832M2.main) where +import T17832M1 +main :: IO () +main = putStrLn "M2" diff --git a/testsuite/tests/rename/should_compile/all.T b/testsuite/tests/rename/should_compile/all.T index 4c295b20a3..6bcb9377bd 100644 --- a/testsuite/tests/rename/should_compile/all.T +++ b/testsuite/tests/rename/should_compile/all.T @@ -172,4 +172,5 @@ test('T15957', normal, compile, ['-Werror -Wredundant-record-wildcards -Wunused- test('T17244A', normal, compile, ['-Wno-error=compat-unqualified-imports']) test('T17244B', normal, compile, ['']) test('T17244C', normal, compile, ['']) +test('T17832', [], multimod_compile, ['T17832M1', 'T17832M2']) test('T17837', normal, compile, ['']) |