GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2020-09-28T14:27:02Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/18528NthCo (FunCo a b) doesn't optimise2020-09-28T14:27:02ZSimon Peyton JonesNthCo (FunCo a b) doesn't optimiseThere is a missing case in `GHC.Core.Coercion.Opt` for `NthCo (FunCo ...)`. There really should be.
In looking at `perf/compiler/T5321Fun` I saw *lots* of opportunities for exploiting this optimisation.
@rae says he'll do this.There is a missing case in `GHC.Core.Coercion.Opt` for `NthCo (FunCo ...)`. There really should be.
In looking at `perf/compiler/T5321Fun` I saw *lots* of opportunities for exploiting this optimisation.
@rae says he'll do this.Richard Eisenbergrae@richarde.devRichard Eisenbergrae@richarde.devhttps://gitlab.haskell.org/ghc/ghc/-/issues/18518Release tracking ticket for 8.10.22020-08-08T21:22:49ZBen GamariRelease tracking ticket for 8.10.2> This is the template to be used to create release tracking tickets. Copy this into a new issue and fill in the TODOs. Those items marked with *major-only* can be ignored for minor releases.
This is the release checklist for the TODO milestone. See #16816 for the template that this was derived from.
# Pre-release checklist
* [x] (*major-only*) Remove the release notes for the previous release (e.g. `docs/users_guide/8.6.*-notes.rst`)
* [x] (*major-only*) Make release branch (e.g. `ghc-8.8`)
* [x] (*major-only*) Make post-release branch (e.g. `ghc-8.9-start`)
* [x] Ensure that submodules are on released tags (the below is produced using [this script](https://gitlab.haskell.org/bgamari/ghc-utils/blob/master/rel-eng/submod-release-summary.py)):
* [x] `libraries/Cabal`: version 3.2.0.0
* [x] `libraries/Win32`: version 2.6.1.0
* [ ] `libraries/array`: *todo* (on `v0.5.3.0-7-gf73f681`)
* [x] `libraries/binary`: version 0.8.8.0
* [x] `libraries/bytestring`: version 0.10.10.0-ghc1
* [x] `libraries/containers`: version 0.6.2.1
* [x] `libraries/deepseq`: version 1.4.4.0-r2
* [x] `libraries/directory`: version 1.3.6.0
* [x] `libraries/exceptions`: version 0.10.4
* [x] `libraries/filepath`: version 1.4.2.1-ghc2
* [x] `libraries/haskeline`: version 0.8.0.0
* [x] `libraries/mtl`: version 2.2.2
* [x] `libraries/parsec`: 3.1.14.0
* [x] `libraries/pretty`: version 1.1.3.6
* [x] `libraries/process`: version 1.6.9.0
* [ ] `libraries/stm`: *todo* (on `v2.5.0.0-ghc1-13-gfaf9904`)
* [x] `libraries/terminfo`: 0.4.1.4
* [x] `libraries/text`: 1.2.3.2
* [x] `libraries/time`: version 1.9.3
* [x] `libraries/transformers`: version 0.5.6.2
* [x] `libraries/unix`: version 2.7.2.2-ghc1
* [x] `libraries/xhtml`: version 3000.2.2.1
* [ ] `utils/haddock`: *todo* (on `haddock-2.24.0-release-17-gb78efc7f`)
* [x] `utils/hsc2hs`: version 0.68.7
* [x] Non-released submodules up-to-date:
* [x] `nofib`
* [x] `libffi-tarballs`
* [x] `libraries/integer-gmp/gmp/gmp-tarballs`
* [x] Release notes (`docs/users_guide/x.y.z-notes.rst`) written
* [x] Release notes linked in `docs/users_guide/index.rst`
* [x] `autoconf` scripts [updated](https://gitlab.haskell.org/ghc/ghc/wikis/making-releases#updating-the-tree)
* [x] Check that Unicode database in `base` (`libraries/base/cbits/README.Unicode`) reflects current standard release (http://www.unicode.org/versions/latest/)
* [x] `LlvmVersion` in `configure.ac` is targetting intended LLVM version
* [x] Release notes mentions LLVM version requirement
* [x] `llvm-targets` file [updated](https://gitlab.haskell.org/ghc/ghc/wikis/making-releases#updating-the-tree)
* [x] Changelogs updated (these can be checked using `.gitlab/linters/check-changelogs.sh`):
* [x] `libraries/ghc-prim`
* [x] `libraries/integer-gmp`
* [x] `libraries/integer-simple`
* [x] `libraries/hpc`
* [x] `libraries/base`
* [x] Verify that the ~"backport needed" label has no more issues/merge requests needing backport
* [x] Verify that all CI builds are green before moving to *release checklist*
# Release checklist
* [x] Push a provision provisional release commit to trigger the release builds using `git push -o ci.variable="RELEASE=yes"`
* [x] Wait until builds finish; verify that they finished successfully
* [x] Fetch release artifacts TODO: documentation
* [ ] Sign and push release artifacts to `downloads.haskell.org` [TODO: documentation]
* [x] [Make a release tag](https://gitlab.haskell.org/ghc/ghc/wikis/making-releases#tagging-the-release)
* [ ] Release/revise GHC-maintained libraries on Hackage [TODO: documentation]
* [ ] `libraries/base`
* [ ] `libraries/ghc-prim`
* [ ] `libraries/array`
* [ ] `libraries/stm`
* [ ] `libraries/ghc-heap`
* [ ] `libraries/ghc-compact`
* [ ] `libraries/ghc-boot`
* [ ] `libraries/ghc-boot-th`
* [ ] `libraries/hpc`
* [ ] `libraries/libiserv`
* [ ] `libraries/template-haskell`
* [ ] `libraries/integer-gmp`
* [ ] `libraries/integer-simple`
* [x] Update ghc/homepage>:
* [x] Write download page (see ghc/homepage>)
* [x] Add news item to [`index.html`](https://gitlab.haskell.org/ghc/homepage/blob/master/index.shtml)
* [x] Add link to [`download.shtml`](https://gitlab.haskell.org/ghc/homepage/blob/master/download.shtml)
* [x] Look over changes locally
* [x] Add release announcement to [GHC blog](https://gitlab.haskell.org/ghc/homepage/tree/master/blog)
* [x] Push changes to `master`
* [x] Announce on: `GHC developers <ghc-devs@haskell.org>, GHC Users <glasgow-haskell-users@haskell.org>, Haskell Cafe <haskell-cafe@haskell.org>`
* [x] Announce on: [Haskell Discourse](https://discourse.haskell.org/), [/r/haskell](https://reddit.com/r/haskell), [Twitter](https://twitter.com/)
* [x] Update `latest` symlink on `downloads.haskell.org`
* [x] Ensure that the [Migration](https://gitlab.haskell.org/ghc/ghc/wikis/migration/) page is up-to-date
# Post-release checklist
* [ ] Update the Wiki [status page](https://gitlab.haskell.org/ghc/ghc/wikis/status)
* [ ] Update the [language pragma history](https://gitlab.haskell.org/ghc/ghc/wikis/language-pragma-history)
* [ ] Mark milestone as *closed*
* [ ] Update `/topic` in `#ghc`
* [ ] Update the [VersionHistory](https://gitlab.haskell.org/ghc/ghc/wikis/commentary/libraries/version-history) wiki page
* [ ] Set `RELEASE=NO`> This is the template to be used to create release tracking tickets. Copy this into a new issue and fill in the TODOs. Those items marked with *major-only* can be ignored for minor releases.
This is the release checklist for the TODO milestone. See #16816 for the template that this was derived from.
# Pre-release checklist
* [x] (*major-only*) Remove the release notes for the previous release (e.g. `docs/users_guide/8.6.*-notes.rst`)
* [x] (*major-only*) Make release branch (e.g. `ghc-8.8`)
* [x] (*major-only*) Make post-release branch (e.g. `ghc-8.9-start`)
* [x] Ensure that submodules are on released tags (the below is produced using [this script](https://gitlab.haskell.org/bgamari/ghc-utils/blob/master/rel-eng/submod-release-summary.py)):
* [x] `libraries/Cabal`: version 3.2.0.0
* [x] `libraries/Win32`: version 2.6.1.0
* [ ] `libraries/array`: *todo* (on `v0.5.3.0-7-gf73f681`)
* [x] `libraries/binary`: version 0.8.8.0
* [x] `libraries/bytestring`: version 0.10.10.0-ghc1
* [x] `libraries/containers`: version 0.6.2.1
* [x] `libraries/deepseq`: version 1.4.4.0-r2
* [x] `libraries/directory`: version 1.3.6.0
* [x] `libraries/exceptions`: version 0.10.4
* [x] `libraries/filepath`: version 1.4.2.1-ghc2
* [x] `libraries/haskeline`: version 0.8.0.0
* [x] `libraries/mtl`: version 2.2.2
* [x] `libraries/parsec`: 3.1.14.0
* [x] `libraries/pretty`: version 1.1.3.6
* [x] `libraries/process`: version 1.6.9.0
* [ ] `libraries/stm`: *todo* (on `v2.5.0.0-ghc1-13-gfaf9904`)
* [x] `libraries/terminfo`: 0.4.1.4
* [x] `libraries/text`: 1.2.3.2
* [x] `libraries/time`: version 1.9.3
* [x] `libraries/transformers`: version 0.5.6.2
* [x] `libraries/unix`: version 2.7.2.2-ghc1
* [x] `libraries/xhtml`: version 3000.2.2.1
* [ ] `utils/haddock`: *todo* (on `haddock-2.24.0-release-17-gb78efc7f`)
* [x] `utils/hsc2hs`: version 0.68.7
* [x] Non-released submodules up-to-date:
* [x] `nofib`
* [x] `libffi-tarballs`
* [x] `libraries/integer-gmp/gmp/gmp-tarballs`
* [x] Release notes (`docs/users_guide/x.y.z-notes.rst`) written
* [x] Release notes linked in `docs/users_guide/index.rst`
* [x] `autoconf` scripts [updated](https://gitlab.haskell.org/ghc/ghc/wikis/making-releases#updating-the-tree)
* [x] Check that Unicode database in `base` (`libraries/base/cbits/README.Unicode`) reflects current standard release (http://www.unicode.org/versions/latest/)
* [x] `LlvmVersion` in `configure.ac` is targetting intended LLVM version
* [x] Release notes mentions LLVM version requirement
* [x] `llvm-targets` file [updated](https://gitlab.haskell.org/ghc/ghc/wikis/making-releases#updating-the-tree)
* [x] Changelogs updated (these can be checked using `.gitlab/linters/check-changelogs.sh`):
* [x] `libraries/ghc-prim`
* [x] `libraries/integer-gmp`
* [x] `libraries/integer-simple`
* [x] `libraries/hpc`
* [x] `libraries/base`
* [x] Verify that the ~"backport needed" label has no more issues/merge requests needing backport
* [x] Verify that all CI builds are green before moving to *release checklist*
# Release checklist
* [x] Push a provision provisional release commit to trigger the release builds using `git push -o ci.variable="RELEASE=yes"`
* [x] Wait until builds finish; verify that they finished successfully
* [x] Fetch release artifacts TODO: documentation
* [ ] Sign and push release artifacts to `downloads.haskell.org` [TODO: documentation]
* [x] [Make a release tag](https://gitlab.haskell.org/ghc/ghc/wikis/making-releases#tagging-the-release)
* [ ] Release/revise GHC-maintained libraries on Hackage [TODO: documentation]
* [ ] `libraries/base`
* [ ] `libraries/ghc-prim`
* [ ] `libraries/array`
* [ ] `libraries/stm`
* [ ] `libraries/ghc-heap`
* [ ] `libraries/ghc-compact`
* [ ] `libraries/ghc-boot`
* [ ] `libraries/ghc-boot-th`
* [ ] `libraries/hpc`
* [ ] `libraries/libiserv`
* [ ] `libraries/template-haskell`
* [ ] `libraries/integer-gmp`
* [ ] `libraries/integer-simple`
* [x] Update ghc/homepage>:
* [x] Write download page (see ghc/homepage>)
* [x] Add news item to [`index.html`](https://gitlab.haskell.org/ghc/homepage/blob/master/index.shtml)
* [x] Add link to [`download.shtml`](https://gitlab.haskell.org/ghc/homepage/blob/master/download.shtml)
* [x] Look over changes locally
* [x] Add release announcement to [GHC blog](https://gitlab.haskell.org/ghc/homepage/tree/master/blog)
* [x] Push changes to `master`
* [x] Announce on: `GHC developers <ghc-devs@haskell.org>, GHC Users <glasgow-haskell-users@haskell.org>, Haskell Cafe <haskell-cafe@haskell.org>`
* [x] Announce on: [Haskell Discourse](https://discourse.haskell.org/), [/r/haskell](https://reddit.com/r/haskell), [Twitter](https://twitter.com/)
* [x] Update `latest` symlink on `downloads.haskell.org`
* [x] Ensure that the [Migration](https://gitlab.haskell.org/ghc/ghc/wikis/migration/) page is up-to-date
# Post-release checklist
* [ ] Update the Wiki [status page](https://gitlab.haskell.org/ghc/ghc/wikis/status)
* [ ] Update the [language pragma history](https://gitlab.haskell.org/ghc/ghc/wikis/language-pragma-history)
* [ ] Mark milestone as *closed*
* [ ] Update `/topic` in `#ghc`
* [ ] Update the [VersionHistory](https://gitlab.haskell.org/ghc/ghc/wikis/commentary/libraries/version-history) wiki page
* [ ] Set `RELEASE=NO`8.10.2Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/18517Consider removing ConDeclGADTPrefixPs2020-09-26T22:36:06ZRyan ScottConsider removing ConDeclGADTPrefixPsThe `ConDecl` has two constructors, `ConDeclH98` and `ConDeclGADT`, as well as an extension constructor, `XConDecl`. Currently, `XConDecl` extends the parsing phase with a GHC-specific data type called `ConDeclGADTPrefix`:
```hs
data ConDeclGADTPrefixPs = ConDeclGADTPrefixPs
{ con_gp_names :: [Located RdrName]
-- ^ The GADT constructor declaration's names.
, con_gp_ty :: LHsSigType GhcPs
-- ^ The type after the @::@.
, con_gp_doc :: Maybe LHsDocString
-- ^ A possible Haddock comment.
}
```
This is used for prefix GADT constructors (e.g., `MkT1 :: a -> T a`), as opposed to record GADT constructors (e.g., `MkT2 :: { unT2 :: a } -> T a`).
Why do we have both `ConDeclGADT` _and_ `ConDeclGADTPrefixPs`? [`Note [GADT abstract syntax]`](https://gitlab.haskell.org/ghc/ghc/-/blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Hs/Decls.hs#L1445-1500) explains the complications of parsing prefix GADT constructors. Here is the relevant excerpt:
```
For prefix GADT constructors, however, the situation is more complicated. It
can be difficult to split a prefix GADT type until we know type operator
fixities. Consider this, for example:
C :: a :*: b -> a :*: b -> a :+: b
Initially, the type of C will parse as:
a :*: (b -> (a :*: (b -> (a :+: b))))
So it's hard to split up the arguments until we've done the precedence
resolution (in the renamer). (Unlike prefix GADT types, record GADT types
do not have this problem because of their uniform syntax.)
As a result, we deliberately avoid splitting prefix GADT types in the parser.
Instead, we store the entire LHsType in ConDeclGADTPrefixPs, a GHC-specific
extension constructor to ConDecl. Later, in the renamer
(in GHC.Rename.Module.rnConDecl), we resolve the fixities of all type operators
in the LHsType, which facilitates splitting it into argument and result types
accurately. We finish renaming a ConDeclGADTPrefixPs by putting the split
components into a ConDeclGADT. This is why ConDeclGADTPrefixPs has the suffix
-Ps, as it is only used by the parser.
```
However, @int-index pointed out to me in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3337#note_282965 that the premise behind this Note is incorrect. GHC always parses function arrows more loosely than any user-definable type operator due to its special treatment in the parser, so `a :*: b -> a :*: b -> a :+: b` will actually be parsed as `(a :*: b) -> ((a :*: b) -> (a :+: b))`, not `a :*: (b -> (a :*: (b -> (a :+: b))))` (as the Note claims). As a consequence, it should be simple to split up a prefix GADT constructor type in the parser, which obviates the need for `ConDeclGADTPrefixPs` in the first place.
I'm opening this issue to track removing `ConDeclGADTPrefixPs` in light of the discussion above. I will post a MR soon, but if anyone can think of any looming issues that I've overlooked, do speak up.The `ConDecl` has two constructors, `ConDeclH98` and `ConDeclGADT`, as well as an extension constructor, `XConDecl`. Currently, `XConDecl` extends the parsing phase with a GHC-specific data type called `ConDeclGADTPrefix`:
```hs
data ConDeclGADTPrefixPs = ConDeclGADTPrefixPs
{ con_gp_names :: [Located RdrName]
-- ^ The GADT constructor declaration's names.
, con_gp_ty :: LHsSigType GhcPs
-- ^ The type after the @::@.
, con_gp_doc :: Maybe LHsDocString
-- ^ A possible Haddock comment.
}
```
This is used for prefix GADT constructors (e.g., `MkT1 :: a -> T a`), as opposed to record GADT constructors (e.g., `MkT2 :: { unT2 :: a } -> T a`).
Why do we have both `ConDeclGADT` _and_ `ConDeclGADTPrefixPs`? [`Note [GADT abstract syntax]`](https://gitlab.haskell.org/ghc/ghc/-/blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Hs/Decls.hs#L1445-1500) explains the complications of parsing prefix GADT constructors. Here is the relevant excerpt:
```
For prefix GADT constructors, however, the situation is more complicated. It
can be difficult to split a prefix GADT type until we know type operator
fixities. Consider this, for example:
C :: a :*: b -> a :*: b -> a :+: b
Initially, the type of C will parse as:
a :*: (b -> (a :*: (b -> (a :+: b))))
So it's hard to split up the arguments until we've done the precedence
resolution (in the renamer). (Unlike prefix GADT types, record GADT types
do not have this problem because of their uniform syntax.)
As a result, we deliberately avoid splitting prefix GADT types in the parser.
Instead, we store the entire LHsType in ConDeclGADTPrefixPs, a GHC-specific
extension constructor to ConDecl. Later, in the renamer
(in GHC.Rename.Module.rnConDecl), we resolve the fixities of all type operators
in the LHsType, which facilitates splitting it into argument and result types
accurately. We finish renaming a ConDeclGADTPrefixPs by putting the split
components into a ConDeclGADT. This is why ConDeclGADTPrefixPs has the suffix
-Ps, as it is only used by the parser.
```
However, @int-index pointed out to me in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3337#note_282965 that the premise behind this Note is incorrect. GHC always parses function arrows more loosely than any user-definable type operator due to its special treatment in the parser, so `a :*: b -> a :*: b -> a :+: b` will actually be parsed as `(a :*: b) -> ((a :*: b) -> (a :+: b))`, not `a :*: (b -> (a :*: (b -> (a :+: b))))` (as the Note claims). As a consequence, it should be simple to split up a prefix GADT constructor type in the parser, which obviates the need for `ConDeclGADTPrefixPs` in the first place.
I'm opening this issue to track removing `ConDeclGADTPrefixPs` in light of the discussion above. I will post a MR soon, but if anyone can think of any looming issues that I've overlooked, do speak up.9.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/18516Move to a more structured error representation2020-09-25T09:53:43ZAlp MestanogullariMove to a more structured error representationGHC spits out errors as SDocs, which makes it hard for clients of the GHC API to respond sensibly to them. (Parsing error message strings seems ... sub-optimal.) This ticket tracks progress towards improving the situation.
Key resources
- [The errors-as-values GHC proposal 306](https://github.com/ghc-proposals/ghc-proposals/pull/306) describes the problem, and the proposed solution
- [The errors-as-values wiki page](https://gitlab.haskell.org/ghc/ghc/-/wikis/Errors-as-(structured)-values) describes the high level design for how we propose to implement it in GHC.
- [This WIP merge request 3691](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3691) is our work in progress.
For design discussion, use this ticket. For code review, use the MR !3691.
GHC spits out errors as SDocs, which makes it hard for clients of the GHC API to respond sensibly to them. (Parsing error message strings seems ... sub-optimal.) This ticket tracks progress towards improving the situation.
Key resources
- [The errors-as-values GHC proposal 306](https://github.com/ghc-proposals/ghc-proposals/pull/306) describes the problem, and the proposed solution
- [The errors-as-values wiki page](https://gitlab.haskell.org/ghc/ghc/-/wikis/Errors-as-(structured)-values) describes the high level design for how we propose to implement it in GHC.
- [This WIP merge request 3691](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3691) is our work in progress.
For design discussion, use this ticket. For code review, use the MR !3691.
Alp MestanogullariAlp Mestanogullarihttps://gitlab.haskell.org/ghc/ghc/-/issues/18513runRW inlining in CorePre may go awry with bottoming continuation2020-07-29T16:41:35ZBen GamarirunRW inlining in CorePre may go awry with bottoming continuationIn `GHC.CoreToSTG.Prep` we inline `runRW` into its call-sites (as described in `Note [runRW magic]`). Specifically, we perform two types of rewrites:
1. a beta-reduction if possible: `runRW (\s -> expr) ~> expr[s / realWorld]`
2. otherwise, a simple inlining: `runRW f ~> f realWorld`
Both rewrites are useful in that they eliminate the indirect call that dispatching to `runRW`'s Haskell definition would usually imply.
However, rewrite (2) may be problematic in the case of bottoming continuations (as described in `Note [runRW arg]`). In particular, consider the application
```haskell
runRW (case bottom of {})
```
In this case, rewrite (2) will result in
```haskell
(case bottom of {}) realWorld
```
However, this will break `collectArgs`, which expects an application chain to be headed by an identifier.
I believe this can only happen with `-O0` since `runRW`'s strictness signature captures the fact that it calls its argument. Consequently, the simplifier can rewrite `runRW (case bottom of {})` to `case bottom of {}`.
We should measure whether rewrite (2) offers any tangible performance benefit and depending upon the answer either fix it or remove it.In `GHC.CoreToSTG.Prep` we inline `runRW` into its call-sites (as described in `Note [runRW magic]`). Specifically, we perform two types of rewrites:
1. a beta-reduction if possible: `runRW (\s -> expr) ~> expr[s / realWorld]`
2. otherwise, a simple inlining: `runRW f ~> f realWorld`
Both rewrites are useful in that they eliminate the indirect call that dispatching to `runRW`'s Haskell definition would usually imply.
However, rewrite (2) may be problematic in the case of bottoming continuations (as described in `Note [runRW arg]`). In particular, consider the application
```haskell
runRW (case bottom of {})
```
In this case, rewrite (2) will result in
```haskell
(case bottom of {}) realWorld
```
However, this will break `collectArgs`, which expects an application chain to be headed by an identifier.
I believe this can only happen with `-O0` since `runRW`'s strictness signature captures the fact that it calls its argument. Consequently, the simplifier can rewrite `runRW (case bottom of {})` to `case bottom of {}`.
We should measure whether rewrite (2) offers any tangible performance benefit and depending upon the answer either fix it or remove it.Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/18511Introduce new language extension name for quick-look impredicativity2020-09-25T19:51:15ZBen GamariIntroduce new language extension name for quick-look impredicativitySee https://github.com/ghc-proposals/ghc-proposals/pull/274#issuecomment-664654358.
Before doing anything we need a consensus on what to do.See https://github.com/ghc-proposals/ghc-proposals/pull/274#issuecomment-664654358.
Before doing anything we need a consensus on what to do.9.2.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/18484New plan for baseline selection of performance metrics2020-07-28T14:39:53ZBen GamariNew plan for baseline selection of performance metricsCurrently the plan for baseline selection in the testsuite driver is both complex and unpredictable. Concretely, to find a baseline value for a given test and metric we do the following
* we walk backwards from the current commit...
* if we find that a change in the given test was accepted (via the commit message) then we stop the walk and return the recorded measurement if any
* if we find a recorded measurement, we return it
* if we reach a depth limit of 75 commits then we give up
This leads to a number of surprising behaviors, particular when pushing the `git notes` at the end of the job fails.
# A new plan
To fix this, we decided on the following, less complex plan:
* Every MR uses its base commit as its baseline
* Every Marge batch pushes its metrics *before* being merged into `master`
This allows the following invariant: **the tip of master always has accurate perf numbers**Currently the plan for baseline selection in the testsuite driver is both complex and unpredictable. Concretely, to find a baseline value for a given test and metric we do the following
* we walk backwards from the current commit...
* if we find that a change in the given test was accepted (via the commit message) then we stop the walk and return the recorded measurement if any
* if we find a recorded measurement, we return it
* if we reach a depth limit of 75 commits then we give up
This leads to a number of surprising behaviors, particular when pushing the `git notes` at the end of the job fails.
# A new plan
To fix this, we decided on the following, less complex plan:
* Every MR uses its base commit as its baseline
* Every Marge batch pushes its metrics *before* being merged into `master`
This allows the following invariant: **the tip of master always has accurate perf numbers**Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/18481Improve instantiation of datacons2020-07-21T08:48:13ZKrzysztof GogolewskiImprove instantiation of dataconsThis ticket tracks a possible improvement to `return_data_con`.
When typechecking a datacon `T`, do we instantiate its arguments? We'd like to avoid instantiation, because it breaks VTA.
Currently, we instantiate levity-polymorphic constructors. Quoting Note [Linear fields generalization]:
```
A small hitch: if the constructor is levity-polymorphic (unboxed tuples, sums,
certain newtypes with -XUnliftedNewtypes) then this strategy produces
\r1 r2 a b (x # p :: a) (y # q :: b) -> (# a, b #)
Which has type
forall r1 r2 a b. a #p-> b #q-> (# a, b #)
Which violates the levity-polymorphism restriction see Note [Levity polymorphism
checking] in DsMonad.
So we really must instantiate r1 and r2 rather than quantify over them. For
simplicity, we just instantiate the entire type, as described in Note
[Instantiating stupid theta]. It breaks visible type application with unboxed
tuples, sums and levity-polymorphic newtypes, but this doesn't appear to be used
anywhere.
A better plan: let's force all representation variable to be *inferred*, so that
they are not subject to visible type applications. Then we can instantiate
inferred argument eagerly.
```
The goal of this ticket is to implement the last paragraph.This ticket tracks a possible improvement to `return_data_con`.
When typechecking a datacon `T`, do we instantiate its arguments? We'd like to avoid instantiation, because it breaks VTA.
Currently, we instantiate levity-polymorphic constructors. Quoting Note [Linear fields generalization]:
```
A small hitch: if the constructor is levity-polymorphic (unboxed tuples, sums,
certain newtypes with -XUnliftedNewtypes) then this strategy produces
\r1 r2 a b (x # p :: a) (y # q :: b) -> (# a, b #)
Which has type
forall r1 r2 a b. a #p-> b #q-> (# a, b #)
Which violates the levity-polymorphism restriction see Note [Levity polymorphism
checking] in DsMonad.
So we really must instantiate r1 and r2 rather than quantify over them. For
simplicity, we just instantiate the entire type, as described in Note
[Instantiating stupid theta]. It breaks visible type application with unboxed
tuples, sums and levity-polymorphic newtypes, but this doesn't appear to be used
anywhere.
A better plan: let's force all representation variable to be *inferred*, so that
they are not subject to visible type applications. Then we can instantiate
inferred argument eagerly.
```
The goal of this ticket is to implement the last paragraph.https://gitlab.haskell.org/ghc/ghc/-/issues/18458Make the printing of types more truthful2020-08-05T14:34:25ZSimon Peyton JonesMake the printing of types more truthfulConsider
```
class C a where
op :: forall b. Eq b => a -> b -> b
```
Then in fact `op :: forall a. C a => forall b. Eq b => a -> b -> b`.
But if we print that type, we display `forall a b. (C a, Eq b) => a -> b -> b`. This is *not* because we instantiate `op` and re-generalise. It's just how we print the type. See `GHC.Iface.Type.splitIfaceSigmaTy`.
We did this to make types seem more intuitive when printed. But I regularly trip over this when debugging, and puzzle about the shapes of types and terms.
I wonder if this is also potentially confusing for users too. Suggestion: print the foralls and constraints as they truly are, not "helpfully" rearranged.Consider
```
class C a where
op :: forall b. Eq b => a -> b -> b
```
Then in fact `op :: forall a. C a => forall b. Eq b => a -> b -> b`.
But if we print that type, we display `forall a b. (C a, Eq b) => a -> b -> b`. This is *not* because we instantiate `op` and re-generalise. It's just how we print the type. See `GHC.Iface.Type.splitIfaceSigmaTy`.
We did this to make types seem more intuitive when printed. But I regularly trip over this when debugging, and puzzle about the shapes of types and terms.
I wonder if this is also potentially confusing for users too. Suggestion: print the foralls and constraints as they truly are, not "helpfully" rearranged.https://gitlab.haskell.org/ghc/ghc/-/issues/18430Try -XMonoLocalBinds in GHC for compile-time performance improvements2020-09-03T17:08:27ZSebastian GrafTry -XMonoLocalBinds in GHC for compile-time performance improvementsIn https://gitlab.haskell.org/ghc/ghc/-/issues/18360#note_284781 Simon said:
> I think it might be interesting to compile GHC, or Cabal, with MonoLocalBinds on throughout, and see if there is any perf difference. Would anyone like to try that?
This was in the context of #18360, where (unnecessary) let generalisation led to failure to recognise a join point.
Edit: Implemented in !3650.In https://gitlab.haskell.org/ghc/ghc/-/issues/18360#note_284781 Simon said:
> I think it might be interesting to compile GHC, or Cabal, with MonoLocalBinds on throughout, and see if there is any perf difference. Would anyone like to try that?
This was in the context of #18360, where (unnecessary) let generalisation led to failure to recognise a join point.
Edit: Implemented in !3650.https://gitlab.haskell.org/ghc/ghc/-/issues/18424[Discussion] Integrating Hlint in the repo: why, what, where2020-09-22T21:39:02ZHécate[Discussion] Integrating Hlint in the repo: why, what, whereThis ticket opens the discussion on Hlint integration in the ghc repository. This is a tricky subject, so let me put some foundations to the discussion:
## Why
* This is **not** about blindly integrating Hlint in the whole codebase
* This is **not** about turning on *all* the lints by default
* This is **not** about ruling out the usage of other tools in the future (like `stan`)
* This is about determining, as a community of contributors and professionals, which are the lints that may benefit us the most
* This is about starting a progressive integration of the linting process
## What
From a personal experience, here are some of the hints I find useful (and use in my professional life):
* `Use DerivingStrategies`
* The `generalise` [group](https://github.com/ndmitchell/hlint/blob/1787cdfc4eb3efee860b5c813bc98d0345e73b55/data/hlint.yaml#L838) (`(++)` -> `(<>)`, `map` -> `fmap`, etc)
* Replacing `sequence` by `sequenceA`, to ease the `Monad` restriction
* Replacing `return` by `pure`
* Replacing `nub` (which is Ο(n^2)) with [`ordNub`](https://hackage.haskell.org/package/relude-0.7.0.0/docs/Relude-Nub.html#v:ordNub)
* Replacing some notoriously unsafe-yet-popular functions like `head`, `tail`, `fromJust` with safe equivalents (using `NonEmpty`, using functions that return a `Maybe a`, etc)
* Turning off the `Eta reduce` hint
This is of course up for discussion, I do not claim that my experience is objectively better than another.
That being said, Hlint is quite a powerful tool in its space, and will definitely help setting coding standards
that might get past a reviewer's attention.
## Where
I suggest that Hlint should be enabled first in the projects of the `libraries/` directory, on a case-by-case basis.
The reason is simple: Each of those libraries may (and will) generate a copious amount of hint warnings, so the work will be easier to get done if we adopt a granular integration (and it can be parallelised).
The older parts of GHC may benefit from more reflection on which hints should be enabled. As said before, this is a tricky subject.
Thank you for reading.This ticket opens the discussion on Hlint integration in the ghc repository. This is a tricky subject, so let me put some foundations to the discussion:
## Why
* This is **not** about blindly integrating Hlint in the whole codebase
* This is **not** about turning on *all* the lints by default
* This is **not** about ruling out the usage of other tools in the future (like `stan`)
* This is about determining, as a community of contributors and professionals, which are the lints that may benefit us the most
* This is about starting a progressive integration of the linting process
## What
From a personal experience, here are some of the hints I find useful (and use in my professional life):
* `Use DerivingStrategies`
* The `generalise` [group](https://github.com/ndmitchell/hlint/blob/1787cdfc4eb3efee860b5c813bc98d0345e73b55/data/hlint.yaml#L838) (`(++)` -> `(<>)`, `map` -> `fmap`, etc)
* Replacing `sequence` by `sequenceA`, to ease the `Monad` restriction
* Replacing `return` by `pure`
* Replacing `nub` (which is Ο(n^2)) with [`ordNub`](https://hackage.haskell.org/package/relude-0.7.0.0/docs/Relude-Nub.html#v:ordNub)
* Replacing some notoriously unsafe-yet-popular functions like `head`, `tail`, `fromJust` with safe equivalents (using `NonEmpty`, using functions that return a `Maybe a`, etc)
* Turning off the `Eta reduce` hint
This is of course up for discussion, I do not claim that my experience is objectively better than another.
That being said, Hlint is quite a powerful tool in its space, and will definitely help setting coding standards
that might get past a reviewer's attention.
## Where
I suggest that Hlint should be enabled first in the projects of the `libraries/` directory, on a case-by-case basis.
The reason is simple: Each of those libraries may (and will) generate a copious amount of hint warnings, so the work will be easier to get done if we adopt a granular integration (and it can be parallelised).
The older parts of GHC may benefit from more reflection on which hints should be enabled. As said before, this is a tricky subject.
Thank you for reading.https://gitlab.haskell.org/ghc/ghc/-/issues/18413Suboptimal constraint solving2020-07-17T13:10:36ZSimon Peyton JonesSuboptimal constraint solvingHere a summary of `-ddump-tc-trace` for this program (part of test T12427a)
```
data T where
T1 :: a -> ((forall b. [b]->[b]) -> Int) -> T
h11 y = case y of T1 _ v -> v
```
I see this sequence
```
{co_awA} {0}:: ((forall b. [b] -> [b]) -> Int)
~# p_awz[tau:1] (CNonCanonical)
==> Hetero equality gives rise to kind equality
inert: {co_awG} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE {co_awF})_N)
work item: {co_awF} :: 'GHC.Types.LiftedRep ~# p_awy[tau:1]
co_awA := Sym ({co_awG} ; Sym (GRefl nominal ((forall b.[b] -> [b]) -> Int)
(TYPE {co_awF})_N))
==> Swap awF, kick out awG
work item: {co_awG} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE {co_awF})_N)
inert (because p_awy is untouchable):
{co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
co_awF := Sym co_awH
==> flatten awG (strange double GRefl)
inert: {co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
inert: {co_awI} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
co_awG := {co_awI} ; (Sym (GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE (Sym {co_awH}))_N)
; GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE {co_awF})_N)
at this point we also make a derived shadow of awI, for some reason.
Solving stops here, but we float out awI, and awH, and then have another go
work: {co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
work: {co_awI} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
==> flatten awI (why?)
work: {co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
inert: {co_awJ} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
co_awI := {co_awJ} ; (Sym (GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE (Sym {co_awH}))_N) ; GRefl nominal ((forall b. [b] -> [b])
-> Int)
(TYPE (Sym {co_awH}))_N)
==> solve awH: p_awy := LiftedRep, kick out awJ
{co_awJ} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
==> flatten awJ
co_awJ := {co_awK} ; GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE (Sym {co_awH}))_N
{co_awK} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int)
```
This seems like we are doing too much work, esp the double GRefls. Why did awI get flattened?
It's not a disaster, but pretty heavy handed.Here a summary of `-ddump-tc-trace` for this program (part of test T12427a)
```
data T where
T1 :: a -> ((forall b. [b]->[b]) -> Int) -> T
h11 y = case y of T1 _ v -> v
```
I see this sequence
```
{co_awA} {0}:: ((forall b. [b] -> [b]) -> Int)
~# p_awz[tau:1] (CNonCanonical)
==> Hetero equality gives rise to kind equality
inert: {co_awG} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE {co_awF})_N)
work item: {co_awF} :: 'GHC.Types.LiftedRep ~# p_awy[tau:1]
co_awA := Sym ({co_awG} ; Sym (GRefl nominal ((forall b.[b] -> [b]) -> Int)
(TYPE {co_awF})_N))
==> Swap awF, kick out awG
work item: {co_awG} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE {co_awF})_N)
inert (because p_awy is untouchable):
{co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
co_awF := Sym co_awH
==> flatten awG (strange double GRefl)
inert: {co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
inert: {co_awI} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
co_awG := {co_awI} ; (Sym (GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE (Sym {co_awH}))_N)
; GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE {co_awF})_N)
at this point we also make a derived shadow of awI, for some reason.
Solving stops here, but we float out awI, and awH, and then have another go
work: {co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
work: {co_awI} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
==> flatten awI (why?)
work: {co_awH} :: p_awy[tau:1] ~# 'GHC.Types.LiftedRep
inert: {co_awJ} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
co_awI := {co_awJ} ; (Sym (GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE (Sym {co_awH}))_N) ; GRefl nominal ((forall b. [b] -> [b])
-> Int)
(TYPE (Sym {co_awH}))_N)
==> solve awH: p_awy := LiftedRep, kick out awJ
{co_awJ} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int |> (TYPE (Sym {co_awH}))_N)
==> flatten awJ
co_awJ := {co_awK} ; GRefl nominal ((forall b. [b] -> [b]) -> Int)
(TYPE (Sym {co_awH}))_N
{co_awK} :: p_awz[tau:1] ~# ((forall b. [b] -> [b]) -> Int)
```
This seems like we are doing too much work, esp the double GRefls. Why did awI get flattened?
It's not a disaster, but pretty heavy handed.Richard Eisenbergrae@richarde.devRichard Eisenbergrae@richarde.devhttps://gitlab.haskell.org/ghc/ghc/-/issues/18410Using the OS and Arch sum types from ghc-boot:GHC.Platform in System.Info2020-08-13T13:03:30ZHécateUsing the OS and Arch sum types from ghc-boot:GHC.Platform in System.InfoI am opening this ticket to resume the discussion started by @bgamari on https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3607#note_285223 regarding the usage of a proper sum type to represent OS and Architecture identifiers in [`System.Info`](https://gitlab.haskell.org/ghc/ghc/-/blob/master/libraries/base/System/Info.hs)
As said by @hsyl20, [ghc-boot:GHC.Platform](https://gitlab.haskell.org/ghc/ghc/-/blob/master/libraries/ghc-boot/GHC/Platform.hs#L112) already exports adequate data types to represent those.
The doors are open, please voice your opinion, should you have one.
To be clear, this ticket is not about the immediate deprecation of the `String`-based API, however unfortunate it may be.I am opening this ticket to resume the discussion started by @bgamari on https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3607#note_285223 regarding the usage of a proper sum type to represent OS and Architecture identifiers in [`System.Info`](https://gitlab.haskell.org/ghc/ghc/-/blob/master/libraries/base/System/Info.hs)
As said by @hsyl20, [ghc-boot:GHC.Platform](https://gitlab.haskell.org/ghc/ghc/-/blob/master/libraries/ghc-boot/GHC/Platform.hs#L112) already exports adequate data types to represent those.
The doors are open, please voice your opinion, should you have one.
To be clear, this ticket is not about the immediate deprecation of the `String`-based API, however unfortunate it may be.HécateHécatehttps://gitlab.haskell.org/ghc/ghc/-/issues/18404users-guide: links to extensions will break on ghc-8.122020-07-14T11:09:07ZTakenobu Taniusers-guide: links to extensions will break on ghc-8.12## Summary
There are lots of valuable web documents and pages on nets that refer to the extension pages of the ghc user's guide. The pages are specifying links in the following format:
```
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-ApplicativeDo
```
However, since ghc-8.12, `glasgow_exts.html` file no longer exists. Therefore, many valuable links are lost. That is, 404 will be displayed as follows:
* https://ghc.gitlab.haskell.org/ghc/doc/users_guide/glasgow_exts.html#extension-ApplicativeDo
## Proposed improvements or changes
So we need a redirect mechanism or a rescue page.
One of just idea is to rename [`users_guide/exts/table.rst`](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/table.html) to `users_guide/glasgow_exts.rst`.
It's not a perfect solution, but it does prevent a 404.
Any better idea?
## Environment
* GHC version used: ghc-8.12## Summary
There are lots of valuable web documents and pages on nets that refer to the extension pages of the ghc user's guide. The pages are specifying links in the following format:
```
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-ApplicativeDo
```
However, since ghc-8.12, `glasgow_exts.html` file no longer exists. Therefore, many valuable links are lost. That is, 404 will be displayed as follows:
* https://ghc.gitlab.haskell.org/ghc/doc/users_guide/glasgow_exts.html#extension-ApplicativeDo
## Proposed improvements or changes
So we need a redirect mechanism or a rescue page.
One of just idea is to rename [`users_guide/exts/table.rst`](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/table.html) to `users_guide/glasgow_exts.rst`.
It's not a perfect solution, but it does prevent a 404.
Any better idea?
## Environment
* GHC version used: ghc-8.129.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/18396Give (some) known-key Ids like `noinline` a special demand transformer2020-07-05T16:35:06ZSebastian GrafGive (some) known-key Ids like `noinline` a special demand transformerIn #16588, we realised that `noinline` should be treated specially in demand analysis. There was an attempt in !1761, but that was deemed too expensive (? I think) and in my opinion could be solved much more elegantly by starting to give known-key Ids like `noinline` special, more precise demand transformers. Here's a list, feel free to add more:
- `noinline`: Has the same demand transformer as its argument. Example: `uncurry (+) (noinline (x,y))`
- `runRW#`: Has a demand signature, but that is only a single point approximation of its demand transformer. See `Note [What are demand signatures?]`
- same for `catch#` and friends.
- `lazy`: Should have the Top demand transformer, for which it is sufficient that it has the default Top demand signature. Thus no special case needed.
Apparently (#16588), treatment of `noinline` is useful, so it should be tackled first.In #16588, we realised that `noinline` should be treated specially in demand analysis. There was an attempt in !1761, but that was deemed too expensive (? I think) and in my opinion could be solved much more elegantly by starting to give known-key Ids like `noinline` special, more precise demand transformers. Here's a list, feel free to add more:
- `noinline`: Has the same demand transformer as its argument. Example: `uncurry (+) (noinline (x,y))`
- `runRW#`: Has a demand signature, but that is only a single point approximation of its demand transformer. See `Note [What are demand signatures?]`
- same for `catch#` and friends.
- `lazy`: Should have the Top demand transformer, for which it is sufficient that it has the default Top demand signature. Thus no special case needed.
Apparently (#16588), treatment of `noinline` is useful, so it should be tackled first.https://gitlab.haskell.org/ghc/ghc/-/issues/18395More uses of HasDebugCallStack2020-07-13T15:38:04ZSimon Peyton JonesMore uses of HasDebugCallStackFor functions that can fail (with a panic) inside GHC, we use `HasDebugCallStack =>` in the type to get more info about who called the function. Periodically we add more. They should have no effect in a non-DEBUG compiler.
This ticket is just a peg to hang MRs that add (or remove) `HasDebugCallStack` debug traces.
* !3597 added a few `HasDebugCallStack` traces in substitution over CoreFor functions that can fail (with a panic) inside GHC, we use `HasDebugCallStack =>` in the type to get more info about who called the function. Periodically we add more. They should have no effect in a non-DEBUG compiler.
This ticket is just a peg to hang MRs that add (or remove) `HasDebugCallStack` debug traces.
* !3597 added a few `HasDebugCallStack` traces in substitution over Corehttps://gitlab.haskell.org/ghc/ghc/-/issues/18394Document fragility of hDuplicateTo2020-07-05T16:34:25ZchessaiDocument fragility of hDuplicateTo## Summary
Using GHC.IO.hDuplicateTo in a concurrent setting can cause some unpredictable failures. I don't think there's anything we can do about this, but we can at least document it. Related to #16819## Summary
Using GHC.IO.hDuplicateTo in a concurrent setting can cause some unpredictable failures. I don't think there's anything we can do about this, but we can at least document it. Related to #16819https://gitlab.haskell.org/ghc/ghc/-/issues/18387Follow-up from "WIP: Make UniqFM typed on it's key"2020-07-05T16:33:51ZAndreas KlebingerFollow-up from "WIP: Make UniqFM typed on it's key"The following discussion from !3577 should be addressed:
- [ ] @rae started a [discussion](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3577#note_283976):
> Ew. Is there a function that can be written that avoids going via a list?
```haskell
transClosureFV :: VarEnv VarSet -> VarEnv VarSet
-- If (f,g), (g,h) are in the input, then (f,h) is in the output
-- as well as (f,g), (g,h)
transClosureFV env
| no_change = env
| otherwise = transClosureFV (listToUFM_Directly new_fv_list)
where
(no_change, new_fv_list) = mapAccumL bump True (nonDetUFMToList env)
-- It's OK to use nonDetUFMToList here because we'll forget the
-- ordering by creating a new set with listToUFM
bump no_change (b,fvs)
| no_change_here = (no_change, (b,fvs))
| otherwise = (False, (b,new_fvs))
where
(new_fvs, no_change_here) = extendFvs env fvs
```The following discussion from !3577 should be addressed:
- [ ] @rae started a [discussion](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3577#note_283976):
> Ew. Is there a function that can be written that avoids going via a list?
```haskell
transClosureFV :: VarEnv VarSet -> VarEnv VarSet
-- If (f,g), (g,h) are in the input, then (f,h) is in the output
-- as well as (f,g), (g,h)
transClosureFV env
| no_change = env
| otherwise = transClosureFV (listToUFM_Directly new_fv_list)
where
(no_change, new_fv_list) = mapAccumL bump True (nonDetUFMToList env)
-- It's OK to use nonDetUFMToList here because we'll forget the
-- ordering by creating a new set with listToUFM
bump no_change (b,fvs)
| no_change_here = (no_change, (b,fvs))
| otherwise = (False, (b,new_fvs))
where
(new_fvs, no_change_here) = extendFvs env fvs
```8.14.1https://gitlab.haskell.org/ghc/ghc/-/issues/18386Do longer experiment of GHCi on multiple console hosts2020-07-05T16:33:44ZTamar ChristinaDo longer experiment of GHCi on multiple console hostsDouble check that GHCi still works correctly after latest changes on:
* cmd
* powershell
* Windows terminal
* rxvt
* msys shellsDouble check that GHCi still works correctly after latest changes on:
* cmd
* powershell
* Windows terminal
* rxvt
* msys shells9.0.1Tamar ChristinaTamar Christinahttps://gitlab.haskell.org/ghc/ghc/-/issues/18385Write release notes and migration guide for winio2020-07-05T16:33:35ZTamar ChristinaWrite release notes and migration guide for winiowrite the release notes and migration guide for WinIO.write the release notes and migration guide for WinIO.9.0.1Tamar ChristinaTamar Christina