Opened 2 years ago

Last modified 15 months ago

#14318 new bug

TH shadowing bind statement triggers -Wunused-matches

Reported by: lyxia Owned by:
Priority: normal Milestone:
Component: Template Haskell Version: 8.2.1
Keywords: Cc: lyxia
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Incorrect error/warning at compile-time Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by lyxia)

{-# LANGUAGE TemplateHaskell #-}
module Test where

import Language.Haskell.TH

m :: (a -> [b]) -> a -> [b]
m =
  $(newName "x" >>= \x ->
    newName "f" >>= \f ->
    lamE [varP f, varP x]
      (doE [ bindS (varP x) (listE [varE f `appE` varE x])
           , noBindS (varE x)])
   )

The splice generates the following expression:

\f x -> do
  x <- [f x]
  x

and -Wunused-matches complains that x is not used, while both bound occurrences are in fact used (the two uses have different types so that's quite certain).

Change History (5)

comment:1 Changed 19 months ago by lyxia

Cc: lyxia added

comment:2 Changed 19 months ago by lyxia

Description: modified (diff)

comment:3 Changed 15 months ago by mgsloan

Owner: set to mgsloan

comment:4 Changed 15 months ago by mgsloan

Owner: mgsloan deleted

I've looked into this a bit. It looks like names created by newName are turned into GHC names via mkSystemNameAt, and integer making the name unique is used directly. See Convert.thRdrName.

I'm guessing that code involving warnings is expecting that these unique names are unique per binding site, whereas in this case the same unique name is bound multiple times.

I'm not sure what the correct approach is to fixing this. It could either be to fix the warning code, or, alternatively, have TH ensure that generated code has per-binding uniqueness.

comment:5 Changed 15 months ago by mgsloan

Ah, here is a ticket about TH allowing you to produce non-unique uniques: https://ghc.haskell.org/trac/ghc/ticket/11812

So, I suspect that the proper solution here would involve making it so that TH cannot produce non-unique binding of unique names.

There is some tricky stuff here, though. I can imagine a scenario where a TH user might rely on storing unique names in memory and re-using them between splices. This makes the task of further unique-ification quite non-trivial.

Note: See TracTickets for help on using tickets.