GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2023-10-03T14:18:19Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24048Allow disjunctions in COMPLETE pragmas2023-10-03T14:18:19ZTeo CamarasuAllow disjunctions in COMPLETE pragmas<!--
READ THIS FIRST: If the feature you are proposing changes the language that GHC accepts
or adds any warnings to `-Wall`, it should be written as a [GHC Proposal](https://github.com/ghc-proposals/ghc-proposals/).
Other features, appr...<!--
READ THIS FIRST: If the feature you are proposing changes the language that GHC accepts
or adds any warnings to `-Wall`, it should be written as a [GHC Proposal](https://github.com/ghc-proposals/ghc-proposals/).
Other features, appropriate for a GitLab feature request, include GHC API/plugin
innovations, new low-impact compiler flags, or other similar additions to GHC.
-->
## Motivation
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/11200#note_525994 lays out a limitation of COMPLETE pragmas.
One might want to have a data type with N sets of M interchangeable patterns, but currently this would require `N * M` COMPLETE pragmas.
I was surprised by this since `MINIMAL` pragmas for typeclasses allow having disjunctions, eg, we can say:
```haskell
{-# MINIMAL foo, (bar | baz) #-}
```
In my mind these two constructs are analogous so I was surprised that they differed in this way.
## Proposal
`COMPLETE` pragmas should support both conjunction and disjunction (with `,` and `|` respectively) just like `MINIMAL` pragmas.
I think this would require a GHC proposal. I don't currently have the time to write one up but I hope I will in the future. But I thought I'd make a ticket in case someone else wanted to and if not so I don't forget about ithttps://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/23704Visible forall in pattern synonyms2023-08-23T17:14:43ZVladislav ZavialovVisible forall in pattern synonymsGHC Proposals [#281](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0281-visible-forall.rst) and [#402](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0402-gadt-syntax.rst) allow the use of vis...GHC Proposals [#281](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0281-visible-forall.rst) and [#402](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0402-gadt-syntax.rst) allow the use of visible forall in data constructors. That is, we should be able to write
```haskell
data T a where
MkT :: forall a -> a -> T a
```
A quite relevant ticket that also mentions this is #18389. But what about pattern synonyms?
```haskell
pattern P :: forall a -> a -> T a
pattern P a x = MkT a x
```
The interaction between `PatternSynonyms` and `RequiredTypeArguments` simply hasn't been discussed or specified anywhere.
It's a feature that makes sense. If we are able to define data constructor `MkT`, then we should also be able to define a synonym for it. I don't see any obstacles to implementing this. However, it would be nice to have a real world use case before putting effort into it.https://gitlab.haskell.org/ghc/ghc/-/issues/23529writing a pattern synonym body doesn't suggest enabling `-XPatternSynonyms` w...2023-06-16T11:19:10ZMagnus Viernickelwriting a pattern synonym body doesn't suggest enabling `-XPatternSynonyms` while writing the type signature does## Motivation
If I write
`pattern X = 4`, I get `Not in scope: data constructor X`
whereas if I write
`pattern X :: Int`, I get `Perhaps you intended to use PatternSynonyms`
## Proposal
I would like to gt the suggestion in the forme...## Motivation
If I write
`pattern X = 4`, I get `Not in scope: data constructor X`
whereas if I write
`pattern X :: Int`, I get `Perhaps you intended to use PatternSynonyms`
## Proposal
I would like to gt the suggestion in the former case as well. :)https://gitlab.haskell.org/ghc/ghc/-/issues/23467GHC internal error when pattern synonym has wrong type signature2023-08-23T13:13:37ZAndreas AbelGHC internal error when pattern synonym has wrong type signatureWhen I forgot an argument in the type signature of a pattern synonym, I got, in addition to the expected error, also a GHC internal error.
MWE:
```haskell
{-# LANGUAGE PatternSynonyms #-}
data ConData = ConData { _pars :: Int }
data De...When I forgot an argument in the type signature of a pattern synonym, I got, in addition to the expected error, also a GHC internal error.
MWE:
```haskell
{-# LANGUAGE PatternSynonyms #-}
data ConData = ConData { _pars :: Int }
data Decl = ConDecl ConData
pattern Con :: Decl -- The correct type would be Int -> Decl
pattern Con { pars } = ConDecl (ConData pars)
foo :: Decl -> Int
foo (Con { pars }) = pars
```
Reported errors are:
```
PatternSyn.hs:7:1: error:
• Pattern synonym ‘Con’ has one argument
but its type signature has 1 fewer arrows
• In the declaration for pattern synonym ‘Con’
|
7 | pattern Con { pars } = ConDecl (ConData pars)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PatternSyn.hs:10:6: error:
• GHC internal error: ‘pars’ is not in scope during type checking, but it passed the renamer
tcl_env of environment: [rh1 :-> Identifier[foo::Decl
-> Int, TopLevelLet {} True]]
• In the pattern: Con {pars}
In an equation for ‘foo’: foo (Con {pars}) = pars
|
10 | foo (Con { pars }) = pars
| ^^^^^^^^^^^^
```
Seems GHC does not recover well from the original error and then throws an internal error.
The internal error is reported by GHC 8.6 and above (tested 8.6.5, 8.8.4, 8.10.7, 9.0.2, 9.2.8, 9.4.5, 9.6.2).
Evidence in CI run, e.g.: https://github.com/agda/agda/actions/runs/5155818185/jobs/9285983967#step:12:3379.8.1sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/23203Cannot generate inline pragmas for pattern synonyms using TH2023-05-08T16:21:34ZJannisCannot generate inline pragmas for pattern synonyms using TH## Summary
When generating pattern synonyms with TH it is currently not possible to also produce an inline pragma for that pattern with TH.
## Steps to reproduce
```haskell
module T1 where
import Language.Haskell.TH
genPat :: Q [Dec...## Summary
When generating pattern synonyms with TH it is currently not possible to also produce an inline pragma for that pattern with TH.
## Steps to reproduce
```haskell
module T1 where
import Language.Haskell.TH
genPat :: Q [Dec]
genPat = sequence [
patSynD name (prefixPatSyn []) unidir wildP
, pure $ PragmaD $ InlineP name Inline FunLike AllPhases
]
where name = mkName "A"
```
```haskell
{-# LANGUAGE TemplateHaskell #-}
module T2 where
import T1
genPat
```
Fails with:
```
src/T2.hs:6:1: error: [GHC-55017]
Illegal variable name: ‘A’
When splicing a TH declaration: {-# INLINE A #-}
|
6 | genPat
```
## Expected behavior
This code compiles just fine and I think so should the TH version that generates it.
```haskell
{-# LANGUAGE PatternSynonyms #-}
module T2 where
pattern A <- _
{-# INLINE A #-}
```
## Environment
* GHC version used: 9.4.4 and I also tested some recent form of the master branch (1-2 weeks old)https://gitlab.haskell.org/ghc/ghc/-/issues/23038A nice pattern synonym record field became naughty in GHC 9.62023-03-03T15:22:44Zsheafsam.derbyshire@gmail.comA nice pattern synonym record field became naughty in GHC 9.6Consider the following:
```haskell
pattern N1 :: forall a. () => forall. () => a -> Any
pattern N1 { fld1 } <- ( unsafeCoerce -> fld1 )
where N1 = unsafeCoerce
pattern N2 :: forall. () => forall a. () => a -> Any
pattern N2 { fld2 } ...Consider the following:
```haskell
pattern N1 :: forall a. () => forall. () => a -> Any
pattern N1 { fld1 } <- ( unsafeCoerce -> fld1 )
where N1 = unsafeCoerce
pattern N2 :: forall. () => forall a. () => a -> Any
pattern N2 { fld2 } <- ( unsafeCoerce -> fld2 )
where N2 = unsafeCoerce
test1, test2 :: forall a. Any -> a
test1 = fld1
test2 = fld2
```
We should accept `test1`, and reject `test2` because we have an existential variable escaping its scope (`fld2` is a "naughty record selector").
This is indeed what happens on GHC 9.4. However, on GHC 9.6, `test1` is rejected as it considers `fld1` to also be a naughty record selector.
This regression showed up when compiling the [`cleff`](https://hackage.haskell.org/package/cleff) package, which contains the following:
```haskell
pattern Any :: forall a. a -> Any
pattern Any {fromAny} <- (unsafeCoerce -> fromAny)
where Any = unsafeCoerce
```
```
src/Cleff/Internal/Monad.hs:46:26: error: [GHC-55876]
• Cannot use record selector ‘fromAny’ as a function due to escaped type variables
• In the first argument of ‘($)’, namely ‘fromAny’
In the expression:
fromAny $ Vec.lookup (unHandlerPtr (Rec.index @e re)) mem
In an equation for ‘readEnv’:
readEnv (Env _ re mem)
= fromAny $ Vec.lookup (unHandlerPtr (Rec.index @e re)) mem
Suggested fix: Use pattern-matching syntax instead
|
46 | readEnv (Env _ re mem) = fromAny $ Vec.lookup (unHandlerPtr (Rec.index @e re)) mem
|9.6.2Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/22843Nested RankNType fails to compile2023-02-07T16:03:21ZIcelandjackNested RankNType fails to compileGHC 8.10.2: Here are pretty sensible pattern synonyms for `E a b`: a Church encoding of `Either a b`.
```haskell
{-# Language PatternSynonyms #-}
{-# Language ImpredicativeTypes #-}
{-# Language RankNTypes #...GHC 8.10.2: Here are pretty sensible pattern synonyms for `E a b`: a Church encoding of `Either a b`.
```haskell
{-# Language PatternSynonyms #-}
{-# Language ImpredicativeTypes #-}
{-# Language RankNTypes #-}
{-# Language ScopedTypeVariables #-}
{-# Language StandaloneKindSignatures #-}
{-# Language ViewPatterns #-}
import Data.Kind
type E :: Type -> Type -> Type
type E a b = forall res. (a -> res) -> (b -> res) -> res
pattern ELeft :: a -> E a b
pattern ELeft a <- ((\e -> e Just (const Nothing)) -> Just a)
where ELeft a left _right = left a
pattern ERight :: b -> E a b
pattern ERight b <- ((\e -> e (const Nothing) Just) -> Just b)
where ERight b _left right = right b
```
When using them in nested positions, inference fails. Maybe this has been fixed or is not supposed to type check, but each of the 3 clauses of `regroup` fail to compile.
```haskell
regroup :: forall a b c. E a (E b c) -> E (E a b) c
-- • Couldn't match type ‘(a -> res0) -> (b0 -> res0) -> res0’
-- with ‘forall res1. (a -> res1) -> (b -> res1) -> res1’
-- Expected type: (E a b -> res) -> (c -> res) -> res
-- Actual type: (((a -> res0) -> (b0 -> res0) -> res0) -> res)
-- -> (c -> res) -> res
regroup (ELeft a) = ELeft (ELeft a)
-- • Couldn't match expected type ‘E b0 b1’
-- with actual type ‘(b -> res1) -> (c -> res1) -> res1’
-- • Couldn't match type ‘(a0 -> res0) -> (b0 -> res0) -> res0’
-- with ‘forall res2. (a -> res2) -> (b -> res2) -> res2’
-- Expected type: (E a b -> res) -> (c -> res) -> res
-- Actual type: (((a0 -> res0) -> (b0 -> res0) -> res0) -> res)
-- -> (c -> res) -> res
regroup (ERight (ELeft b)) = ELeft (ERight b)
-- • Couldn't match expected type ‘E a0 c’
-- with actual type ‘(b -> res0) -> (c -> res0) -> res0’
regroup (ERight (ERight c)) = ERight c
```https://gitlab.haskell.org/ghc/ghc/-/issues/22731Implement pattern constructor signatures2023-01-17T16:43:31ZDavid FeuerImplement pattern constructor signaturesSomeone should implement the accepted proposal [Pattern synonym construction function signatures](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0042-bidir-constr-sigs.rst). The need for such signatures keeps poppin...Someone should implement the accepted proposal [Pattern synonym construction function signatures](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0042-bidir-constr-sigs.rst). The need for such signatures keeps popping up from time to time.https://gitlab.haskell.org/ghc/ghc/-/issues/22581Explicit namespace type import can bring a value into scope2023-08-03T20:11:39Zsheafsam.derbyshire@gmail.comExplicit namespace type import can bring a value into scopeAs an example, recall that `Data.Functor.Product` exports
```haskell
data Product f g a = Pair (f a) (g a)
```
It seems that importing `Data.Functor.Product ( Product ( type Pair ) )` imports both the data constructor `Pair` (a value) ...As an example, recall that `Data.Functor.Product` exports
```haskell
data Product f g a = Pair (f a) (g a)
```
It seems that importing `Data.Functor.Product ( Product ( type Pair ) )` imports both the data constructor `Pair` (a value) as well as its promotion:
```haskell
ghci> :seti -XExplicitNamespaces -XDataKinds
ghci>
ghci> import Data.Functor.Product ( Product ( type Pair ) )
ghci>
ghci> :type Pair
Pair
:: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
ghci>
ghci> :kind Pair
Pair :: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
```
This seems a bit odd: if I'm explicitly asking for the **type** `Pair`, shouldn't I only get the promoted data constructor, and not the value? This is an example of a `type` import bringing in a value into scope, which seems odd.
The users' guide isn't very clear about this, but it says that `type` is a disambiguation mechanism more than anything else, so if the item is unambiguous then it doesn't change the behaviour, so that in the above example `import Data.Functor.Product ( Product ( type Pair ) )` is equivalent to `import Data.Functor.Product ( Product ( Pair ) )`.
In the same vein, we have:
```haskell
ghci> :seti -XExplicitNamespaces -XDataKinds -XPatternSynonyms
ghci>
ghci> import Data.Functor.Product ( pattern Pair )
ghci>
ghci> :type Pair
Pair
:: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
ghci>
ghci> :kind Pair
Pair :: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
```
In this case we have a `pattern` import bringing in a type into scope. I suppose the same reasoning holds as above.https://gitlab.haskell.org/ghc/ghc/-/issues/22328Confusing interaction of pattern synonyms and view patterns2023-03-06T10:47:47ZlierdakilConfusing interaction of pattern synonyms and view patterns## Summary
I'm using the bug report template, but I'm not entirely convinced it's a bug. Anyway.
This code rather surprisingly fails to compile:
```haskell
{-# LANGUAGE PatternSynonyms, GADTs, ViewPatterns #-}
import Data.Typeable
d...## Summary
I'm using the bug report template, but I'm not entirely convinced it's a bug. Anyway.
This code rather surprisingly fails to compile:
```haskell
{-# LANGUAGE PatternSynonyms, GADTs, ViewPatterns #-}
import Data.Typeable
data Gadt x y where
ExistentialInGadt :: Typeable a => a -> Gadt x x
pattern CastGadt :: Typeable a => x ~ y => a -> Gadt x y
pattern CastGadt a <- ExistentialInGadt (cast -> Just a)
test :: Gadt i o -> Bool
test gadt = case gadt of
CastGadt a -> a
_ -> False
```
The complete error message says:
```
test.hs:13:3: error:
• No instance for (Typeable a0) arising from a pattern
• In the pattern: CastGadt a
In a case alternative: CastGadt a -> a
In the expression:
case gadt of
CastGadt a -> a
_ -> False
|
13 | CastGadt a -> a
| ^^^^^^^^^^
test.hs:13:17: error:
• Couldn't match expected type ‘Bool’ with actual type ‘a0’
‘a0’ is untouchable
inside the constraints: i ~ o
bound by a pattern with pattern synonym:
CastGadt :: forall a x y. Typeable a => (x ~ y) => a -> Gadt x y,
in a case alternative
at test.hs:13:3-12
• In the expression: a
In a case alternative: CastGadt a -> a
In the expression:
case gadt of
CastGadt a -> a
_ -> False
• Relevant bindings include a :: a0 (bound at test.hs:13:12)
|
13 | CastGadt a -> a
| ^
```
Note that `Typeable` isn't particularly relevant here, and neither are `GADTs`, those are used for illustrative purposes -- the crux of the issue is given constraints on a pattern synonym using a view pattern that needs the required constraints.
It's not obvious why GHC insists `a0` is untouchable. What's even more confusing, a pattern synonym without given constraints works as expected (i.e. it doesn't provide the constraint `x ~ y`, but it does compile):
```haskell
-- this compiles fine
pattern CastGadtNoGivens :: Typeable a => a -> Gadt x y
pattern CastGadtNoGivens a <- ExistentialInGadt (cast -> Just a)
test :: Gadt i o -> Bool
test gadt = case gadt of
CastGadtNoGivens a -> a
_ -> False
-- as expected, this would fail:
-- testGivens :: Gadt i o -> (i ~ o => Bool -> r) -> r
-- testGivens gadt f = case gadt of
-- CastGadtNoGivens x -> f x
```
Furthermore, the code substituting the pattern synonym definition compiles just fine, but that's not really a surprise:
```haskell
-- This is totally fine
{-# LANGUAGE GADTs, ViewPatterns, TypeOperators #-}
import Data.Typeable
import Data.Type.Equality
data Gadt x y where
ExistentialInGadt :: Typeable a => a -> Gadt x x
test :: Gadt i o -> (Bool, i :~: o)
test gadt = case gadt of
ExistentialInGadt (cast -> Just a) -> (a, Refl)
_ -> undefined
```
Now, thanks to @int-index being very generous with his time, we more or less figured out why this happens. Specifically, in `GHC.Tc.Gen.Pat.tcPatSynPat` we have:
```haskell
; (ev_binds, (arg_pats', res))
<- checkConstraints skol_info ex_tvs' prov_dicts' $
tcConArgs (PatSynCon pat_syn) arg_tys_scaled tenv penv arg_pats thing_inside
```
All seems reasonable enough, however with the pattern synonym above, we run into a bit of an issue: `checkConstraints` wants to know if `a` is `Typeable` to construct an implication, however it didn't actually typecheck the constructor arguments yet, as `tcConArgs` is to be run later. Hence, it can't know yet what `a` is and whether it's `Typeable`.
The pattern synonym without givens apparently works because `checkConstraints` goes into the "fast path" and actually skips building the implications.
I didn't really investigate the code without pattern synonyms, but my hunch is `cast` is applied before givens are brought into scope (semantically this makes sense at least).
#19847 and #21501 seem to be symptoms of this very same issue (to be clear: I didn't run traces, but the setup is the same), but those also use pattern type applications, and that complicates things a bit.
## Steps to reproduce
Copy the code above and try to compile it (or load it in GHCi)
## Expected behavior
The code compiles, or at least a less arcane error message is produced.
## Environment
* GHC version used: 9.0, 9.2, 9.4sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/22212HEAD-only panic (isUnliftedType) with PatternSynonyms + OverloadedStrings2022-09-21T13:49:04ZRyan ScottHEAD-only panic (isUnliftedType) with PatternSynonyms + OverloadedStrings_(Originally observed in a `head.hackage` CI job [here](https://gitlab.haskell.org/ghc/head.hackage/-/jobs/1173571#L731).)_
GHC HEAD (at commit bd0f418422a3ace8d05c8ce93850190e57321465) panics when building the `what4-1.3` library on Ha..._(Originally observed in a `head.hackage` CI job [here](https://gitlab.haskell.org/ghc/head.hackage/-/jobs/1173571#L731).)_
GHC HEAD (at commit bd0f418422a3ace8d05c8ce93850190e57321465) panics when building the `what4-1.3` library on Hackage. Here is a minimized example:
```hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
module Bug where
import qualified Data.ByteString as BS
data Sort = MkSort BS.ByteString [()]
pattern Array :: () -> () -> Sort
pattern Array x y = MkSort "Array" [x,y]
```
This panics when compiled with optimization on HEAD:
```
$ ~/Software/ghc-9.5.20220918/bin/ghc -fforce-recomp Bug.hs -O
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
WARNING:
Simplifier bailing out
Bug, after 4 iterations [58, 28, 31, 3]
Size = {terms: 192, types: 120, coercions: 0, joins: 2/2}
Call stack:
CallStack (from HasCallStack):
warnPprTrace, called at compiler/GHC/Core/Opt/Simplify.hs:192:9 in ghc:GHC.Core.Opt.Simplify
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.5.20220918:
isUnliftedType
r_s1bI :: TYPE rep_s1bH
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/GHC/Utils/Panic.hs:188:37 in ghc:GHC.Utils.Panic
pprPanic, called at compiler/GHC/Core/Type.hs:2483:7 in ghc:GHC.Core.Type
isUnliftedType, called at compiler/GHC/Stg/InferTags/Rewrite.hs:220:15 in ghc:GHC.Stg.InferTags.Rewrite
Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
```
But not with GHC 9.4 and earlier:
```
$ ghc-9.4.2 -fforce-recomp Bug.hs -O
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
```9.6.1Andreas Klebingersheafsam.derbyshire@gmail.comAndreas Klebingerhttps://gitlab.haskell.org/ghc/ghc/-/issues/22153COMPLETE pragma doesn't know about module name2022-09-08T17:54:06ZDaneel S. YaitskovCOMPLETE pragma doesn't know about module nameCOMPLETE pragma doesn't support disambiguation.
It is not possible to resolve a name collision between a pattern synonym and a constructor:
```
{-# LANGUAGE PatternSynonyms #-}
module Main where
import Prelude as P
pattern Nothing :: ...COMPLETE pragma doesn't support disambiguation.
It is not possible to resolve a name collision between a pattern synonym and a constructor:
```
{-# LANGUAGE PatternSynonyms #-}
module Main where
import Prelude as P
pattern Nothing :: Maybe a
pattern Nothing = P.Nothing
pattern Just1 :: a -> Maybe a
pattern Just1 a = Just a
{-# COMPLETE Just1, Nothing #-}
main :: IO ()
main = pure ()
```
error
```
Main.hs:12:21: error:
Ambiguous occurrence ‘Nothing’
It could refer to
either ‘P.Nothing’,
imported from ‘Prelude’ at Main.hs:4:1-19
(and originally defined in ‘GHC.Maybe’)
or ‘Main.Nothing’, defined at Main.hs:7:1
|
12 | {-# COMPLETE Just1, Nothing #-}
```
Module name is not handled correctly
```
{-# LANGUAGE PatternSynonyms #-}
module Main where
import Prelude as P
pattern Nothing :: Maybe a
pattern Nothing = P.Nothing
pattern Just1 :: a -> Maybe a
pattern Just1 a = Just a
{-# COMPLETE Just1, Main.Nothing #-}
main :: IO ()
main = pure ()
```
error
```
Main.hs:12:21: error: parse error on input ‘Main.Nothing’
|
12 | {-# COMPLETE Just1, Main.Nothing #-}
| ^^^^^^^^^^^^
```
GHC 8.10.7https://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/22145Allow promotion of one-to-one pattern synonyms2022-09-06T13:36:09ZOleg GrenrusAllow promotion of one-to-one pattern synonyms```haskell
{-# LANGUAGE PatternSynonyms, DataKinds #-}
import Data.Proxy
import Data.Kind
pattern JustJust :: a -> Maybe (Maybe a)
pattern JustJust x = Just (Just x)
p :: Proxy (JustJust Type)
p = Proxy
```
is rejected because of
``...```haskell
{-# LANGUAGE PatternSynonyms, DataKinds #-}
import Data.Proxy
import Data.Kind
pattern JustJust :: a -> Maybe (Maybe a)
pattern JustJust x = Just (Just x)
p :: Proxy (JustJust Type)
p = Proxy
```
is rejected because of
```
• Pattern synonym ‘JustJust’ cannot be used here
(pattern synonyms cannot be promoted)
```
but I don't see why not.
This issue allows to distinguish between pattern synonym and real constructor, e.g. a pattern synonym like
```haskell
pattern Some :: a -> Maybe a
pattern Some x = Just x
```
cannot be used to provide backwards compatibility when renaming constructors! (e.g. upcoming `Solo` to `MkSolo` is a real example).https://gitlab.haskell.org/ghc/ghc/-/issues/21946Type-directed disambiguation doesn't work for record updates using pattern sy...2023-03-30T13:28:39Zsheafsam.derbyshire@gmail.comType-directed disambiguation doesn't work for record updates using pattern synonyms; poor error message ```haskell
{-# LANGUAGE DuplicateRecordFields, PatternSynonyms #-}
module T21946 where
pattern R1 :: Int -> Int
pattern R1 { fld } = fld
pattern R2 :: Bool -> Bool
pattern R2 { fld } = fld
f r = (r :: Int) { fld = undefined }
```
T... ```haskell
{-# LANGUAGE DuplicateRecordFields, PatternSynonyms #-}
module T21946 where
pattern R1 :: Int -> Int
pattern R1 { fld } = fld
pattern R2 :: Bool -> Bool
pattern R2 { fld } = fld
f r = (r :: Int) { fld = undefined }
```
This fails with the error message:
```
* `fld' is not a (visible) field of type `Int'
* In the expression: (r :: Int) {fld = undefined}
In an equation for `f': f r = (r :: Int) {fld = undefined}
|
| f r = (r :: Int) { fld = undefined }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
If one removes the definition of `R2` then it works.
This is because the logic in `GHC.Tc.Gen.Expr.identifyParent` only deals with the `TyCon` parent case, and not the `PatSyn` parent case. But this type-directed disambiguation is scheduled to be removed in the future anyway.9.8.1sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/21898Problems disambiguating a record update with pattern synonyms2023-03-30T13:28:39Zsheafsam.derbyshire@gmail.comProblems disambiguating a record update with pattern synonymsThe parent of a pattern synonym record field is the pattern synonym itself, which I think makes sense (a pattern synonym behaves much like a data constructor). However, it seems that the following variant on #21443 causes GHC to trip ove...The parent of a pattern synonym record field is the pattern synonym itself, which I think makes sense (a pattern synonym behaves much like a data constructor). However, it seems that the following variant on #21443 causes GHC to trip over:
```haskell
{-# LANGUAGE DuplicateRecordFields, PatternSynonyms #-}
pattern P :: Int -> Int -> (Int, Int)
pattern P { proj_x, proj_y } = (proj_x, proj_y)
pattern Q1 :: Int -> Int
pattern Q1 { proj_x } = proj_x
pattern Q2 :: Int -> Int
pattern Q2 { proj_y } = proj_y
blah :: (Int, Int) -> (Int, Int)
blah p = p { proj_x = 0, proj_y = 1 }
```
```
error:
* GHC internal error: `T21443b.$sel:proj_x:P' is not in scope during type checking, but it passed the renamer
tcl_env of environment: [auv :-> Identifier[p::(Int,
Int), NotLetBound],
rgF :-> Identifier[blah::(Int, Int)
-> (Int, Int), TopLevelLet {} True]]
* In the expression: p {proj_x = 0, proj_y = 1}
In an equation for `blah': blah p = p {proj_x = 0, proj_y = 1}
|
| blah p = p { proj_x = 0, proj_y = 1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```9.8.1sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/21757PatternSynonyms problems with provided constraints2022-06-20T12:53:03ZIcelandjackPatternSynonyms problems with provided constraintsUsing the newly added `TypeRep` pattern synonym (#19691)
```haskell
pattern TypeRep :: forall (k :: Type) (a :: k). () => Typeable a => TypeRep a
```
it is possible to define this
```haskell
pattern TFalse :: TypeRep False
pattern TFa...Using the newly added `TypeRep` pattern synonym (#19691)
```haskell
pattern TypeRep :: forall (k :: Type) (a :: k). () => Typeable a => TypeRep a
```
it is possible to define this
```haskell
pattern TFalse :: TypeRep False
pattern TFalse = TypeRep
```
but not
```haskell
-- • Couldn't match type ‘bool’ with ‘'False’
-- arising from the "provided" constraints claimed by
-- the signature of ‘TFalse’
-- ‘bool’ is a rigid type variable bound by
-- the signature for pattern synonym ‘TFalse’
-- at /home/baldur/hs/5456.hs:15:1-52
-- • In the declaration for pattern synonym ‘TFalse’
pattern TFalse :: () => bool ~ False => TypeRep bool
pattern TFalse = TypeRep
```
I was thinking it could be used to quickly define singletons, is this not expected to work?
```haskell
which :: TypeRep bool -> If bool Double (Int, Int)
which TTrue = pi
which TFalse = (20, 30)
```https://gitlab.haskell.org/ghc/ghc/-/issues/21653GHC panic with duplicate exports due to record pattern synonym2022-05-25T22:47:05ZJason CarrGHC panic with duplicate exports due to record pattern synonym## Summary
GHC panics when a duplicate export is from a record pattern synonym and another module attempts to import it.
## Steps to reproduce
With these two files:
bad1.hs:
```haskell
{-# LANGUAGE PatternSynonyms #-}
module Bad1 (T...## Summary
GHC panics when a duplicate export is from a record pattern synonym and another module attempts to import it.
## Steps to reproduce
With these two files:
bad1.hs:
```haskell
{-# LANGUAGE PatternSynonyms #-}
module Bad1 (T(TSyn, getTSyn), getTSyn) where
data T = T Int
pattern TSyn :: Int -> T
pattern TSyn {getTSyn} <- T getTSyn where
TSyn i = T i
```
bad2.hs:
```haskell
module Bad2 where
import Bad1 (getTSyn)
```
Run `ghc ./bad1.hs ./bad2.hs`
should result in this output:
```
bad1.hs:3:32: warning: [-Wduplicate-exports]
‘getTSyn’ is exported by ‘getTSyn’ and ‘T(TSyn, getTSyn)’
|
3 | module Bad1 (T(TSyn, getTSyn), getTSyn) where
| ^^^^^^^
[2 of 2] Compiling Bad2 ( bad2.hs, bad2.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.8.4 for x86_64-unknown-linux):
filterImports/combine
(getTSyn, getTSyn, Nothing)
(getTSyn, T{T, TSyn, getTSyn;}, Nothing)
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1159:37 in ghc:Outputable
pprPanic, called at compiler/rename/RnNames.hs:899:23 in ghc:RnNames
Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
```
## Expected behavior
This should be accepted, since the exporting module compiled
## Environment
* GHC version used: 8.8.4
Optional:
* Operating System: Linux (NixOS)
* System Architecture: AMD64https://gitlab.haskell.org/ghc/ghc/-/issues/21631Pattern synonym succeeds with constraint tuple, but fails with curried constr...2022-05-31T14:33:51ZAndreas AbelPattern synonym succeeds with constraint tuple, but fails with curried constraintsMy pattern synonym is accepted if I pass the constraints as a tuple, but fails if I pass the constraints one after the other (curried).
```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PatternSynonyms ...My pattern synonym is accepted if I pass the constraints as a tuple, but fails if I pass the constraints one after the other (curried).
```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import Data.Proxy
import GHC.TypeLits
newtype Modulo a (n :: Nat) = Mod a
pattern Works :: forall n a. (Integral a , KnownNat n) => a -> Modulo a n
pattern Works a <- Mod a where
Works a = Mod $ mod a $ fromIntegral $ natVal $ Proxy @n
-- No instance for (KnownNat n) arising from the "provided" constraints
pattern Fails :: forall n a. Integral a => KnownNat n => a -> Modulo a n
pattern Fails a <- Mod a where
Fails a = Mod $ mod a $ fromIntegral $ natVal $ Proxy @n
-- No instance for (Integral a) arising from the "provided" constraints
pattern Fails2 :: forall n a. KnownNat n => Integral a => a -> Modulo a n
pattern Fails2 a <- Mod a where
Fails2 a = Mod $ mod a $ fromIntegral $ natVal $ Proxy @n
```
So, isn't `C1 => C2 => a -> b` the same as `(C1, C2) => a -> b`?
This is on GHC 8.0 - GHC 9.2.2 (same error always).
Maybe related: #12975