GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2024-01-30T14:59:19Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24357Backpack Regression for Representation-Polymorphic Binders2024-01-30T14:59:19ZAndrew MartinBackpack Regression for Representation-Polymorphic Binders## Summary
If you use `let x = Z`, where the type of `Z` is `TYPE R`, where `R` is an abstract top-level runtime rep from a signature, you get a compiler panic. But if you write `case Z of {x -> ...}`, the panic goes away.
This did not...## Summary
If you use `let x = Z`, where the type of `Z` is `TYPE R`, where `R` is an abstract top-level runtime rep from a signature, you get a compiler panic. But if you write `case Z of {x -> ...}`, the panic goes away.
This did not happen in GHC 8.10 or in GHC 9.2 (I have not tested GHC 9.0), but it happens in GHC 9.4 and every release since then.
## Steps to reproduce
Here is a minimal reproducer:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
unit example where
signature Order where
import GHC.Exts
data R :: RuntimeRep
data E :: TYPE R
pickMinimum :: E -> E -> E
pickMaximum :: E -> E -> E
module OrderedPair where
import Order (E,pickMinimum,pickMaximum)
makeOrderedPair :: E -> E -> (# E, E #)
makeOrderedPair a b =
let greater = pickMaximum a b
lesser = pickMinimum a b
in (# greater, lesser #)
Building this with `ghc --backpack buggy.bkp` results in:
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.6.4:
isUnliftedType
E :: TYPE R
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic
pprPanic, called at compiler/GHC/Core/Type.hs:2257:7 in ghc:GHC.Core.Type
CallStack (from HasCallStack):
panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error
Notice that we do not have to instantiate the indefinite unit to trigger the bug. Merely defining it is enough. The problematic lines (not indicated by the error message) are the binding sites of `greater` and `lesser`. If we bind using `case` instead of `let`, GHC is able to compile the program. My observation in larger projects that instantiate functions like this is that everything else downstream works once we trick GHC into correctly compiling the function. Here is the workaround using `case` instead of `let`:
makeOrderedPair :: E -> E -> (# E, E #)
makeOrderedPair a b = case pickMaximum a b of
greater -> case pickMinimum a b of
lesser -> (# greater, lesser #)
## Context Around Why This Might Be Happening
I'm not sure why this is happening, and I am not able to dig into it. Here's what I've considered. In GHC, `isUnliftedType` is defined like this:
```
isUnliftedType :: HasDebugCallStack => Type -> Bool
isUnliftedType ty =
case typeLevity_maybe ty of
Just Lifted -> False
Just Unlifted -> True
Nothing -> pprPanic "isUnliftedType" (ppr ty <+> dcolon <+> ppr (typeKind ty))
```
So representation-polymorphic types lead to panics. In an indefinite module, we still want to panic when we encounter a binding whose type's runtime representation includes a locally bound `Rep`. But we do not want to panic when the representation is a top-level abstract representation. I've not been able to investigate this further.
## Environment
* GHC versions that trigger the panic: 9.4, 9.6, 9.8
* GHC versions that do not trigger the panic: 8.10, 9.2sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/24202DataToTag instances in signature files don't work2023-11-21T23:06:40ZMatthew Cravenclyring@gmail.comDataToTag instances in signature files don't work## Summary
Since !8912 landed, signature files are allowed to contain/request instances for the special `DataToTag` class. But these are not actually usable, and fail with a very unhelpful error message.
In principle there is no reason...## Summary
Since !8912 landed, signature files are allowed to contain/request instances for the special `DataToTag` class. But these are not actually usable, and fail with a very unhelpful error message.
In principle there is no reason it shouldn't be possible to support `DataToTag` instances in signatures, but doing so doesn't appear completely trivial and there seems to be little or no demand for this feature.
See also the test case `T15379-DataToTag`.https://gitlab.haskell.org/ghc/ghc/-/issues/24065panic: Given constraint without given origin2023-10-10T14:18:53ZRodrigo Mesquitapanic: Given constraint without given origin## Summary
During compilation of a backpack heavy library I get the following error:
```
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.6.2:
Given constraint without given origin
$dApplicative_aafq
...## Summary
During compilation of a backpack heavy library I get the following error:
```
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.6.2:
Given constraint without given origin
$dApplicative_aafq
arising when attempting to show that
instance [safe] Applicative m => Applicative (CommandM m)
-- Defined in ‘Ghengin.Vulkan.Renderer.Command’
is provided by ‘Ghengin.Vulkan.Renderer.Command’
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic
pprPanic, called at compiler/GHC/Tc/Solver/Canonical.hs:600:31 in ghc:GHC.Tc.Solver.Canonical
CallStack (from HasCallStack):
panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error
```
Unfortunately, my reproducer is *far* from minimal.
It's reproducible by cloning at a particular commit a considerably large project...
Nonetheless, I figured I should report it.
## Steps to reproduce
```
git clone https://github.com/alt-romes/ghengin.git && cd ghengin
git checkout 2e007f0c9bf88018db424d11c96b2de9b0b4d14a
cabal build ghengin-core
```
## Environment
* GHC version used: 9.6.2
Optional:
* Operating System: macOS
* System Architecture: M2 / Aarch64https://gitlab.haskell.org/ghc/ghc/-/issues/23648bkpcabal08 now has non-deterministic output2023-08-04T16:26:25ZBen Gamaribkpcabal08 now has non-deterministic outputSince updating the `Cabal` submodule in 1228d3a4a08d30eaf0138a52d1be25b38339ef0b, the `bkpcabal08` test now has non-deterministic output. Specifically, we see spurious changes of the shape:
```patch
--- /var/folders/4t/wfp01mj9693c09ymg0...Since updating the `Cabal` submodule in 1228d3a4a08d30eaf0138a52d1be25b38339ef0b, the `bkpcabal08` test now has non-deterministic output. Specifically, we see spurious changes of the shape:
```patch
--- /var/folders/4t/wfp01mj9693c09ymg070wvs40000hm/T/ghctest-yx1dtmlg/test spaces/testsuite/tests/backpack/cabal/bkpcabal08/bkpcabal08.run/bkpcabal08.stdout.normalised 2023-07-13 02:55:25.000000000 -0400
+++ /var/folders/4t/wfp01mj9693c09ymg070wvs40000hm/T/ghctest-yx1dtmlg/test spaces/testsuite/tests/backpack/cabal/bkpcabal08/bkpcabal08.run/bkpcabal08.run.stdout.normalised 2023-07-13 02:55:25.000000000 -0400
@@ -1,11 +1,11 @@
-Preprocessing library 'impl' for bkpcabal08-<VERSION>-<HASH>
-Building library 'impl' for bkpcabal08-<VERSION>-<HASH>
Preprocessing library 'p' for bkpcabal08-<VERSION>-<HASH>
Building library 'p' instantiated with
A = <A>
B = <B>
for bkpcabal08-<VERSION>-<HASH>
[2 of 2] Compiling B[sig] ( p/B.hsig, nothing )
+Preprocessing library 'impl' for bkpcabal08-<VERSION>-<HASH>
+Building library 'impl' for bkpcabal08-<VERSION>-<HASH>
Preprocessing library 'q' for bkpcabal08-<VERSION>-<HASH>
Building library 'q' instantiated with
A = <A>
@@ -19,7 +19,7 @@
A = bkpcabal08-<VERSION>-<HASH>:A
B = bkpcabal08-<VERSION>-<HASH>:B
for bkpcabal08-<VERSION>-<HASH>
-[1 of 3] Compiling A[sig] ( q/A.hsig, dist/build/bkpcabal08-<VERSION>-<HASH>+5IA1jA4bEzCFcXtraqAC38/A.o ) [Prelude package changed]
-[2 of 3] Compiling B[sig] ( q/B.hsig, dist/build/bkpcabal08-<VERSION>-<HASH>+5IA1jA4bEzCFcXtraqAC38/B.o ) [Prelude package changed]
+[1 of 3] Compiling A[sig] ( q/A.hsig, dist/build/bkpcabal08-<VERSION>-<HASH>+J0rW2GVAn1n7KqPCQDq1Pq/A.o ) [Prelude package changed]
+[2 of 3] Compiling B[sig] ( q/B.hsig, dist/build/bkpcabal08-<VERSION>-<HASH>+J0rW2GVAn1n7KqPCQDq1Pq/B.o ) [Prelude package changed]
Preprocessing library 'r' for bkpcabal08-<VERSION>-<HASH>
Building library 'r' for bkpcabal08-<VERSION>-<HASH>
```https://gitlab.haskell.org/ghc/ghc/-/issues/23443Backpack silently substitutes missing signatures with empty ones instead of t...2023-05-30T15:09:36ZBartłomiej CieślarBackpack silently substitutes missing signatures with empty ones instead of throwing an error## Motivation
It's easy to mistakenly name signature files with .sig instead of .hsig. In such a situation, instead of throwing an error, backpack will assume a file with no definitions and proceed to throw an error during renaming inst...## Motivation
It's easy to mistakenly name signature files with .sig instead of .hsig. In such a situation, instead of throwing an error, backpack will assume a file with no definitions and proceed to throw an error during renaming instead of on the cabal-level. With how buggy that part of the codebase can sometimes be, it makes it often difficult to figure out whether the error stems from backpack or the code compiled with it.
## Proposal
Throw an error when a signature file is not found instead of silently assuming an empty signaturehttps://gitlab.haskell.org/ghc/ghc/-/issues/23437Backpack shadowing of same-named signatures necessitates different home units...2023-05-23T15:08:40ZBartłomiej CieślarBackpack shadowing of same-named signatures necessitates different home units for signatures in different home units in bkp files## Motivation
Because backpack currently does not differentiate between modules with the same name in the same bkp file, trying to add features that load interface files during the processing of backpack (e.g. [!10283](https://gitlab.ha...## Motivation
Because backpack currently does not differentiate between modules with the same name in the same bkp file, trying to add features that load interface files during the processing of backpack (e.g. [!10283](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10283)) introduces aliasing issues in some cases.
For example, in test `bkp44` trying to load signature `p:B` when `q:A` has been merged, it causes the type checking of `p:B` to try to import `q:A` instead of `p:A`, which in turn causes an error where `A.T` was not found in `A` (because `q:A` restricts the imports of `p:A`)
## Proposal
Like with GHCi, make bkp signatures from different units be cached in different home units, which will remove the aliasing issue. In that case, also remove the workaround for export deprecations in signature merging where the ImpSpec module is set to a hole module instead of the actual source signaturehttps://gitlab.haskell.org/ghc/ghc/-/issues/23350Backpack panic: Duplicate nodes keys in backpack file2023-05-05T13:01:10Zsheafsam.derbyshire@gmail.comBackpack panic: Duplicate nodes keys in backpack fileConsider this `.bkp` file:
```haskell
unit p where
signature H where
unit q where
module H where
unit r where
dependency p
dependency q[H=p:H]
```
There's a mistake: we mixed up `p` and `q` in the unit `r`.
This causes the f...Consider this `.bkp` file:
```haskell
unit p where
signature H where
unit q where
module H where
unit r where
dependency p
dependency q[H=p:H]
```
There's a mistake: we mixed up `p` and `q` in the unit `r`.
This causes the following panic:
```
ghc: panic! (the 'impossible' happened)
GHC version 9.7.20230504:
Duplicate nodes keys in backpack file
[q+q-9dU7VXZcSfk3MwGleJHyst:H, q+q-9dU7VXZcSfk3MwGleJHyst:H]
```
I am inclined to believe this is a bkpism (affects only the `.bkp` format and not `cabal` projects that use Backpack), but I haven't checked.https://gitlab.haskell.org/ghc/ghc/-/issues/23344Backpack accepts invalid impredicativity in implementation of abstract data2023-05-15T22:33:56Zsheafsam.derbyshire@gmail.comBackpack accepts invalid impredicativity in implementation of abstract dataWhen checking that `type T = rhs` is a valid implementation of an abstract data declaration `data T`, backpack fails to check whether `rhs` contains any nested foralls, which means it accepts e.g.
```haskell
{-# LANGUAGE StandaloneKindS...When checking that `type T = rhs` is a valid implementation of an abstract data declaration `data T`, backpack fails to check whether `rhs` contains any nested foralls, which means it accepts e.g.
```haskell
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ImpredicativeTypes #-}
unit p where
module M where
import Data.Kind
type C :: Type -> Constraint
class C a where
type family F a :: Type
unit q where
dependency p
signature H where
data T
module N where
import M ( C(F) )
import H ( T )
instance C T where
type F T = T
unit r where
dependency p
module H where
import Data.Kind
type S :: Type -> Type
data S a = MkS
type T = S (forall (a :: Type). a -> a)
unit s where
dependency p
dependency r
dependency q[H=r:H]
```
There should be a check that mirrors the check that there are no type family applications in the RHS.sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/23342Backpack: poor error message implementing abstract data with a forall type2023-05-15T22:33:56Zsheafsam.derbyshire@gmail.comBackpack: poor error message implementing abstract data with a forall typeBackpack currently accepts an abstract data type to be implemented as a forall or quantified type:
```haskell
unit p where
signature H where
data T1
data T2
data T3
unit q where
module H where
class C a where {}
...Backpack currently accepts an abstract data type to be implemented as a forall or quantified type:
```haskell
unit p where
signature H where
data T1
data T2
data T3
unit q where
module H where
class C a where {}
data S
type T1 = forall a. a -> a
type T2 = forall a. C a => a
type T3 = C S => S -> S
unit r where
dependency q
dependency p[H=q:H]
```
We get errors like the following:
```
* Type constructor `T3' has conflicting definitions in the module
and its hsig file
Main module: type T3 :: *
type T3 = C S => S -> S
Hsig file: type T3 :: *
data T3
```
It doesn't specify what the issue is (that a quantified type is not allowed in the RHS of the type synonym implementing the abstract datatype).sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/23322Backpack: Import standalone modules from indefinite packages in instancing mo...2023-07-02T23:06:56ZRodrigo MesquitaBackpack: Import standalone modules from indefinite packages in instancing modules failsSay I have the following modules and signatures in a cabal project
```haskell
module A where
data SomeUsefulThing = SomeUsefulThing
```
```haskell
signature B where
import A
someUsefulFun :: SomeUsefulThing -> ()
```
```haskell
module...Say I have the following modules and signatures in a cabal project
```haskell
module A where
data SomeUsefulThing = SomeUsefulThing
```
```haskell
signature B where
import A
someUsefulFun :: SomeUsefulThing -> ()
```
```haskell
module B.Instance where
import A
someUsefulFun :: SomeUsefulThing -> ()
someUsefulFun SomeUsefulThing = ()
```
Note that in B's signature and instance, `someUsefulFun` share the same type `SomeUsefulThing` imported from `A`.
```haskell
import A
import B
main = pure (someUsefulFun SomeUsefulThing)
```
```cabal
cabal-version: 3.4
name: ex2
version: 0.1.0.0
build-type: Simple
library pa
build-depends: base
exposed-modules: A
signatures: B
hs-source-dirs: pa
library pb
build-depends: base, ex2:pa
exposed-modules: B.Instance
hs-source-dirs: pb
library
exposed-modules: Main
build-depends: base, ex2:pa, ex2:pb
mixins: ex2:pa requires (B as B.Instance),
hs-source-dirs: main
```
When compiling this project, it fails with
```
<no location info>: error:
• Identifier ‘someUsefulFun’ has conflicting definitions in the module
and its hsig file
Main module: someUsefulFun ::
ex2-0.1.0.0:pa[B=<B>]:A.SomeUsefulThing -> ()
Hsig file: someUsefulFun :: A.SomeUsefulThing -> ()
The two types are different
• while checking that B.Instance implements signature B in ex2-0.1.0.0:pa[B=B.Instance]
```
The cause is `SomeUsefulThing`, in the context of `pa` is imported from `A`, but in the context of `pb`, is imported from `ex2:pa[B=<B>]:A`.
I think it should be possible to use the shared definition of `SomeUsefulThing`, since `A` is a completely standalone module (doesn't depend on any indefinite signatures). Even if it did, it is reasonable to think it should also work.
Is this a fundamental limitation or something we can overcome?
Many thanks.sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/23315Documentation declarations not attached to signature module ASTs2023-07-21T12:02:33ZFinley McIlwaineDocumentation declarations not attached to signature module ASTs## Summary
The parser for signature modules does not include docs in the resulting AST as the parser for regular modules does.
## Steps to reproduce
A fairly minimal reproducer follows.
`sig-parse.cabal`:
```
cabal-version: 3.8
name:...## Summary
The parser for signature modules does not include docs in the resulting AST as the parser for regular modules does.
## Steps to reproduce
A fairly minimal reproducer follows.
`sig-parse.cabal`:
```
cabal-version: 3.8
name: sig-parse
version: 0.1.0
library
build-depends: base
signatures: A
exposed-modules: B
```
`A.hsig`:
```
signature A where
-- | Just '()'
a :: ()
-- ^ More docs
```
`B.hs`:
```
module B where
-- | Just '()'
b :: ()
-- ^ More docs
```
Although this will fail to build due to the lack of an accompanying binding for `b`, it will still parse. I've made the modules as similar as possible for the sake of comparison between their ASTs.
Running `cabal build --ghc-options=-haddock -ddump-to-file -ddump-parsed-ast` yields the following dumps.
`A.dump-parsed-ast`:
```
==================== Parser AST ====================
2023-04-28 01:56:46.534016 UTC
(L
{ A.hsig:1:1 }
(HsModule
(XModulePs
(EpAnn
(Anchor
{ A.hsig:1:1 }
(UnchangedAnchor))
(AnnsModule
[(AddEpAnn AnnSignature (EpaSpan { A.hsig:1:1-9 }))
,(AddEpAnn AnnWhere (EpaSpan { A.hsig:1:13-17 }))]
(AnnList
(Nothing)
(Nothing)
(Nothing)
[]
[]))
(EpaComments
[]))
(VirtualBraces
(1))
(Nothing)
(Nothing))
(Just
(L
(SrcSpanAnn (EpAnnNotUsed) { A.hsig:1:11 })
{ModuleName: A}))
(Nothing)
[]
[(L
(SrcSpanAnn (EpAnn
(Anchor
{ A.hsig:4:1-7 }
(UnchangedAnchor))
(AnnListItem
[])
(EpaComments
[])) { A.hsig:4:1-7 })
(SigD
(NoExtField)
(TypeSig
(EpAnn
(Anchor
{ A.hsig:4:1 }
(UnchangedAnchor))
(AnnSig
(AddEpAnn AnnDcolon (EpaSpan { A.hsig:4:3-4 }))
[])
(EpaComments
[]))
[(L
(SrcSpanAnn (EpAnnNotUsed) { A.hsig:4:1 })
(Unqual
{OccName: a}))]
(HsWC
(NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { A.hsig:4:6-7 })
(HsSig
(NoExtField)
(HsOuterImplicit
(NoExtField))
(L
(SrcSpanAnn (EpAnnNotUsed) { A.hsig:4:6-7 })
(HsTupleTy
(EpAnn
(Anchor
{ A.hsig:4:6 }
(UnchangedAnchor))
(AnnParen
(AnnParens)
(EpaSpan { A.hsig:4:6 })
(EpaSpan { A.hsig:4:7 }))
(EpaComments
[]))
(HsBoxedOrConstraintTuple)
[]))))))))]))
```
`B.dump-parsed-ast`:
```
==================== Parser AST ====================
2023-04-28 01:56:46.556019 UTC
(L
{ B.hs:1:1 }
(HsModule
(XModulePs
(EpAnn
(Anchor
{ B.hs:1:1 }
(UnchangedAnchor))
(AnnsModule
[(AddEpAnn AnnModule (EpaSpan { B.hs:1:1-6 }))
,(AddEpAnn AnnWhere (EpaSpan { B.hs:1:10-14 }))]
(AnnList
(Nothing)
(Nothing)
(Nothing)
[]
[]))
(EpaCommentsBalanced
[]
[(L
(Anchor
{ B.hs:6:1 }
(UnchangedAnchor))
(EpaComment
(EpaEofComment)
{ B.hs:6:1 }))]))
(VirtualBraces
(1))
(Nothing)
(Nothing))
(Just
(L
(SrcSpanAnn (EpAnnNotUsed) { B.hs:1:8 })
{ModuleName: B}))
(Nothing)
[]
[(L
(SrcSpanAnn (EpAnnNotUsed) { B.hs:3:1-14 })
(DocD
(NoExtField)
(DocCommentNext
(L
{ B.hs:3:1-14 }
(WithHsDocIdentifiers
(MultiLineDocString
(HsDocStringNext)
(:|
(L
{ B.hs:3:5-14 }
(HsDocStringChunk
" Just '()'"))
[]))
[])))))
,(L
(SrcSpanAnn (EpAnn
(Anchor
{ B.hs:4:1-7 }
(UnchangedAnchor))
(AnnListItem
[])
(EpaComments
[])) { B.hs:4:1-7 })
(SigD
(NoExtField)
(TypeSig
(EpAnn
(Anchor
{ B.hs:4:1 }
(UnchangedAnchor))
(AnnSig
(AddEpAnn AnnDcolon (EpaSpan { B.hs:4:3-4 }))
[])
(EpaComments
[]))
[(L
(SrcSpanAnn (EpAnnNotUsed) { B.hs:4:1 })
(Unqual
{OccName: b}))]
(HsWC
(NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { B.hs:4:6-7 })
(HsSig
(NoExtField)
(HsOuterImplicit
(NoExtField))
(L
(SrcSpanAnn (EpAnnNotUsed) { B.hs:4:6-7 })
(HsTupleTy
(EpAnn
(Anchor
{ B.hs:4:6 }
(UnchangedAnchor))
(AnnParen
(AnnParens)
(EpaSpan { B.hs:4:6 })
(EpaSpan { B.hs:4:7 }))
(EpaComments
[]))
(HsBoxedOrConstraintTuple)
[]))))))))
,(L
(SrcSpanAnn (EpAnnNotUsed) { B.hs:5:1-14 })
(DocD
(NoExtField)
(DocCommentPrev
(L
{ B.hs:5:1-14 }
(WithHsDocIdentifiers
(MultiLineDocString
(HsDocStringPrevious)
(:|
(L
{ B.hs:5:5-14 }
(HsDocStringChunk
" More docs"))
[]))
[])))))]))
```
Notice that the signature module AST (`A.hsig`) lacks any `DocD` declarations in its AST.
## Expected behavior
I would expect signature module ASTs to be populated with `DocD` declarations, as regular modules are.
## Environment
* GHC version used: 9.6.1 (reproduced on HEAD as well)
* Cabal version used: 3.6.2.0Finley McIlwaineFinley McIlwainehttps://gitlab.haskell.org/ghc/ghc/-/issues/23080Backpack nameModule panic2023-03-06T14:03:11Zsheafsam.derbyshire@gmail.comBackpack nameModule panicThe following variation on the `bkpreex01` test causes a panic:
```haskell
unit t23080-unit1 where
signature H1 where
data T
unit t23080-unit2 where
dependency t23080-unit1[H1=<H2>]
module B where
data T = MkT
signature ...The following variation on the `bkpreex01` test causes a panic:
```haskell
unit t23080-unit1 where
signature H1 where
data T
unit t23080-unit2 where
dependency t23080-unit1[H1=<H2>]
module B where
data T = MkT
signature H2(T(MkT)) where
import B
```
```
λ ghc --backpack T23080.bkp
[1 of 2] Processing t23080-unit1
[1 of 1] Compiling H1[sig] ( t23080-unit1\H1.hsig, nothing )
[2 of 2] Processing t23080-unit2
[1 of 3] Compiling B ( t23080-unit2\B.hs, nothing )
[2 of 3] Compiling H2[sig] ( t23080-unit2\H2.hsig, nothing )
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.4.4:
nameModule
internal MkT_02y
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler\GHC\Utils\Panic.hs:182:37 in ghc:GHC.Utils.Panic
pprPanic, called at compiler\GHC\Types\Name.hs:325:3 in ghc:GHC.Types.Name
Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
```
The issue has to do with the export of the data constructor `MkT` from `H2`... changing the export to `T(..)` makes the panic go away.https://gitlab.haskell.org/ghc/ghc/-/issues/22945Backpack, mergeSignatures is called when there are no signatures to merge2023-02-14T16:13:55ZMatthew PickeringBackpack, mergeSignatures is called when there are no signatures to mergeThe `mergeSignatures` code is complicated and looks expensive it would be better to avoid the complexity of calling it if there are no signatures to merge.
This works around #22944 for example.The `mergeSignatures` code is complicated and looks expensive it would be better to avoid the complexity of calling it if there are no signatures to merge.
This works around #22944 for example.https://gitlab.haskell.org/ghc/ghc/-/issues/22944Backpack signatures can't be compiled in one shot mode2023-02-14T16:15:14ZMatthew PickeringBackpack signatures can't be compiled in one shot mode```
signature Sig where
data A
data B
foo :: A -> B
```
```
[nix-shell:~/ghc-abi]$ ghc Sig.hsig -this-component-id sig -instantiated-with Sig=\<Sig\> -this-unit-id=sig -c
typecheckIfacesForMerging
Declaration for foo:
Bad interface ...```
signature Sig where
data A
data B
foo :: A -> B
```
```
[nix-shell:~/ghc-abi]$ ghc Sig.hsig -this-component-id sig -instantiated-with Sig=\<Sig\> -this-unit-id=sig -c
typecheckIfacesForMerging
Declaration for foo:
Bad interface file: Sig.hi
Sig.hi: openBinaryFile: does not exist (No such file or directory)
Cannot continue after interface file error
```https://gitlab.haskell.org/ghc/ghc/-/issues/22234Backpack insufficiently thins interfaces when recompiling2022-09-29T22:46:28ZMatthew PickeringBackpack insufficiently thins interfaces when recompiling
The backpack test bkp44 started failing in the implementaiton of !8995, which provides stronger determinism guarantees for when interface files are loaded. It turns out that this revealed a latent issue in the recompilation checking log...
The backpack test bkp44 started failing in the implementaiton of !8995, which provides stronger determinism guarantees for when interface files are loaded. It turns out that this revealed a latent issue in the recompilation checking logic of backpack.
Here is a modified version of bkp44 which works with cabal - [bkp44-b.zip](/uploads/cd9d315fc1c9d8c7c4af229f940a93a6/bkp44-b.zip)
For reference, the equivalent `.bkp`:
```haskell
unit p where
signature A where
data T
signature B where
import A
y :: T
unit q where
dependency signature p[A=<C>,B=<D>]
signature C () where
signature D () where
```
The first time you build `bkp44-b`, the build works fine.
If you modify `B.hsig` to add anything, say `e :: Bool`, and run `cabal build` again, then you get a recompilation error:
```
Resolving dependencies...
Build profile: -w ghc-9.2.2 -O1
In order, the following will be built (use -v for more details):
- bkp44-b-0.1.0.0 (lib:p) (configuration changed)
- bkp44-b-0.1.0.0 (lib:q) (configuration changed)
Configuring library 'p' for bkp44-b-0.1.0.0..
Preprocessing library 'p' for bkp44-b-0.1.0.0..
Building library 'p' instantiated with
A = <A>
B = <B>
for bkp44-b-0.1.0.0..
Configuring library 'q' for bkp44-b-0.1.0.0..
Preprocessing library 'q' for bkp44-b-0.1.0.0..
Building library 'q' instantiated with
C = <C>
D = <D>
for bkp44-b-0.1.0.0..
<no location info>: error:
The identifier T does not exist in the signature for <C>
(Try adding it to the export list in that hsig file.)
```
If you turn on `-ddump-if-trace`, then you see `B.hi` is loaded to check if the hash is the same as before.
```
Reading interface for bkp44-b-0.1.0.0-inplace-p:B;
reason: need version info for B
readIFace /home/matt/Downloads/bkp44b/dist-newstyle/build/x86_64-linux/ghc-9.2.2/bkp44-b-0.1.0.0/l/p/build/p/B.hi
```
and then the error comes from `computeInterface` which attempts to rename the interface for `B` because `B` is instantiated to `D`.
In order to properly thin the module you need to know the exports of module `D` and apply that before the renaming happens (so we don't try to rename `y` and hence `T`, which are not part of the thinning). However it's not clear when loading the interface to check the hash of B how to determine what the exports of D are.. we haven't committed to compiling D yet and don't know if the interface is up to date.https://gitlab.haskell.org/ghc/ghc/-/issues/21125Cyclic backpack2023-02-27T14:11:58ZJohn EricsonCyclic backpackBackpack is very similar to hs-boot, but while hs-boot can break cycles (that is it's main purpose!) backpack cannot yet.
@ezyang has written about this so I was surprised I couldn't find an existing issue.
Here is a rough plan:
1. (#...Backpack is very similar to hs-boot, but while hs-boot can break cycles (that is it's main purpose!) backpack cannot yet.
@ezyang has written about this so I was surprised I couldn't find an existing issue.
Here is a rough plan:
1. (#20890) Use multiple home unit support to get rid of the backpack-specific rewrites
2. Do enough of https://gitlab.haskell.org/ghc/ghc/-/issues/20030 so the work graph properly understands hs-boot / hsig, and instantiation nodes. I linked some backpack bugs that should be solved by that to the ticket.
3. Dedup backpack and hs-boot. With better instantiation nodes, I think that should be fairly straight-forward.
4. Get cylic backpack for almost free, since hs-boot suports it.
Note that https://gitlab.haskell.org/ghc/ghc/-/issues/14095 will also benefit from doing this step might either be helped by this or become a dependency of this. Basically, as the module graph increasingly understands how with hs-boot/hsig we don't compiler/link, and with regular hs corresponding to those two we need to do "extra typechecking", the module graph will inevitably start becoming aware of intra-module compilation stage dependencies.https://gitlab.haskell.org/ghc/ghc/-/issues/20890Multiple home units and Backpack together2024-02-12T13:02:19ZMatthew PickeringMultiple home units and Backpack togetherMultiple Home Units opens up some more natural implementation strategies for backpack but currently
Opportunities
* Unit instantiations can be expressed more naturally in terms of unit dependencies rather than shoe-horned into the mod...Multiple Home Units opens up some more natural implementation strategies for backpack but currently
Opportunities
* Unit instantiations can be expressed more naturally in terms of unit dependencies rather than shoe-horned into the module graph.
Known Problems
* Hole units assume a singular home unit (see the special case for `loadInterface` for `isHoleModule`).
* No tests at all combining MHU/Backpack
All we need is a backpack lover to try and wrangle things so that things work nicely!https://gitlab.haskell.org/ghc/ghc/-/issues/20701Remove implicit module declaration syntax in .bkp mode2021-11-20T17:39:27ZMatthew PickeringRemove implicit module declaration syntax in .bkp mode.bkp mode had this unused feature where you could write
```
module A
```
and it would go looking for A.hs on the file system and use that rather
than provide the definition inline.
This isn't use anywhere in the testsuite a....bkp mode had this unused feature where you could write
```
module A
```
and it would go looking for A.hs on the file system and use that rather
than provide the definition inline.
This isn't use anywhere in the testsuite and the code to find the module
A looks dubious. Therefore to reduce .bkp complexity I propose to remove
it.https://gitlab.haskell.org/ghc/ghc/-/issues/20522Backpack puts information in the EPS that depends on the HPT, causing issues ...2022-02-23T20:02:02Zsheafsam.derbyshire@gmail.comBackpack puts information in the EPS that depends on the HPT, causing issues with recompilationI've noticed a strange interaction of Backpack with `GHCi`. For readability I'm giving the test case as a `.bkp`, but note that as `--backpack` isn't supported by `GHCi`, the actual test case uses cabal.
```haskell
unit p where
sign...I've noticed a strange interaction of Backpack with `GHCi`. For readability I'm giving the test case as a `.bkp`, but note that as `--backpack` isn't supported by `GHCi`, the actual test case uses cabal.
```haskell
unit p where
signature H where
data S1
data S2
module A where
import H
data T = T S1 S2
unit q where
dependency p[H=<H2>] (A as A2)
module L where
data S1 = MkS1
signature H2(S1(MkS1), S2) where
import L
data S2
module B where
import A2
import H2
t = T :: S1 -> S2 -> T
```
When processing `q`, we instantiate `p` with `H = H2` and add it to the EPS, even though it refers to `L` and `H2` which are in the HPT. This is a problem, as the EPS is supposed to only contain stable information, whereas the HPT can be updated; any change to the HPT will not be reflected in the EPS and thus will refer to out of date information.
To demonstrate this, we can load everything in GHCi, change `H2` and reload. (Recall: using cabal, not `--backpack` mode which doesn't work with `GHCi`.)
```
[1 of 2] Compiling H[sig] ( p\H.hsig, nothing )
[2 of 2] Compiling A ( p\A.hs, nothing )
[1 of 1] Instantiating bkp10-0-inplace-p
[1 of 4] Compiling H2[sig] ( q\H2.hsig, nothing )
[2 of 4] Instantiating bkp10-0-inplace-p
[3 of 4] Compiling B ( q\B.hs, nothing )
[4 of 4] Compiling L ( q\L.hs, nothing )
Ok, three modules loaded.
now I change H2 so that S1 is defined in H2 instead of imported from L
ghci> :r
[2 of 4] Compiling H2[sig] ( q\H2.hsig, nothing ) [Source file changed]
[3 of 4] Instantiating bkp10-0-inplace-p
[4 of 4] Compiling B ( q\B.hs, nothing ) [H2 changed]
q\B.hs:4:9: error:
* Couldn't match type `{H2.S1}' with `S1'
Expected: S1 -> S2 -> T
Actual: {H2.S1} -> S2 -> T
NB: `S1' is defined at q\L.hs:3:3-16
`{H2.S1}' is defined at q\H2.hsig:3:5-11
if I quit and restart, it works:
[1 of 1] Instantiating bkp10-0-inplace-p
[3 of 4] Instantiating bkp10-0-inplace-p
[4 of 4] Compiling B ( q\B.hs, nothing ) [H2 changed]
Ok, three modules loaded.
```https://gitlab.haskell.org/ghc/ghc/-/issues/20517Backpack doesn't reject insufficiently instantiated units early enough2022-02-23T14:03:03Zsheafsam.derbyshire@gmail.comBackpack doesn't reject insufficiently instantiated units early enoughFailing to instantiate a unit which has free holes does not raise an error when it should, so we get a confusing error later on:
```haskell
unit p where
signature H where
data S
unit q where
dependency p -- we should instantiat...Failing to instantiate a unit which has free holes does not raise an error when it should, so we get a confusing error later on:
```haskell
unit p where
signature H where
data S
unit q where
dependency p -- we should instantiate, e.g. by writing p[H=<H>], but we don't
module N where
import H
```
```
error:
Could not find module `H'
It is not a module in the current program, or in any known package.
|
7 | import H
| ^^^^^^^^
```
I think we should be required to instantiate `p`, getting an error early on.
This doesn't only affect `.bkp` files, as omitting instantiation can also cause "Could not find module" errors when using `cabal`.