GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2021-10-14T08:39:12Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/15683coerce fails for Coercible type families2021-10-14T08:39:12ZIcelandjackcoerce fails for Coercible type familiesI want to bring attention to this [reddit post](https://www.reddit.com/r/haskell/comments/9io4xw/coercing_type_families_when_type_instances_are/) that boils down to
```hs
type family X a
type instance X Int = String
type instance X B...I want to bring attention to this [reddit post](https://www.reddit.com/r/haskell/comments/9io4xw/coercing_type_families_when_type_instances_are/) that boils down to
```hs
type family X a
type instance X Int = String
type instance X Bool = String
data T a = T (X a)
```
but not being able to coerce
```hs
coerce :: T Int -> T Bool
```
This gives the error “Couldn't match type ‘`Int`’ with ‘`Bool`’ arising from a use of ‘`coerce`’”.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"coerce fails for Coercible type families","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":["TypeFamilies"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I want to bring attention to this [https://www.reddit.com/r/haskell/comments/9io4xw/coercing_type_families_when_type_instances_are/ reddit post] that boils down to \r\n\r\n{{{#!hs\r\ntype family X a\r\ntype instance X Int = String\r\ntype instance X Bool = String\r\n\r\ndata T a = T (X a)\r\n}}}\r\n\r\nbut not being able to coerce\r\n\r\n{{{#!hs\r\ncoerce :: T Int -> T Bool\r\n}}}\r\n\r\nThis gives the error “Couldn't match type ‘`Int`’ with ‘`Bool`’ arising from a use of ‘`coerce`’”.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15540GHCi does not follow the XDG Base Directory Specification2021-04-01T11:23:17ZRichard SzibeleGHCi does not follow the XDG Base Directory SpecificationHello,
GHCi does not follow the XDG Base Directory Specification by default on GNU/Linux based operating systems.
It creates for instance the file $HOME/.ghc/ghci_history which belongs in $XDG_CACHE_HOME/ghc/ , or $HOME/.cache/ghc/ if ...Hello,
GHCi does not follow the XDG Base Directory Specification by default on GNU/Linux based operating systems.
It creates for instance the file $HOME/.ghc/ghci_history which belongs in $XDG_CACHE_HOME/ghc/ , or $HOME/.cache/ghc/ if $XDG_CACHE_HOME is not set.
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.0.2
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.0.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHCi does not follow the XDG Base Directory Specification","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Hello,\r\n\r\nGHCi does not follow the XDG Base Directory Specification by default on GNU/Linux based operating systems.\r\n\r\nIt creates for instance the file $HOME/.ghc/ghci_history which belongs in $XDG_CACHE_HOME/ghc/ , or $HOME/.cache/ghc/ if $XDG_CACHE_HOME is not set.\r\n\r\n$ ghci --version\r\nThe Glorious Glasgow Haskell Compilation System, version 8.0.2","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/14335Plugins don't work with -fexternal-interpreter2023-08-08T13:45:03ZBen GamariPlugins don't work with -fexternal-interpreterPlugins don't work with -fexternal-interpreter.
The current plan to fix this is to enable GHC to always use the internal interpreter for plugins, even when `-fexternal-interpreter` is given. `-fexternal-interpreter` only determines whic...Plugins don't work with -fexternal-interpreter.
The current plan to fix this is to enable GHC to always use the internal interpreter for plugins, even when `-fexternal-interpreter` is given. `-fexternal-interpreter` only determines which interpreter is used for running Template Haskell splices. The following tasks have been identified:
- [X] Support loading two different `UnitState` (available units): one for the target, one for plugins
- [ ] Add command-line flags (`-plugin-package-db`, etc.) to build the plugins UnitState
- [ ] Refactor many functions to explicitly pass Platform configuration (Platform, ways, etc.) as arguments. Currently we often pass `DynFlags` and callee functions implicitly use the `UnitState` of the target platform. It doesn't compose well and we want to be explicit about the platform we are using (target or host) (see also #17957).
- [x] Pretty-printing of `Unit` (via its `Outputable` instance) implicitly queries the `UnitState` of the target platform (via `sdocWithDynFlags`). We need to remove this `Outputable` instance.8.6.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/10346Cross-module SpecConstr2022-05-12T20:34:01ZSimon Peyton JonesCross-module SpecConstrType-class specialisation now happens flawlessly across modules. That is, if I define
```
module DefineF where
f :: Num a => a -> a
{-# INLINEABLE f #-}
f x = ...f x'....
```
then modules that import `DefineF` and call `f` at ...Type-class specialisation now happens flawlessly across modules. That is, if I define
```
module DefineF where
f :: Num a => a -> a
{-# INLINEABLE f #-}
f x = ...f x'....
```
then modules that import `DefineF` and call `f` at some particular type (say `Int`) will generate a specialised copy of `f`'s code.
But this does not happen for `SpecConstr`; we only specialise a function for calls made in the same module. For example:
```
module M where
{-# INLINABLE foo #-}
foo True y = y
foo False (a,b) = foo True (a+b,b)
module X where
import M
bar = ...(foo (x,y))...
```
Here `foo` is called with an explicit `(x,y)` argument in module `X`, and we'd like to !SpecConstr it, as it would be if the call was in module `M`.
All the infrastructure is in place to allow cross-module `SpecConstr`; it just hasn't been done yet. This ticket is to record the idea.8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15680Flag for printing absolute paths in diagnostics2022-11-20T11:19:42ZquasicomputationalFlag for printing absolute paths in diagnosticsCurrently, GHC will produce errors and warnings with relative paths pointing to the input that caused it.
This is less than ideal for any tooling consuming these diagnostics, because build tools will concurrently build many packages in ...Currently, GHC will produce errors and warnings with relative paths pointing to the input that caused it.
This is less than ideal for any tooling consuming these diagnostics, because build tools will concurrently build many packages in different working directories and interleave the output from multiple GHC invocations.
In particular, this makes using `next-error` in emacs a lot less useful than it could be with cabal-install's output.
[Stack has some rather hackish code to post-process the diagnostics and to turn the relative paths absolute.](https://github.com/commercialhaskell/stack/blob/0740444175f41e6ea5ed236cd2c53681e4730003/src/Stack/Build/Execute.hs#L1896) I can personally report that this makes the development process a lot more pleasant!
I think it'd be much cleaner to have a GHC flag for this at the source. `-fabsolute-diagnostic-paths` or something similar, subject to bikeshedding.
I had a look at implementing this myself, and `mkLocMessageAnn` in `ErrUtils` would be the locus of the change. However, I can't figure out how that function should learn what the current working directory is! Any tips? Is that information lurking somewhere in `DynFlags`?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Flag for printing absolute paths in diagnostics","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Currently, GHC will produce errors and warnings with relative paths pointing to the input that caused it.\r\n\r\nThis is less than ideal for any tooling consuming these diagnostics, because build tools will concurrently build many packages in different working directories and interleave the output from multiple GHC invocations.\r\n\r\nIn particular, this makes using `next-error` in emacs a lot less useful than it could be with cabal-install's output.\r\n\r\n[https://github.com/commercialhaskell/stack/blob/0740444175f41e6ea5ed236cd2c53681e4730003/src/Stack/Build/Execute.hs#L1896 Stack has some rather hackish code to post-process the diagnostics and to turn the relative paths absolute.] I can personally report that this makes the development process a lot more pleasant!\r\n\r\nI think it'd be much cleaner to have a GHC flag for this at the source. `-fabsolute-diagnostic-paths` or something similar, subject to bikeshedding.\r\n\r\nI had a look at implementing this myself, and `mkLocMessageAnn` in `ErrUtils` would be the locus of the change. However, I can't figure out how that function should learn what the current working directory is! Any tips? Is that information lurking somewhere in `DynFlags`?","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15573Make bindings with multiple occurrences a join point instead of duplicating c...2019-07-07T18:04:04ZAndreas KlebingerMake bindings with multiple occurrences a join point instead of duplicating code during inlining.I have some intermediate core of the form:
```
-- RHS size: {terms: 9, types: 2, coercions: 0, joins: 0/0}
cseAlts_s1dD [Occ=Once!T[1]] :: T -> Int#
[LclId, CallArity=1, Str=<S,1*U>]
cseAlts_s1dD
= \ (lamVar_s1dw [Occ=Once!, Dmd=<S,1*...I have some intermediate core of the form:
```
-- RHS size: {terms: 9, types: 2, coercions: 0, joins: 0/0}
cseAlts_s1dD [Occ=Once!T[1]] :: T -> Int#
[LclId, CallArity=1, Str=<S,1*U>]
cseAlts_s1dD
= \ (lamVar_s1dw [Occ=Once!, Dmd=<S,1*U>, OS=OneShot] :: T) ->
case lamVar_s1dw of wild_Xc [Dmd=<L,A>] {
__DEFAULT -> 1#;
B -> 2#;
C -> 3#
}
-- RHS size: {terms: 14, types: 3, coercions: 0, joins: 0/0}
$wfmerge_s1cZ [InlPrag=NOUSERINLINE[0]] :: T -> T -> Int#
[LclId, Arity=2, CallArity=2, Str=<S,1*U><L,1*U>]
$wfmerge_s1cZ
= \ (w_s1cU [Occ=Once!, Dmd=<S,1*U>] :: T)
(w_s1cV [Occ=Once*, Dmd=<L,1*U>] :: T) ->
case w_s1cU of wild_XA [Dmd=<L,A>] {
__DEFAULT -> -1#;
A -> 2#;
B -> cseAlts_s1dD w_s1cV;
C -> cseAlts_s1dD w_s1cV
}
```
Which after the simplifier ran got inlined into the branches to give us:
```
fmerge
= \ (w_s1cU :: T) (w_s1cV :: T) ->
case w_s1cU of {
__DEFAULT -> GHC.Types.I# -1#;
A -> GHC.Types.I# 2#;
B ->
case w_s1cV of {
__DEFAULT -> GHC.Types.I# 1#;
B -> GHC.Types.I# 2#;
C -> GHC.Types.I# 3#
};
C ->
case w_s1cV of {
__DEFAULT -> GHC.Types.I# 1#;
B -> GHC.Types.I# 2#;
C -> GHC.Types.I# 3#
}
}
```
What I would really like GHC to do instead though is to make `cseAlts_s1dD` a join point when possible.
This would eliminate both the call overhead AND the call duplication.
The current behavior seems fine when we can't make it a join point. But when we can we should try to take advantage of that opportunity.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.4.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make bindings with multiple occurrences a join point instead of duplicating code during inlining.","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":["JoinPoints"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"I have some intermediate core of the form:\r\n\r\n{{{\r\n-- RHS size: {terms: 9, types: 2, coercions: 0, joins: 0/0}\r\ncseAlts_s1dD [Occ=Once!T[1]] :: T -> Int#\r\n[LclId, CallArity=1, Str=<S,1*U>]\r\ncseAlts_s1dD\r\n = \\ (lamVar_s1dw [Occ=Once!, Dmd=<S,1*U>, OS=OneShot] :: T) ->\r\n case lamVar_s1dw of wild_Xc [Dmd=<L,A>] {\r\n __DEFAULT -> 1#;\r\n B -> 2#;\r\n C -> 3#\r\n }\r\n\r\n-- RHS size: {terms: 14, types: 3, coercions: 0, joins: 0/0}\r\n$wfmerge_s1cZ [InlPrag=NOUSERINLINE[0]] :: T -> T -> Int#\r\n[LclId, Arity=2, CallArity=2, Str=<S,1*U><L,1*U>]\r\n$wfmerge_s1cZ\r\n = \\ (w_s1cU [Occ=Once!, Dmd=<S,1*U>] :: T)\r\n (w_s1cV [Occ=Once*, Dmd=<L,1*U>] :: T) ->\r\n case w_s1cU of wild_XA [Dmd=<L,A>] {\r\n __DEFAULT -> -1#;\r\n A -> 2#;\r\n B -> cseAlts_s1dD w_s1cV;\r\n C -> cseAlts_s1dD w_s1cV\r\n }\r\n}}}\r\n\r\nWhich after the simplifier ran got inlined into the branches to give us:\r\n\r\n{{{\r\nfmerge\r\n = \\ (w_s1cU :: T) (w_s1cV :: T) ->\r\n case w_s1cU of {\r\n __DEFAULT -> GHC.Types.I# -1#;\r\n A -> GHC.Types.I# 2#;\r\n B ->\r\n case w_s1cV of {\r\n __DEFAULT -> GHC.Types.I# 1#;\r\n B -> GHC.Types.I# 2#;\r\n C -> GHC.Types.I# 3#\r\n };\r\n C ->\r\n case w_s1cV of {\r\n __DEFAULT -> GHC.Types.I# 1#;\r\n B -> GHC.Types.I# 2#;\r\n C -> GHC.Types.I# 3#\r\n }\r\n }\r\n}}}\r\n\r\nWhat I would really like GHC to do instead though is to make `cseAlts_s1dD` a join point when possible.\r\nThis would eliminate both the call overhead AND the call duplication.\r\n\r\nThe current behavior seems fine when we can't make it a join point. But when we can we should try to take advantage of that opportunity.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15521Provide a strict version of sum2019-07-07T18:04:19ZdnadalesProvide a strict version of sumWhen adding huge list of numbers, a strict version of `sum` is preferred to avoid an unnecessary use of memory. A strict version of `sum` can be easily written using `foldl'` but it'd be nicer if a function such as:
```hs
sum' = foldl' ...When adding huge list of numbers, a strict version of `sum` is preferred to avoid an unnecessary use of memory. A strict version of `sum` can be easily written using `foldl'` but it'd be nicer if a function such as:
```hs
sum' = foldl' (+) 0
```
would be provided in the prelude already.
Does this makes sense?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.4.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Prelude |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Provide a strict version of sum","status":"New","operating_system":"","component":"Prelude","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"When adding huge list of numbers, a strict version of `sum` is preferred to avoid an unnecessary use of memory. A strict version of `sum` can be easily written using `foldl'` but it'd be nicer if a function such as:\r\n\r\n{{{#!hs\r\nsum' = foldl' (+) 0\r\n}}}\r\n\r\nwould be provided in the prelude already. \r\n\r\nDoes this makes sense?","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15412"Instance head is not headed by a class" when `Constraint` replaced with `typ...2019-07-07T18:05:02ZIcelandjack"Instance head is not headed by a class" when `Constraint` replaced with `type C = Constraint````hs
{-# Language DataKinds, TypeInType, TypeFamilies #-}
import Data.Kind
newtype I a = I a
type C = Constraint
type family
UnitC :: Constraint where
UnitC = ()
instance UnitC => Functor I where
fmap = undefined
```
this w...```hs
{-# Language DataKinds, TypeInType, TypeFamilies #-}
import Data.Kind
newtype I a = I a
type C = Constraint
type family
UnitC :: Constraint where
UnitC = ()
instance UnitC => Functor I where
fmap = undefined
```
this works fine, but if I try to use the constraint synonym `C` (`UnitC :: C where`) fails with "Instance head is not headed by a class" which has **no** Google hits outside of the [compiler](https://hackage.haskell.org/package/ghc-8.4.1/docs/src/TcValidity.html#checkValidInstance)
```
$ ghci -ignore-dot-ghci hs/249.hs
GHCi, version 8.5.20180128: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( hs/249.hs, interpreted )
hs/249.hs:13:10: error:
• Instance head is not headed by a class
• In the instance declaration for ‘Functor I’
|
13 | instance UnitC => Functor I where
| ^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
Prelude>
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.4.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"\"Instance head is not headed by a class\" when `Constraint` replaced with `type C = Constraint`","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{-# Language DataKinds, TypeInType, TypeFamilies #-}\r\n\r\nimport Data.Kind\r\n\r\nnewtype I a = I a\r\n\r\ntype C = Constraint\r\n\r\ntype family\r\n UnitC :: Constraint where\r\n UnitC = ()\r\n\r\ninstance UnitC => Functor I where\r\n fmap = undefined \r\n}}}\r\n\r\nthis works fine, but if I try to use the constraint synonym `C` (`UnitC :: C where`) fails with \"Instance head is not headed by a class\" which has '''no''' Google hits outside of the [https://hackage.haskell.org/package/ghc-8.4.1/docs/src/TcValidity.html#checkValidInstance compiler]\r\n\r\n{{{\r\n$ ghci -ignore-dot-ghci hs/249.hs\r\nGHCi, version 8.5.20180128: http://www.haskell.org/ghc/ :? for help\r\n[1 of 1] Compiling Main ( hs/249.hs, interpreted )\r\n\r\nhs/249.hs:13:10: error:\r\n • Instance head is not headed by a class\r\n • In the instance declaration for ‘Functor I’\r\n |\r\n13 | instance UnitC => Functor I where\r\n | ^^^^^^^^^^^^^^^^^^\r\nFailed, no modules loaded.\r\nPrelude> \r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/14473Implement Underscores in Numeric Literals Proposal (NumericUnderscores extens...2019-07-07T18:16:53ZTakenobu TaniImplement Underscores in Numeric Literals Proposal (NumericUnderscores extension)Implement Underscores in Numeric Literals Proposal.
GHC supports various numeric literals such as decimal, octal, hexadecimal, binary, and floating point numbers. However, large numeric literals are hard to read. This proposal improves ...Implement Underscores in Numeric Literals Proposal.
GHC supports various numeric literals such as decimal, octal, hexadecimal, binary, and floating point numbers. However, large numeric literals are hard to read. This proposal improves the readability, quality, expressiveness of numeric literals.
This proposal allows underscores to numeric literals when the `NumericUnderscores` language extension is enabled.
Underscores (`_`) in numeric literals are simply ignored.
The specification of the feature is available here:\\\\
https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0009-numeric-underscores.rst
For a discussion:\\\\
https://github.com/ghc-proposals/ghc-proposals/pull/76
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Implement Underscores in Numeric Literals Proposal (NumericUnderscores extension)","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Implement Underscores in Numeric Literals Proposal.\r\n\r\nGHC supports various numeric literals such as decimal, octal, hexadecimal, binary, and floating point numbers. However, large numeric literals are hard to read. This proposal improves the readability, quality, expressiveness of numeric literals.\r\n\r\nThis proposal allows underscores to numeric literals when the `NumericUnderscores` language extension is enabled.\r\nUnderscores (`_`) in numeric literals are simply ignored.\r\n\r\nThe specification of the feature is available here:\\\\\r\nhttps://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0009-numeric-underscores.rst\r\n\r\nFor a discussion:\\\\\r\nhttps://github.com/ghc-proposals/ghc-proposals/pull/76","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1Takenobu TaniTakenobu Tanihttps://gitlab.haskell.org/ghc/ghc/-/issues/10933REMOVED pragma2022-03-22T18:32:58ZRichard Eisenbergrae@richarde.devREMOVED pragmaSay I have a function that's been deprecated for some time. Then I remove it. Some clients will still use the now-missing function. It would be nice to give a helpful error message, instead of a "symbol not found" error.
I thus propose ...Say I have a function that's been deprecated for some time. Then I remove it. Some clients will still use the now-missing function. It would be nice to give a helpful error message, instead of a "symbol not found" error.
I thus propose a `REMOVED` pragma. The syntax is identical to `DEPRECATED`, except for the name of the pragma. Whenever a `REMOVED` function is mentioned, the error message includes the string from the pragma. (This includes trying to define a `REMOVED` class method in an instance.)
See https://gitlab.haskell.org/ghc/ghc/-/wikis/design/deprecation-mechanisms for more info and related efforts.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.10.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"REMOVED pragma","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Say I have a function that's been deprecated for some time. Then I remove it. Some clients will still use the now-missing function. It would be nice to give a helpful error message, instead of a \"symbol not found\" error.\r\n\r\nI thus propose a `REMOVED` pragma. The syntax is identical to `DEPRECATED`, except for the name of the pragma. Whenever a `REMOVED` function is mentioned, the error message includes the string from the pragma. (This includes trying to define a `REMOVED` class method in an instance.)\r\n\r\nSee Design/DeprecationMechanisms for more info and related efforts.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/4879Deprecate exports (in modules)2023-08-18T13:53:25ZbasvandijkDeprecate exports (in modules)*Since this was originally written, https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0134-deprecating-exports-proposal.rst was created and approved formalizing the feature we want. The rest of this is subsumed by that...*Since this was originally written, https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0134-deprecating-exports-proposal.rst was created and approved formalizing the feature we want. The rest of this is subsumed by that and just for historical interest.*
------
## Motivation
During the library submission process there's sometimes the desire to have the ability to deprecate an export from a module.
For example [during the discussing](http://article.gmane.org/gmane.comp.lang.haskell.libraries/14524) about ticket #4422, I would have liked the ability to deprecate the exports of the `String` functions: `lines`, `words`, `unlines` and `unwords` from `Data.List` in favour of importing them from `Data.String`. However I wasn't able to do so, so these exports remain.
Similarly, [during the discussion](http://article.gmane.org/gmane.comp.lang.haskell.libraries/14925) about ticket #4865, Ian also desired to deprecate the export of `catch` from `System.IO.Error` but was unable to do so.
## Syntax
To deprecate an export simply place a `DEPRECATE` pragma for the export inside the export list, as in:
```
module Data.List
( ...
{-# DEPRECATE lines "Exported from Data.String instead" #-}
, lines
...
) where
...
```
Another design might be to have a different pragma as in:
```
{-# DEPRECATE_EXPORT lines "Exported from Data.String instead" #-}
```
But I find the former much prettier and more obvious.
## Semantics
If the `lines` export from `Data.List` is deprecated the following should raise deprecation warnings:
- Directly importing a deprecated export:
```
import Data.List (lines)
```
- Referring to a deprecated export:
```
import Data.List
foo = lines
```
If you import the same symbol from different modules and only some of them are deprecated exports then referring to the symbol won't give a deprecation warning. For example the following should not give deprecation warnings:
```
import Data.List
import Data.String
foo = lines
```
### What exports can be deprecated?
- Functions.
- Types.
- Classes.
- Constructors. Possible syntax:
```
module A
( {-# DEPRECATE T(C1) "The export of C1 is deprecated" #-}
T(C1, C2, C3)
) where
```
- Modules. Possible syntax:
```
module A
( {-# DEPRECATE module B "The export of module B is deprecated" #-}
module B
) where
```
The semantics of deprecating a module export is that you get deprecation warnings for all symbols from module `B` that you refer to inside a module that imports `A`. (Does that make sense?)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.0.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Deprecate exports","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"== Motivation ==\r\nDuring the library submission process there's sometimes the desire to have the ability to deprecate an export from a module.\r\n\r\nFor example [http://article.gmane.org/gmane.comp.lang.haskell.libraries/14524 during the discussing] about ticket #4422, I would have liked the ability to deprecate the exports of the `String` functions: `lines`, `words`, `unlines` and `unwords` from `Data.List` in favour of importing them from `Data.String`. However I wasn't able to do so, so these exports remain.\r\n\r\nSimilarly, [http://article.gmane.org/gmane.comp.lang.haskell.libraries/14925 during the discussion] about ticket #4865, Ian also desired to deprecate the export of `catch` from `System.IO.Error` but was unable to do so.\r\n\r\n== Syntax ==\r\n\r\nTo deprecate an export simply place a `DEPRECATE` pragma for the export inside the export list, as in: \r\n\r\n{{{\r\nmodule Data.List\r\n ( ...\r\n {-# DEPRECATE lines \"Exported from Data.String instead\" #-}\r\n , lines\r\n ...\r\n ) where\r\n...\r\n}}}\r\n\r\nAnother design might be to have a different pragma as in:\r\n\r\n{{{\r\n{-# DEPRECATE_EXPORT lines \"Exported from Data.String instead\" #-}\r\n}}}\r\n\r\nBut I find the former much prettier and more obvious.\r\n\r\n== Semantics ==\r\n\r\nIf the `lines` export from `Data.List` is deprecated the following should raise deprecation warnings:\r\n\r\n * Directly importing a deprecated export:\r\n{{{\r\nimport Data.List (lines)\r\n}}}\r\n\r\n * Referring to a deprecated export:\r\n{{{\r\nimport Data.List\r\nfoo = lines\r\n}}}\r\n\r\nIf you import the same symbol from different modules and only some of them are deprecated exports then referring to the symbol won't give a deprecation warning. For example the following should not give deprecation warnings:\r\n\r\n{{{\r\nimport Data.List\r\nimport Data.String\r\nfoo = lines\r\n}}}\r\n\r\n=== What exports can be deprecated? ===\r\n\r\n * Functions.\r\n * Types.\r\n * Classes.\r\n * Constructors. Possible syntax:\r\n{{{\r\nmodule A\r\n ( {-# DEPRECATE T(C1) \"The export of C1 is deprecated\" #-}\r\n T(C1, C2, C3)\r\n ) where\r\n}}}\r\n * Modules. Possible syntax:\r\n{{{\r\nmodule A\r\n ( {-# DEPRECATE module B \"The export of module B is deprecated\" #-}\r\n module B\r\n ) where\r\n}}}\r\nThe semantics of deprecating a module export is that you get deprecation warnings for all symbols from module `B` that you refer to inside a module that imports `A`. (Does that make sense?)","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15707More liberally kinded coercions for newtypes2019-07-07T18:03:21ZmniipMore liberally kinded coercions for newtypesConsider the infinite data family (possible thanks to #12369):
```hs
data family I :: k -> k
newtype instance I a = I0 (a)
newtype instance I a x = I1 (a x)
newtype instance I a x y = I2 (a x y)
newtype instance I a x y z = I3 (a x y z)...Consider the infinite data family (possible thanks to #12369):
```hs
data family I :: k -> k
newtype instance I a = I0 (a)
newtype instance I a x = I1 (a x)
newtype instance I a x y = I2 (a x y)
newtype instance I a x y z = I3 (a x y z)
...
```
We end up with a family of eta-contracted coercions:
```hs
forall (a :: *). a ~R I a
forall (a :: k -> *). a ~R I a
forall (a :: k -> l -> *). a ~R I a
forall (a :: k -> l -> m -> *). a ~R I a
...
```
What if we could somehow indicate that we desire a polykinded newtype (so to speak) with a coercion `forall (a :: k). a ~R I a`
Maybe even do so by default: `newtype I a = I0 a` would create such a polykinded coercion. Though the `I0` data constructor and pattern would still only use the \*-kinded restriction of it.
We could then recover other constructors with:
```hs
i1 :: a x -> I a x
i1 = coerce
...
```8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15705Confusing parser error in 8.62020-02-24T21:36:31ZIavor S. DiatchkiConfusing parser error in 8.6Consider the following example:
```
f x =
case x of
A -> 'a'
B -> 'b'
```
The problem here is that `B` is misaligned, which is quite a common mistake, especially in a bigger case block.
GHC reports the following error:
```
...Consider the following example:
```
f x =
case x of
A -> 'a'
B -> 'b'
```
The problem here is that `B` is misaligned, which is quite a common mistake, especially in a bigger case block.
GHC reports the following error:
```
Unexpected case expression in function application:
case x of { A -> 'a' }
You could write it with parentheses
Or perhaps you meant to enable BlockArguments?
```
This is quite confusing, especially since the program won't parse, `BlockArguments` or not. My guess is that we are being a bit too eager with reporting the `BlockArguments` issue.
One way to work around this would be to just remember if we used `BlockArguments` while parsing, but only do the check that the extension is enabled after a successful parse.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Parser) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Confusing parser error in 8.6","status":"New","operating_system":"","component":"Compiler (Parser)","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following example:\r\n{{{\r\nf x =\r\n case x of\r\n A -> 'a'\r\n B -> 'b'\r\n}}}\r\n\r\nThe problem here is that `B` is misaligned, which is quite a common mistake, especially in a bigger case block.\r\n\r\nGHC reports the following error:\r\n{{{\r\n Unexpected case expression in function application:\r\n case x of { A -> 'a' }\r\n You could write it with parentheses\r\n Or perhaps you meant to enable BlockArguments?\r\n}}}\r\nThis is quite confusing, especially since the program won't parse, `BlockArguments` or not. My guess is that we are being a bit too eager with reporting the `BlockArguments` issue.\r\n\r\nOne way to work around this would be to just remember if we used `BlockArguments` while parsing, but only do the check that the extension is enabled after a successful parse.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15704Different saturations of the same polymorphic-kinded type constructor aren't ...2019-07-07T18:03:22ZmniipDifferent saturations of the same polymorphic-kinded type constructor aren't seen as apart types```hs
{-# LANGUAGE TypeFamilies, PolyKinds #-}
module A where
data family D :: k
type family F (a :: k) :: *
type instance F (D Int) = Int
type instance F (f a b) = Char
type instance F (D Int Bool) = Char
```
The last equation, eve...```hs
{-# LANGUAGE TypeFamilies, PolyKinds #-}
module A where
data family D :: k
type family F (a :: k) :: *
type instance F (D Int) = Int
type instance F (f a b) = Char
type instance F (D Int Bool) = Char
```
The last equation, even though a specialization of the middle one, trips up the equality consistency check:
```hs
a.hs:9:15: error:
Conflicting family instance declarations:
F (D Int) = Int -- Defined at a.hs:9:15
F (D Int Bool) = Char -- Defined at a.hs:10:15
|
9 | type instance F (D Int) = Int
| ^
```
So GHC is able to infer that `D Int ~/~ f a b` because `D ~/~ f a`, but for some reason the same reasoning doesn't work for `D ~/~ D a`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Different saturations of the same polymorphic-kinded type constructor aren't seen as apart types","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":["TypeFamilies"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{-# LANGUAGE TypeFamilies, PolyKinds #-}\r\n\r\nmodule A where\r\n\r\ndata family D :: k\r\n\r\ntype family F (a :: k) :: *\r\n\r\ntype instance F (D Int) = Int\r\ntype instance F (f a b) = Char\r\ntype instance F (D Int Bool) = Char\r\n}}}\r\n\r\nThe last equation, even though a specialization of the middle one, trips up the equality consistency check:\r\n{{{#!hs\r\na.hs:9:15: error:\r\n Conflicting family instance declarations:\r\n F (D Int) = Int -- Defined at a.hs:9:15\r\n F (D Int Bool) = Char -- Defined at a.hs:10:15\r\n |\r\n9 | type instance F (D Int) = Int\r\n | ^\r\n}}}\r\n\r\nSo GHC is able to infer that `D Int ~/~ f a b` because `D ~/~ f a`, but for some reason the same reasoning doesn't work for `D ~/~ D a`.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1mniipmniiphttps://gitlab.haskell.org/ghc/ghc/-/issues/15699Run sanity checker in more testsuite runs2019-07-07T18:03:23ZBen GamariRun sanity checker in more testsuite runsEvery testsuite run should run at least a subset of tests with the sanity checker enabled.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- ...Every testsuite run should run at least a subset of tests with the sanity checker enabled.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- |
| Version | 8.4.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Continuous Integration |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Run sanity checker in more testsuite runs","status":"New","operating_system":"","component":"Continuous Integration","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"bgamari"},"version":"8.4.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Every testsuite run should run at least a subset of tests with the sanity checker enabled.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/15698SingleEntry update flag for Stg bindings is not used2019-07-07T18:03:23ZÖmer Sinan AğacanSingleEntry update flag for Stg bindings is not usedI was looking at code generation for bindings with different update flags. Update flag type is defined as:
```
data UpdateFlag = ReEntrant | Updatable | SingleEntry
```
I realized that we don't care about the difference between `ReEntr...I was looking at code generation for bindings with different update flags. Update flag type is defined as:
```
data UpdateFlag = ReEntrant | Updatable | SingleEntry
```
I realized that we don't care about the difference between `ReEntrant` and `SingleEntry`, we only care about whether a binding is updatable or not, which is defined as
```
isUpdatable :: UpdateFlag -> Bool
isUpdatable ReEntrant = False
isUpdatable SingleEntry = False
isUpdatable Updatable = True
```
So we could remove `SingleEntry` and replace all uses of it with `ReEntrant` and everything would work the same.
This raises the question of whether we're missing an optimisation in the code generator. Looking at code generation differences of updatable and non-updatable bindings, it seems like for a thunk (a binding with no arguments) we generate a thunk header and push an update frame regardless of the update flag. As far as I can see, update flag is only used when generating AP and selector thunks (we don't generate AP or selector thunks if the binding is not updatable).
My question is: it seems to me that if a thunk is single entry then we should be able to give it a non-thunk type (maybe FUN?) and avoid pushing an update frame in `closureCodeBody`. Am I missing anything or is this possible? Is this worth trying?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | lowest |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"SingleEntry update flag for Stg bindings is not used","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"I was looking at code generation for bindings with different update flags. Update flag type is defined as:\r\n\r\n{{{\r\ndata UpdateFlag = ReEntrant | Updatable | SingleEntry\r\n}}}\r\n\r\nI realized that we don't care about the difference between `ReEntrant` and `SingleEntry`, we only care about whether a binding is updatable or not, which is defined as\r\n\r\n{{{\r\nisUpdatable :: UpdateFlag -> Bool\r\nisUpdatable ReEntrant = False\r\nisUpdatable SingleEntry = False\r\nisUpdatable Updatable = True\r\n}}}\r\n\r\nSo we could remove `SingleEntry` and replace all uses of it with `ReEntrant` and everything would work the same.\r\n\r\nThis raises the question of whether we're missing an optimisation in the code generator. Looking at code generation differences of updatable and non-updatable bindings, it seems like for a thunk (a binding with no arguments) we generate a thunk header and push an update frame regardless of the update flag. As far as I can see, update flag is only used when generating AP and selector thunks (we don't generate AP or selector thunks if the binding is not updatable).\r\n\r\n\r\nMy question is: it seems to me that if a thunk is single entry then we should be able to give it a non-thunk type (maybe FUN?) and avoid pushing an update frame in `closureCodeBody`. Am I missing anything or is this possible? Is this worth trying?","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15697Typed holes inferring a more polymorphic type2019-07-08T11:15:20ZsreenidhiTyped holes inferring a more polymorphic typeConsider these two snippets.
```hs
testFailure :: Char
testFailure =
let x = id _
in x
```
Suggestions provided were
```
/home/sreenidhi/Experiments/TypedHole.hs:3:14: error:
• Found hole: _ :: a
Where: ‘a’ is a rigid t...Consider these two snippets.
```hs
testFailure :: Char
testFailure =
let x = id _
in x
```
Suggestions provided were
```
/home/sreenidhi/Experiments/TypedHole.hs:3:14: error:
• Found hole: _ :: a
Where: ‘a’ is a rigid type variable bound by
the inferred type of x :: a
at /home/sreenidhi/Experiments/TypedHole.hs:3:7-14
• In the first argument of ‘id’, namely ‘_’
In the expression: id _
In an equation for ‘x’: x = id _
• Relevant bindings include
x :: a (bound at /home/sreenidhi/Experiments/TypedHole.hs:3:7)
testFailure :: Char
(bound at /home/sreenidhi/Experiments/TypedHole.hs:2:1)
```
whereas for this one
```hs
testSuccess :: Char
testSuccess = _
```
It correctly suggests
```
/home/sreenidhi/Experiments/TypedHole.hs:7:15: error:
• Found hole: _ :: Char
• In the expression: _
In an equation for ‘testSuccess’: testSuccess = _
• Relevant bindings include
testSuccess :: Char
(bound at /home/sreenidhi/Experiments/TypedHole.hs:7:1)
Valid hole fits include
testSuccess :: Char
(bound at /home/sreenidhi/Experiments/TypedHole.hs:7:1)
testFailure :: Char
(defined at /home/sreenidhi/Experiments/TypedHole.hs:2:1)
maxBound :: forall a. Bounded a => a
with maxBound @Char
(imported from ‘Prelude’ at /home/sreenidhi/Experiments/TypedHole.hs:1:1
(and originally defined in ‘GHC.Enum’))
minBound :: forall a. Bounded a => a
with minBound @Char
(imported from ‘Prelude’ at /home/sreenidhi/Experiments/TypedHole.hs:1:1
(and originally defined in ‘GHC.Enum’))
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Typed holes inferring a more polymorphic type","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider these two snippets.\r\n\r\n{{{#!hs\r\ntestFailure :: Char\r\ntestFailure =\r\n let x = id _\r\n in x\r\n}}}\r\n\r\n\r\nSuggestions provided were\r\n{{{\r\n/home/sreenidhi/Experiments/TypedHole.hs:3:14: error:\r\n • Found hole: _ :: a\r\n Where: ‘a’ is a rigid type variable bound by\r\n the inferred type of x :: a\r\n at /home/sreenidhi/Experiments/TypedHole.hs:3:7-14\r\n • In the first argument of ‘id’, namely ‘_’\r\n In the expression: id _\r\n In an equation for ‘x’: x = id _\r\n • Relevant bindings include\r\n x :: a (bound at /home/sreenidhi/Experiments/TypedHole.hs:3:7)\r\n testFailure :: Char\r\n (bound at /home/sreenidhi/Experiments/TypedHole.hs:2:1)\r\n\r\n}}}\r\n\r\nwhereas for this one\r\n\r\n{{{#!hs\r\ntestSuccess :: Char\r\ntestSuccess = _\r\n}}}\r\n\r\nIt correctly suggests\r\n\r\n{{{\r\n/home/sreenidhi/Experiments/TypedHole.hs:7:15: error:\r\n • Found hole: _ :: Char\r\n • In the expression: _\r\n In an equation for ‘testSuccess’: testSuccess = _\r\n • Relevant bindings include\r\n testSuccess :: Char\r\n (bound at /home/sreenidhi/Experiments/TypedHole.hs:7:1)\r\n Valid hole fits include\r\n testSuccess :: Char\r\n (bound at /home/sreenidhi/Experiments/TypedHole.hs:7:1)\r\n testFailure :: Char\r\n (defined at /home/sreenidhi/Experiments/TypedHole.hs:2:1)\r\n maxBound :: forall a. Bounded a => a\r\n with maxBound @Char\r\n (imported from ‘Prelude’ at /home/sreenidhi/Experiments/TypedHole.hs:1:1\r\n (and originally defined in ‘GHC.Enum’))\r\n minBound :: forall a. Bounded a => a\r\n with minBound @Char\r\n (imported from ‘Prelude’ at /home/sreenidhi/Experiments/TypedHole.hs:1:1\r\n (and originally defined in ‘GHC.Enum’))\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15694GHC panic from pattern synonym, "Type-correct unfilled coercion hole"2019-07-07T18:03:25ZIcelandjackGHC panic from pattern synonym, "Type-correct unfilled coercion hole"```hs
{-# Language RankNTypes, PatternSynonyms, TypeOperators, DataKinds, PolyKinds, KindSignatures, GADTs #-}
import Data.Kind
import Data.Type.Equality
data Ctx :: Type -> Type where
E :: Ctx(Type)
(:&:) :: a -> Ctx(as) -> Ctx(...```hs
{-# Language RankNTypes, PatternSynonyms, TypeOperators, DataKinds, PolyKinds, KindSignatures, GADTs #-}
import Data.Kind
import Data.Type.Equality
data Ctx :: Type -> Type where
E :: Ctx(Type)
(:&:) :: a -> Ctx(as) -> Ctx(a -> as)
data ApplyT(kind::Type) :: kind -> Ctx(kind) -> Type where
AO :: a -> ApplyT(Type) a E
AS :: ApplyT(ks) (f a) ctx
-> ApplyT(k -> ks) f (a:&:ctx)
pattern ASSO :: () => forall ks k (f :: k -> ks) (a1 :: k) (ctx :: Ctx ks) (ks1 :: Type) k1 (a2 :: k1) (ctx1 :: Ctx ks1) a3. (kind ~ (k -> ks), a ~~ f, b ~~ (a1 :&: ctx), ks ~ (k1 -> ks1), ctx ~~ (a2 :&: E), ks1 ~ Type, f a1 a2 ~~ a3) => a3 -> ApplyT kind a b
pattern ASSO a = AS (AS (AO a))
```
```
$ ghci -ignore-dot-ghci 465.hs
GHCi, version 8.7.20180828: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( 465.hs, interpreted )
WARNING: file compiler/types/TyCoRep.hs, line 2378
in_scope InScope {kind_a1Cw a_a1Cx b_a1Cy ks_a1Cz k_a1CA f_a1CB
a1_a1CC ctx_a1CD ks1_a1CE k1_a1CF a2_a1CG ctx1_a1CH a3_a1CI
k0_a1F8}
tenv [a1Cw :-> kind_a1Cw[sk:0], a1Cx :-> a_a1Cx[sk:0],
a1Cy :-> b_a1Cy[sk:0], a1Cz :-> ks_a1Cz[sk:0],
a1CA :-> k_a1CA[sk:0], a1CB :-> f_a1CB[sk:0],
a1CC :-> a1_a1CC[sk:0], a1CD :-> ctx_a1CD[sk:0],
a1CE :-> ks1_a1CE[sk:0], a1CF :-> k1_a1CF[sk:0],
a1CG :-> a2_a1CG[sk:0], a1CH :-> ctx1_a1CH[sk:0],
a1CI :-> a3_a1CI[sk:0]]
cenv []
tys [kind_a1Cw[sk:1] ~ (k_a1CA[sk:2] -> ks_a1Cz[sk:2]),
a_a1Cx[sk:1] ~~ f_a1CB[sk:2],
b_a1Cy[sk:1] ~~ (a1_a1CC[sk:2] ':&: ctx_a1CD[sk:2]),
ks_a1Cz[sk:2] ~ (k1_a1CF[sk:2] -> ks1_a1CE[sk:2]),
ctx_a1CD[sk:2] ~~ (a2_a1CG[sk:2] ':&: 'E), ks1_a1CE[sk:2] ~ *,
(f_a1CB[sk:2] a1_a1CC[sk:2] |> {co_a1Fc}) a2_a1CG[sk:2]
~~ a3_a1CI[sk:2]]
cos []
needInScope [a1F8 :-> k0_a1F8[sk:2], a1Fc :-> co_a1Fc]
WARNING: file compiler/types/TyCoRep.hs, line 2378
in_scope InScope {kind_a1Cw a_a1Cx b_a1Cy k0_a1HA ks_a1HB k_a1HC
f_a1HD a1_a1HE ctx_a1HF ks1_a1HG k1_a1HH a2_a1HI ctx1_a1HJ a3_a1HK}
tenv [a1Cz :-> ks_a1HB[tau:4], a1CA :-> k_a1HC[tau:4],
a1CB :-> f_a1HD[tau:4], a1CC :-> a1_a1HE[tau:4],
a1CD :-> ctx_a1HF[tau:4], a1CE :-> ks1_a1HG[tau:4],
a1CF :-> k1_a1HH[tau:4], a1CG :-> a2_a1HI[tau:4],
a1CH :-> ctx1_a1HJ[tau:4], a1CI :-> a3_a1HK[tau:4],
a1F8 :-> k0_a1HA[tau:4]]
cenv []
tys [kind_a1Cw[sk:0] ~ (k_a1CA[sk:0] -> ks_a1Cz[sk:0]),
a_a1Cx[sk:0] ~~ f_a1CB[sk:0],
b_a1Cy[sk:0] ~~ (a1_a1CC[sk:0] ':&: ctx_a1CD[sk:0]),
ks_a1Cz[sk:0] ~ (k1_a1CF[sk:0] -> ks1_a1CE[sk:0]),
ctx_a1CD[sk:0] ~~ (a2_a1CG[sk:0] ':&: 'E), ks1_a1CE[sk:0] ~ *,
(f_a1CB[sk:0] a1_a1CC[sk:0] |> {co_a1Fc}) a2_a1CG[sk:0]
~~ a3_a1CI[sk:0]]
cos []
needInScope [a1Cw :-> kind_a1Cw[sk:0], a1Cx :-> a_a1Cx[sk:0],
a1Cy :-> b_a1Cy[sk:0], a1Fc :-> co_a1Fc]
ghc-stage2: panic! (the 'impossible' happened)
(GHC version 8.7.20180828 for x86_64-unknown-linux):
ASSERT failed!
Type-correct unfilled coercion hole {co_a1Fc}
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable
pprPanic, called at compiler/utils/Outputable.hs:1219:5 in ghc:Outputable
assertPprPanic, called at compiler/typecheck/TcHsSyn.hs:1716:99 in ghc:TcHsSyn
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
>
```8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15693Abstracting out pattern into a pattern synonym fails with scary error2019-07-07T18:03:25ZIcelandjackAbstracting out pattern into a pattern synonym fails with scary errorThis **works**
```hs
{-# Language DataKinds, TypeOperators, PolyKinds, PatternSynonyms, GADTs #-}
import Data.Kind
data Ctx :: Type -> Type where
E :: Ctx(Type)
(:&:) :: a -> Ctx(as) -> Ctx(a -> as)
data ApplyT(kind::Type) :: k...This **works**
```hs
{-# Language DataKinds, TypeOperators, PolyKinds, PatternSynonyms, GADTs #-}
import Data.Kind
data Ctx :: Type -> Type where
E :: Ctx(Type)
(:&:) :: a -> Ctx(as) -> Ctx(a -> as)
data ApplyT(kind::Type) :: kind -> Ctx(kind) -> Type where
AO :: a -> ApplyT(Type) a E
AS :: ApplyT(ks) (f a) ctx
-> ApplyT(k -> ks) f (a:&:ctx)
foo :: ApplyT(Type -> Type -> Type) Either a -> ()
foo (ASSO (Left a)) = ()
pattern ASSO a = AS (AS (AO a))
```
but then you might think, let's give a name (pattern synonym) to `ASSO (Left a)`
This **fails**
```hs
{-# Language DataKinds, TypeOperators, PolyKinds, PatternSynonyms, GADTs #-}
import Data.Kind
data Ctx :: Type -> Type where
E :: Ctx(Type)
(:&:) :: a -> Ctx(as) -> Ctx(a -> as)
data ApplyT(kind::Type) :: kind -> Ctx(kind) -> Type where
AO :: a -> ApplyT(Type) a E
AS :: ApplyT(ks) (f a) ctx
-> ApplyT(k -> ks) f (a:&:ctx)
pattern ASSO a = AS (AS (AO a))
pattern ASSOLeft a = ASSO (Left a)
```
```
$ ghci -ignore-dot-ghci 464.hs
GHCi, version 8.7.20180828: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( hs/464.hs, interpreted )
hs/464.hs:16:22: error:
• Couldn't match type ‘k1’ with ‘*’
‘k1’ is a rigid type variable bound by
the signature for pattern synonym ‘ASSOLeft’
at hs/464.hs:16:1-34
Expected type: ApplyT kind a b
Actual type: ApplyT (* -> * -> *) Either (a1 ':&: (a20 ':&: 'E))
• In the expression: ASSO (Left a)
In an equation for ‘ASSOLeft’: ASSOLeft a = ASSO (Left a)
|
16 | pattern ASSOLeft a = ASSO (Left a)
| ^^^^^^^^^^^^^
hs/464.hs:16:28: error:
• Could not deduce: k1 ~ *
from the context: (kind ~ (k -> ks), a ~~ f, b ~~ (a2 ':&: ctx),
ks ~ (k1 -> ks1), f a2 ~~ f1, ctx ~~ (a3 ':&: ctx1), ks1 ~ *,
f1 a3 ~~ a4, ctx1 ~~ 'E)
bound by a pattern with pattern synonym:
ASSO :: forall kind (a :: kind) (b :: Ctx kind).
() =>
forall ks k (f :: k -> ks) (a1 :: k) (ctx :: Ctx
ks) ks1 k1 (f1 :: k1
-> ks1) (a2 :: k1) (ctx1 :: Ctx
ks1) a3.
(kind ~ (k -> ks), a ~~ f, b ~~ (a1 ':&: ctx), ks ~ (k1 -> ks1),
f a1 ~~ f1, ctx ~~ (a2 ':&: ctx1), ks1 ~ *, f1 a2 ~~ a3,
ctx1 ~~ 'E) =>
a3 -> ApplyT kind a b,
in a pattern synonym declaration
at hs/464.hs:16:22-34
‘k1’ is a rigid type variable bound by
a pattern with pattern synonym:
ASSO :: forall kind (a :: kind) (b :: Ctx kind).
() =>
forall ks k (f :: k -> ks) (a1 :: k) (ctx :: Ctx
ks) ks1 k1 (f1 :: k1
-> ks1) (a2 :: k1) (ctx1 :: Ctx
ks1) a3.
(kind ~ (k -> ks), a ~~ f, b ~~ (a1 ':&: ctx), ks ~ (k1 -> ks1),
f a1 ~~ f1, ctx ~~ (a2 ':&: ctx1), ks1 ~ *, f1 a2 ~~ a3,
ctx1 ~~ 'E) =>
a3 -> ApplyT kind a b,
in a pattern synonym declaration
at hs/464.hs:16:22-34
When matching types
a3 :: k1
b0 :: *
Expected type: a4
Actual type: Either a1 b0
• In the pattern: Left a
In the pattern: ASSO (Left a)
In the declaration for pattern synonym ‘ASSOLeft’
|
16 | pattern ASSOLeft a = ASSO (Left a)
| ^^^^^^
Failed, no modules loaded.
Prelude>
```
----
Can I, as a user, assume that any valid pattern `foo (ASSO (Left a)) = ...` can be abstracted into a pattern synonym? There error message is too scary for me to sensibly know what to expect
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Abstracting out pattern into a pattern synonym fails with scary error","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":["PatternSynonyms"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This '''works'''\r\n\r\n{{{#!hs\r\n{-# Language DataKinds, TypeOperators, PolyKinds, PatternSynonyms, GADTs #-}\r\n\r\nimport Data.Kind\r\n\r\ndata Ctx :: Type -> Type where\r\n E :: Ctx(Type)\r\n (:&:) :: a -> Ctx(as) -> Ctx(a -> as)\r\n\r\ndata ApplyT(kind::Type) :: kind -> Ctx(kind) -> Type where\r\n AO :: a -> ApplyT(Type) a E\r\n AS :: ApplyT(ks) (f a) ctx\r\n -> ApplyT(k -> ks) f (a:&:ctx)\r\n\r\nfoo :: ApplyT(Type -> Type -> Type) Either a -> ()\r\nfoo (ASSO (Left a)) = ()\r\n\r\npattern ASSO a = AS (AS (AO a))\r\n}}}\r\n\r\nbut then you might think, let's give a name (pattern synonym) to `ASSO (Left a)`\r\n\r\nThis '''fails'''\r\n{{{#!hs\r\n{-# Language DataKinds, TypeOperators, PolyKinds, PatternSynonyms, GADTs #-}\r\n\r\nimport Data.Kind\r\n\r\ndata Ctx :: Type -> Type where\r\n E :: Ctx(Type)\r\n (:&:) :: a -> Ctx(as) -> Ctx(a -> as)\r\n\r\ndata ApplyT(kind::Type) :: kind -> Ctx(kind) -> Type where\r\n AO :: a -> ApplyT(Type) a E\r\n AS :: ApplyT(ks) (f a) ctx\r\n -> ApplyT(k -> ks) f (a:&:ctx)\r\n\r\npattern ASSO a = AS (AS (AO a))\r\n\r\npattern ASSOLeft a = ASSO (Left a)\r\n}}}\r\n\r\n{{{\r\n$ ghci -ignore-dot-ghci 464.hs\r\nGHCi, version 8.7.20180828: http://www.haskell.org/ghc/ :? for help\r\n[1 of 1] Compiling Main ( hs/464.hs, interpreted )\r\n\r\nhs/464.hs:16:22: error:\r\n • Couldn't match type ‘k1’ with ‘*’\r\n ‘k1’ is a rigid type variable bound by\r\n the signature for pattern synonym ‘ASSOLeft’\r\n at hs/464.hs:16:1-34\r\n Expected type: ApplyT kind a b\r\n Actual type: ApplyT (* -> * -> *) Either (a1 ':&: (a20 ':&: 'E))\r\n • In the expression: ASSO (Left a)\r\n In an equation for ‘ASSOLeft’: ASSOLeft a = ASSO (Left a)\r\n |\r\n16 | pattern ASSOLeft a = ASSO (Left a)\r\n | ^^^^^^^^^^^^^\r\n\r\nhs/464.hs:16:28: error:\r\n • Could not deduce: k1 ~ *\r\n from the context: (kind ~ (k -> ks), a ~~ f, b ~~ (a2 ':&: ctx),\r\n ks ~ (k1 -> ks1), f a2 ~~ f1, ctx ~~ (a3 ':&: ctx1), ks1 ~ *,\r\n f1 a3 ~~ a4, ctx1 ~~ 'E)\r\n bound by a pattern with pattern synonym:\r\n ASSO :: forall kind (a :: kind) (b :: Ctx kind).\r\n () =>\r\n forall ks k (f :: k -> ks) (a1 :: k) (ctx :: Ctx\r\n ks) ks1 k1 (f1 :: k1\r\n -> ks1) (a2 :: k1) (ctx1 :: Ctx\r\n ks1) a3.\r\n (kind ~ (k -> ks), a ~~ f, b ~~ (a1 ':&: ctx), ks ~ (k1 -> ks1),\r\n f a1 ~~ f1, ctx ~~ (a2 ':&: ctx1), ks1 ~ *, f1 a2 ~~ a3,\r\n ctx1 ~~ 'E) =>\r\n a3 -> ApplyT kind a b,\r\n in a pattern synonym declaration\r\n at hs/464.hs:16:22-34\r\n ‘k1’ is a rigid type variable bound by\r\n a pattern with pattern synonym:\r\n ASSO :: forall kind (a :: kind) (b :: Ctx kind).\r\n () =>\r\n forall ks k (f :: k -> ks) (a1 :: k) (ctx :: Ctx\r\n ks) ks1 k1 (f1 :: k1\r\n -> ks1) (a2 :: k1) (ctx1 :: Ctx\r\n ks1) a3.\r\n (kind ~ (k -> ks), a ~~ f, b ~~ (a1 ':&: ctx), ks ~ (k1 -> ks1),\r\n f a1 ~~ f1, ctx ~~ (a2 ':&: ctx1), ks1 ~ *, f1 a2 ~~ a3,\r\n ctx1 ~~ 'E) =>\r\n a3 -> ApplyT kind a b,\r\n in a pattern synonym declaration\r\n at hs/464.hs:16:22-34\r\n When matching types\r\n a3 :: k1\r\n b0 :: *\r\n Expected type: a4\r\n Actual type: Either a1 b0\r\n • In the pattern: Left a\r\n In the pattern: ASSO (Left a)\r\n In the declaration for pattern synonym ‘ASSOLeft’\r\n |\r\n16 | pattern ASSOLeft a = ASSO (Left a)\r\n | ^^^^^^\r\nFailed, no modules loaded.\r\nPrelude> \r\n}}}\r\n\r\n----\r\n\r\nCan I, as a user, assume that any valid pattern `foo (ASSO (Left a)) = ...` can be abstracted into a pattern synonym? There error message is too scary for me to sensibly know what to expect","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15691Marking Pred(S n) = n as injective2019-07-07T18:03:26ZIcelandjackMarking Pred(S n) = n as injectiveShould `Pred` be injective? Please close the ticket if this is a known limitation
```hs
{-# Language DataKinds, TypeFamilyDependencies #-}
data N = O | S N
type family
Pred n = res | res -> n where
Pred(S n) = n
```
fails with
```...Should `Pred` be injective? Please close the ticket if this is a known limitation
```hs
{-# Language DataKinds, TypeFamilyDependencies #-}
data N = O | S N
type family
Pred n = res | res -> n where
Pred(S n) = n
```
fails with
```
• Type family equation violates injectivity annotation.
RHS of injective type family equation is a bare type variable
but these LHS type and kind patterns are not bare variables: ‘'S n’
Pred ('S n) = n -- Defined at 462.hs:7:2
• In the equations for closed type family ‘Pred’
In the type family declaration for ‘Pred’
|
7 | Pred(S n) = n
| ^^^^^^^^^^^^^
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Marking Pred(S n) = n as injective","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":["InjectiveFamilies","TypeFamilies,"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Should `Pred` be injective? Please close the ticket if this is a known limitation \r\n\r\n{{{#!hs\r\n{-# Language DataKinds, TypeFamilyDependencies #-}\r\n\r\ndata N = O | S N\r\n\r\ntype family\r\n Pred n = res | res -> n where\r\n Pred(S n) = n\r\n}}}\r\n\r\nfails with\r\n\r\n{{{\r\n • Type family equation violates injectivity annotation.\r\n RHS of injective type family equation is a bare type variable\r\n but these LHS type and kind patterns are not bare variables: ‘'S n’\r\n Pred ('S n) = n -- Defined at 462.hs:7:2\r\n • In the equations for closed type family ‘Pred’\r\n In the type family declaration for ‘Pred’\r\n |\r\n7 | Pred(S n) = n\r\n | ^^^^^^^^^^^^^\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1