diff options
author | Roland Senn <rsx@bluewin.ch> | 2019-03-02 16:53:06 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-03-08 14:11:19 -0500 |
commit | 2762f94dc27cc065dded7755f99c66cba26683dd (patch) | |
tree | b35a96cfe8e6619e186a6eb023feefcec07ab988 | |
parent | 224a6b864c6aa0d851fcbf79469e5702b1116dbc (diff) | |
download | haskell-2762f94dc27cc065dded7755f99c66cba26683dd.tar.gz |
Fix #13839: GHCi warnings do not respect the default module headerwip/magic-carpet-ride
-rw-r--r-- | compiler/typecheck/TcRnExports.hs | 38 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T13839.script | 4 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T13839.stdout | 5 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T13839a.hs | 10 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T13839a.stderr | 3 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/T13839b.hs | 10 | ||||
-rw-r--r-- | testsuite/tests/rename/should_compile/all.T | 2 | ||||
-rw-r--r-- | testsuite/tests/rename/should_fail/T13839b.hs | 10 | ||||
-rw-r--r-- | testsuite/tests/rename/should_fail/T13839b.stderr | 3 | ||||
-rw-r--r-- | testsuite/tests/rename/should_fail/all.T | 1 |
10 files changed, 82 insertions, 4 deletions
diff --git a/compiler/typecheck/TcRnExports.hs b/compiler/typecheck/TcRnExports.hs index b3baf6c406..ea52b12741 100644 --- a/compiler/typecheck/TcRnExports.hs +++ b/compiler/typecheck/TcRnExports.hs @@ -170,22 +170,24 @@ tcRnExports explicit_mod exports -- list, to avoid bleating about re-exporting a deprecated -- thing (especially via 'module Foo' export item) do { - -- In interactive mode, we behave as if he had - -- written "module Main where ..." ; dflags <- getDynFlags ; let is_main_mod = mainModIs dflags == this_mod ; let default_main = case mainFunIs dflags of 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) + -- See Note [Modules without a module header] ; let real_exports | explicit_mod = exports - | ghcLink dflags == LinkInMemory = Nothing - | otherwise + | has_main = Just (noLoc [noLoc (IEVar noExt (noLoc (IEName $ noLoc default_main)))]) -- ToDo: the 'noLoc' here is unhelpful if 'main' -- turns out to be out of scope + | otherwise = Nothing ; let do_it = exports_from_avail real_exports rdr_env imports this_mod ; (rn_exports, final_avails) @@ -436,6 +438,34 @@ isDoc _ = False -- Renaming and typechecking of exports happens after everything else has -- been typechecked. +{- +Note [Modules without a module header] +-------------------------------------------------- + +The Haskell 2010 report says in section 5.1: + +>> An abbreviated form of module, consisting only of the module body, is +>> permitted. If this is used, the header is assumed to be +>> ‘module Main(main) where’. + +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. + 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 NO main function: + Then export all top-level functions. This marks all top level + functions as 'used'. + In GHCi this has the effect, that we don't get any 'non-used' warnings. + In GHC, however, the 'has-main-module' check in the module + compiler/typecheck/TcRnDriver (functions checkMain / check-main) fires, + and we get the error: + The IO action ‘main’ is not defined in module ‘Main’ +-} -- Renaming exports lists is a minefield. Five different things can appear in diff --git a/testsuite/tests/rename/should_compile/T13839.script b/testsuite/tests/rename/should_compile/T13839.script new file mode 100644 index 0000000000..212d7f7d42 --- /dev/null +++ b/testsuite/tests/rename/should_compile/T13839.script @@ -0,0 +1,4 @@ +:l T13839a.hs +:t nonUsed +:l T13839b.hs +:t nonUsed diff --git a/testsuite/tests/rename/should_compile/T13839.stdout b/testsuite/tests/rename/should_compile/T13839.stdout new file mode 100644 index 0000000000..a700b1441c --- /dev/null +++ b/testsuite/tests/rename/should_compile/T13839.stdout @@ -0,0 +1,5 @@ + +T13839a.hs:10:1: warning: [-Wunused-top-binds (in -Wextra, -Wunused-binds)] + Defined but not used: ‘nonUsed’ +nonUsed :: () +nonUsed :: () diff --git a/testsuite/tests/rename/should_compile/T13839a.hs b/testsuite/tests/rename/should_compile/T13839a.hs new file mode 100644 index 0000000000..74235be147 --- /dev/null +++ b/testsuite/tests/rename/should_compile/T13839a.hs @@ -0,0 +1,10 @@ +{-# OPTIONS_GHC -Wall #-} + +main :: IO () +main = putStrLn used + +used :: String +used = "T13839" + +nonUsed :: () +nonUsed = () diff --git a/testsuite/tests/rename/should_compile/T13839a.stderr b/testsuite/tests/rename/should_compile/T13839a.stderr new file mode 100644 index 0000000000..84b987364a --- /dev/null +++ b/testsuite/tests/rename/should_compile/T13839a.stderr @@ -0,0 +1,3 @@ + +T13839a.hs:10:1: warning: [-Wunused-top-binds (in -Wextra, -Wunused-binds)] + Defined but not used: ‘nonUsed’ diff --git a/testsuite/tests/rename/should_compile/T13839b.hs b/testsuite/tests/rename/should_compile/T13839b.hs new file mode 100644 index 0000000000..da7b0f4073 --- /dev/null +++ b/testsuite/tests/rename/should_compile/T13839b.hs @@ -0,0 +1,10 @@ +{-# OPTIONS_GHC -Wall #-} + +nomain :: IO () +nomain = putStrLn used + +used :: String +used = "T13839" + +nonUsed :: () +nonUsed = () diff --git a/testsuite/tests/rename/should_compile/all.T b/testsuite/tests/rename/should_compile/all.T index 4d427de44f..51684f1eb3 100644 --- a/testsuite/tests/rename/should_compile/all.T +++ b/testsuite/tests/rename/should_compile/all.T @@ -155,6 +155,8 @@ test('T12597', normal, compile, ['']) test('T12548', normal, compile, ['']) test('T13132', normal, compile, ['']) test('T13646', normal, compile, ['']) +test('T13839', combined_output, ghci_script, ['T13839.script']) +test('T13839a', normal, compile, ['']) test('LookupSub', [], multimod_compile, ['LookupSub', '-v0']) test('T14881', [], multimod_compile, ['T14881', '-W']) test('T14487', [], multimod_compile, ['T14487', '-v0']) diff --git a/testsuite/tests/rename/should_fail/T13839b.hs b/testsuite/tests/rename/should_fail/T13839b.hs new file mode 100644 index 0000000000..da7b0f4073 --- /dev/null +++ b/testsuite/tests/rename/should_fail/T13839b.hs @@ -0,0 +1,10 @@ +{-# OPTIONS_GHC -Wall #-} + +nomain :: IO () +nomain = putStrLn used + +used :: String +used = "T13839" + +nonUsed :: () +nonUsed = () diff --git a/testsuite/tests/rename/should_fail/T13839b.stderr b/testsuite/tests/rename/should_fail/T13839b.stderr new file mode 100644 index 0000000000..93846bd410 --- /dev/null +++ b/testsuite/tests/rename/should_fail/T13839b.stderr @@ -0,0 +1,3 @@ + +T13839b.hs:1:1: error: + The IO action ‘main’ is not defined in module ‘Main’ diff --git a/testsuite/tests/rename/should_fail/all.T b/testsuite/tests/rename/should_fail/all.T index 4f1b1fa34b..4b5e9e9a72 100644 --- a/testsuite/tests/rename/should_fail/all.T +++ b/testsuite/tests/rename/should_fail/all.T @@ -126,6 +126,7 @@ test('T11592', normal, compile_fail, ['']) test('T12879', normal, compile_fail, ['']) test('T13644', normal, multimod_compile_fail, ['T13644','-v0']) test('T13568', normal, multimod_compile_fail, ['T13568','-v0']) +test('T13839b', normal, compile_fail, ['']) test('T13947', normal, compile_fail, ['']) test('T13847', normal, multimod_compile_fail, ['T13847','-v0']) test('T14225', normal, ghci_script, ['T14225.script']) |