GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2024-03-28T21:45:40Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24483Can't re-export duplicate field names from identical constructor names2024-03-28T21:45:40ZTom EllisCan't re-export duplicate field names from identical constructor namesThis is a new ticket to track [an issue explained by @adamgundry](https://gitlab.haskell.org/ghc/ghc/-/issues/13352#note_294968) in a prior (closed) ticket. That is, the following code leads to the following error. The error is still pr...This is a new ticket to track [an issue explained by @adamgundry](https://gitlab.haskell.org/ghc/ghc/-/issues/13352#note_294968) in a prior (closed) ticket. That is, the following code leads to the following error. The error is still present as of GHC 9.8. It seems like an artificial limitation and it would be great if it could be lifted. This is particularly annoying if we want to create a custom `Prelude`. It makes it impossible to create a custom `Prelude` containing two different fields with the same name, if their constructors also share the same name.
```
{-# LANGUAGE DuplicateRecordFields #-}
module A where
data S = C { foo :: Int }
{-# LANGUAGE DuplicateRecordFields #-}
module B where
data T = C { foo :: Int }
{-# LANGUAGE DuplicateRecordFields #-}
module C (S(foo), T(foo)) where
import A (S(..))
import B (T(..))
```
```
Conflicting exports for ‘foo’:
‘S(foo)’ exports ‘foo’
imported from ‘A’ at C.hs:5:28-32
(and originally defined at A.hs:3:16-18)
‘T(foo)’ exports ‘foo’
imported from ‘B’ at C.hs:6:28-32
(and originally defined at B.hs:5:14-16)
```
----
It's also an interesting puzzle to try to imagine the implementation details that allow both `foo`s to be used within the same module but not re-exported from the same module! I haven't been able to work it out ...
EDIT: Ah, I think I have an explanation: in a given module, duplicate field names are disambiguated by the module they were imported from plus the constructor name.https://gitlab.haskell.org/ghc/ghc/-/issues/24481Support NoFieldSelectors as a datatype and field annotation2024-02-26T09:45:21ZAdam GundrySupport NoFieldSelectors as a datatype and field annotationThe GHC Steering Committee has accepted [proposal 512: NoFieldSelectors as a datatype and field annotation](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0512-nofieldselectors-per-datatype.md). This makes it possib...The GHC Steering Committee has accepted [proposal 512: NoFieldSelectors as a datatype and field annotation](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0512-nofieldselectors-per-datatype.md). This makes it possible to annotate individual datatypes or fields as to whether they should use `FieldSelectors` or `NoFieldSelectors`.https://gitlab.haskell.org/ghc/ghc/-/issues/24330hpc complains that record field referencing an existential is never executed2024-01-23T14:31:17ZShea Levyshea@shealevy.comhpc complains that record field referencing an existential is never executed## Summary
```haskell
{-# LANGUAGE ExistentialQuantification #-}
module Main where
data Any = forall a. Any { any :: a }
main :: IO ()
main = do
let x = Any 'c'
case x of
Any _ -> pure ()
```
![image](/uploads/f561b311655ef76...## Summary
```haskell
{-# LANGUAGE ExistentialQuantification #-}
module Main where
data Any = forall a. Any { any :: a }
main :: IO ()
main = do
let x = Any 'c'
case x of
Any _ -> pure ()
```
![image](/uploads/f561b311655ef76e403e6a69bfcce000/image.png)
## Steps to reproduce
`ghc -fhpc Test.hs && ./Test && hpc report Test`
## Expected behavior
`any` is not marked up as `never executed`, as there is no way to call it
## Environment
* GHC version used: 9.2.4, 9.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/24174OverloadedRecordDot: "type" can't be used as a field name2023-11-15T04:02:22ZHaisheng, WuOverloadedRecordDot: "type" can't be used as a field name## Summary
* I cannot use "type" as a field name.
* Looks like same problem as #21226 #20723 but looks like it didn't fix the problem for all others reserved keywords in `reservedid`
## Steps to reproduce
Given following code:
```has...## Summary
* I cannot use "type" as a field name.
* Looks like same problem as #21226 #20723 but looks like it didn't fix the problem for all others reserved keywords in `reservedid`
## Steps to reproduce
Given following code:
```haskell
{-# LANGUAGE OverloadedRecordDot, DataKinds #-}
module Main where
import GHC.Records ( HasField(..) )
data Product = Product
{ prodName :: String
, prodType :: String
}
sampleProduct :: Product
sampleProduct = Product "Foo" "Sport"
instance HasField "type" Product String where
getField :: Product -> String
getField = prodType
main :: IO ()
main = putStrLn sampleProduct.type
```
I got compilation error:
```plaintext
[1 of 2] Compiling Main ( main.hs, main.o ) [Source file changed]
main.hs:19:31: error: [GHC-58481] parse error on input ‘type’
|
19 | main = putStrLn sampleProduct.type
```
## Expected behavior
Compile and run successfully.
## Environment
* GHC version used: 9.6.3
Optional:
* Operating System: MacOS-14.4
* System Architecture:https://gitlab.haskell.org/ghc/ghc/-/issues/24035incorrect `-Wunused-imports` when module exports multiple records with the sa...2023-10-03T14:13:43ZMagnus Viernickelincorrect `-Wunused-imports` when module exports multiple records with the same accessor names## Summary
GHC emits unused imports warnings when the module that is imported from has `DuplicatRecordFields` activated and exports Records with same acessor fields
## Steps to reproduce
```hs
{-# LANGUAGE DuplicateRecordFields #-}
...## Summary
GHC emits unused imports warnings when the module that is imported from has `DuplicatRecordFields` activated and exports Records with same acessor fields
## Steps to reproduce
```hs
{-# LANGUAGE DuplicateRecordFields #-}
module A where
data R = MkR {ra :: Int, rb :: Bool}
data R' = MkR' {ra :: Int, rb :: Bool}
```
```hs
{-# LANGUAGE OverloadedRecordDot #-}
{-# OPTIONS_GHC -Wall #-}
module B where
import A (R (ra), rb) -- this line emits the warnings for `rb`
x :: R -> Bool
x a = a.rb
y :: R -> Int
y a = a.ra
```
## Expected behavior
No unused import warning
## Environment
* GHC version used: ghc 9.6.2
Optional:
* Operating System: NixOS 23.11
* System Architecture: x86_64-linuxsheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/23992`$` converts ambiguous record update error to a warning2023-09-26T14:44:03ZEmeka Nkurumeh`$` converts ambiguous record update error to a warning## Summary
Inserting `$` between a function call and a record update can change ambiguous record update errors, into warnings. This behavior is specific to `$` since using `Data.Function.&` or aliasing `$` still produce error. As far as...## Summary
Inserting `$` between a function call and a record update can change ambiguous record update errors, into warnings. This behavior is specific to `$` since using `Data.Function.&` or aliasing `$` still produce error. As far as I can tell this seems to be a regression since before GHC 9.2.5, only type applications were able to change this error to a warning.
## Steps to reproduce
```haskell
{-# LANGUAGE DuplicateRecordFields #-}
data Foo1 = Foo1
{ foo :: Int
, bar :: Int
}
data Foo2 = Foo2
{ foo :: Int
, baz :: Int
}
setFoo :: Int -> Foo1 -> Foo1
setFoo x f = id f {foo = x}
```
GHC gives the following error:
```
Example.hs:14:17: error: [GHC-99339]
• Record update is ambiguous, and requires a type signature
• In the first argument of ‘id’, namely ‘f {foo = x}’
In the expression: id f {foo = x}
In an equation for ‘setFoo’: setFoo x f = id f {foo = x}
|
14 | setFoo x f = id f {foo = x}
|
```
If we insert a `$` into `setFoo` as so: `setFoo x f = id $ f {foo = x}`, we get a warning instead:
```
Example.hs:14:22: warning: [GHC-02256] [-Wambiguous-fields]
The record update f {foo = x} with type Foo1 is ambiguous.
This will not be supported by -XDuplicateRecordFields in future releases of GHC.
|
14 | setFoo x f = id $ f {foo = x}
|
```
## Expected behavior
Return the same error as if there were no `$`.
## Environment
* GHC version used: 9.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/23963Cannot disambiguate duplicate pattern synonym record fields in exports2023-10-06T13:18:39ZAdam GundryCannot disambiguate duplicate pattern synonym record fields in exportsConsider the following module:
```hs
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PatternSynonyms #-}
module RecPatSyn (B(B, x)) where
data A = MkA {x_ :: Int}
data B = MkB {x_ :: Int}
pattern A :: Int...Consider the following module:
```hs
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PatternSynonyms #-}
module RecPatSyn (B(B, x)) where
data A = MkA {x_ :: Int}
data B = MkB {x_ :: Int}
pattern A :: Int -> A
pattern A{x} <- MkA x
pattern B :: Int -> B
pattern B{x} <- MkB x
```
There is no way to express the fact that in the export list we mean the `x` originating from pattern synonym `B`. Hence this is rejected with an ambiguous occurrence error:
```
RecPatSyn.hs:5:19: error: [GHC-66025]
• Pattern synonyms can only be bundled with matching type constructors
Couldn't match expected type of ‘B’ with actual type of ‘A’
• In the pattern synonym record selector: x
In the export: B(B, x)
|
5 | module RecPatSyn (B(B, x)) where
| ^^^^^^^
RecPatSyn.hs:5:19: error: [GHC-87543]
• Ambiguous occurrence ‘x’.
It could refer to
either the field ‘x’ of pattern synonym ‘A’,
defined at RecPatSyn.hs:12:11,
or the field ‘x’ of pattern synonym ‘B’,
defined at RecPatSyn.hs:15:11.
• In the export: B(B, x)
|
5 | module RecPatSyn (B(B, x)) where
| ^^^^^^^
```
The "Pattern synonyms can only be bundled with matching type constructors" bit of the error seems to be bogus. Presumably the ambiguous identifier is "resolved" to the first option to allow type-checking to continue. But it leads to the awkward situation where the renamer considers it ambiguous which `x` is meant, yet the type-checker apparently "knows" that `x` cannot come from `A`.
It's not obvious to me how we could do better here, but it's an awkward corner of the `PatternSynonyms`/`DuplicateRecordFields` interaction that I wanted to record.
This was originally reported at https://discourse.haskell.org/t/how-to-export-record-pattern-synonym-duplicate-field-names-in-the-same-module/7594.https://gitlab.haskell.org/ghc/ghc/-/issues/23535Chunkify large records similar to large tuples2023-06-20T15:07:55ZAlex McKennaChunkify large records similar to large tuples## Motivation
During a conversation at ZuriHac, the problem of inefficiency when using large records came up (for a good write up of this problem, see [this blog post from Well Typed](https://well-typed.com/blog/2021/08/large-records/))...## Motivation
During a conversation at ZuriHac, the problem of inefficiency when using large records came up (for a good write up of this problem, see [this blog post from Well Typed](https://well-typed.com/blog/2021/08/large-records/)). Towards the end of the blog post some concerns / ideas are raised:
- The solution in the blog post involves using a library, it is not a solution baked into GHC
- It may be possible to alleviate the problem with more sharing (see https://gitlab.haskell.org/ghc/ghc/-/issues/20264)
- Record pattern matches are still linear in the size of the record
## Proposal
Thinking out loud I asked Simon whether we could do something similar to the treatment of large tuples, and have GHC keep a representation internally that was more nested.[^1] Simon enthusiastically raised some points, which I will attempt to faithfully relay here:
- We have machinery in the compiler for specifying a more efficient internal representation for data, `mkDataConRep` etc.
- We already go the other way in GHC and expand records (e.g. using `{-# UNPACK #-}` on a strict tuple field)
- Using a chunked representation means selector functions become a case tree
- Record updates can share chunks of a record which are not changed
To give some examples (in deliberately invalid Haskell): a large record
```
{ x0 :: A0, ..., xn :: An }
```
would be internally represented as something similar to
```
{ { x0 :: A0, ..., xK-1 :: AK-1 }, { xK :: AK, ... }, { ..., xn :: An } }
```
where each chunk has K number of fields. The selector functions change accordingly
```
sel_xn_old r =
case r of
C0 _ ... xn -> xn -- Pattern linear to number of fields
sel_xn_new r =
case r of
C1 _ c1 -> -- Each item here is just a chunk
case c1 of
C2 _ ... xn -> xn -- Match on chunks until we find the element we want
```
Thinking about this the past week or so I have some more questions about this:
- How would `{-# UNPACK #-}` play nicely with a chunked record representation? We do not have to think about this for tuples because it is not valid to write something like `(Int, {-# UNPACK #-} !Int)` in Haskell. Intuitively, I would guess that such strict unpacked fields would be floated to the top of the record alongside the chunks.
- Would we generate new types for the chunks, or use tuples internally to represent the chunks. I feel like tuples would be simpler, but perhaps there is some reason to not favour this?
[^1]: Due to a limit set by the format of info tables, GHC only allows tuples of up to 64 elements internally. However, when writing code in the surface syntax of Haskell, we can use tuples larger than 64. Internally, GHC splits the tuple into a tuple of smaller tuples which can contain all the elements. This is transparent to the user writing the code.
---
@simonpj As promised, I have written this up as an issue. Hopefully this is clear enough starting point for people to discuss.https://gitlab.haskell.org/ghc/ghc/-/issues/23040`OverloadedRecordDot` and `COLUMN`-pragmas don't play nice together2023-02-28T15:27:27ZSimon Hengelsol@typeful.net`OverloadedRecordDot` and `COLUMN`-pragmas don't play nice together## Summary
`foo.foo` is accepted while `foo{-# COLUMN 23 #-}.foo` results in a parse error.
This is surprising from a users perspective and can break `OverloadedRecordDot` with source-to-source transformations / pre-processors (as it d...## Summary
`foo.foo` is accepted while `foo{-# COLUMN 23 #-}.foo` results in a parse error.
This is surprising from a users perspective and can break `OverloadedRecordDot` with source-to-source transformations / pre-processors (as it does for me).
## Steps to reproduce
```
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
data Foo = Foo { foo :: String }
foo :: Foo
foo = Foo "foo"
main :: IO ()
main = do
putStrLn foo.foo -- works
putStrLn foo{-# COLUMN 23 #-}.foo -- parse error
```
## Expected behavior
Both `foo.foo` and `foo{-# COLUMN 23 #-}.foo` should be accepted.
## Investigation
`foo.foo` is tokenized to:
[ITvarid "foo", ITproj False, ITvarid "bar"]
However, `foo{-# COLUMN 23 #-}.foo` is tokenized to:
[ITvarid "foo", ITproj True, ITvarid "bar"]
So from what I understand, even though this manifests as a parse error, the bug is actually in the lexer.
## Environment
* GHC version used: 9.6.0.20230111
Optional:
* Operating System: Linux
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc/-/issues/23032Disambiguating record updates in the renamer using as-patterns2023-06-05T12:06:39Zsheafsam.derbyshire@gmail.comDisambiguating record updates in the renamer using as-patternsI think the following could reasonably be expected to work:
```haskell
{-# LANGUAGE DuplicateRecordFields #-}
module M where
data A a = MkA { fld :: a }
data B b = MkB { fld :: b }
foo x r@(MkA{}) = r { fld = x }
```
When renaming the...I think the following could reasonably be expected to work:
```haskell
{-# LANGUAGE DuplicateRecordFields #-}
module M where
data A a = MkA { fld :: a }
data B b = MkB { fld :: b }
foo x r@(MkA{}) = r { fld = x }
```
When renaming the record update on the RHS of `foo`, the renamer would see `r`, and look up in some environment to see it is associated with the pattern `MkA{}` which disambiguates which record field `fld` refers to.
Currently `rnPat` doesn't create any kind of environment to keep track of the connection in an as-pattern:
```haskell
rnPatAndThen mk (AsPat _ rdr at pat)
= do { new_name <- newPatLName mk rdr
; pat' <- rnLPatAndThen mk pat
; return (AsPat noExtField new_name at pat') }
```
whereas the typechecker does:
```haskell
tc_pat pat_ty penv ps_pat thing_inside = case ps_pat of
...
AsPat x (L nm_loc name) at pat -> do
{ ...
; (wrap, bndr_id) <- setSrcSpanA nm_loc (tcPatBndr penv name pat_ty)
; (pat', res) <- tcExtendIdEnv1 name bndr_id $
tc_lpat (pat_ty `scaledSet`(mkCheckExpType $ idType bndr_id))
penv pat thing_inside
; ... }
```
I think this would be a rather satisfying way to disambiguate record updates, although one shortcoming is that it does not handle sum types very well, as one has to have a separate case for each constructor. We would want something like or-patterns:
```haskell
data C c = MkC1 { fld1, fld2, fld3 :: c } | MkC2 { fld1, fld2 :: c }
data D d = MkD1 { fld1, fld2 :: d }
-- OK, but requires listing all the constructors
bar1 c1 c2 r@(MkC1{} or MkC2{}) = r { fld1 = c1, fld2 = c2 }
-- Even better, just mention a single constructor!
bar2 c1 c2 r@(MkC1{} or _) = r { fld1 = c1, fld2 = c2 }
```https://gitlab.haskell.org/ghc/ghc/-/issues/22384Visible type application in record patterns2022-11-01T08:49:22ZTarmeanVisible type application in record patterns## Motivation
I've been using type applications in patterns quite a bit recently and struggled when adding or removing an argument from the constructors because all pattern matches must add/remove wildcards.
```haskell
lookupQMap :: fo...## Motivation
I've been using type applications in patterns quite a bit recently and struggled when adding or removing an argument from the constructors because all pattern matches must add/remove wildcards.
```haskell
lookupQMap :: forall a. Typeable a => QKey a -> QMap -> Maybe a
lookupQMap qid qmap =
-- This could use a Data.Typeable.cast, but it's simplified from some more complex code
case lookupQ qid qmap of
ResultEntry @r' dat _
| Just Refl <- eqT @r @r' -> ...
```
The nice way to avoid the problem would be to use record patterns. But mixing type applications with record patterns results in a parse error!
```haskell
case lookupQ qid qmap of
ResultEntry @r {resultData=dat}
-- [parser] [E] parser error on input '{'
```
I'm not sure if this is intentional, an oversight, or whether I'm missing the right syntax. It'd be really useful, though!
## Proposal
If the missing syntax is an oversight it hopefully could be added without making the grammar overly ambiguous. I do not know whether this would require a separate proposal.
If the feature already exists or is intentionally missing it maybe could be documented somewhere, though I'm not sure what the right place would be. I couldn't find a mention in the proposal or paper at least.https://gitlab.haskell.org/ghc/ghc/-/issues/22267OverloadedRecordDot is broken when records have a constraint2023-06-07T10:31:18ZGautier DI FOLCOOverloadedRecordDot is broken when records have a constraint## Summary
Whenever I try to reference a function with a constraint with OverloadedRecordDot syntax, I have an error.
## Steps to reproduce
While this code compiles:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R...## Summary
Whenever I try to reference a function with a constraint with OverloadedRecordDot syntax, I have an error.
## Steps to reproduce
While this code compiles:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R {myFunc :: String -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
Adding a constraint:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
import GHC.Stack
data R = R {myFunc :: HasCallStack => String -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
gives me an error:
```
B.hs:9:13: error:
• No instance for (GHC.Records.HasField "myFunc" R (String -> Int))
arising from selecting the field ‘myFunc’
(maybe you haven't applied a function to enough arguments?)
• In the expression: r.myFunc
In the expression: r.myFunc "42"
In an equation for ‘myUsage’: myUsage r = r.myFunc "42"
|
9 | myUsage r = r.myFunc "42"
```
it also fails with a more classic one:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R {myFunc :: forall a. Show a => a -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
which gives
```
B.hs:7:13: error:
• No instance for (GHC.Records.HasField "myFunc" R (String -> Int))
arising from selecting the field ‘myFunc’
(maybe you haven't applied a function to enough arguments?)
• In the expression: r.myFunc
In the expression: r.myFunc "42"
In an equation for ‘myUsage’: myUsage r = r.myFunc "42"
|
7 | myUsage r = r.myFunc "42"
```
## Expected behavior
I expects the type-check works as there's no constraint (while propagating it).
## Environment
* GHC version used: 9.4.2 / 9.2.2
Optional:
* Operating System: NixOS unstable
* System Architecture: x86_64Gautier DI FOLCOGautier DI FOLCOhttps://gitlab.haskell.org/ghc/ghc/-/issues/22150Record pattern synonyms for fields covering multiple constructors2023-02-07T23:21:51ZAdam GundryRecord pattern synonyms for fields covering multiple constructorsIf a field belongs to multiple constructors of a datatype, it is not possible to replace the constructors with pattern synonyms, because each pattern synonym has independent fields. For example:
```hs
{-# LANGUAGE DuplicateRecordFields ...If a field belongs to multiple constructors of a datatype, it is not possible to replace the constructors with pattern synonyms, because each pattern synonym has independent fields. For example:
```hs
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PatternSynonyms #-}
{-# OPTIONS_GHC -Wall #-}
module PatSynMulti where
data S = MkS1 { f :: Int } | MkS2 { f :: Int }
pattern MkT1 { g } = MkS1 { f = g }
pattern MkT2 { g } = MkS2 { f = g }
{-# COMPLETE MkT1, MkT2 #-}
bar = f -- accepted
baz = g -- rejected
```
(Here `DuplicateRecordFields` is necessary to allow `g` to be defined twice; without it the pattern synonym definitions are rejected.)
Similar problems also arise with record updates, and the `HasField` typeclass.
Ideally, it would be possible to replace a datatype with an equivalent collection of pattern synonyms, and this issue prevents that. It seems to me that resolving this would need some notion of "pattern synonym collections" where fields cover all the pattern synonyms in the collection, rather like souped-up `COMPLETE` pragmas.https://gitlab.haskell.org/ghc/ghc/-/issues/22149Allow record patterns that are not headed by constructors2022-09-12T09:11:03Zsheafsam.derbyshire@gmail.comAllow record patterns that are not headed by constructorsI would like record patterns that are not headed by constructors to be accepted. For example:
```haskell
data D
= Mk1
| Mk2 { fld1 :: Int, fld2 :: Bool, fld3 :: Int }
| Mk3 { fld1 :: Int }
-- no pattern match warnings
f :: D -> I...I would like record patterns that are not headed by constructors to be accepted. For example:
```haskell
data D
= Mk1
| Mk2 { fld1 :: Int, fld2 :: Bool, fld3 :: Int }
| Mk3 { fld1 :: Int }
-- no pattern match warnings
f :: D -> Int
f (_ { fld1 = x }) = x -- matches both Mk2 and Mk3
f Mk1 = 0
-- pattern match warning: constructor not matched: 'Mk3'
g :: D -> Int
g (r { fld1 = x, fld2 = y }) = if y then x else x + fld3 r -- matches only Mk2
g Mk1 = 0
```
That is, a record pattern can be headed by an underscore or variable name instead of a constructor name,
and the constructors matched by that pattern are precisely those that have all of the required fields.https://gitlab.haskell.org/ghc/ghc/-/issues/22107-ddump-minimal-imports for record fields is not minimal2023-02-21T16:59:46ZAdam Gundry-ddump-minimal-imports for record fields is not minimal## Summary
When `-ddump-minimal-imports` is used for a module that uses a record field but not the corresponding type constructor, it generates an import of the form `T(x)` when it would suffice to import `x`.
`Note [Overloaded field i...## Summary
When `-ddump-minimal-imports` is used for a module that uses a record field but not the corresponding type constructor, it generates an import of the form `T(x)` when it would suffice to import `x`.
`Note [Overloaded field import]` in `GHC.Rename.Names` addresses a special case of this situation, when `DuplicateRecordFields` is used. I think this is outdated though because it claims "when `DuplicateRecordFields` is enabled, field selectors are not in scope without their enclosing datatype" which is no longer true in general.
## Steps to reproduce
```hs
module M where
data T = MkT { x :: Int }
module N where
import M
foo = x
```
Now `ghc -ddump-minimal-imports N.hs` will generate `N.imports` containing `import M (T(foo))`.
## Expected behavior
The `N.imports` file should contain `import M (foo)`. Using this import is sufficient to compile the module.
## Environment
* GHC version used: 9.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/21324HasField instances cannot be defined on newtypes that have a field selector e...2022-06-12T06:54:36ZOllie CharlesHasField instances cannot be defined on newtypes that have a field selector even if that isn't exported## Motivation
I would like to able to provide a `HasField` instance for `reactive-banana` [`Behavior`](https://hackage.haskell.org/package/reactive-banana-1.3.0.0/docs/Reactive-Banana-Combinators.html#t:Behavior)s. Specifically, I want ...## Motivation
I would like to able to provide a `HasField` instance for `reactive-banana` [`Behavior`](https://hackage.haskell.org/package/reactive-banana-1.3.0.0/docs/Reactive-Banana-Combinators.html#t:Behavior)s. Specifically, I want to write
```haskell
instance HasField x a b => HasField (x :: Symbol) (Behavior a) (Behavior b) where
getField behavior = behavior <&> getField @x
```
Unfortunately, GHC refuses to allow me to write this, reporting:
```
lib/Reactive/Banana/Orphans.hs:36:28: error:
• Illegal instance declaration for
‘HasField x (Behavior a) (Behavior b)’
Behavior has fields
• In the instance declaration for
‘HasField (x :: Symbol) (Behavior a) (Behavior b)’
|
36 | instance HasField x a b => HasField (x :: Symbol) (Behavior a) (Behavior b) where
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
but I disagree that `Behavior` has fields. *Internally* `Behavior` is defined as
```haskell
newtype Behavior a = B { unB :: Prim.Behavior a }
```
but that is never exported - no module expect the defining one can see that field.
## Proposal
I am able to write the instance.https://gitlab.haskell.org/ghc/ghc/-/issues/20193RecordWildCards undocumented behavior2021-08-16T08:33:20ZYuriy SyrovetskiyRecordWildCards undocumented behavior## Summary
https://downloads.haskell.org/ghc/latest/docs/html/users_guide/exts/record_wildcards.html
There are two behaviors of RecordWildCards (RWC) undocumented or documented unclearly.
### 1. Unclear qualified names
> For both pat...## Summary
https://downloads.haskell.org/ghc/latest/docs/html/users_guide/exts/record_wildcards.html
There are two behaviors of RecordWildCards (RWC) undocumented or documented unclearly.
### 1. Unclear qualified names
> For both pattern and expression wildcards, the “`..`” expands to the missing in-scope record fields...
>
> The record field `f` is in scope somehow (either qualified or unqualified).
>
> ```hs
> module M where
> data R = R { a,b,c :: Int }
> module X where
> import M( R(R,a,c) )
> f a b = R { .. }
> ```
>
> The `R{..}` expands to `R{a=a}`
There should be an example of qualified in-scope presence, which I find very useful
```hs
module M where
data R = R{a, b, c :: Int}
module X where
import M (R (R))
import M qualified
f a b = R{..}
```
The `R{..}` expands to `R{M.a = a, M.b = b}`, so you can use fields without messing with getters.
### 2. RWC interferes with NamedFieldPuns
With NamedFieldPuns (NFP) enabled and RWC disabled:
```hs
import M (R (R))
import M qualified
f foo = R{foo} -- use of NFP syntax, not RWC
```
```
error:
Not in scope: ‘foo’
Perhaps you want to add ‘foo’ to the import list in the import of
```
With RWC additionally enabled, the same code is compiled successfully!
So, RWC desugars NFP syntax `R{foo}` to `R{M.foo = foo}`, which must be documented.
## Proposed improvements or changes
I'm not sure about specific wording.
## Environment
* GHC version used: 8.10.4https://gitlab.haskell.org/ghc/ghc/-/issues/19312Unbound record/field names in Template Haskell Quotes2021-04-07T19:55:24ZAdam GundryUnbound record/field names in Template Haskell QuotesIn a Template Haskell expression quotation, unbound variables and constructors are allowed, and are represented using `UnboundVarE`. However unbound names are not permitted in record construction (`RecConE`) or update (`RecUpdE`), and le...In a Template Haskell expression quotation, unbound variables and constructors are allowed, and are represented using `UnboundVarE`. However unbound names are not permitted in record construction (`RecConE`) or update (`RecUpdE`), and lead to scope errors in the quotation. This leads to strangely inconsistent behaviour:
```
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Prelude> :set -XTemplateHaskellQuotes
Prelude> import Language.Haskell.TH.Syntax as TH
Prelude TH> unQ [| foo |]
UnboundVarE foo
Prelude TH> unQ [| Foo |]
UnboundVarE Foo
Prelude TH> unQ [| Foo {} |]
<interactive>:5:8: error:
• Not in scope: data constructor ‘Foo’
• In the Template Haskell quotation [| Foo {} |]
Prelude TH> unQ [| Foo { foo = bar } |]
<interactive>:6:8: error:
• Not in scope: data constructor ‘Foo’
• In the Template Haskell quotation [| Foo {foo = bar} |]
<interactive>:6:14: error:
• Not in scope: ‘foo’
• In the Template Haskell quotation [| Foo {foo = bar} |]
Prelude TH> unQ [| Just { pi = bar } |]
RecConE GHC.Maybe.Just [(GHC.Float.pi,UnboundVarE bar)]
```
It seems odd that:
* `Foo` is accepted but `Foo {}` is not.
* `Foo { foo = bar }` leads to not-in-scope errors for `Foo` and `foo` but not `bar`.
* `Just { pi = bar }` is accepted even though it is complete nonsense, because `Just` is not a record constructor and `pi` is not a field.
I'm not sure what the right behaviour is here. One possibility would be to drop `UnboundVarE` and instead add a constructor to `Name` for unbound names, which would allow us to represent arbitrary expressions involving out-of-scope names.
Thanks to @edsko for highlighting this. I've tested that this behaviour occurs with 8.6.5, 8.10.2 and a relatively recent HEAD.https://gitlab.haskell.org/ghc/ghc/-/issues/18869Include field type in missing field error message2021-01-18T12:48:39ZparsonsmattInclude field type in missing field error message## Motivation
I'm working on some code that hasn't been touched in a while (*cough* test suite *cough), and a lot of types have been updated with new fields and changed fields. So all of the record creation stuff needs addressing.
An e...## Motivation
I'm working on some code that hasn't been touched in a while (*cough* test suite *cough), and a lot of types have been updated with new fields and changed fields. So all of the record creation stuff needs addressing.
An example error message is:
```
lumi-mojo > /home/matt/Projects/lumi/mojo/common/test/Lumi/Gen/Schema/Quote.hs:85:20: error:
lumi-mojo > • Constructor ‘QuoteVariant’ does not have the required strict field(s): quoteVariantCloneDescription
lumi-mojo > • In the expression:
lumi-mojo > QuoteVariant
```
So I'll throw in the line:
```diff
, quoteVariantThing = Nothing
+ , quoteVariantCloneDescription = ""
}
```
But this isn't right! `quoteVariantCloneDescription` has the type `Maybe Text`. So I need to go through and do another edit:
```diff
, quoteVariantThing = Nothing
- , quoteVariantCloneDescription = ""
+ , quoteVariantCloneDescription = Nothing
}
```
## Proposal
This minor inconvenience can easily be fixed by supplying the type of the missing field.
```diff
/home/matt/Projects/lumi/mojo/common/test/Lumi/Gen/Schema/Quote.hs:85:20: error:
- • Constructor ‘QuoteVariant’ does not have the required strict field(s): quoteVariantCloneDescription
+ • Constructor ‘QuoteVariant’ does not have the required strict field(s): quoteVariantCloneDescription :: Maybe Text
• In the expression:
QuoteVariant
```https://gitlab.haskell.org/ghc/ghc/-/issues/18759Types with different forall placements don't unify with QL ImpredicativeTypes2022-06-30T00:52:03ZAndrzej RybczakTypes with different forall placements don't unify with QL ImpredicativeTypesThe following program:
```haskell
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ImpredicativeTypes #-}
{-# LANGUAGE KindSignatures...The following program:
```haskell
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ImpredicativeTypes #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall #-}
import GHC.TypeLits
main :: IO ()
main = pure ()
data X = X { x :: forall a. a -> a }
class HasField (name :: Symbol) s a | name s -> a where
getField :: s -> a
instance a ~ (forall x. x -> x) => HasField "x" X a where
getField = x
getX_Ok_sel :: X -> forall a. a -> a
getX_Ok_sel = x
getX_Bad_sel :: forall a. X -> a -> a
getX_Bad_sel = x
getX_Ok_class :: X -> forall a. a -> a
getX_Ok_class = getField @"x"
getX_Bad_class :: forall a. X -> a -> a
getX_Bad_class = getField @"x"
getX_Bad_classUsage :: String
getX_Bad_classUsage = getField @"x" (X id) "hello world"
```
produces errors with GHC 9.1.0.20200927:
```
unknown@electronics _build $ ./ghc-stage1 it.hs
[1 of 1] Compiling Main ( it.hs, it.o )
it.hs:29:16: error:
• Couldn't match type: forall a1. a1 -> a1
with: a -> a
Expected: X -> a -> a
Actual: X -> forall a. a -> a
• In the expression: x
In an equation for ‘getX_Bad_sel’: getX_Bad_sel = x
• Relevant bindings include
getX_Bad_sel :: X -> a -> a (bound at it.hs:29:1)
|
29 | getX_Bad_sel = x
| ^
it.hs:35:18: error:
• Couldn't match type: a -> a
with: forall x. x -> x
arising from a use of ‘getField’
• In the expression: getField @"x"
In an equation for ‘getX_Bad_class’: getX_Bad_class = getField @"x"
• Relevant bindings include
getX_Bad_class :: X -> a -> a (bound at it.hs:35:1)
|
35 | getX_Bad_class = getField @"x"
| ^^^^^^^^
it.hs:38:23: error:
• Couldn't match type: String -> String
with: forall x. x -> x
arising from a use of ‘getField’
• In the expression: getField @"x" (X id) "hello world"
In an equation for ‘getX_Bad_classUsage’:
getX_Bad_classUsage = getField @"x" (X id) "hello world"
|
38 | getX_Bad_classUsage = getField @"x" (X id) "hello world"
```
The `Bad_sel` and `Bad_class` issues look very similar, but produce error messages with flipped actual and expected types, which confuses me a bit.
`Bad_classUsage` looks like a consequence of `Bad_class` not working.