[GHC] #10347: Spurious "unused constructor" warning with Coercible

GHC ghc-devs at haskell.org
Mon Nov 19 09:02:04 UTC 2018


#10347: Spurious "unused constructor" warning with Coercible
-------------------------------------+-------------------------------------
        Reporter:  goldfire          |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  7.11
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  Incorrect         |            Test Case:
  warning at compile-time            |  typecheck/should_compile/T10347
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 I wonder if you get an unused-import warning if you say
 {{{
 import Foo( N( N ) ) where
   test :: Test
   test = Test $ coerce (0::Int)
 }}}
 That is, does the problem apply to imported newtype constructors too?

 I took at quick look at what to do.  The obvious thing to do is
 * Make `tcg_dus` into a `TcRef` (like `tcg_keep` and `tcg_used_gres`)
 * Make the constraint solve add a use to `tcg_dus` when solving
 `Coercible` constraints. (We'd need to change the representation of
 `tcg_dus` from a list to an `OrdList` or something, else we'd bet
 inefficient appends.)
 * Move `reportUnusedNames` after the type checker.

 Standing back a bit, we carefully gather `tcg_dus :: [DefUse]`, were `type
 DefUse  = (Maybe Defs, Uses)`.  So from
 {{{
   type S = Int
   type T = S -> R
 }}}
 we the `DefUse` pairs `(Just S, {})`, and `(Just T, {S,R})`.

 The idea is that if `T` is unused we can report `S` as unused too.

 A simpler alternative is simply to gather all the binders `{S,T}` and all
 the occurrences `{S,R}` and report things that are defined but not
 referred to. That would report `T` but not `S`.  If you deleted `T` you'd
 get a new warning about `S`.

 But it's debatable whether reporting `S` unused is a feature or a bug.  It
 certainly confusing -- you can see a reference to `S` -- and if the lack
 of a reference to `T` was a mistake, then the unused-S warning is simply
 distracting.

 So my thought is this:
 * Suppose instead of gathering `[DefUse]` we simply gather a `NameSet` of
 things that are referred to; and report as unused anything that it not
 referred to.

 That would be significantly simpler. The defs are the declarations
 themselves, of course.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10347#comment:13>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list