GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:40:14Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/9508Rename package key2019-07-07T18:40:14ZEdward Z. YangRename package keyWe were planning on renaming package key to something different. The two proposals on the table are "package instance" (which I don't like) and "library ID".
<details><summary>Trac metadata</summary>
| Trac field | Value ...We were planning on renaming package key to something different. The two proposals on the table are "package instance" (which I don't like) and "library ID".
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.9 |
| 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":"Rename package key","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"7.9","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"We were planning on renaming package key to something different. The two proposals on the table are \"package instance\" (which I don't like) and \"library ID\".","type_of_failure":"OtherFailure","blocking":[]} -->7.10.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/9265Create PackageKey to replace PackageId, including version dependency information2019-07-07T18:41:08ZEdward Z. YangCreate PackageKey to replace PackageId, including version dependency information[Multipleinstalledinstancesofapackage](commentary/packages/multi-instances) has been a long sought after feature to alleviate Cabal hell, and was the subject of an [GSoC project](wiki:Commentary/GSoCMultipleInstances) that ultimately nev...[Multipleinstalledinstancesofapackage](commentary/packages/multi-instances) has been a long sought after feature to alleviate Cabal hell, and was the subject of an [GSoC project](wiki:Commentary/GSoCMultipleInstances) that ultimately never got merged into HEAD.
This ticket is our latest attack on the problem, summarized as: add a version dependency hash to the `PackageId` (NOT the `InstalledPackageId`) associated with packages in the database. This approach is distinguished from the prior attempts as follows:
- We make no attempt to support multiple installations of different ways or ABI-compatible versions of a library (e.g. with/without optimizations.) This corresponds to supporting multiple InstalledPackageIds in a database; in our case, we're supporting multiple `PackageId`.
- We do not have to deal with conflicting "instances" in GHC's package resolver: multiple instances can be simultaneously loaded and used in a single compiled program. This is because PackageIds are baked into the exported linker symbols, so different versions will have different names and can peacefully coexist.
- We do not have to deal with the delicate ordering problem of calculating an ABI hash when configuring a package, which is prior to when we actually know it (ABI hash is only known after compilation), because our hash is based ONLY on dependency resolution choice.
- In absence of preference for previously installed packages, our Cabal dependency resolution stays exactly the same: Cabal picks versions, and from these choices we calculate the dependency hashes. With preference, we will have to do a little more work.
- We do not attempt to garbage collect old packages. Because we are not dependent on ABI, there is not an explosion of installed pacakges from package development; new installed packages only occur when version numbers are bumped up, or packages are installed in a combinatorially different fashion.7.10.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/9243Recompilation avoidance doesn't work for -fno-code/-fwrite-interface2019-07-07T18:41:13ZEdward Z. YangRecompilation avoidance doesn't work for -fno-code/-fwrite-interfaceWith the latest `-fwrite-interface` enhancements, a build directory can contain interface files independently of object files. In cases like this, we would like to have recompilation avoidance avoid typechecking files whose interface fil...With the latest `-fwrite-interface` enhancements, a build directory can contain interface files independently of object files. In cases like this, we would like to have recompilation avoidance avoid typechecking files whose interface files are up-to-date.
However, this does not currently work: we always re-typecheck:
```
t-edyang@cam-05-unx:/5playpen/t-edyang/sandbox/q$ /5playpen/t-edyang/ghc-backpack/inplace/bin/ghc-stage2 --make A.hs -fno-code -fwrite-interface
[1 of 1] Compiling A ( A.hs, nothing )
t-edyang@cam-05-unx:/5playpen/t-edyang/sandbox/q$ /5playpen/t-edyang/ghc-backpack/inplace/bin/ghc-stage2 --make A.hs -fno-code -fwrite-interface
[1 of 1] Compiling A ( A.hs, nothing )
```
The reason for this is that recompilation avoidance logic in `compileOne` (in `DriverPipeline.hs`) seems to rely exclusively on "linkables" in order to figure out if source has been modified or not. We never generate an object file with `-fwrite-interface`, so the compiler always concludes that we need to retypecheck.
However, recompilation avoidance for hs-boot does work. The reason for this is because we create a dummy o-boot linkable. We can't use this strategy for `-fno-code`, because the dummy object file would imply that we actually compiled the file (which we didn't).
The upshot is that to fix this problem, it looks like we might have to rejigger all of the logic in `compileOne`, which why I gave up on this for now.
Related to https://github.com/haskell/cabal/issues/1179
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.9 |
| 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":"Recompilation avoidance works imperfectly with -fno-code/-fwrite-interface","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"With the latest `-fwrite-interface` enhancements, a build directory can contain interface files independently of object files. In cases like this, we would like to have recompilation avoidance avoid typechecking files whose interface files are up-to-date.\r\n\r\nHowever, this does not currently work: we always re-typecheck:\r\n\r\n{{{\r\nt-edyang@cam-05-unx:/5playpen/t-edyang/sandbox/q$ /5playpen/t-edyang/ghc-backpack/inplace/bin/ghc-stage2 --make A.hs -fno-code -fwrite-interface\r\n[1 of 1] Compiling A ( A.hs, nothing )\r\nt-edyang@cam-05-unx:/5playpen/t-edyang/sandbox/q$ /5playpen/t-edyang/ghc-backpack/inplace/bin/ghc-stage2 --make A.hs -fno-code -fwrite-interface\r\n[1 of 1] Compiling A ( A.hs, nothing )\r\n}}}\r\n\r\nThe reason for this is that recompilation avoidance logic in `compileOne` (in `DriverPipeline.hs`) seems to rely exclusively on \"linkables\" in order to figure out if source has been modified or not. We never generate an object file with `-fwrite-interface`, so the compiler always concludes that we need to retypecheck.\r\n\r\nHowever, recompilation avoidance for hs-boot does work. The reason for this is because we create a dummy o-boot linkable. We can't use this strategy for `-fno-code`, because the dummy object file would imply that we actually compiled the file (which we didn't).\r\n\r\nThe upshot is that to fix this problem, it looks like we might have to rejigger all of the logic in `compileOne`, which why I gave up on this for now.\r\n\r\nRelated to https://github.com/haskell/cabal/issues/1179","type_of_failure":"OtherFailure","blocking":[]} -->7.10.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/8407Module re-exports at the package level2019-07-07T18:45:11ZJoachim Breitnermail@joachim-breitner.deModule re-exports at the package levelFor various package reorganization purposes, especially for possibly turning `base` into a shim package that re-exports some modules from more specialized packages, good support for module re-exports would be nice.
I wrote up a design s...For various package reorganization purposes, especially for possibly turning `base` into a shim package that re-exports some modules from more specialized packages, good support for module re-exports would be nice.
I wrote up a design spec at ModuleReexports; this bug is to track the progress.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.6.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Package system |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Module re-exports at the package level","status":"New","operating_system":"","component":"Package system","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"For various package reorganization purposes, especially for possibly turning `base` into a shim package that re-exports some modules from more specialized packages, good support for module re-exports would be nice.\r\n\r\nI wrote up a design spec at ModuleReexports; this bug is to track the progress.","type_of_failure":"OtherFailure","blocking":[]} -->7.10.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/9507ghc-pkg mode to query by package-key2019-07-07T18:40:14ZEdward Z. Yangghc-pkg mode to query by package-keyRight now, ghc-pkg understands package names and IPIDs. It should support package keys too.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version ...Right now, ghc-pkg understands package names and IPIDs. It should support package keys too.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | ghc-pkg |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghc-pkg mode to query by package-key","status":"New","operating_system":"","component":"ghc-pkg","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"7.9","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Right now, ghc-pkg understands package names and IPIDs. It should support package keys too.","type_of_failure":"OtherFailure","blocking":[]} -->7.10.2Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/10714After implementing new installed package ID (hash of sdist), get rid of packa...2019-07-07T18:34:26ZEdward Z. YangAfter implementing new installed package ID (hash of sdist), get rid of package keysGHC tracking bug for https://github.com/haskell/cabal/issues/2745
Externally, GHC's flags do not have to change much; a user simply passes the installed package ID to the flag currently named `-this-package-key` (but perhaps we should r...GHC tracking bug for https://github.com/haskell/cabal/issues/2745
Externally, GHC's flags do not have to change much; a user simply passes the installed package ID to the flag currently named `-this-package-key` (but perhaps we should rename this.)
Internally, if we can assume that `PackageKey == InstalledPackageId`, we can do away with the `InstalledPackageId` map and get rid of the level of indirection between the bin-pkg-db (which records installed package IDs\`) and GHC's guts (which record package keys).
Blocked on Cabal not actually using ABI hashes to identify packages.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.10.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Package system |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"After implementing new installed package ID (hash of sdist), get rid of package keys","status":"New","operating_system":"","component":"Package system","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"7.10.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"GHC tracking bug for https://github.com/haskell/cabal/issues/2745\r\n\r\nExternally, GHC's flags do not have to change much; a user simply passes the installed package ID to the flag currently named `-this-package-key` (but perhaps we should rename this.)\r\n\r\nInternally, if we can assume that `PackageKey == InstalledPackageId`, we can do away with the `InstalledPackageId` map and get rid of the level of indirection between the bin-pkg-db (which records installed package IDs`) and GHC's guts (which record package keys). \r\n\r\nBlocked on Cabal not actually using ABI hashes to identify packages.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/10622Rename Backpack packages to units2019-07-07T18:34:59ZEdward Z. YangRename Backpack packages to unitsAfter today's weekly Backpack call, we have come to the conclusion that we have two different types of "packages" in the Backpack world:
1. Cabal packages, which have a single `.cabal` file and are a unit of distribution which get uploa...After today's weekly Backpack call, we have come to the conclusion that we have two different types of "packages" in the Backpack world:
1. Cabal packages, which have a single `.cabal` file and are a unit of distribution which get uploaded to Hackage, and
1. Backpack packages, of which there may be multiple defined in a Backpack file shipped with a Cabal package; and are the building blocks for modular development in the small.
It's really confusing to have both of these called packages: thus, we propose to rename all occurrences of Backpack package to unit. A Cabal *package* may contain MULTIPLE Backpack *units*, and old-style Cabal files will only define one unit. Every Cabal package has a distinguished unit (with the same name as the package) that serves as the publically visible unit.
A Cabal package remains
- The unit of distribution
- The unit that Hackage handles
- The unit of versioning
- The unit of ownership (who maintains it etc)
Here are some of the consequences:
1. The "installed package database" no longer maintains a one-to-one mapping between Cabal packages and entries in the database. This invariant is being dropped for two reasons: (1) With a Nix-style database, a package `foo-0.1` may be installed many times with different dependencies / source code, all of which live in the installed package database. (2) With Backpack, a package containing a Backpack file may install multiple units. To avoid having to rename \*everything\*, we'll keep calling this the installed package database, but really it's more like an installed \*unit\* database.
1. We rename `PackageKey` to `UnitKey`, as it identifies a unit rather than a Cabal package. (I think this actually makes the function of these identifiers clearer.) We'll also distinguish Cabal-file level `PackageName`s from Backpack-file `UnitName`s. Installed units are identified by an `InstalledUnitId` instead of an `InstalledPackageId`.
1. The source-level syntax of Backpack files will use `unit` in place of where `package` was used before.
1. For old-style packages, Cabal will continue to write and register a single entry in the installed package database. For Backpack packages, Cabal will register as many entries as is necessary to install a package. The entry with the same `UnitName` as `PackageName` is publically visible to other packages. If a Backpack file defines other packages, those packages are registered with different `UnitName`s (giving them different `InstalledPackageId`s) which are not publically visible. The non-publically visible packages will have their description/URL/etc fields blank, and have a pointer to the "real" package.
1. If when installing a unit, we discover that it is already present in the database, we check if the ABI hashes are the same. If they are, we simply skip installing the unit but otherwise proceed. If the ABI hashes are not the same, we error: the units we are installing need to be recompiled against the unit present in the database.
1. Dependency tracking should be fine-grained within a PACKAGE, and coarse-grained outside. So we need to let interface files track module dependencies for files which are not in the same unit, but are in the same package.8.0.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/13335Non-abstract types also have skolem nature2019-07-07T18:22:23ZEdward Z. YangNon-abstract types also have skolem natureIn #12680, we determined that abstract types from signatures need to be treated like skolem variables.
But it turns out other types from signatures also need to be treated like skolem variables too:
```
{-# LANGUAGE GADTs #-}
unit p wh...In #12680, we determined that abstract types from signatures need to be treated like skolem variables.
But it turns out other types from signatures also need to be treated like skolem variables too:
```
{-# LANGUAGE GADTs #-}
unit p where
signature M1 where
data A = MkA
signature M2 where
data A = MkA
module A where
import qualified M1
import qualified M2
f :: M1.A ~ M2.A => a -> b
f x = x
```
This is bad because these As could be the same thing in the end. I think the real, final fix, is to not test for "skolem abstractness" (as we do now), but just look and see if the Name for the TyCon is a name hole or not. Then we can eliminate skolem abstract completely.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.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":"Non-abstract types also have skolem nature","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"In #12680, we determined that abstract types from signatures need to be treated like skolem variables.\r\n\r\nBut it turns out other types from signatures also need to be treated like skolem variables too:\r\n\r\n{{{\r\n{-# LANGUAGE GADTs #-}\r\nunit p where\r\n signature M1 where\r\n data A = MkA\r\n signature M2 where\r\n data A = MkA\r\n module A where\r\n import qualified M1\r\n import qualified M2\r\n f :: M1.A ~ M2.A => a -> b\r\n f x = x\r\n}}}\r\n\r\nThis is bad because these As could be the same thing in the end. I think the real, final fix, is to not test for \"skolem abstractness\" (as we do now), but just look and see if the Name for the TyCon is a name hole or not. Then we can eliminate skolem abstract completely.","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1https://gitlab.haskell.org/ghc/ghc/-/issues/13250Backpack: matching newtype selectors doesn't work2019-07-07T18:22:47ZEdward Z. YangBackpack: matching newtype selectors doesn't work```
unit p where
signature A where
newtype F a = F { mkF :: a }
unit q where
module A where
newtype F a = F { mkF :: a }
unit r where
dependency p[A=q:A]
```
fails with
```
ezyang@sabre:~$ ghc-head --backpac...```
unit p where
signature A where
newtype F a = F { mkF :: a }
unit q where
module A where
newtype F a = F { mkF :: a }
unit r where
dependency p[A=q:A]
```
fails with
```
ezyang@sabre:~$ ghc-head --backpack selector.bkp -dppr-debug
[1 of 3] Processing p
[2 of 3] Processing q
Instantiating q
[1 of 1] Compiling A ( q/A.hs, q/A.o )
[3 of 3] Processing r
Instantiating r
[1 of 1] Including p[A=q:A]
Instantiating p[A=q:A]
[1 of 1] Compiling A[sig] ( p/A.hsig, p/p-HVmFlcYSefiK5n1aDP1v7x/A.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.1.20170123 for x86_64-unknown-linux):
TcIface.find_lbl
missing: mkF{v}
known labels: [mkF{q:A.mkF{v rb}}]
Call stack:
CallStack (from HasCallStack):
prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1166:58 in ghc:Outputable
callStackDoc, called at compiler/utils/Outputable.hs:1170:37 in ghc:Outputable
pprPanic, called at compiler/iface/TcIface.hs:841:41 in ghc:TcIface
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.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":"Backpack: matching newtype selectors doesn't work","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"8.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\nunit p where\r\n signature A where\r\n newtype F a = F { mkF :: a }\r\nunit q where\r\n module A where\r\n newtype F a = F { mkF :: a }\r\nunit r where\r\n dependency p[A=q:A]\r\n}}}\r\n\r\nfails with\r\n\r\n{{{\r\nezyang@sabre:~$ ghc-head --backpack selector.bkp -dppr-debug\r\n[1 of 3] Processing p\r\n[2 of 3] Processing q\r\n Instantiating q\r\n [1 of 1] Compiling A ( q/A.hs, q/A.o )\r\n[3 of 3] Processing r\r\n Instantiating r\r\n [1 of 1] Including p[A=q:A]\r\n Instantiating p[A=q:A]\r\n [1 of 1] Compiling A[sig] ( p/A.hsig, p/p-HVmFlcYSefiK5n1aDP1v7x/A.o )\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 8.1.20170123 for x86_64-unknown-linux):\r\n\tTcIface.find_lbl\r\n missing: mkF{v}\r\n known labels: [mkF{q:A.mkF{v rb}}]\r\n Call stack:\r\n CallStack (from HasCallStack):\r\n prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1166:58 in ghc:Outputable\r\n callStackDoc, called at compiler/utils/Outputable.hs:1170:37 in ghc:Outputable\r\n pprPanic, called at compiler/iface/TcIface.hs:841:41 in ghc:TcIface\r\n\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/13214Orphan instances in Backpack signatures don't work2019-07-07T18:23:09ZEdward Z. YangOrphan instances in Backpack signatures don't work```
unit p where
signature A where
instance Show (a -> b)
module B where
import A
f = show (\x -> x)
```
There are probably other problems too but here's the start.
<details><summary>Trac metadata</summa...```
unit p where
signature A where
instance Show (a -> b)
module B where
import A
f = show (\x -> x)
```
There are probably other problems too but here's the start.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.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":"Orphan instances in Backpack signatures don't work","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"8.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\nunit p where\r\n signature A where\r\n instance Show (a -> b)\r\n module B where\r\n import A\r\n f = show (\\x -> x)\r\n}}}\r\n\r\nThere are probably other problems too but here's the start.","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/13068GHC should not allow modules to define instances of abstract type classes2019-07-07T18:23:51ZEdward Z. YangGHC should not allow modules to define instances of abstract type classeshs-boot files permit a type class to be given "abstractly", in which case any implementation of the type class is permissible. But it does not reject instances defined for such a class.
```hs
-- A.hs-boot
module A where
class C a
-- B....hs-boot files permit a type class to be given "abstractly", in which case any implementation of the type class is permissible. But it does not reject instances defined for such a class.
```hs
-- A.hs-boot
module A where
class C a
-- B.hs
module B where
import {-# SOURCE #-} A
instance C Int where
-- A.hs
module A where
import B
class C a where
f :: a
-- Main.hs
import A
main = print (f :: Int)
```
I get this when I build with `--make`:
```
ezyang@sabre:~$ ghc-head --make C.hs -fforce-recomp
[1 of 4] Compiling A[boot] ( A.hs-boot, A.o-boot )
[2 of 4] Compiling B ( B.hs, B.o )
[3 of 4] Compiling A ( A.hs, A.o )
[4 of 4] Compiling Main ( C.hs, C.o )
Linking C ...
./B.o:(.data+0x0): undefined reference to `A_CZCC_con_info'
collect2: error: ld returned 1 exit status
```8.2.1https://gitlab.haskell.org/ghc/ghc/-/issues/13067Abstract closed type families don't work with Backpack2019-07-07T18:23:51ZEdward Z. YangAbstract closed type families don't work with BackpackThis should typecheck:
```
{-# LANGUAGE TypeFamilies #-}
unit p where
module A where
type family ClosedFam a where
ClosedFam a = Int
unit sig where
signature A where
type family ClosedFam a where ..
...This should typecheck:
```
{-# LANGUAGE TypeFamilies #-}
unit p where
module A where
type family ClosedFam a where
ClosedFam a = Int
unit sig where
signature A where
type family ClosedFam a where ..
unit main where
dependency sig[A=p:A]
```
but instead we confusingly report:
```
foo.bkp:9:9: error:
Type constructor ‘ClosedFam’ has conflicting definitions in the module
and its hsig file
Main module: type family ClosedFam a :: *
Hsig file: type family ClosedFam a :: *
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.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":"Abstract closed type families don't work with Backpack","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"8.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This should typecheck:\r\n\r\n{{{\r\n{-# LANGUAGE TypeFamilies #-}\r\nunit p where\r\n module A where\r\n type family ClosedFam a where\r\n ClosedFam a = Int\r\n\r\nunit sig where\r\n signature A where\r\n type family ClosedFam a where ..\r\n\r\nunit main where\r\n dependency sig[A=p:A]\r\n}}}\r\n\r\nbut instead we confusingly report:\r\n\r\n{{{\r\nfoo.bkp:9:9: error:\r\n Type constructor ‘ClosedFam’ has conflicting definitions in the module\r\n and its hsig file\r\n Main module: type family ClosedFam a :: *\r\n Hsig file: type family ClosedFam a :: *\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/13066Backpack doesn't check for fixity consistency2019-07-07T18:23:51ZEdward Z. YangBackpack doesn't check for fixity consistencyThis should fail, but instead it prints 7.
```
unit p where
signature A where
infixl 6 `mul`
infixl 7 `plu`
mul :: Int -> Int -> Int
plu :: Int -> Int -> Int
module P where
import A
...This should fail, but instead it prints 7.
```
unit p where
signature A where
infixl 6 `mul`
infixl 7 `plu`
mul :: Int -> Int -> Int
plu :: Int -> Int -> Int
module P where
import A
x = 2 `mul` 3 `plu` 1
unit i where
module A where
infixl 7 `mul`
infixl 6 `plu`
mul :: Int -> Int -> Int
mul x y = x * y
plu :: Int -> Int -> Int
plu x y = x + y
unit main where
dependency p[A=i:A]
module Main where
import P
main = print x
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.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":"Backpack doesn't check for fixity consistency","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"8.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This should fail, but instead it prints 7.\r\n\r\n{{{\r\nunit p where\r\n signature A where\r\n infixl 6 `mul`\r\n infixl 7 `plu`\r\n mul :: Int -> Int -> Int\r\n plu :: Int -> Int -> Int\r\n module P where\r\n import A\r\n x = 2 `mul` 3 `plu` 1\r\nunit i where\r\n module A where\r\n infixl 7 `mul`\r\n infixl 6 `plu`\r\n mul :: Int -> Int -> Int\r\n mul x y = x * y\r\n plu :: Int -> Int -> Int\r\n plu x y = x + y\r\nunit main where\r\n dependency p[A=i:A]\r\n module Main where\r\n import P\r\n main = print x\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/12955Confusing error (module is not loaded) when more hsigs provided than -instant...2019-07-07T18:24:28ZEdward Z. YangConfusing error (module is not loaded) when more hsigs provided than -instantiated-withSteps to reproduce:
1. Create an `A.hsig` file with `signature A where`
1. Try to build it with `ghc --make A.hsig`
Expected: Some error indicating an unexpected signature (you need to specify `-instantiated-with`
Actual: This error:
...Steps to reproduce:
1. Create an `A.hsig` file with `signature A where`
1. Try to build it with `ghc --make A.hsig`
Expected: Some error indicating an unexpected signature (you need to specify `-instantiated-with`
Actual: This error:
```
[1 of 1] Compiling A[sig] (.hsig -> .o)
attempting to use module ‘main:A’ (A.hsig) which is not loaded
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.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":"Confusing error (module is not loaded) when more hsigs provided than -instantiated-with","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"8.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Steps to reproduce:\r\n\r\n1. Create an `A.hsig` file with `signature A where`\r\n2. Try to build it with `ghc --make A.hsig`\r\n\r\nExpected: Some error indicating an unexpected signature (you need to specify `-instantiated-with`\r\n\r\nActual: This error:\r\n\r\n{{{\r\n[1 of 1] Compiling A[sig] (.hsig -> .o)\r\nattempting to use module ‘main:A’ (A.hsig) which is not loaded\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/12945Backpack signature matching doesn't pick up orphan instances2019-07-07T18:24:31ZEdward Z. YangBackpack signature matching doesn't pick up orphan instancesRepro:
```
unit impl where
module A where
data T = T
module B(module A, module B) where
import A
instance Show T where
show T = "T"
unit sig where
signature B where
data T = T
...Repro:
```
unit impl where
module A where
data T = T
module B(module A, module B) where
import A
instance Show T where
show T = "T"
unit sig where
signature B where
data T = T
instance Show T
module App where
import B
app = print T
unit main where
dependency sig[B=impl:B]
module Main where
import App
main = app
```
I get:
```
ezyang@sabre:~$ ghc-head --backpack foo.bkp
[1 of 3] Processing impl
Instantiating impl
[1 of 2] Compiling A (.hs -> .o)
[2 of 2] Compiling B (.hs -> .o)
[2 of 3] Processing sig
[3 of 3] Processing main
Instantiating main
[1 of 1] Including sig[B=impl:B]
Instantiating sig[B=impl:B]
[1 of 2] Compiling B[sig] (.hsig -> .o)
sig/sig-HVnmSw44WZeBfwnUur4wzl/../B.hi:1:1: error:
No instance for (GHC.Show.Show impl:A.T)
arising when attempting to show that
instance [safe] GHC.Show.Show impl:A.T -- Defined in ‘impl:B’
is provided by ‘impl:B’
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Backpack signature matching doesn't pick up orphan instances","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"8.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Repro:\r\n\r\n{{{\r\nunit impl where\r\n module A where\r\n data T = T\r\n module B(module A, module B) where\r\n import A\r\n instance Show T where\r\n show T = \"T\"\r\n\r\nunit sig where\r\n signature B where\r\n data T = T\r\n instance Show T\r\n module App where\r\n import B\r\n app = print T\r\n\r\nunit main where\r\n dependency sig[B=impl:B]\r\n module Main where\r\n import App\r\n main = app\r\n}}}\r\n\r\nI get:\r\n\r\n{{{\r\nezyang@sabre:~$ ghc-head --backpack foo.bkp\r\n[1 of 3] Processing impl\r\n Instantiating impl\r\n [1 of 2] Compiling A (.hs -> .o)\r\n [2 of 2] Compiling B (.hs -> .o)\r\n[2 of 3] Processing sig\r\n[3 of 3] Processing main\r\n Instantiating main\r\n [1 of 1] Including sig[B=impl:B]\r\n Instantiating sig[B=impl:B]\r\n [1 of 2] Compiling B[sig] (.hsig -> .o)\r\n\r\nsig/sig-HVnmSw44WZeBfwnUur4wzl/../B.hi:1:1: error:\r\n No instance for (GHC.Show.Show impl:A.T)\r\n arising when attempting to show that\r\n instance [safe] GHC.Show.Show impl:A.T -- Defined in ‘impl:B’\r\n is provided by ‘impl:B’\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/14304Instantiated libraries (Backpack) don't get linked with enough deps2019-07-07T18:17:33ZEdward Z. YangInstantiated libraries (Backpack) don't get linked with enough depsOne downstream instance of this reported at https://github.com/haskell/cabal/issues/4755
Basically, if you instantiate a library q with library p, you need to make sure libHSp.so shows up in its linker dependencies. This is not the case...One downstream instance of this reported at https://github.com/haskell/cabal/issues/4755
Basically, if you instantiate a library q with library p, you need to make sure libHSp.so shows up in its linker dependencies. This is not the case right now.
Patch coming (I filed this to get a bug number :)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------ |
| Version | 8.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Linking) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Instantiated libraries (Backpack) don't get linked with enough deps","status":"New","operating_system":"","component":"Compiler (Linking)","related":[],"milestone":"8.2.2","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"One downstream instance of this reported at https://github.com/haskell/cabal/issues/4755\r\n\r\nBasically, if you instantiate a library q with library p, you need to make sure libHSp.so shows up in its linker dependencies. This is not the case right now.\r\n\r\nPatch coming (I filed this to get a bug number :)","type_of_failure":"OtherFailure","blocking":[]} -->8.2.2https://gitlab.haskell.org/ghc/ghc/-/issues/13955Backpack does not handle unlifted types2021-07-19T22:53:12ZAndrew MartinBackpack does not handle unlifted typesIn the code snippet below, I attempt to use backpack with levity polymorphism:
```
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
unit number-unknown where
signature Numbe...In the code snippet below, I attempt to use backpack with levity polymorphism:
```
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
unit number-unknown where
signature NumberUnknown where
import GHC.Types
data Number
plus :: Number -> Number -> Number
multiply :: Number -> Number -> Number
module NumberStuff where
import NumberUnknown
funcA :: Number -> Number -> Number
funcA x y = plus x (multiply x y)
unit number-int where
module NumberUnknown where
type Number = Int
plus :: Int -> Int -> Int
plus = (+)
multiply :: Int -> Int -> Int
multiply = (*)
unit number-unboxed-int where
module NumberUnknown where
import GHC.Prim
type Number = Int#
plus :: Int# -> Int# -> Int#
plus = (+#)
multiply :: Int# -> Int# -> Int#
multiply = (*#)
unit main where
dependency number-unknown[NumberUnknown=number-unboxed-int:NumberUnknown]
module Main where
import NumberStuff
main = putStrLn "Hello world!"
```
Compiling this with `ghc --backpack packer.bkp` fails with the following error:
```
- Type constructor ‘Number’ has conflicting definitions in the module
and its hsig file
Main module: type Number = GHC.Prim.Int# :: TYPE 'GHC.Types.IntRep
Hsig file: data Number
The types have different kinds
- while checking that number-unboxed-int:NumberUnknown implements signature NumberUnknown in number-unknown[NumberUnknown=number-unboxed-int:NumberUnknown]
type Number = Int#
```
The error is pretty clear: `Number` can only be instantiated by types of kind `Type` (aka `TYPE LiftedRep`). Even while remaining levity monomorphic, there doesn't seem to be a way to pick a different kind. For example, redefining `Number` in the signature as
```
data Number :: TYPE IntRep
```
leads to the following immediate failure:
```
Kind signature on data type declaration has non-* return kind TYPE 'IntRep
```
I do not understand any of the internals of backpack, so I do not understand if there's anything fundamental that makes this impossible. Going one step further, I would like to be able to do something like this (the syntax here is not even currently valid for a backpack signature):
```
type MyRep :: RuntimeRep
data Number :: TYPE MyRep
```
This may be instantiated with something like this:
```
type MyRep = IntRep
type Number = Int#
```
And then end users would be able to monomorphize levity-polymorphic functions. This would be really neat because there is currently no way to do this in GHC.
So, I guess there are really two feature requests in here. One is the ability to use unlifted data types with backpack. The other is the ability to use backpack to monomorphize levity-polymorphic functions.
It seems unlikely to sneak this into GHC 8.2 but who knows!8.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/13140Handle subtyping relation for roles in Backpack2019-07-07T18:23:29ZEdward Z. YangHandle subtyping relation for roles in BackpackIf I understand correctly, GHC's three currently supported roles follow the following subtyping relation: `phantom <: representational <: nominal`. So it would make sense to adjust Backpack and `hs-boot` files to handle this subtyping re...If I understand correctly, GHC's three currently supported roles follow the following subtyping relation: `phantom <: representational <: nominal`. So it would make sense to adjust Backpack and `hs-boot` files to handle this subtyping relation appropriately. Here's my proposal.
- Today, roles in signature files default to representational. Let's change the default to nominal, as this is the most flexible implementation side. If a client of the signature needs to coerce with a type, the signature can be adjusted to have more stringent requirements.
- If a parameter is declared as nominal in a signature, it can be implemented by a data type which is actually representational.
- When merging abstract data declarations, we take the smallest role for every parameter. The roles are considered fix once we specify the structure of an ADT.
I actually don't know if the proofs about roles actually say anything about this subtyping relation.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.1 |
| Type | FeatureRequest |
| 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":"Handle subtyping relation for roles in Backpack","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"8.1","keywords":["backpack","hs-boot"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"If I understand correctly, GHC's three currently supported roles follow the following subtyping relation: `phantom <: representational <: nominal`. So it would make sense to adjust Backpack and `hs-boot` files to handle this subtyping relation appropriately. Here's my proposal.\r\n\r\n* Today, roles in signature files default to representational. Let's change the default to nominal, as this is the most flexible implementation side. If a client of the signature needs to coerce with a type, the signature can be adjusted to have more stringent requirements.\r\n* If a parameter is declared as nominal in a signature, it can be implemented by a data type which is actually representational.\r\n* When merging abstract data declarations, we take the smallest role for every parameter. The roles are considered fix once we specify the structure of an ADT.\r\n\r\nI actually don't know if the proofs about roles actually say anything about this subtyping relation.","type_of_failure":"OtherFailure","blocking":[]} -->8.4.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/15594--abi-hash with Backpack incorrectly loads modules from dependent packages2020-09-28T07:11:37ZEdward Z. Yang--abi-hash with Backpack incorrectly loads modules from dependent packagesRepro at: https://github.com/alexbiehl/cabal-backpack-register-repro
If you use Backpack with data families, you might fail during `--abi-hash` with:
```
cabal:
'/nix/store/m338klajhqlw7v4jd61fiqd82wx305fj-ghc-8.4.3-with-packages/bin/g...Repro at: https://github.com/alexbiehl/cabal-backpack-register-repro
If you use Backpack with data families, you might fail during `--abi-hash` with:
```
cabal:
'/nix/store/m338klajhqlw7v4jd61fiqd82wx305fj-ghc-8.4.3-with-packages/bin/ghc'
exited with an error:
Failed to load interface for ‘Stuff’
no unit id matching ‘backpack-trans-0.1.0.0-L6CFTQZAAWWFpCQD2NXR4W-indef’ was
found
```8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15041rnIfaceBndr implementation in RnModIface looks incorrect2019-07-07T18:14:35ZMatthew PickeringrnIfaceBndr implementation in RnModIface looks incorrect```
rnIfaceBndr :: Rename IfaceBndr
rnIfaceBndr (IfaceIdBndr (fs, ty)) = IfaceIdBndr <$> ((,) fs <$> rnIfaceType ty)
rnIfaceBndr (IfaceTvBndr tv_bndr) = IfaceIdBndr <$> rnIfaceTvBndr tv_bndr
```
This is the implementation currently. Not...```
rnIfaceBndr :: Rename IfaceBndr
rnIfaceBndr (IfaceIdBndr (fs, ty)) = IfaceIdBndr <$> ((,) fs <$> rnIfaceType ty)
rnIfaceBndr (IfaceTvBndr tv_bndr) = IfaceIdBndr <$> rnIfaceTvBndr tv_bndr
```
This is the implementation currently. Notice in the second branch that an `IfaceTvBndr` is converted to an `IfaceIdBndr`. Should it instead be `IfaceTvBndr`?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ezyang |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"rnIfaceBndr implementation in RnModIface looks incorrect","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.2","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":["ezyang"],"type":"Bug","description":"{{{\r\nrnIfaceBndr :: Rename IfaceBndr\r\nrnIfaceBndr (IfaceIdBndr (fs, ty)) = IfaceIdBndr <$> ((,) fs <$> rnIfaceType ty)\r\nrnIfaceBndr (IfaceTvBndr tv_bndr) = IfaceIdBndr <$> rnIfaceTvBndr tv_bndr\r\n}}}\r\n\r\nThis is the implementation currently. Notice in the second branch that an `IfaceTvBndr` is converted to an `IfaceIdBndr`. Should it instead be `IfaceTvBndr`?","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1