Commit 1818b48e authored by Ömer Sinan Ağacan's avatar Ömer Sinan Ağacan Committed by Austin Seipp

Fix incorrect import warnings when methods with identical names are imported

Currently, GHC's warning generation code is assuming that a name (`RdrName`)
can be imported at most once. This is a correct assumption, because 1) it's OK
to import same names as long as we don't use any of them 2) when we use one of
them, GHC generates an error because it doesn't disambiguate it automatically.

But apparently the story is different with typeclass methods. If I import two
methods with same names, it's OK to use them in typeclass instance
declarations, because the context specifies which one to use. For example, this
is OK (where modules A and B define typeclasses A and B, both with a function
has),

    import A
    import B

    data Blah = Blah

    instance A Blah where
      has = Blah

    instance B Blah where
      has = Blah

But GHC's warning generator is not taking this into account, and so if I change
import list of this program to:

    import A (A (has))
    import B (B (has))

GHC is printing these warnings:

    Main.hs:5:1: Warning:
        The import of ‘A.has’ from module ‘A’ is redundant

    Main.hs:6:1: Warning:
        The import of ‘B.has’ from module ‘B’ is redundant

Why? Because warning generation code is _silently_ ignoring multiple symbols
with same names.

With this patch, GHC takes this into account. If there's only one name, then
this patch reduces to the previous version, that is, it works exactly the same
as current GHC (thanks goes to @quchen for realizing this).

Reviewed By: austin

Differential Revision: https://phabricator.haskell.org/D1257

GHC Trac Issues: #10890
parent d2f9972a
......@@ -1461,13 +1461,11 @@ extendImportMap :: GlobalRdrEnv -> RdrName -> ImportMap -> ImportMap
-- it into scope; choose one of them (bestImport), and record
-- the RdrName in that import decl's entry in the ImportMap
extendImportMap rdr_env rdr imp_map
| [gre] <- lookupGRE_RdrName rdr rdr_env
, GRE { gre_lcl = lcl, gre_imp = imps } <- gre
, not lcl
= add_imp gre (bestImport imps) imp_map
| otherwise
= imp_map
= foldr recordRdrName imp_map nonLocalGREs
where
recordRdrName gre m = add_imp gre (bestImport (gre_imp gre)) m
nonLocalGREs = filter (not . gre_lcl) (lookupGRE_RdrName rdr rdr_env)
add_imp :: GlobalRdrElt -> ImportSpec -> ImportMap -> ImportMap
add_imp gre (ImpSpec { is_decl = imp_decl_spec }) imp_map
= Map.insertWith add decl_loc [avail] imp_map
......
module A where
class A a where
has :: a
module B where
class B a where
has :: a
module Base (AClass(..), BClass()) where
import Extends (BClass ())
class AClass a where
has :: a
module Extends where
class BClass b where
has :: b
TOP=../../../..
include $(TOP)/mk/boilerplate.mk
include $(TOP)/mk/test.mk
module Main where
-- Previously GHC was printing this warning:
--
-- Main.hs:5:1: Warning:
-- The import of ‘A.has’ from module ‘A’ is redundant
--
-- Main.hs:6:1: Warning:
-- The import of ‘B.has’ from module ‘B’ is redundant
import A (A (has))
import B (B (has))
data Blah = Blah
instance A Blah where
has = Blah
instance B Blah where
has = Blah
main :: IO ()
main = return ()
module Main where
import Base
import Extends
-- Previously GHC was giving this false positive:
--
-- T10890_1.hs:4:1: Warning:
-- The import of ‘Extends’ is redundant
-- except perhaps to import instances from ‘Extends’
-- To import instances alone, use: import Extends()
data Bar = Bar
instance AClass Bar where
has = Bar
instance BClass Bar where
has = Bar
main :: IO ()
main = return ()
test('T10890',
extra_clean(['A.o', 'A.hi', 'B.o', 'B.hi']),
multimod_compile, ['T10890', '-v0 -fwarn-unused-imports'])
test('T10890_1',
extra_clean(['Base.o', 'Base.hi', 'Extends.o', 'Extends.hi']),
multimod_compile, ['T10890_1', '-v0 -fwarn-unused-imports'])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment