[GHC] #14307: NamedFieldPuns should allow "ambiguous" field names (was: Nonexistent constructor name + NamedFieldPuns + DuplicateRecordFields can cause ambiguous occurrence message)

GHC ghc-devs at haskell.org
Tue Oct 3 09:50:33 UTC 2017


#14307: NamedFieldPuns should allow "ambiguous" field names
-------------------------------------+-------------------------------------
        Reporter:  mgsloan           |                Owner:  (none)
            Type:  feature request   |               Status:  new
        Priority:  low               |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Description changed by mgsloan:

Old description:

> This is a minor issue with error message clarity. I was confused for a
> few minutes because in a more complicated example I did not see the out
> of scope error, and was instead focused on the ambiguity error.
>
> {{{
> {-# LANGUAGE DuplicateRecordFields #-}
> {-# LANGUAGE NamedFieldPuns #-}
>
> data A = A { field :: Int }
> data B = B { field :: Int }
>
> f :: A -> Int
> f C { field } = field
> }}}
>
> yields
>
> {{{
> duplicate_records_bug.hs:8:3: error:
>     Not in scope: data constructor ‘C’
>   |
> 8 | f C { field } = field
>   |   ^
>
> duplicate_records_bug.hs:8:7: error:
>     Ambiguous occurrence ‘field’
>     It could refer to either the field ‘field’,
>                              defined at duplicate_records_bug.hs:5:14
>                           or the field ‘field’, defined at
> duplicate_records_bug.hs:4:14
>   |
> 8 | f C { field } = field
>   |       ^^^^^
> }}}
>
> I actually think it would make sense to allow ambiguous identifiers in
> field puns even if DuplicateRecordFields is not enabled.  This makes
> sense, because for an unambiguous constructor, a particular field name is
> always unambiguous.  So, that might be another way to frame this issue:
> Should ambiguous field identifiers always be allowed in puns?
>
> In particular, this would make things more consistent with
> RecordWildCards, which does not care if the field names shadow anything
> that is in scope / other field names.
>
> I realize that broadening the code allowed by NamedFieldPuns could lead
> to issues where code written for newer GHC versions does not work with
> older GHC versions.  This certainly will not change the meaning of older
> code.  What's the policy on this?

New description:

 Consider the following example:

 {{{#!haskell
 {-# LANGUAGE NamedFieldPuns #-}

 import DupType

 data A = A { field :: Int }

 f :: A -> Int
 f A { field } = field
 }}}

 with

 {{{#!haskell
 module DupType where

 data B = B { field :: Int }
 }}}

 This results in the following error:

 {{{
 A.hs:8:7: error:
     Ambiguous occurrence ‘field’
     It could refer to either ‘DupType.field’,
                              imported from ‘DupType’ at A.hs:3:1-14
                              (and originally defined at
 DupType.hs:3:14-18)
                           or ‘Main.field’, defined at A.hs:5:14
   |
 8 | f A { field } = field
   |       ^^^^^
 }}}

 This seems like poor behavior, because since a particular constructor is
 used, it is unambiguous which field is intended.  In particular, this is
 inconsistent with `RecordWildCards`.  Consider that `f A { .. } = field`
 compiles perfectly fine.

 I actually encountered this issue in a bit of a different usecase.  I was
 using `NamedFieldPuns` along with `DuplicateFieldNames`.  However, I got
 the constructor name wrong.  After the scope error in the output, there
 was an ambiguous field name error.  This was quite confusing because
 `DuplicateFieldNames` was on, so ambiguity should be fine!  Took me a
 while to realize that the scope error was the root issue.  With the
 constructor name fixed, the code compiled. If the constructor was used to
 resolve field names, then the 2nd error wouldn't have been emitted.

 I realize that broadening the code allowed by `NamedFieldPuns` could lead
 to issues where code written for newer GHC versions does not work with
 older GHC versions.  This certainly will not change the meaning of older
 code.  What's the policy on this?

--

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


More information about the ghc-tickets mailing list