Opened 6 months ago

Last modified 5 months ago

#14848 new bug

-XDuplicateRecordFields breaks record expression splices

Reported by: dailectic Owned by:
Priority: normal Milestone:
Component: Compiler Version: 8.2.2
Keywords: ORF Cc: adamgundry
Operating System: Linux Architecture: x86_64 (amd64)
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


{-# language TemplateHaskell #-}
{-# language DuplicateRecordFields #-}
module Lib where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax

data A = A {x :: Int, y :: String}
a = A 3 "test"
test = $([e|case a of A {x = b} -> b|])

Without DuplicateRecordFields it compiles correctly so test = 3 but with DuplicateRecordFields enabled it gives:

     • Illegal variable name: ‘$sel:x:A’
      When splicing a TH expression:
        case Lib.a of
    (Lib.A {Lib.$sel:x:A = b_0}) -> b_0
    • In the untyped splice: $([| case a of { A {x = b} -> b } |])

Additionally, there doesn't seem to be a workaround for munging the name manually, since the $sel:x:A name is the one actually in scope, there is no A.x like there would be normally, even when the label is not a duplicate.

Is there a way to get around this? Ex: by changing the binding name somehow manually?

Change History (3)

comment:1 Changed 6 months ago by RyanGlScott

Keywords: ORF added

comment:2 Changed 6 months ago by adamgundry

Cc: adamgundry added

comment:3 Changed 5 months ago by adamgundry

I think a possible fix here is to apply the approach described in Note [Reifying field labels] from TcSplice in the HsRecFld case of DsMeta.repE. That is, rather than representing the field as a NameG containing the mangled selector name (which isn't a legal variable name, let alone in scope), we could represent it as a NameQ containing the field label.

Note: See TracTickets for help on using tickets.