GHC issueshttps://gitlab.haskell.org/ghc/ghc//issues20200922T21:43:23Zhttps://gitlab.haskell.org/ghc/ghc//issues/18723"Can't find interfacefile declaration" error when using a large tuple in a d...20200922T21:43:23ZRyan Scott"Can't find interfacefile declaration" error when using a large tuple in a data typeThe following programs all report rather cryptic error messages on GHC 8.2 or later:
* ```hs
module Bug1 where
data T1 = MkT1
( Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug1.hs
[1 of 1] Compiling Bug1 ( Bug1.hs, Bug1.o )
Bug1.hs:1:1: error:
Can't find interfacefile declaration for variable GHC.Tuple.$tc(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
Probable cause: bug in .hiboot file, or inconsistent .hi file
Use ddumpiftrace to get an idea of which file caused the error

1  module Bug1 where
 ^
```
* ```hs
{# LANGUAGE DataKinds #}
module Bug2 where
import Data.Proxy
data T2 = MkT2 (Proxy
'( Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
))
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug2.hs
[1 of 1] Compiling Bug2 ( Bug2.hs, Bug2.o )
Bug2.hs:1:1: error:
Can't find interfacefile declaration for variable GHC.Tuple.$tc(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
Probable cause: bug in .hiboot file, or inconsistent .hi file
Use ddumpiftrace to get an idea of which file caused the error

1  {# LANGUAGE DataKinds #}
 ^
```
* ```hs
{# LANGUAGE UnboxedTuples #}
module Bug3 where
data T3 = MkT3
(# Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
#)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug3.hs
[1 of 1] Compiling Bug3 ( Bug3.hs, Bug3.o )
Bug3.hs:1:1: error:
Can't find interfacefile declaration for variable GHC.Types.$tc(#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#)
Probable cause: bug in .hiboot file, or inconsistent .hi file
Use ddumpiftrace to get an idea of which file caused the error

1  {# LANGUAGE UnboxedTuples #}
 ^
```
Interestingly, the following programs do _not_ throw a "Can't find interfacefile declaration" error:
* ```hs
{# LANGUAGE ConstraintKinds #}
module Bug4 where
import Data.Proxy
data T4 = MkT4 (Proxy
(( Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int
)))
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug4.hs
[1 of 1] Compiling Bug4 ( Bug4.hs, Bug4.o )
Bug4.hs:7:3: error:
• Constraint tuple arity too large: 63 (max arity = 62)
Instead, use a nested tuple
• In the first argument of ‘Proxy’, namely
‘((Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int))’
In the type ‘(Proxy ((Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int)))’
In the definition of data constructor ‘MkT4’

7  (( Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
```
The reason is that there is a dedicated validity check for large constraint tuples in [`GHC.Tc.Gen.HsType.finish_tuple`](https://gitlab.haskell.org/ghc/ghc//blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Tc/Gen/HsType.hs#L11891190), unlike for boxed or unboxed tuples.
* ```hs
module Bug5 where
f ::
( Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
)
f =
( 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123
)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug5.hs
[1 of 1] Compiling Bug5 ( Bug5.hs, Bug5.o )
Bug5.hs:13:3: error:
A 63tuple is too large for GHC
(max size is 62)
Workaround: use nested tuples or define a data type

13  ( 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
```
Using an overly large tuple _expression_ fails because there is a dedicated validity check ([`GHC.Rename.Utils.checkTupSize`](https://gitlab.haskell.org/ghc/ghc//blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Rename/Utils.hs#L441448)) that is used when renaming tuple expressions and patterns. Curiously, the same check is _not_ used when renaming tuple types.
* ```hs
module Bug6 where
data T6 = MkT6
((,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug6.hs
[1 of 1] Compiling Bug6 ( Bug6.hs, Bug6.o )
Bug6.hs:4:4: error:
A 63tuple is too large for GHC
(max size is 62)
Workaround: use nested tuples or define a data type

4  ((,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
This is because GHC goes through a different code path when renaming prefix applications of tuple types than when renaming mixfix tuple types, and the code for renaming prefix applications of tuple types [uses `checkTupSize`](https://gitlab.haskell.org/ghc/ghc//blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Rename/Env.hs#L286).
Perhaps we should use `checkTupSize` when renaming mixfix tuple types in `rnHsTyKi`?The following programs all report rather cryptic error messages on GHC 8.2 or later:
* ```hs
module Bug1 where
data T1 = MkT1
( Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug1.hs
[1 of 1] Compiling Bug1 ( Bug1.hs, Bug1.o )
Bug1.hs:1:1: error:
Can't find interfacefile declaration for variable GHC.Tuple.$tc(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
Probable cause: bug in .hiboot file, or inconsistent .hi file
Use ddumpiftrace to get an idea of which file caused the error

1  module Bug1 where
 ^
```
* ```hs
{# LANGUAGE DataKinds #}
module Bug2 where
import Data.Proxy
data T2 = MkT2 (Proxy
'( Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
))
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug2.hs
[1 of 1] Compiling Bug2 ( Bug2.hs, Bug2.o )
Bug2.hs:1:1: error:
Can't find interfacefile declaration for variable GHC.Tuple.$tc(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
Probable cause: bug in .hiboot file, or inconsistent .hi file
Use ddumpiftrace to get an idea of which file caused the error

1  {# LANGUAGE DataKinds #}
 ^
```
* ```hs
{# LANGUAGE UnboxedTuples #}
module Bug3 where
data T3 = MkT3
(# Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
#)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug3.hs
[1 of 1] Compiling Bug3 ( Bug3.hs, Bug3.o )
Bug3.hs:1:1: error:
Can't find interfacefile declaration for variable GHC.Types.$tc(#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#)
Probable cause: bug in .hiboot file, or inconsistent .hi file
Use ddumpiftrace to get an idea of which file caused the error

1  {# LANGUAGE UnboxedTuples #}
 ^
```
Interestingly, the following programs do _not_ throw a "Can't find interfacefile declaration" error:
* ```hs
{# LANGUAGE ConstraintKinds #}
module Bug4 where
import Data.Proxy
data T4 = MkT4 (Proxy
(( Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
, Show Int, Show Int, Show Int
)))
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug4.hs
[1 of 1] Compiling Bug4 ( Bug4.hs, Bug4.o )
Bug4.hs:7:3: error:
• Constraint tuple arity too large: 63 (max arity = 62)
Instead, use a nested tuple
• In the first argument of ‘Proxy’, namely
‘((Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int))’
In the type ‘(Proxy ((Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int, Show Int,
Show Int, Show Int, Show Int, Show Int, Show Int)))’
In the definition of data constructor ‘MkT4’

7  (( Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int, Show Int
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
```
The reason is that there is a dedicated validity check for large constraint tuples in [`GHC.Tc.Gen.HsType.finish_tuple`](https://gitlab.haskell.org/ghc/ghc//blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Tc/Gen/HsType.hs#L11891190), unlike for boxed or unboxed tuples.
* ```hs
module Bug5 where
f ::
( Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
, Int, Int, Int
)
f =
( 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
, 123, 123, 123
)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug5.hs
[1 of 1] Compiling Bug5 ( Bug5.hs, Bug5.o )
Bug5.hs:13:3: error:
A 63tuple is too large for GHC
(max size is 62)
Workaround: use nested tuples or define a data type

13  ( 123, 123, 123, 123, 123, 123, 123, 123, 123, 123
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
```
Using an overly large tuple _expression_ fails because there is a dedicated validity check ([`GHC.Rename.Utils.checkTupSize`](https://gitlab.haskell.org/ghc/ghc//blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Rename/Utils.hs#L441448)) that is used when renaming tuple expressions and patterns. Curiously, the same check is _not_ used when renaming tuple types.
* ```hs
module Bug6 where
data T6 = MkT6
((,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int Int Int Int Int Int Int Int
Int Int Int)
```
```
$ /opt/ghc/8.10.2/bin/ghc Bug6.hs
[1 of 1] Compiling Bug6 ( Bug6.hs, Bug6.o )
Bug6.hs:4:4: error:
A 63tuple is too large for GHC
(max size is 62)
Workaround: use nested tuples or define a data type

4  ((,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
This is because GHC goes through a different code path when renaming prefix applications of tuple types than when renaming mixfix tuple types, and the code for renaming prefix applications of tuple types [uses `checkTupSize`](https://gitlab.haskell.org/ghc/ghc//blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/compiler/GHC/Rename/Env.hs#L286).
Perhaps we should use `checkTupSize` when renaming mixfix tuple types in `rnHsTyKi`?https://gitlab.haskell.org/ghc/ghc//issues/17569Why do we have both typeRep# and typeRep?20200519T12:52:49ZRichard Eisenbergrae@richarde.devWhy do we have both typeRep# and typeRep?In `Data.Typeable.Internal`, we see
```hs
class Typeable (a :: k) where
typeRep# :: TypeRep a
typeRep :: Typeable a => TypeRep a
typeRep = typeRep#
```
Why have `typeRep` separate from `typeRep#`? The only difference I can see is the specificity of the `k` variable. To wit, we have
```hs
typeRep# :: forall (k :: Type) (a :: k). Typeable @k a => TypeRep @k a
typeRep :: forall {k :: Type} (a :: k). Typeable @k a => TypeRep @k a
```
The *only* difference is the braces.
But we needn't do all this. Instead, we could define
```hs
class Typeable a where
typeRep :: TypeRep a
```
It's unfortunate not to make that explicitly polykinded, but it would be inferred to be polykinded, and `typeRep` would get the right specificity.
So, is there anything stopping us from this simplification?In `Data.Typeable.Internal`, we see
```hs
class Typeable (a :: k) where
typeRep# :: TypeRep a
typeRep :: Typeable a => TypeRep a
typeRep = typeRep#
```
Why have `typeRep` separate from `typeRep#`? The only difference I can see is the specificity of the `k` variable. To wit, we have
```hs
typeRep# :: forall (k :: Type) (a :: k). Typeable @k a => TypeRep @k a
typeRep :: forall {k :: Type} (a :: k). Typeable @k a => TypeRep @k a
```
The *only* difference is the braces.
But we needn't do all this. Instead, we could define
```hs
class Typeable a where
typeRep :: TypeRep a
```
It's unfortunate not to make that explicitly polykinded, but it would be inferred to be polykinded, and `typeRep` would get the right specificity.
So, is there anything stopping us from this simplification?https://gitlab.haskell.org/ghc/ghc//issues/16627Trouble resolving Typeable 'LiftedRep20191104T11:43:15ZDavid FeuerTrouble resolving Typeable 'LiftedRep# Summary
Inference fails with a simple `TypeRep` application.
# Steps to reproduce
```haskell
{# language TypeInType, ScopedTypeVariables #}
module Silly where
import Type.Reflection (Typeable, typeRep, TypeRep)
import Type.Reflection.Unsafe (mkTrApp)
import GHC.Exts (TYPE, RuntimeRep (..))
import Data.Kind (Type)
mkTrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
(a :: TYPE r1) (b :: TYPE r2).
TypeRep a > TypeRep b > TypeRep ((a > b) :: Type)
mkTrFun a b = typeRep `mkTrApp` a `mkTrApp` b
```
# Expected behavior
I expected this to compile.
# Actual behavior
```
Silly.hs:11:15: error:
• No instance for (Typeable 'LiftedRep)
arising from a use of ‘typeRep’
• In the first argument of ‘mkTrApp’, namely ‘typeRep’
In the first argument of ‘mkTrApp’, namely ‘typeRep `mkTrApp` a’
In the expression: typeRep `mkTrApp` a `mkTrApp` b

11  mkTrFun a b = typeRep `mkTrApp` a `mkTrApp` b
 ^^^^^^^
```
This is a rather perplexing error, because `'LiftedRep` is most assuredly typeable.
# Environment
* GHC version used: 8.6.3
Optional:
* Operating System:
* System Architecture:# Summary
Inference fails with a simple `TypeRep` application.
# Steps to reproduce
```haskell
{# language TypeInType, ScopedTypeVariables #}
module Silly where
import Type.Reflection (Typeable, typeRep, TypeRep)
import Type.Reflection.Unsafe (mkTrApp)
import GHC.Exts (TYPE, RuntimeRep (..))
import Data.Kind (Type)
mkTrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
(a :: TYPE r1) (b :: TYPE r2).
TypeRep a > TypeRep b > TypeRep ((a > b) :: Type)
mkTrFun a b = typeRep `mkTrApp` a `mkTrApp` b
```
# Expected behavior
I expected this to compile.
# Actual behavior
```
Silly.hs:11:15: error:
• No instance for (Typeable 'LiftedRep)
arising from a use of ‘typeRep’
• In the first argument of ‘mkTrApp’, namely ‘typeRep’
In the first argument of ‘mkTrApp’, namely ‘typeRep `mkTrApp` a’
In the expression: typeRep `mkTrApp` a `mkTrApp` b

11  mkTrFun a b = typeRep `mkTrApp` a `mkTrApp` b
 ^^^^^^^
```
This is a rather perplexing error, because `'LiftedRep` is most assuredly typeable.
# Environment
* GHC version used: 8.6.3
Optional:
* Operating System:
* System Architecture:https://gitlab.haskell.org/ghc/ghc//issues/16626TypeRep fingerprints for arrow types are problematic20190522T21:03:08ZDavid FeuerTypeRep fingerprints for arrow types are problematic# Motivation
I'm hacking together a package for typeindexed type fingerprints, for situations where `typeRep` is too heavy and `Typeable` reflection isn't necessary. There are two basic approaches one might consider, both of which start out similarly.
```haskell
{# language ScopedTypeVariables, TypeInType, GADTs, RoleAnnotations, TypeApplications, RankNTypes,
MultiParamTypeClasses, TypeOperators, TypeFamilies, FlexibleContexts, FlexibleInstances,
UndecidableInstances, AllowAmbiguousTypes, MagicHash #}
module Type.Fingerprint.Internal where
import GHC.Fingerprint (fingerprintFingerprints)
import qualified GHC.Fingerprint as F
import Data.Type.Equality
import Type.Reflection
import qualified Type.Reflection.Unsafe as TU
import Data.Kind
import GHC.Exts (TYPE, RuntimeRep (..))
import Unsafe.Coerce
newtype Fingerprint (a :: k) = Fingerprint F.Fingerprint
deriving (Eq, Ord)
type role Fingerprint nominal
class Fingerprinted (a :: k) where
fingerprint# :: Fingerprint a
fingerprint :: Fingerprinted a => Fingerprint a
fingerprint = fingerprint#
withFingerprinted
:: forall k (a :: k) rep (r :: TYPE rep) .
Fingerprint a > (Fingerprinted a => r) > r
 The same sort of implementation as withTypeable
```
From there the approaches diverge.
## Lean entirely on Typeable
The easiest way to create `Fingerprinted` instances is to just write
```haskell
instance Typeable a => Fingerprinted a where
fingerprint# = Fingerprint . TU.typeRepFingerprint $ typeRep @a
```
Unfortunately, this loses a lot of nonreflection functionality compared to `Typeable`. In particular, if you use `withFingerprinted` with fingerprints of `f`, `a`, and `b`, you do *not* automatically get instances for `Fingerprinted (f a)` or `Fingerprinted (a > b)`. So I'm really not too interested in this approach.
## Calculate fingerprints much like Typeable
The other major option is to calculate fingerprints by hand, and then use type familyguided instance resolution to distinguish between two cases:
1. The type is an application: calculate fingerprints recursively and combine them using `fingerprintFingerprints`.
2. The type is not an application: get the fingerprint using `TU.typeRepFingerprint`.
This approach will produce a perfectly good fingerprinting scheme. There's only one problem: the fingerprints it produces will not, in general, be the same as the ones obtained by `TU.typeRepFingerprint`. GHC fingerprints arrow types specially. When calculating the fingerprint of an application, it uses reflection to check whether the first argument is a partially applied arrow. If so, it extracts the left side of the arrow, and combines its fingerprint with that of the right side of the arrow, leaving out the arrow itself. With just fingerprints, this is impossible. We have no way to see that a type was produced by applying `(>)` to another type, let alone a way to extract that other type.
# Proposal
I can think of two ways to fix this.
## The easy way
Remove the special case for fingerprinting arrow types. There will be some performance regressions, but I hope they won't be intolerable.
## The hard way
Use a separate fingerprint combining function for `Typeable` fingerprints than for other fingerprinting purposes. This would make it possible to arrange for the result of combining the fingerprint of `(>)` with another fingerprint (in the appropriate order) to just produce the other fingerprint. This should (nearly) eliminate the performance penalty.# Motivation
I'm hacking together a package for typeindexed type fingerprints, for situations where `typeRep` is too heavy and `Typeable` reflection isn't necessary. There are two basic approaches one might consider, both of which start out similarly.
```haskell
{# language ScopedTypeVariables, TypeInType, GADTs, RoleAnnotations, TypeApplications, RankNTypes,
MultiParamTypeClasses, TypeOperators, TypeFamilies, FlexibleContexts, FlexibleInstances,
UndecidableInstances, AllowAmbiguousTypes, MagicHash #}
module Type.Fingerprint.Internal where
import GHC.Fingerprint (fingerprintFingerprints)
import qualified GHC.Fingerprint as F
import Data.Type.Equality
import Type.Reflection
import qualified Type.Reflection.Unsafe as TU
import Data.Kind
import GHC.Exts (TYPE, RuntimeRep (..))
import Unsafe.Coerce
newtype Fingerprint (a :: k) = Fingerprint F.Fingerprint
deriving (Eq, Ord)
type role Fingerprint nominal
class Fingerprinted (a :: k) where
fingerprint# :: Fingerprint a
fingerprint :: Fingerprinted a => Fingerprint a
fingerprint = fingerprint#
withFingerprinted
:: forall k (a :: k) rep (r :: TYPE rep) .
Fingerprint a > (Fingerprinted a => r) > r
 The same sort of implementation as withTypeable
```
From there the approaches diverge.
## Lean entirely on Typeable
The easiest way to create `Fingerprinted` instances is to just write
```haskell
instance Typeable a => Fingerprinted a where
fingerprint# = Fingerprint . TU.typeRepFingerprint $ typeRep @a
```
Unfortunately, this loses a lot of nonreflection functionality compared to `Typeable`. In particular, if you use `withFingerprinted` with fingerprints of `f`, `a`, and `b`, you do *not* automatically get instances for `Fingerprinted (f a)` or `Fingerprinted (a > b)`. So I'm really not too interested in this approach.
## Calculate fingerprints much like Typeable
The other major option is to calculate fingerprints by hand, and then use type familyguided instance resolution to distinguish between two cases:
1. The type is an application: calculate fingerprints recursively and combine them using `fingerprintFingerprints`.
2. The type is not an application: get the fingerprint using `TU.typeRepFingerprint`.
This approach will produce a perfectly good fingerprinting scheme. There's only one problem: the fingerprints it produces will not, in general, be the same as the ones obtained by `TU.typeRepFingerprint`. GHC fingerprints arrow types specially. When calculating the fingerprint of an application, it uses reflection to check whether the first argument is a partially applied arrow. If so, it extracts the left side of the arrow, and combines its fingerprint with that of the right side of the arrow, leaving out the arrow itself. With just fingerprints, this is impossible. We have no way to see that a type was produced by applying `(>)` to another type, let alone a way to extract that other type.
# Proposal
I can think of two ways to fix this.
## The easy way
Remove the special case for fingerprinting arrow types. There will be some performance regressions, but I hope they won't be intolerable.
## The hard way
Use a separate fingerprint combining function for `Typeable` fingerprints than for other fingerprinting purposes. This would make it possible to arrange for the result of combining the fingerprint of `(>)` with another fingerprint (in the appropriate order) to just produce the other fingerprint. This should (nearly) eliminate the performance penalty.https://gitlab.haskell.org/ghc/ghc//issues/15322`KnownNat` does not imply `Typeable` any more when used with plugin20200123T19:18:02ZDmitrii Kovanikov`KnownNat` does not imply `Typeable` any more when used with pluginI have the following Haskell code which uses `ghctypelitsknownnat0.5` package as a plugin:
```hs
{# LANGUAGE DataKinds #}
{# LANGUAGE ScopedTypeVariables #}
{# LANGUAGE TypeOperators #}
{# OPTIONS_GHC fplugin GHC.TypeLits.KnownNat.Solver #}
module Nats where
import Data.Proxy (Proxy (..))
import Data.Typeable (Typeable)
import GHC.TypeLits (KnownNat, type (+))
f :: forall n . (Typeable n, KnownNat n) => Proxy n > ()
f _ = ()
f _ = f (Proxy :: Proxy (n + 1))
```
When I try to compile this code I observe the following error message:
```
• Could not deduce (Typeable (n + 1)) arising from a use of ‘f’
from the context: (Typeable n, KnownNat n)
bound by the type signature for:
f :: forall (n :: ghcprim0.5.2.0:GHC.Types.Nat).
(Typeable n, KnownNat n) =>
Proxy n > ()
at src/Nats.hs:13:157
• In the expression: f (Proxy :: Proxy (n + 1))
In an equation for ‘f’: f _ = f (Proxy :: Proxy (n + 1))

15  f _ = f (Proxy :: Proxy (n + 1))
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
```
This code works for both GHC8.2.2 and GHC8.0.2. I found similar ticket with exactly this problem but looks like this is broken again: #10348 (bug).
Originally reported at Github for `ghctypelitsknownnat` package:
 https://github.com/clashlang/ghctypelitsknownnat/issues/21
`ghctypelitsknownnat` package correctly infers `KnownNat (n + 1)` constraint so GHC should be able to infer `Typeable (n + 1)`.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.4.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"`KnownNat` does not imply `Typeable` any more when used with plugin","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":["typeable,knownnat"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I have the following Haskell code which uses `ghctypelitsknownnat0.5` package as a plugin:\r\n\r\n{{{#!hs\r\n{# LANGUAGE DataKinds #}\r\n{# LANGUAGE ScopedTypeVariables #}\r\n{# LANGUAGE TypeOperators #}\r\n\r\n{# OPTIONS_GHC fplugin GHC.TypeLits.KnownNat.Solver #}\r\n\r\nmodule Nats where\r\n\r\nimport Data.Proxy (Proxy (..))\r\nimport Data.Typeable (Typeable)\r\nimport GHC.TypeLits (KnownNat, type (+))\r\n\r\nf :: forall n . (Typeable n, KnownNat n) => Proxy n > ()\r\nf _ = ()\r\nf _ = f (Proxy :: Proxy (n + 1))\r\n}}}\r\n\r\nWhen I try to compile this code I observe the following error message:\r\n\r\n{{{\r\n • Could not deduce (Typeable (n + 1)) arising from a use of ‘f’\r\n from the context: (Typeable n, KnownNat n)\r\n bound by the type signature for:\r\n f :: forall (n :: ghcprim0.5.2.0:GHC.Types.Nat).\r\n (Typeable n, KnownNat n) =>\r\n Proxy n > ()\r\n at src/Nats.hs:13:157\r\n • In the expression: f (Proxy :: Proxy (n + 1))\r\n In an equation for ‘f’: f _ = f (Proxy :: Proxy (n + 1))\r\n \r\n15  f _ = f (Proxy :: Proxy (n + 1))\r\n  ^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n\r\n}}}\r\n\r\nThis code works for both GHC8.2.2 and GHC8.0.2. I found similar ticket with exactly this problem but looks like this is broken again: #10348 (bug).\r\n\r\nOriginally reported at Github for `ghctypelitsknownnat` package:\r\n\r\n* https://github.com/clashlang/ghctypelitsknownnat/issues/21\r\n\r\n`ghctypelitsknownnat` package correctly infers `KnownNat (n + 1)` constraint so GHC should be able to infer `Typeable (n + 1)`.","type_of_failure":"OtherFailure","blocking":[]} >I have the following Haskell code which uses `ghctypelitsknownnat0.5` package as a plugin:
```hs
{# LANGUAGE DataKinds #}
{# LANGUAGE ScopedTypeVariables #}
{# LANGUAGE TypeOperators #}
{# OPTIONS_GHC fplugin GHC.TypeLits.KnownNat.Solver #}
module Nats where
import Data.Proxy (Proxy (..))
import Data.Typeable (Typeable)
import GHC.TypeLits (KnownNat, type (+))
f :: forall n . (Typeable n, KnownNat n) => Proxy n > ()
f _ = ()
f _ = f (Proxy :: Proxy (n + 1))
```
When I try to compile this code I observe the following error message:
```
• Could not deduce (Typeable (n + 1)) arising from a use of ‘f’
from the context: (Typeable n, KnownNat n)
bound by the type signature for:
f :: forall (n :: ghcprim0.5.2.0:GHC.Types.Nat).
(Typeable n, KnownNat n) =>
Proxy n > ()
at src/Nats.hs:13:157
• In the expression: f (Proxy :: Proxy (n + 1))
In an equation for ‘f’: f _ = f (Proxy :: Proxy (n + 1))

15  f _ = f (Proxy :: Proxy (n + 1))
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
```
This code works for both GHC8.2.2 and GHC8.0.2. I found similar ticket with exactly this problem but looks like this is broken again: #10348 (bug).
Originally reported at Github for `ghctypelitsknownnat` package:
 https://github.com/clashlang/ghctypelitsknownnat/issues/21
`ghctypelitsknownnat` package correctly infers `KnownNat (n + 1)` constraint so GHC should be able to infer `Typeable (n + 1)`.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.4.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"`KnownNat` does not imply `Typeable` any more when used with plugin","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":["typeable,knownnat"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I have the following Haskell code which uses `ghctypelitsknownnat0.5` package as a plugin:\r\n\r\n{{{#!hs\r\n{# LANGUAGE DataKinds #}\r\n{# LANGUAGE ScopedTypeVariables #}\r\n{# LANGUAGE TypeOperators #}\r\n\r\n{# OPTIONS_GHC fplugin GHC.TypeLits.KnownNat.Solver #}\r\n\r\nmodule Nats where\r\n\r\nimport Data.Proxy (Proxy (..))\r\nimport Data.Typeable (Typeable)\r\nimport GHC.TypeLits (KnownNat, type (+))\r\n\r\nf :: forall n . (Typeable n, KnownNat n) => Proxy n > ()\r\nf _ = ()\r\nf _ = f (Proxy :: Proxy (n + 1))\r\n}}}\r\n\r\nWhen I try to compile this code I observe the following error message:\r\n\r\n{{{\r\n • Could not deduce (Typeable (n + 1)) arising from a use of ‘f’\r\n from the context: (Typeable n, KnownNat n)\r\n bound by the type signature for:\r\n f :: forall (n :: ghcprim0.5.2.0:GHC.Types.Nat).\r\n (Typeable n, KnownNat n) =>\r\n Proxy n > ()\r\n at src/Nats.hs:13:157\r\n • In the expression: f (Proxy :: Proxy (n + 1))\r\n In an equation for ‘f’: f _ = f (Proxy :: Proxy (n + 1))\r\n \r\n15  f _ = f (Proxy :: Proxy (n + 1))\r\n  ^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n\r\n}}}\r\n\r\nThis code works for both GHC8.2.2 and GHC8.0.2. I found similar ticket with exactly this problem but looks like this is broken again: #10348 (bug).\r\n\r\nOriginally reported at Github for `ghctypelitsknownnat` package:\r\n\r\n* https://github.com/clashlang/ghctypelitsknownnat/issues/21\r\n\r\n`ghctypelitsknownnat` package correctly infers `KnownNat (n + 1)` constraint so GHC should be able to infer `Typeable (n + 1)`.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/14663Deriving Typeable for enumerations seems expensive20200511T16:44:48ZniteriaDeriving Typeable for enumerations seems expensiveI have a module `A10000` that looks like this:
```
module A10000 where
data A = A
 A00001
 A00002
...
 A10000
```
Currently compiling it with `./inplace/bin/ghcstage2 A10000.hs +RTS s` produces:
```
[1 of 1] Compiling A10000 ( A10000.hs, A10000.o )
4,133,470,392 bytes allocated in the heap
1,194,866,080 bytes copied during GC
141,604,816 bytes maximum residency (14 sample(s))
813,104 bytes maximum slop
341 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 329 colls, 0 par 0.551s 0.551s 0.0017s 0.0246s
Gen 1 14 colls, 0 par 0.453s 0.453s 0.0323s 0.1031s
TASKS: 4 (1 bound, 3 peak workers (3 total), using N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.000s ( 0.000s elapsed)
MUT time 1.498s ( 1.730s elapsed)
GC time 1.004s ( 1.004s elapsed)
EXIT time 0.000s ( 0.006s elapsed)
Total time 2.502s ( 2.740s elapsed)
Alloc rate 2,759,911,143 bytes per MUT second
Productivity 59.9% of total user, 63.4% of total elapsed
```
I've noticed a lot of code getting generated (\>500k lines of ASM), particularly interesting was code that supported `TyCon`s.
I've tried again disabling the generation of `TyCon`s by modifying:
```
mkTypeRepTodoBinds :: [TypeRepTodo] > TcM TcGblEnv
mkTypeRepTodoBinds _ = getGblEnv
```
This is the result:
```
[1 of 1] Compiling A10000 ( A10000.hs, A10000.o )
1,731,693,280 bytes allocated in the heap
280,362,376 bytes copied during GC
41,423,608 bytes maximum residency (10 sample(s))
746,272 bytes maximum slop
102 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 401 colls, 0 par 0.111s 0.111s 0.0003s 0.0065s
Gen 1 10 colls, 0 par 0.124s 0.124s 0.0124s 0.0298s
TASKS: 4 (1 bound, 3 peak workers (3 total), using N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.000s ( 0.000s elapsed)
MUT time 0.773s ( 0.889s elapsed)
GC time 0.235s ( 0.235s elapsed)
EXIT time 0.000s ( 0.007s elapsed)
Total time 1.008s ( 1.130s elapsed)
Alloc rate 2,241,052,377 bytes per MUT second
Productivity 76.7% of total user, 79.2% of total elapsed
```
It appears that by default I pay \>50% of compile time for a feature that I probably won't use.
I'm sorry if this is a duplicate, I've looked at https://ghc.haskell.org/trac/ghc/wiki/Typeable, but nothing seemed relevant.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  low 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Deriving Typeable for enumerations seems expensive","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I have a module `A10000` that looks like this:\r\n{{{\r\nmodule A10000 where\r\n\r\ndata A = A\r\n  A00001\r\n  A00002\r\n...\r\n  A10000\r\n}}}\r\n\r\nCurrently compiling it with `./inplace/bin/ghcstage2 A10000.hs +RTS s` produces:\r\n{{{\r\n[1 of 1] Compiling A10000 ( A10000.hs, A10000.o ) \r\n 4,133,470,392 bytes allocated in the heap \r\n 1,194,866,080 bytes copied during GC \r\n 141,604,816 bytes maximum residency (14 sample(s)) \r\n 813,104 bytes maximum slop \r\n 341 MB total memory in use (0 MB lost due to fragmentation) \r\n\r\n Tot time (elapsed) Avg pause Max pause \r\n Gen 0 329 colls, 0 par 0.551s 0.551s 0.0017s 0.0246s \r\n Gen 1 14 colls, 0 par 0.453s 0.453s 0.0323s 0.1031s \r\n\r\n TASKS: 4 (1 bound, 3 peak workers (3 total), using N1) \r\n\r\n SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) \r\n\r\n INIT time 0.000s ( 0.000s elapsed) \r\n MUT time 1.498s ( 1.730s elapsed) \r\n GC time 1.004s ( 1.004s elapsed) \r\n EXIT time 0.000s ( 0.006s elapsed) \r\n Total time 2.502s ( 2.740s elapsed) \r\n\r\n Alloc rate 2,759,911,143 bytes per MUT second \r\n\r\n Productivity 59.9% of total user, 63.4% of total elapsed \r\n}}}\r\n\r\n\r\nI've noticed a lot of code getting generated (>500k lines of ASM), particularly interesting was code that supported `TyCon`s.\r\n\r\nI've tried again disabling the generation of `TyCon`s by modifying:\r\n{{{\r\nmkTypeRepTodoBinds :: [TypeRepTodo] > TcM TcGblEnv\r\nmkTypeRepTodoBinds _ = getGblEnv\r\n}}}\r\n\r\n\r\nThis is the result:\r\n{{{\r\n[1 of 1] Compiling A10000 ( A10000.hs, A10000.o ) \r\n 1,731,693,280 bytes allocated in the heap \r\n 280,362,376 bytes copied during GC \r\n 41,423,608 bytes maximum residency (10 sample(s)) \r\n 746,272 bytes maximum slop \r\n 102 MB total memory in use (0 MB lost due to fragmentation) \r\n\r\n Tot time (elapsed) Avg pause Max pause \r\n Gen 0 401 colls, 0 par 0.111s 0.111s 0.0003s 0.0065s \r\n Gen 1 10 colls, 0 par 0.124s 0.124s 0.0124s 0.0298s \r\n\r\n TASKS: 4 (1 bound, 3 peak workers (3 total), using N1) \r\n\r\n SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) \r\n\r\n INIT time 0.000s ( 0.000s elapsed) \r\n MUT time 0.773s ( 0.889s elapsed) \r\n GC time 0.235s ( 0.235s elapsed) \r\n EXIT time 0.000s ( 0.007s elapsed) \r\n Total time 1.008s ( 1.130s elapsed) \r\n\r\n Alloc rate 2,241,052,377 bytes per MUT second \r\n\r\n Productivity 76.7% of total user, 79.2% of total elapsed\r\n}}}\r\n\r\n\r\nIt appears that by default I pay >50% of compile time for a feature that I probably won't use.\r\n\r\nI'm sorry if this is a duplicate, I've looked at https://ghc.haskell.org/trac/ghc/wiki/Typeable, but nothing seemed relevant.","type_of_failure":"OtherFailure","blocking":[]} >I have a module `A10000` that looks like this:
```
module A10000 where
data A = A
 A00001
 A00002
...
 A10000
```
Currently compiling it with `./inplace/bin/ghcstage2 A10000.hs +RTS s` produces:
```
[1 of 1] Compiling A10000 ( A10000.hs, A10000.o )
4,133,470,392 bytes allocated in the heap
1,194,866,080 bytes copied during GC
141,604,816 bytes maximum residency (14 sample(s))
813,104 bytes maximum slop
341 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 329 colls, 0 par 0.551s 0.551s 0.0017s 0.0246s
Gen 1 14 colls, 0 par 0.453s 0.453s 0.0323s 0.1031s
TASKS: 4 (1 bound, 3 peak workers (3 total), using N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.000s ( 0.000s elapsed)
MUT time 1.498s ( 1.730s elapsed)
GC time 1.004s ( 1.004s elapsed)
EXIT time 0.000s ( 0.006s elapsed)
Total time 2.502s ( 2.740s elapsed)
Alloc rate 2,759,911,143 bytes per MUT second
Productivity 59.9% of total user, 63.4% of total elapsed
```
I've noticed a lot of code getting generated (\>500k lines of ASM), particularly interesting was code that supported `TyCon`s.
I've tried again disabling the generation of `TyCon`s by modifying:
```
mkTypeRepTodoBinds :: [TypeRepTodo] > TcM TcGblEnv
mkTypeRepTodoBinds _ = getGblEnv
```
This is the result:
```
[1 of 1] Compiling A10000 ( A10000.hs, A10000.o )
1,731,693,280 bytes allocated in the heap
280,362,376 bytes copied during GC
41,423,608 bytes maximum residency (10 sample(s))
746,272 bytes maximum slop
102 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 401 colls, 0 par 0.111s 0.111s 0.0003s 0.0065s
Gen 1 10 colls, 0 par 0.124s 0.124s 0.0124s 0.0298s
TASKS: 4 (1 bound, 3 peak workers (3 total), using N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.000s ( 0.000s elapsed)
MUT time 0.773s ( 0.889s elapsed)
GC time 0.235s ( 0.235s elapsed)
EXIT time 0.000s ( 0.007s elapsed)
Total time 1.008s ( 1.130s elapsed)
Alloc rate 2,241,052,377 bytes per MUT second
Productivity 76.7% of total user, 79.2% of total elapsed
```
It appears that by default I pay \>50% of compile time for a feature that I probably won't use.
I'm sorry if this is a duplicate, I've looked at https://ghc.haskell.org/trac/ghc/wiki/Typeable, but nothing seemed relevant.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  low 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Deriving Typeable for enumerations seems expensive","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I have a module `A10000` that looks like this:\r\n{{{\r\nmodule A10000 where\r\n\r\ndata A = A\r\n  A00001\r\n  A00002\r\n...\r\n  A10000\r\n}}}\r\n\r\nCurrently compiling it with `./inplace/bin/ghcstage2 A10000.hs +RTS s` produces:\r\n{{{\r\n[1 of 1] Compiling A10000 ( A10000.hs, A10000.o ) \r\n 4,133,470,392 bytes allocated in the heap \r\n 1,194,866,080 bytes copied during GC \r\n 141,604,816 bytes maximum residency (14 sample(s)) \r\n 813,104 bytes maximum slop \r\n 341 MB total memory in use (0 MB lost due to fragmentation) \r\n\r\n Tot time (elapsed) Avg pause Max pause \r\n Gen 0 329 colls, 0 par 0.551s 0.551s 0.0017s 0.0246s \r\n Gen 1 14 colls, 0 par 0.453s 0.453s 0.0323s 0.1031s \r\n\r\n TASKS: 4 (1 bound, 3 peak workers (3 total), using N1) \r\n\r\n SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) \r\n\r\n INIT time 0.000s ( 0.000s elapsed) \r\n MUT time 1.498s ( 1.730s elapsed) \r\n GC time 1.004s ( 1.004s elapsed) \r\n EXIT time 0.000s ( 0.006s elapsed) \r\n Total time 2.502s ( 2.740s elapsed) \r\n\r\n Alloc rate 2,759,911,143 bytes per MUT second \r\n\r\n Productivity 59.9% of total user, 63.4% of total elapsed \r\n}}}\r\n\r\n\r\nI've noticed a lot of code getting generated (>500k lines of ASM), particularly interesting was code that supported `TyCon`s.\r\n\r\nI've tried again disabling the generation of `TyCon`s by modifying:\r\n{{{\r\nmkTypeRepTodoBinds :: [TypeRepTodo] > TcM TcGblEnv\r\nmkTypeRepTodoBinds _ = getGblEnv\r\n}}}\r\n\r\n\r\nThis is the result:\r\n{{{\r\n[1 of 1] Compiling A10000 ( A10000.hs, A10000.o ) \r\n 1,731,693,280 bytes allocated in the heap \r\n 280,362,376 bytes copied during GC \r\n 41,423,608 bytes maximum residency (10 sample(s)) \r\n 746,272 bytes maximum slop \r\n 102 MB total memory in use (0 MB lost due to fragmentation) \r\n\r\n Tot time (elapsed) Avg pause Max pause \r\n Gen 0 401 colls, 0 par 0.111s 0.111s 0.0003s 0.0065s \r\n Gen 1 10 colls, 0 par 0.124s 0.124s 0.0124s 0.0298s \r\n\r\n TASKS: 4 (1 bound, 3 peak workers (3 total), using N1) \r\n\r\n SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) \r\n\r\n INIT time 0.000s ( 0.000s elapsed) \r\n MUT time 0.773s ( 0.889s elapsed) \r\n GC time 0.235s ( 0.235s elapsed) \r\n EXIT time 0.000s ( 0.007s elapsed) \r\n Total time 1.008s ( 1.130s elapsed) \r\n\r\n Alloc rate 2,241,052,377 bytes per MUT second \r\n\r\n Productivity 76.7% of total user, 79.2% of total elapsed\r\n}}}\r\n\r\n\r\nIt appears that by default I pay >50% of compile time for a feature that I probably won't use.\r\n\r\nI'm sorry if this is a duplicate, I've looked at https://ghc.haskell.org/trac/ghc/wiki/Typeable, but nothing seemed relevant.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/14582Review and improve the Typeable API20190707T18:16:25ZSimon Peyton JonesReview and improve the Typeable APIThis ticket is to track improvements in the `Typeable` API
There are a number of points I'm uncomfortable about
 `Data.Typable` is presumably meant to be the public API, and is
fairly small. But `Data.Typeable.Internal` has a much larger
API, which includes pattern synonyms and suchlike that appear
to be for the benefit of clients, not just internal use.
 The `Typeable` API has `type TypeRep = I.SomeTypeRep` which is
different to the typeindexed `data TypeRep a` defined in
`Data.Typeable.Internals`. This is exteremly confusing. Perhaps
this is intended to be temporary, while we are moving over to the new typeindexed
representation. But then what's the transition plan?
 I cordially dislike this stuff about `IsApplication` in
`Internals` ([this commit](https://git.haskell.org/ghc.git/commitdiff/1acb922bb1186662919c1dbc0af596584e5db3ac)). It's hard for me to understand what's going on. I
believe that the two pattern synonyms `App` and `Con` are supposed
to be exhaustive  if so, let's just write a COMPLETE pragma.
 The code has many uses of `unsafeCoerce`, whereas the drive of
our "Typed reflection in Haskell" paper was to reduced the size
of the trusted code base. I'd like to see a comment on each of
those uses of `unsafeCoerce` to explain.
 Do we really need `Con'` as well as `Con`?
 The API could do with some careful documentation, in Haddock,
but perhaps also an accomanying wiki page. It's tricky stuff.
Here's the [Typeablewikipage](typeable)
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.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":"Review and improve the Typeable API","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This ticket is to track improvements in the `Typeable` API\r\n\r\nThere are a number of points I'm uncomfortable about\r\n\r\n* `Data.Typable` is presumably meant to be the public API, and is\r\n fairly small. But `Data.Typeable.Internal` has a much larger\r\n API, which includes pattern synonyms and suchlike that appear\r\n to be for the benefit of clients, not just internal use.\r\n\r\n* The `Typeable` API has `type TypeRep = I.SomeTypeRep` which is\r\n different to the typeindexed `data TypeRep a` defined in\r\n `Data.Typeable.Internals`. This is exteremly confusing. Perhaps\r\n this is intended to be temporary, while we are moving over to the new typeindexed\r\n representation. But then what's the transition plan?\r\n\r\n* I cordially dislike this stuff about `IsApplication` in\r\n `Internals` ([https://git.haskell.org/ghc.git/commitdiff/1acb922bb1186662919c1dbc0af596584e5db3ac this commit]). It's hard for me to understand what's going on. I\r\n believe that the two pattern synonyms `App` and `Con` are supposed\r\n to be exhaustive  if so, let's just write a COMPLETE pragma.\r\n\r\n* The code has many uses of `unsafeCoerce`, whereas the drive of\r\n our \"Typed reflection in Haskell\" paper was to reduced the size\r\n of the trusted code base. I'd like to see a comment on each of\r\n those uses of `unsafeCoerce` to explain.\r\n\r\n* Do we really need `Con'` as well as `Con`?\r\n\r\n* The API could do with some careful documentation, in Haddock,\r\n but perhaps also an accomanying wiki page. It's tricky stuff.\r\n\r\nHere's the [wiki:Typeable Typeable wiki page]","type_of_failure":"OtherFailure","blocking":[]} >This ticket is to track improvements in the `Typeable` API
There are a number of points I'm uncomfortable about
 `Data.Typable` is presumably meant to be the public API, and is
fairly small. But `Data.Typeable.Internal` has a much larger
API, which includes pattern synonyms and suchlike that appear
to be for the benefit of clients, not just internal use.
 The `Typeable` API has `type TypeRep = I.SomeTypeRep` which is
different to the typeindexed `data TypeRep a` defined in
`Data.Typeable.Internals`. This is exteremly confusing. Perhaps
this is intended to be temporary, while we are moving over to the new typeindexed
representation. But then what's the transition plan?
 I cordially dislike this stuff about `IsApplication` in
`Internals` ([this commit](https://git.haskell.org/ghc.git/commitdiff/1acb922bb1186662919c1dbc0af596584e5db3ac)). It's hard for me to understand what's going on. I
believe that the two pattern synonyms `App` and `Con` are supposed
to be exhaustive  if so, let's just write a COMPLETE pragma.
 The code has many uses of `unsafeCoerce`, whereas the drive of
our "Typed reflection in Haskell" paper was to reduced the size
of the trusted code base. I'd like to see a comment on each of
those uses of `unsafeCoerce` to explain.
 Do we really need `Con'` as well as `Con`?
 The API could do with some careful documentation, in Haddock,
but perhaps also an accomanying wiki page. It's tricky stuff.
Here's the [Typeablewikipage](typeable)
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.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":"Review and improve the Typeable API","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This ticket is to track improvements in the `Typeable` API\r\n\r\nThere are a number of points I'm uncomfortable about\r\n\r\n* `Data.Typable` is presumably meant to be the public API, and is\r\n fairly small. But `Data.Typeable.Internal` has a much larger\r\n API, which includes pattern synonyms and suchlike that appear\r\n to be for the benefit of clients, not just internal use.\r\n\r\n* The `Typeable` API has `type TypeRep = I.SomeTypeRep` which is\r\n different to the typeindexed `data TypeRep a` defined in\r\n `Data.Typeable.Internals`. This is exteremly confusing. Perhaps\r\n this is intended to be temporary, while we are moving over to the new typeindexed\r\n representation. But then what's the transition plan?\r\n\r\n* I cordially dislike this stuff about `IsApplication` in\r\n `Internals` ([https://git.haskell.org/ghc.git/commitdiff/1acb922bb1186662919c1dbc0af596584e5db3ac this commit]). It's hard for me to understand what's going on. I\r\n believe that the two pattern synonyms `App` and `Con` are supposed\r\n to be exhaustive  if so, let's just write a COMPLETE pragma.\r\n\r\n* The code has many uses of `unsafeCoerce`, whereas the drive of\r\n our \"Typed reflection in Haskell\" paper was to reduced the size\r\n of the trusted code base. I'd like to see a comment on each of\r\n those uses of `unsafeCoerce` to explain.\r\n\r\n* Do we really need `Con'` as well as `Con`?\r\n\r\n* The API could do with some careful documentation, in Haddock,\r\n but perhaps also an accomanying wiki page. It's tricky stuff.\r\n\r\nHere's the [wiki:Typeable Typeable wiki page]","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/14480Clean up tyConTYPE20190707T18:16:52ZDavid FeuerClean up tyConTYPEPhab:4085 builds a `TyCon` representing `TYPE` by hand in `Data.Typeable.Internal`. This is pretty disgusting, but it was the only way I managed to smash the last of the mysterious loops. It would be very nice to find a cleaner way, but we want to get that merged.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Clean up tyConTYPE","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Phab:4085 builds a `TyCon` representing `TYPE` by hand in `Data.Typeable.Internal`. This is pretty disgusting, but it was the only way I managed to smash the last of the mysterious loops. It would be very nice to find a cleaner way, but we want to get that merged.","type_of_failure":"OtherFailure","blocking":[]} >Phab:4085 builds a `TyCon` representing `TYPE` by hand in `Data.Typeable.Internal`. This is pretty disgusting, but it was the only way I managed to smash the last of the mysterious loops. It would be very nice to find a cleaner way, but we want to get that merged.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Clean up tyConTYPE","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Phab:4085 builds a `TyCon` representing `TYPE` by hand in `Data.Typeable.Internal`. This is pretty disgusting, but it was the only way I managed to smash the last of the mysterious loops. It would be very nice to find a cleaner way, but we want to get that merged.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/14401Add a test ensuring that TypeReps can be stored in compact regions20200123T19:27:40ZDavid FeuerAdd a test ensuring that TypeReps can be stored in compact regionsMy work thus far on [D4085](https://phabricator.haskell.org/D4085) has involved `TypeRep`s with cyclical structure. That bit me in `break011` and `break024` because `:force` doesn't work with cyclical structures. This would also have caused trouble for storing `TypeRep`s in compact regions. If we eventually make `:force` work with cyclical structures (see #14400), then cyclical `TypeRep`s won't break the test suite but might break user code using compact regions. So let's test for that.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Test Suite 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Add a test ensuring that TypeReps can be stored in compact regions","status":"New","operating_system":"","component":"Test Suite","related":[],"milestone":"8.2.2","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"My work thus far on Phab:D4085 has involved `TypeRep`s with cyclical structure. That bit me in `break011` and `break024` because `:force` doesn't work with cyclical structures. This would also have caused trouble for storing `TypeRep`s in compact regions. If we eventually make `:force` work with cyclical structures (see #14400), then cyclical `TypeRep`s won't break the test suite but might break user code using compact regions. So let's test for that.","type_of_failure":"OtherFailure","blocking":[]} >My work thus far on [D4085](https://phabricator.haskell.org/D4085) has involved `TypeRep`s with cyclical structure. That bit me in `break011` and `break024` because `:force` doesn't work with cyclical structures. This would also have caused trouble for storing `TypeRep`s in compact regions. If we eventually make `:force` work with cyclical structures (see #14400), then cyclical `TypeRep`s won't break the test suite but might break user code using compact regions. So let's test for that.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Test Suite 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Add a test ensuring that TypeReps can be stored in compact regions","status":"New","operating_system":"","component":"Test Suite","related":[],"milestone":"8.2.2","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"My work thus far on Phab:D4085 has involved `TypeRep`s with cyclical structure. That bit me in `break011` and `break024` because `:force` doesn't work with cyclical structures. This would also have caused trouble for storing `TypeRep`s in compact regions. If we eventually make `:force` work with cyclical structures (see #14400), then cyclical `TypeRep`s won't break the test suite but might break user code using compact regions. So let's test for that.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/14341Show instance for TypeReps is a bit broken20200117T10:15:14ZDavid FeuerShow instance for TypeReps is a bit brokenThere are three problems.
1. Showing typereps of tuples can produce unnecessary parentheses:
```
Prelude K T> typeRep @(Int, Maybe Bool)
(Int,(Maybe Bool))
```
The fix is trivial.
2. Showing typereps of ticked (i.e., lifted) tuples and lists gives hardtoread results, because it does not use the usual special syntax:
```
Prelude K T> typeRep @'(Int, Maybe Bool)
'(,) * * Int (Maybe Bool)
Prelude K T> typeRep @'[1,2,3]
': Nat 1 (': Nat 2 (': Nat 3 ('[] Nat)))
```
Fixing the lifted tuple case is trivial. Fixing the lifted list case is slightly less trivial, but not hard.
3. Type operator applications are not shown infix.
```
Prelude K T> typeRep @(Maybe :*: Either Int)
:*: * Maybe (Either Int)
```
This is the hardest problem to fix, although it's probably not too terribly hard. See [ticket:14341\#comment:143749](https://gitlab.haskell.org//ghc/ghc/issues/14341#note_143749) for thoughts.There are three problems.
1. Showing typereps of tuples can produce unnecessary parentheses:
```
Prelude K T> typeRep @(Int, Maybe Bool)
(Int,(Maybe Bool))
```
The fix is trivial.
2. Showing typereps of ticked (i.e., lifted) tuples and lists gives hardtoread results, because it does not use the usual special syntax:
```
Prelude K T> typeRep @'(Int, Maybe Bool)
'(,) * * Int (Maybe Bool)
Prelude K T> typeRep @'[1,2,3]
': Nat 1 (': Nat 2 (': Nat 3 ('[] Nat)))
```
Fixing the lifted tuple case is trivial. Fixing the lifted list case is slightly less trivial, but not hard.
3. Type operator applications are not shown infix.
```
Prelude K T> typeRep @(Maybe :*: Either Int)
:*: * Maybe (Either Int)
```
This is the hardest problem to fix, although it's probably not too terribly hard. See [ticket:14341\#comment:143749](https://gitlab.haskell.org//ghc/ghc/issues/14341#note_143749) for thoughts.8.6.1https://gitlab.haskell.org/ghc/ghc//issues/14337typeRepKind can perform substantial amounts of allocation20200123T19:27:39ZDavid FeuertypeRepKind can perform substantial amounts of allocationI came up with a (rather contrived) test case to demonstrate that [D4082](https://phabricator.haskell.org/D4082) reduced bigO time complexity in pathological cases. But I expected it to increase space usage by a constant factor. What I found was very much the opposite: it dramatically reduced allocation. The reason for this is obvious in hindsight. Every time we call `typeRepKind`, we recalculate the kind entirely from scratch. That recalculation is only a potential *time* problem for `TrApp`, because we only need to walk down links, but it's also a *space* problem for `TrTyCon`, because we're building up a `TypeRep` from a `KindRep`.
The solution, assuming we choose to keep `typeRepKind`, seems fairly clear: whether or not we choose to cache the kind in `TrApp`, we should almost certainly do so in `TrTyCon`.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  bgamari 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"typeRepKind can perform substantial amounts of allocation","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":["bgamari"],"type":"Bug","description":"I came up with a (rather contrived) test case to demonstrate that Phab:D4082 reduced bigO time complexity in pathological cases. But I expected it to increase space usage by a constant factor. What I found was very much the opposite: it dramatically reduced allocation. The reason for this is obvious in hindsight. Every time we call `typeRepKind`, we recalculate the kind entirely from scratch. That recalculation is only a potential ''time'' problem for `TrApp`, because we only need to walk down links, but it's also a ''space'' problem for `TrTyCon`, because we're building up a `TypeRep` from a `KindRep`.\r\n\r\nThe solution, assuming we choose to keep `typeRepKind`, seems fairly clear: whether or not we choose to cache the kind in `TrApp`, we should almost certainly do so in `TrTyCon`.","type_of_failure":"OtherFailure","blocking":[]} >I came up with a (rather contrived) test case to demonstrate that [D4082](https://phabricator.haskell.org/D4082) reduced bigO time complexity in pathological cases. But I expected it to increase space usage by a constant factor. What I found was very much the opposite: it dramatically reduced allocation. The reason for this is obvious in hindsight. Every time we call `typeRepKind`, we recalculate the kind entirely from scratch. That recalculation is only a potential *time* problem for `TrApp`, because we only need to walk down links, but it's also a *space* problem for `TrTyCon`, because we're building up a `TypeRep` from a `KindRep`.
The solution, assuming we choose to keep `typeRepKind`, seems fairly clear: whether or not we choose to cache the kind in `TrApp`, we should almost certainly do so in `TrTyCon`.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  bgamari 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"typeRepKind can perform substantial amounts of allocation","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":["bgamari"],"type":"Bug","description":"I came up with a (rather contrived) test case to demonstrate that Phab:D4082 reduced bigO time complexity in pathological cases. But I expected it to increase space usage by a constant factor. What I found was very much the opposite: it dramatically reduced allocation. The reason for this is obvious in hindsight. Every time we call `typeRepKind`, we recalculate the kind entirely from scratch. That recalculation is only a potential ''time'' problem for `TrApp`, because we only need to walk down links, but it's also a ''space'' problem for `TrTyCon`, because we're building up a `TypeRep` from a `KindRep`.\r\n\r\nThe solution, assuming we choose to keep `typeRepKind`, seems fairly clear: whether or not we choose to cache the kind in `TrApp`, we should almost certainly do so in `TrTyCon`.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/14270GHC HEAD's ghcstage1 panics on Data.Typeable.Internal20200123T18:39:28ZHerbert Valerio Riedelhvr@gnu.orgGHC HEAD's ghcstage1 panics on Data.Typeable.InternalWhen doing a default build of GHC HEAD (i.e. without `mk/build.mk`), GHC panics:
```
$ make V=0
=== building phase 0
make noprintdirectory f ghc.mk phase=0 phase_0_builds
make[1]: Nothing to be done for 'phase_0_builds'.
=== building phase 1
make noprintdirectory f ghc.mk phase=1 phase_1_builds
make[1]: Nothing to be done for 'phase_1_builds'.
=== building final phase
make noprintdirectory f ghc.mk phase=final all
HC [stage 1] libraries/base/distinstall/build/Data/Typeable/Internal.o
ghcstage1: panic! (the 'impossible' happened)
(GHC version 8.3.20170922 for x86_64unknownlinux):
Template variable unbound in rewrite rule
Variable: cobox_a3S9
Rule "SC:mkTrApp0"
Rule bndrs: [k1_X4g7, b_X4gb, k1_a3RW, a_a3RX, k1_X426, b_X42a,
b_a3RY, sc_s7Yv, sc_s7Yr, sc_s7Ys, sc_s7Yt, cobox_a3S9, cobox_a3RZ,
cobox_X42x, cobox_a3S8]
LHS args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),
TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),
TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N
(Nth:2 (Sym cobox_a3S8))))
(Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N
(Nth:2
(Sym cobox_a3S8))) ; Sym cobox_a3RZ)),
TrTyCon
@ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))
> TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)
@ (>)
sc_s7Yr
sc_s7Ys
$tc(>)
sc_s7Yt,
sc_s7Yv]
Actual args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),
TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),
TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N
(Nth:2 (Sym cobox_a3S8))))
(Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N
(Nth:2
(Sym cobox_a3S8))) ; Sym cobox_a3RZ)),
TrTyCon
@ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))
> TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)
@ (>)
dt_a2Vb
dt_a2Vc
$tc(>)
kind_vars_X37r,
...
```
You can see a more complete error in the build log at
https://launchpadlibrarian.net/337888338/buildlog_ubuntutrustyamd64.ghchead_8.3.20170922+git.0.5a8b8437\~14.04_BUILDING.txt.gz
This panic seems to be causally connected to cc6be3a2f23c9b2e04f9f491099149e1e1d4d20b (which addressed #14236) because reverting that commit allows me to avoid the panic.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  high 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"GHC HEAD's ghcstage1 panics on Data.Typeable.Internal","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When doing a default build of GHC HEAD (i.e. without `mk/build.mk`), GHC panics:\r\n\r\n{{{\r\n$ make V=0 \r\n=== building phase 0\r\nmake noprintdirectory f ghc.mk phase=0 phase_0_builds\r\nmake[1]: Nothing to be done for 'phase_0_builds'.\r\n=== building phase 1\r\nmake noprintdirectory f ghc.mk phase=1 phase_1_builds\r\nmake[1]: Nothing to be done for 'phase_1_builds'.\r\n=== building final phase\r\nmake noprintdirectory f ghc.mk phase=final all\r\n HC [stage 1] libraries/base/distinstall/build/Data/Typeable/Internal.o\r\nghcstage1: panic! (the 'impossible' happened)\r\n (GHC version 8.3.20170922 for x86_64unknownlinux):\r\n\tTemplate variable unbound in rewrite rule\r\n Variable: cobox_a3S9\r\n Rule \"SC:mkTrApp0\"\r\n Rule bndrs: [k1_X4g7, b_X4gb, k1_a3RW, a_a3RX, k1_X426, b_X42a,\r\n b_a3RY, sc_s7Yv, sc_s7Yr, sc_s7Ys, sc_s7Yt, cobox_a3S9, cobox_a3RZ,\r\n cobox_X42x, cobox_a3S8]\r\n LHS args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),\r\n TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),\r\n TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N\r\n (Nth:2 (Sym cobox_a3S8))))\r\n (Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N\r\n (Nth:2\r\n (Sym cobox_a3S8))) ; Sym cobox_a3RZ)),\r\n TrTyCon\r\n @ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))\r\n > TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)\r\n @ (>)\r\n sc_s7Yr\r\n sc_s7Ys\r\n $tc(>)\r\n sc_s7Yt,\r\n sc_s7Yv]\r\n Actual args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),\r\n TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),\r\n TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N\r\n (Nth:2 (Sym cobox_a3S8))))\r\n (Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N\r\n (Nth:2\r\n (Sym cobox_a3S8))) ; Sym cobox_a3RZ)),\r\n TrTyCon\r\n @ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))\r\n > TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)\r\n @ (>)\r\n dt_a2Vb\r\n dt_a2Vc\r\n $tc(>)\r\n kind_vars_X37r,\r\n...\r\n}}}\r\n\r\nYou can see a more complete error in the build log at\r\n\r\n https://launchpadlibrarian.net/337888338/buildlog_ubuntutrustyamd64.ghchead_8.3.20170922+git.0.5a8b8437~14.04_BUILDING.txt.gz\r\n\r\n\r\nThis panic seems to be causally connected to cc6be3a2f23c9b2e04f9f491099149e1e1d4d20b (which addressed #14236) because reverting that commit allows me to avoid the panic.","type_of_failure":"OtherFailure","blocking":[]} >When doing a default build of GHC HEAD (i.e. without `mk/build.mk`), GHC panics:
```
$ make V=0
=== building phase 0
make noprintdirectory f ghc.mk phase=0 phase_0_builds
make[1]: Nothing to be done for 'phase_0_builds'.
=== building phase 1
make noprintdirectory f ghc.mk phase=1 phase_1_builds
make[1]: Nothing to be done for 'phase_1_builds'.
=== building final phase
make noprintdirectory f ghc.mk phase=final all
HC [stage 1] libraries/base/distinstall/build/Data/Typeable/Internal.o
ghcstage1: panic! (the 'impossible' happened)
(GHC version 8.3.20170922 for x86_64unknownlinux):
Template variable unbound in rewrite rule
Variable: cobox_a3S9
Rule "SC:mkTrApp0"
Rule bndrs: [k1_X4g7, b_X4gb, k1_a3RW, a_a3RX, k1_X426, b_X42a,
b_a3RY, sc_s7Yv, sc_s7Yr, sc_s7Ys, sc_s7Yt, cobox_a3S9, cobox_a3RZ,
cobox_X42x, cobox_a3S8]
LHS args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),
TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),
TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N
(Nth:2 (Sym cobox_a3S8))))
(Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N
(Nth:2
(Sym cobox_a3S8))) ; Sym cobox_a3RZ)),
TrTyCon
@ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))
> TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)
@ (>)
sc_s7Yr
sc_s7Ys
$tc(>)
sc_s7Yt,
sc_s7Yv]
Actual args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),
TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),
TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N
(Nth:2 (Sym cobox_a3S8))))
(Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N
(Nth:2
(Sym cobox_a3S8))) ; Sym cobox_a3RZ)),
TrTyCon
@ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))
> TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)
@ (>)
dt_a2Vb
dt_a2Vc
$tc(>)
kind_vars_X37r,
...
```
You can see a more complete error in the build log at
https://launchpadlibrarian.net/337888338/buildlog_ubuntutrustyamd64.ghchead_8.3.20170922+git.0.5a8b8437\~14.04_BUILDING.txt.gz
This panic seems to be causally connected to cc6be3a2f23c9b2e04f9f491099149e1e1d4d20b (which addressed #14236) because reverting that commit allows me to avoid the panic.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  high 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"GHC HEAD's ghcstage1 panics on Data.Typeable.Internal","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When doing a default build of GHC HEAD (i.e. without `mk/build.mk`), GHC panics:\r\n\r\n{{{\r\n$ make V=0 \r\n=== building phase 0\r\nmake noprintdirectory f ghc.mk phase=0 phase_0_builds\r\nmake[1]: Nothing to be done for 'phase_0_builds'.\r\n=== building phase 1\r\nmake noprintdirectory f ghc.mk phase=1 phase_1_builds\r\nmake[1]: Nothing to be done for 'phase_1_builds'.\r\n=== building final phase\r\nmake noprintdirectory f ghc.mk phase=final all\r\n HC [stage 1] libraries/base/distinstall/build/Data/Typeable/Internal.o\r\nghcstage1: panic! (the 'impossible' happened)\r\n (GHC version 8.3.20170922 for x86_64unknownlinux):\r\n\tTemplate variable unbound in rewrite rule\r\n Variable: cobox_a3S9\r\n Rule \"SC:mkTrApp0\"\r\n Rule bndrs: [k1_X4g7, b_X4gb, k1_a3RW, a_a3RX, k1_X426, b_X42a,\r\n b_a3RY, sc_s7Yv, sc_s7Yr, sc_s7Ys, sc_s7Yt, cobox_a3S9, cobox_a3RZ,\r\n cobox_X42x, cobox_a3S8]\r\n LHS args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),\r\n TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),\r\n TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N\r\n (Nth:2 (Sym cobox_a3S8))))\r\n (Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N\r\n (Nth:2\r\n (Sym cobox_a3S8))) ; Sym cobox_a3RZ)),\r\n TrTyCon\r\n @ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))\r\n > TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)\r\n @ (>)\r\n sc_s7Yr\r\n sc_s7Ys\r\n $tc(>)\r\n sc_s7Yt,\r\n sc_s7Yv]\r\n Actual args: [TYPE: TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8)),\r\n TYPE: TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *, TYPE: (>),\r\n TYPE: (b_X4gb > Sym (cobox_a3S9 (Coh (Sym (Coh <b_a3RY>_N\r\n (Nth:2 (Sym cobox_a3S8))))\r\n (Nth:2 (Sym cobox_a3S8)) ; Coh <b_a3RY>_N\r\n (Nth:2\r\n (Sym cobox_a3S8))) ; Sym cobox_a3RZ)),\r\n TrTyCon\r\n @ (TYPE (b_a3RY > Nth:2 (Sym cobox_a3S8))\r\n > TYPE (b_X42a > Nth:2 (Sym cobox_X42x)) > *)\r\n @ (>)\r\n dt_a2Vb\r\n dt_a2Vc\r\n $tc(>)\r\n kind_vars_X37r,\r\n...\r\n}}}\r\n\r\nYou can see a more complete error in the build log at\r\n\r\n https://launchpadlibrarian.net/337888338/buildlog_ubuntutrustyamd64.ghchead_8.3.20170922+git.0.5a8b8437~14.04_BUILDING.txt.gz\r\n\r\n\r\nThis panic seems to be causally connected to cc6be3a2f23c9b2e04f9f491099149e1e1d4d20b (which addressed #14236) because reverting that commit allows me to avoid the panic.","type_of_failure":"OtherFailure","blocking":[]} >9.0.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc//issues/14255Typeindexed type fingerprints20190707T18:17:45ZDavid FeuerTypeindexed type fingerprintsI have the feeling that it might well be possible to reduce the size of the trusted codebase somewhat by introducing typeindexed fingerprints. Imagine
```hs
data TypeRep (a :: k) where
TrTyCon :: {# UNPACK #} !FingerprintIx a > !TyCon > [SomeTypeRep]
> TypeRep (a :: k)
TrApp :: forall k1 k2 (a :: k1 > k2) (b :: k1).
{# UNPACK #} !FingerprintIx (a b)
> TypeRep (a :: k1 > k2)
> TypeRep (b :: k1)
> TypeRep (a b)
TrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
(a :: TYPE r1) (b :: TYPE r2).
{# UNPACK #} !FingerprintIx (a > b)
> TypeRep a
> TypeRep b
> TypeRep (a > b)
```
We could have some primitive operations like
```hs
mkFunFP :: FingerPrintIx a > FingerPrintIx b > FingerPrintIx (a > b)
mkAppFP :: FingerPrintIx (a > b) > FingerPrintIx a > FingerPrintIx b
eq :: FingerPrintIx a > FingerPrintIx b > Maybe (a :~~: b)
eqE :: FingerPrintIx a > FingerPrintIx b > Either (a :~~: b > c) (a :~~: b)
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Typeindexed type fingerprints","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I have the feeling that it might well be possible to reduce the size of the trusted codebase somewhat by introducing typeindexed fingerprints. Imagine\r\n\r\n{{{#!hs\r\ndata TypeRep (a :: k) where\r\n TrTyCon :: {# UNPACK #} !FingerprintIx a > !TyCon > [SomeTypeRep]\r\n > TypeRep (a :: k)\r\n TrApp :: forall k1 k2 (a :: k1 > k2) (b :: k1).\r\n {# UNPACK #} !FingerprintIx (a b)\r\n > TypeRep (a :: k1 > k2)\r\n > TypeRep (b :: k1)\r\n > TypeRep (a b)\r\n TrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)\r\n (a :: TYPE r1) (b :: TYPE r2).\r\n {# UNPACK #} !FingerprintIx (a > b)\r\n > TypeRep a\r\n > TypeRep b\r\n > TypeRep (a > b)\r\n}}}\r\n\r\nWe could have some primitive operations like\r\n\r\n{{{#!hs\r\nmkFunFP :: FingerPrintIx a > FingerPrintIx b > FingerPrintIx (a > b)\r\nmkAppFP :: FingerPrintIx (a > b) > FingerPrintIx a > FingerPrintIx b\r\n\r\neq :: FingerPrintIx a > FingerPrintIx b > Maybe (a :~~: b)\r\neqE :: FingerPrintIx a > FingerPrintIx b > Either (a :~~: b > c) (a :~~: b)\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >I have the feeling that it might well be possible to reduce the size of the trusted codebase somewhat by introducing typeindexed fingerprints. Imagine
```hs
data TypeRep (a :: k) where
TrTyCon :: {# UNPACK #} !FingerprintIx a > !TyCon > [SomeTypeRep]
> TypeRep (a :: k)
TrApp :: forall k1 k2 (a :: k1 > k2) (b :: k1).
{# UNPACK #} !FingerprintIx (a b)
> TypeRep (a :: k1 > k2)
> TypeRep (b :: k1)
> TypeRep (a b)
TrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
(a :: TYPE r1) (b :: TYPE r2).
{# UNPACK #} !FingerprintIx (a > b)
> TypeRep a
> TypeRep b
> TypeRep (a > b)
```
We could have some primitive operations like
```hs
mkFunFP :: FingerPrintIx a > FingerPrintIx b > FingerPrintIx (a > b)
mkAppFP :: FingerPrintIx (a > b) > FingerPrintIx a > FingerPrintIx b
eq :: FingerPrintIx a > FingerPrintIx b > Maybe (a :~~: b)
eqE :: FingerPrintIx a > FingerPrintIx b > Either (a :~~: b > c) (a :~~: b)
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Typeindexed type fingerprints","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I have the feeling that it might well be possible to reduce the size of the trusted codebase somewhat by introducing typeindexed fingerprints. Imagine\r\n\r\n{{{#!hs\r\ndata TypeRep (a :: k) where\r\n TrTyCon :: {# UNPACK #} !FingerprintIx a > !TyCon > [SomeTypeRep]\r\n > TypeRep (a :: k)\r\n TrApp :: forall k1 k2 (a :: k1 > k2) (b :: k1).\r\n {# UNPACK #} !FingerprintIx (a b)\r\n > TypeRep (a :: k1 > k2)\r\n > TypeRep (b :: k1)\r\n > TypeRep (a b)\r\n TrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)\r\n (a :: TYPE r1) (b :: TYPE r2).\r\n {# UNPACK #} !FingerprintIx (a > b)\r\n > TypeRep a\r\n > TypeRep b\r\n > TypeRep (a > b)\r\n}}}\r\n\r\nWe could have some primitive operations like\r\n\r\n{{{#!hs\r\nmkFunFP :: FingerPrintIx a > FingerPrintIx b > FingerPrintIx (a > b)\r\nmkAppFP :: FingerPrintIx (a > b) > FingerPrintIx a > FingerPrintIx b\r\n\r\neq :: FingerPrintIx a > FingerPrintIx b > Maybe (a :~~: b)\r\neqE :: FingerPrintIx a > FingerPrintIx b > Either (a :~~: b > c) (a :~~: b)\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/14190Typeable imposes seemingly redundant constraints on polykinded instances20200123T19:27:40ZDavid FeuerTypeable imposes seemingly redundant constraints on polykinded instancesTo derive `Data` for `Const`, we need
```hs
deriving instance (Typeable k, Data a, Typeable (b :: k)) => Data (Const a b)
```
Where's that `Typeable k` constraint come from? It turns out that for reasons I haven't looked into, we can only obtain `Typeable (Const a (b :: k))` if we have `Typeable k`; `(Typeable a, Typeable b)` is insufficient. Is there a reason for that?
Annoyingly, we can actually *get* that:
```hs
weGotThat :: forall k (a :: k). Typeable a : Typeable k
weGotThat = Sub $ withTypeable (typeRepKind (typeRep :: TypeRep a)) Dict
```
But of course that doesn't help us.
Could we use `UndecidableSuperClasses` to work around this problem? I think we likely can, although I'm concerned about the performance implications:
```hs
class (Typeable a, Typeable' k) => Typeable' (a :: k)
instance (Typeable a, Typeable' k) => Typeable' (a :: k)
withTypeable' :: forall k (a :: k) r. TypeRep a > (Typeable' a => r) > r
withTypeable' tr f = withTypeable tr $ withTypeable (typeRepKind (typeRep @a)) f
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler (Type checker) 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  bgamari 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Typeable imposes seemingly redundant constraints on polykinded instances","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["TypeableReflection"],"differentials":[],"test_case":"","architecture":"","cc":["bgamari"],"type":"Bug","description":"To derive `Data` for `Const`, we need\r\n\r\n{{{#!hs\r\nderiving instance (Typeable k, Data a, Typeable (b :: k)) => Data (Const a b)\r\n}}}\r\n\r\nWhere's that `Typeable k` constraint come from? It turns out that for reasons I haven't looked into, we can only obtain `Typeable (Const a (b :: k))` if we have `Typeable k`; `(Typeable a, Typeable b)` is insufficient. Is there a reason for that?\r\n\r\nAnnoyingly, we can actually ''get'' that:\r\n\r\n{{{#!hs\r\nweGotThat :: forall k (a :: k). Typeable a : Typeable k\r\nweGotThat = Sub $ withTypeable (typeRepKind (typeRep :: TypeRep a)) Dict\r\n}}}\r\n\r\nBut of course that doesn't help us.\r\n\r\nCould we use `UndecidableSuperClasses` to work around this problem? I think we likely can, although I'm concerned about the performance implications:\r\n\r\n{{{#!hs\r\nclass (Typeable a, Typeable' k) => Typeable' (a :: k)\r\ninstance (Typeable a, Typeable' k) => Typeable' (a :: k)\r\n\r\nwithTypeable' :: forall k (a :: k) r. TypeRep a > (Typeable' a => r) > r\r\nwithTypeable' tr f = withTypeable tr $ withTypeable (typeRepKind (typeRep @a)) f\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >To derive `Data` for `Const`, we need
```hs
deriving instance (Typeable k, Data a, Typeable (b :: k)) => Data (Const a b)
```
Where's that `Typeable k` constraint come from? It turns out that for reasons I haven't looked into, we can only obtain `Typeable (Const a (b :: k))` if we have `Typeable k`; `(Typeable a, Typeable b)` is insufficient. Is there a reason for that?
Annoyingly, we can actually *get* that:
```hs
weGotThat :: forall k (a :: k). Typeable a : Typeable k
weGotThat = Sub $ withTypeable (typeRepKind (typeRep :: TypeRep a)) Dict
```
But of course that doesn't help us.
Could we use `UndecidableSuperClasses` to work around this problem? I think we likely can, although I'm concerned about the performance implications:
```hs
class (Typeable a, Typeable' k) => Typeable' (a :: k)
instance (Typeable a, Typeable' k) => Typeable' (a :: k)
withTypeable' :: forall k (a :: k) r. TypeRep a > (Typeable' a => r) > r
withTypeable' tr f = withTypeable tr $ withTypeable (typeRepKind (typeRep @a)) f
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler (Type checker) 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  bgamari 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Typeable imposes seemingly redundant constraints on polykinded instances","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["TypeableReflection"],"differentials":[],"test_case":"","architecture":"","cc":["bgamari"],"type":"Bug","description":"To derive `Data` for `Const`, we need\r\n\r\n{{{#!hs\r\nderiving instance (Typeable k, Data a, Typeable (b :: k)) => Data (Const a b)\r\n}}}\r\n\r\nWhere's that `Typeable k` constraint come from? It turns out that for reasons I haven't looked into, we can only obtain `Typeable (Const a (b :: k))` if we have `Typeable k`; `(Typeable a, Typeable b)` is insufficient. Is there a reason for that?\r\n\r\nAnnoyingly, we can actually ''get'' that:\r\n\r\n{{{#!hs\r\nweGotThat :: forall k (a :: k). Typeable a : Typeable k\r\nweGotThat = Sub $ withTypeable (typeRepKind (typeRep :: TypeRep a)) Dict\r\n}}}\r\n\r\nBut of course that doesn't help us.\r\n\r\nCould we use `UndecidableSuperClasses` to work around this problem? I think we likely can, although I'm concerned about the performance implications:\r\n\r\n{{{#!hs\r\nclass (Typeable a, Typeable' k) => Typeable' (a :: k)\r\ninstance (Typeable a, Typeable' k) => Typeable' (a :: k)\r\n\r\nwithTypeable' :: forall k (a :: k) r. TypeRep a > (Typeable' a => r) > r\r\nwithTypeable' tr f = withTypeable tr $ withTypeable (typeRepKind (typeRep @a)) f\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/13933Support Typeable instances for types with coercions20190707T18:19:21ZRichard Eisenbergrae@richarde.devSupport Typeable instances for types with coercionsIf I say
```hs
{# LANGUAGE GADTs, TypeApplications, TypeInType #}
module Bug where
import Type.Reflection
data G a where
MkG :: a ~ Bool => G a
rep = typeRep @MkG
```
I get
```
Bug.hs:10:7: error:
• No instance for (Typeable <>) arising from a use of ‘typeRep’
• In the expression: typeRep @MkG
In an equation for ‘rep’: rep = typeRep @MkG

10  rep = typeRep @MkG

```
First off, the error message is confusing, mentioning the mysterious `<>`. But more importantly, it would be nice if the `Typeable` mechanism supported coercions.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Support Typeable instances for types with coercions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":["TypeInType,","Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"If I say\r\n\r\n{{{#!hs\r\n{# LANGUAGE GADTs, TypeApplications, TypeInType #}\r\n\r\nmodule Bug where\r\n\r\nimport Type.Reflection\r\n\r\ndata G a where\r\n MkG :: a ~ Bool => G a\r\n\r\nrep = typeRep @MkG\r\n}}}\r\n\r\nI get\r\n\r\n{{{\r\nBug.hs:10:7: error:\r\n • No instance for (Typeable <>) arising from a use of ‘typeRep’\r\n • In the expression: typeRep @MkG\r\n In an equation for ‘rep’: rep = typeRep @MkG\r\n \r\n10  rep = typeRep @MkG\r\n  \r\n}}}\r\n\r\nFirst off, the error message is confusing, mentioning the mysterious `<>`. But more importantly, it would be nice if the `Typeable` mechanism supported coercions.","type_of_failure":"OtherFailure","blocking":[]} >If I say
```hs
{# LANGUAGE GADTs, TypeApplications, TypeInType #}
module Bug where
import Type.Reflection
data G a where
MkG :: a ~ Bool => G a
rep = typeRep @MkG
```
I get
```
Bug.hs:10:7: error:
• No instance for (Typeable <>) arising from a use of ‘typeRep’
• In the expression: typeRep @MkG
In an equation for ‘rep’: rep = typeRep @MkG

10  rep = typeRep @MkG

```
First off, the error message is confusing, mentioning the mysterious `<>`. But more importantly, it would be nice if the `Typeable` mechanism supported coercions.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Support Typeable instances for types with coercions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":["TypeInType,","Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"If I say\r\n\r\n{{{#!hs\r\n{# LANGUAGE GADTs, TypeApplications, TypeInType #}\r\n\r\nmodule Bug where\r\n\r\nimport Type.Reflection\r\n\r\ndata G a where\r\n MkG :: a ~ Bool => G a\r\n\r\nrep = typeRep @MkG\r\n}}}\r\n\r\nI get\r\n\r\n{{{\r\nBug.hs:10:7: error:\r\n • No instance for (Typeable <>) arising from a use of ‘typeRep’\r\n • In the expression: typeRep @MkG\r\n In an equation for ‘rep’: rep = typeRep @MkG\r\n \r\n10  rep = typeRep @MkG\r\n  \r\n}}}\r\n\r\nFirst off, the error message is confusing, mentioning the mysterious `<>`. But more importantly, it would be nice if the `Typeable` mechanism supported coercions.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/13647Tidy up TcTypeable20200123T19:31:02ZSimon Peyton JonesTidy up TcTypeableThere is code in `TcTypeable` that generates a `KindRep` for each `TyCon` (see `Note [Representing TyCon kinds: KindRep]`). There's nothing actually wrong with it.
But it's pretty hard to understand. And it generates a staggering amount of data structure, when
compiling `GHC.Types`.
```
Result size of Tidy Core
= {terms: 74,615, types: 41,335, coercions: 2, joins: 0/0}
```
Why? Well, it injects a `TyCon` binding for each unboxed tuple size.
For example, here is the code for pairs `(#,#)`
```
$tc(#,#)
= TyCon 16533601304077481746##
7902994497850328874##
tr$ModuleGHCPrim
$tc(#,#)2
2#
$tc(#,#)1
 TYPE #0 > TYPE #1 > TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))
$tc(#,#)1 :: KindRep
$tc(#,#)1 = KindRepFun $krep2115_r6ji $krep18009_rarE
$krep18009_rarE = KindRepFun $krep2117_r6jk $krep18008_rarD
 TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))
$krep18008_rarD = KindRepTyConApp $tcTYPE $krep18007_rarC
$krep18007_rarC = : @ KindRep $krep18006_rarB ([] @ KindRep)
 TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep)))
$krep18006_rarB = KindRepTyConApp $tc'TupleRep $krep18005_rarA
$krep18005_rarA = : @ KindRep $krep2283_r6m0 ([] @ KindRep)
 ': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))
$krep2283_r6m0 = KindRepTyConApp $tc': $krep2282_r6lZ
$krep2282_r6lZ = : @ KindRep $tc'AddrRep1 $krep2281_r6lY
$krep2281_r6lY = : @ KindRep $krep61_r5Ma $krep2280_r6lX
$krep2280_r6lX = : @ KindRep $krep2279_r6lW ([] @ KindRep)
 ': RuntimeRep #1 ('[] RuntimeRep)
$krep2279_r6lW = KindRepTyConApp $tc': $krep2278_r6lV
$krep2278_r6lV = : @ KindRep $tc'AddrRep1 $krep2277_r6lU
$krep2277_r6lU = : @ KindRep $krep60_r5M9 $krep2276_r6lT
$krep2276_r6lT = : @ KindRep $krep2274_r6lR ([] @ KindRep)
 '[] RuntimeRep
$krep2274_r6lR = KindRepTyConApp $tc'[] $krep2273_r6lQ
$krep2273_r6lQ = : @ KindRep $tc'AddrRep1 ([] @ KindRep)
 RuntimeRep
$tc'AddrRep1 = KindRepTyConApp $tcRuntimeRep ([] @ KindRep)
 TYPE #0
$krep2115_r6ji = KindRepTyConApp $tcTYPE $krep2114_r6jh
$krep2114_r6jh = : @ KindRep $krep61_r5Ma ([] @ KindRep)
$krep61_r5Ma = KindRepVar 0#
 TYPE #1
$krep2117_r6jk = KindRepTyConApp $tcTYPE $krep2116_r6jj
$krep2116_r6jj = : @ KindRep $krep60_r5M9 ([] @ KindRep)
$krep60_r5M9 = KindRepVar 1#
```
That's a lot, and it's only for pairs.
We generate all this up to 62tuples!
Suggestions (read `Note [Representing TyCon kinds: KindRep]` first)
 `KindRep` is a description of a polykind; an interpreter, called `instantiateKindRep` turns it into a kind. So we can add whatever constructors we like to `KindRep`.
 One good one would be `UnboxedTupleRep n`, which `instantiateKindRep` can instantiate to the kind of an unboxed tuple. It just moves the work somewhere else, of course, but it will make the generated code dramatically smaller.
 We have a few canned kindreps, via `TcTypeable.builtInKindReps`. It'd be simpler and easier instead to make each of them into a data constructor of `KindRep`.
 Once that is done, I suspect that the entire machinery of tyring to share `KindReps` (which makes my head hurt) would be unnecessary
None of this is essential, but I think that matters can be improved.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.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":"Tidy up TcTypeable","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"There is code in `TcTypeable` that generates a `KindRep` for each `TyCon` (see `Note [Representing TyCon kinds: KindRep]`). There's nothing actually wrong with it.\r\n\r\nBut it's pretty hard to understand. And it generates a staggering amount of data structure, when\r\ncompiling `GHC.Types`.\r\n{{{\r\nResult size of Tidy Core\r\n = {terms: 74,615, types: 41,335, coercions: 2, joins: 0/0}\r\n}}}\r\nWhy? Well, it injects a `TyCon` binding for each unboxed tuple size.\r\nFor example, here is the code for pairs `(#,#)`\r\n{{{\r\n$tc(#,#)\r\n = TyCon 16533601304077481746##\r\n 7902994497850328874##\r\n tr$ModuleGHCPrim\r\n $tc(#,#)2\r\n 2#\r\n $tc(#,#)1\r\n\r\n TYPE #0 > TYPE #1 > TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))\r\n$tc(#,#)1 :: KindRep\r\n$tc(#,#)1 = KindRepFun $krep2115_r6ji $krep18009_rarE\r\n\r\n$krep18009_rarE = KindRepFun $krep2117_r6jk $krep18008_rarD\r\n\r\n TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))\r\n$krep18008_rarD = KindRepTyConApp $tcTYPE $krep18007_rarC\r\n$krep18007_rarC = : @ KindRep $krep18006_rarB ([] @ KindRep)\r\n\r\n TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep)))\r\n$krep18006_rarB = KindRepTyConApp $tc'TupleRep $krep18005_rarA\r\n$krep18005_rarA = : @ KindRep $krep2283_r6m0 ([] @ KindRep)\r\n\r\n ': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))\r\n$krep2283_r6m0 = KindRepTyConApp $tc': $krep2282_r6lZ\r\n$krep2282_r6lZ = : @ KindRep $tc'AddrRep1 $krep2281_r6lY\r\n$krep2281_r6lY = : @ KindRep $krep61_r5Ma $krep2280_r6lX\r\n$krep2280_r6lX = : @ KindRep $krep2279_r6lW ([] @ KindRep)\r\n\r\n ': RuntimeRep #1 ('[] RuntimeRep)\r\n$krep2279_r6lW = KindRepTyConApp $tc': $krep2278_r6lV\r\n$krep2278_r6lV = : @ KindRep $tc'AddrRep1 $krep2277_r6lU\r\n$krep2277_r6lU = : @ KindRep $krep60_r5M9 $krep2276_r6lT\r\n$krep2276_r6lT = : @ KindRep $krep2274_r6lR ([] @ KindRep)\r\n\r\n '[] RuntimeRep\r\n$krep2274_r6lR = KindRepTyConApp $tc'[] $krep2273_r6lQ\r\n$krep2273_r6lQ = : @ KindRep $tc'AddrRep1 ([] @ KindRep)\r\n\r\n RuntimeRep\r\n$tc'AddrRep1 = KindRepTyConApp $tcRuntimeRep ([] @ KindRep)\r\n\r\n TYPE #0\r\n$krep2115_r6ji = KindRepTyConApp $tcTYPE $krep2114_r6jh\r\n$krep2114_r6jh = : @ KindRep $krep61_r5Ma ([] @ KindRep)\r\n$krep61_r5Ma = KindRepVar 0#\r\n\r\n TYPE #1\r\n$krep2117_r6jk = KindRepTyConApp $tcTYPE $krep2116_r6jj\r\n$krep2116_r6jj = : @ KindRep $krep60_r5M9 ([] @ KindRep)\r\n$krep60_r5M9 = KindRepVar 1#\r\n}}}\r\nThat's a lot, and it's only for pairs.\r\nWe generate all this up to 62tuples!\r\n\r\nSuggestions (read `Note [Representing TyCon kinds: KindRep]` first)\r\n\r\n* `KindRep` is a description of a polykind; an interpreter, called `instantiateKindRep` turns it into a kind. So we can add whatever constructors we like to `KindRep`.\r\n\r\n* One good one would be `UnboxedTupleRep n`, which `instantiateKindRep` can instantiate to the kind of an unboxed tuple. It just moves the work somewhere else, of course, but it will make the generated code dramatically smaller.\r\n\r\n* We have a few canned kindreps, via `TcTypeable.builtInKindReps`. It'd be simpler and easier instead to make each of them into a data constructor of `KindRep`.\r\n\r\n* Once that is done, I suspect that the entire machinery of tyring to share `KindReps` (which makes my head hurt) would be unnecessary\r\n\r\nNone of this is essential, but I think that matters can be improved.\r\n","type_of_failure":"OtherFailure","blocking":[]} >There is code in `TcTypeable` that generates a `KindRep` for each `TyCon` (see `Note [Representing TyCon kinds: KindRep]`). There's nothing actually wrong with it.
But it's pretty hard to understand. And it generates a staggering amount of data structure, when
compiling `GHC.Types`.
```
Result size of Tidy Core
= {terms: 74,615, types: 41,335, coercions: 2, joins: 0/0}
```
Why? Well, it injects a `TyCon` binding for each unboxed tuple size.
For example, here is the code for pairs `(#,#)`
```
$tc(#,#)
= TyCon 16533601304077481746##
7902994497850328874##
tr$ModuleGHCPrim
$tc(#,#)2
2#
$tc(#,#)1
 TYPE #0 > TYPE #1 > TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))
$tc(#,#)1 :: KindRep
$tc(#,#)1 = KindRepFun $krep2115_r6ji $krep18009_rarE
$krep18009_rarE = KindRepFun $krep2117_r6jk $krep18008_rarD
 TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))
$krep18008_rarD = KindRepTyConApp $tcTYPE $krep18007_rarC
$krep18007_rarC = : @ KindRep $krep18006_rarB ([] @ KindRep)
 TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep)))
$krep18006_rarB = KindRepTyConApp $tc'TupleRep $krep18005_rarA
$krep18005_rarA = : @ KindRep $krep2283_r6m0 ([] @ KindRep)
 ': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))
$krep2283_r6m0 = KindRepTyConApp $tc': $krep2282_r6lZ
$krep2282_r6lZ = : @ KindRep $tc'AddrRep1 $krep2281_r6lY
$krep2281_r6lY = : @ KindRep $krep61_r5Ma $krep2280_r6lX
$krep2280_r6lX = : @ KindRep $krep2279_r6lW ([] @ KindRep)
 ': RuntimeRep #1 ('[] RuntimeRep)
$krep2279_r6lW = KindRepTyConApp $tc': $krep2278_r6lV
$krep2278_r6lV = : @ KindRep $tc'AddrRep1 $krep2277_r6lU
$krep2277_r6lU = : @ KindRep $krep60_r5M9 $krep2276_r6lT
$krep2276_r6lT = : @ KindRep $krep2274_r6lR ([] @ KindRep)
 '[] RuntimeRep
$krep2274_r6lR = KindRepTyConApp $tc'[] $krep2273_r6lQ
$krep2273_r6lQ = : @ KindRep $tc'AddrRep1 ([] @ KindRep)
 RuntimeRep
$tc'AddrRep1 = KindRepTyConApp $tcRuntimeRep ([] @ KindRep)
 TYPE #0
$krep2115_r6ji = KindRepTyConApp $tcTYPE $krep2114_r6jh
$krep2114_r6jh = : @ KindRep $krep61_r5Ma ([] @ KindRep)
$krep61_r5Ma = KindRepVar 0#
 TYPE #1
$krep2117_r6jk = KindRepTyConApp $tcTYPE $krep2116_r6jj
$krep2116_r6jj = : @ KindRep $krep60_r5M9 ([] @ KindRep)
$krep60_r5M9 = KindRepVar 1#
```
That's a lot, and it's only for pairs.
We generate all this up to 62tuples!
Suggestions (read `Note [Representing TyCon kinds: KindRep]` first)
 `KindRep` is a description of a polykind; an interpreter, called `instantiateKindRep` turns it into a kind. So we can add whatever constructors we like to `KindRep`.
 One good one would be `UnboxedTupleRep n`, which `instantiateKindRep` can instantiate to the kind of an unboxed tuple. It just moves the work somewhere else, of course, but it will make the generated code dramatically smaller.
 We have a few canned kindreps, via `TcTypeable.builtInKindReps`. It'd be simpler and easier instead to make each of them into a data constructor of `KindRep`.
 Once that is done, I suspect that the entire machinery of tyring to share `KindReps` (which makes my head hurt) would be unnecessary
None of this is essential, but I think that matters can be improved.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.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":"Tidy up TcTypeable","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"There is code in `TcTypeable` that generates a `KindRep` for each `TyCon` (see `Note [Representing TyCon kinds: KindRep]`). There's nothing actually wrong with it.\r\n\r\nBut it's pretty hard to understand. And it generates a staggering amount of data structure, when\r\ncompiling `GHC.Types`.\r\n{{{\r\nResult size of Tidy Core\r\n = {terms: 74,615, types: 41,335, coercions: 2, joins: 0/0}\r\n}}}\r\nWhy? Well, it injects a `TyCon` binding for each unboxed tuple size.\r\nFor example, here is the code for pairs `(#,#)`\r\n{{{\r\n$tc(#,#)\r\n = TyCon 16533601304077481746##\r\n 7902994497850328874##\r\n tr$ModuleGHCPrim\r\n $tc(#,#)2\r\n 2#\r\n $tc(#,#)1\r\n\r\n TYPE #0 > TYPE #1 > TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))\r\n$tc(#,#)1 :: KindRep\r\n$tc(#,#)1 = KindRepFun $krep2115_r6ji $krep18009_rarE\r\n\r\n$krep18009_rarE = KindRepFun $krep2117_r6jk $krep18008_rarD\r\n\r\n TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))\r\n$krep18008_rarD = KindRepTyConApp $tcTYPE $krep18007_rarC\r\n$krep18007_rarC = : @ KindRep $krep18006_rarB ([] @ KindRep)\r\n\r\n TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep)))\r\n$krep18006_rarB = KindRepTyConApp $tc'TupleRep $krep18005_rarA\r\n$krep18005_rarA = : @ KindRep $krep2283_r6m0 ([] @ KindRep)\r\n\r\n ': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))\r\n$krep2283_r6m0 = KindRepTyConApp $tc': $krep2282_r6lZ\r\n$krep2282_r6lZ = : @ KindRep $tc'AddrRep1 $krep2281_r6lY\r\n$krep2281_r6lY = : @ KindRep $krep61_r5Ma $krep2280_r6lX\r\n$krep2280_r6lX = : @ KindRep $krep2279_r6lW ([] @ KindRep)\r\n\r\n ': RuntimeRep #1 ('[] RuntimeRep)\r\n$krep2279_r6lW = KindRepTyConApp $tc': $krep2278_r6lV\r\n$krep2278_r6lV = : @ KindRep $tc'AddrRep1 $krep2277_r6lU\r\n$krep2277_r6lU = : @ KindRep $krep60_r5M9 $krep2276_r6lT\r\n$krep2276_r6lT = : @ KindRep $krep2274_r6lR ([] @ KindRep)\r\n\r\n '[] RuntimeRep\r\n$krep2274_r6lR = KindRepTyConApp $tc'[] $krep2273_r6lQ\r\n$krep2273_r6lQ = : @ KindRep $tc'AddrRep1 ([] @ KindRep)\r\n\r\n RuntimeRep\r\n$tc'AddrRep1 = KindRepTyConApp $tcRuntimeRep ([] @ KindRep)\r\n\r\n TYPE #0\r\n$krep2115_r6ji = KindRepTyConApp $tcTYPE $krep2114_r6jh\r\n$krep2114_r6jh = : @ KindRep $krep61_r5Ma ([] @ KindRep)\r\n$krep61_r5Ma = KindRepVar 0#\r\n\r\n TYPE #1\r\n$krep2117_r6jk = KindRepTyConApp $tcTYPE $krep2116_r6jj\r\n$krep2116_r6jj = : @ KindRep $krep60_r5M9 ([] @ KindRep)\r\n$krep60_r5M9 = KindRepVar 1#\r\n}}}\r\nThat's a lot, and it's only for pairs.\r\nWe generate all this up to 62tuples!\r\n\r\nSuggestions (read `Note [Representing TyCon kinds: KindRep]` first)\r\n\r\n* `KindRep` is a description of a polykind; an interpreter, called `instantiateKindRep` turns it into a kind. So we can add whatever constructors we like to `KindRep`.\r\n\r\n* One good one would be `UnboxedTupleRep n`, which `instantiateKindRep` can instantiate to the kind of an unboxed tuple. It just moves the work somewhere else, of course, but it will make the generated code dramatically smaller.\r\n\r\n* We have a few canned kindreps, via `TcTypeable.builtInKindReps`. It'd be simpler and easier instead to make each of them into a data constructor of `KindRep`.\r\n\r\n* Once that is done, I suspect that the entire machinery of tyring to share `KindReps` (which makes my head hurt) would be unnecessary\r\n\r\nNone of this is essential, but I think that matters can be improved.\r\n","type_of_failure":"OtherFailure","blocking":[]} >Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc//issues/13276Unboxed sums are not Typeable20190707T18:22:38ZBen GamariUnboxed sums are not TypeableWhile the Typeable machinery introduce in the typeindexed Typeable rework (#11011) is fully capable of representing unboxed sums, we currently don't allow this since it would require that we generate an enormous number of bindings in `GHC.Types`. This is because we need to generate both `TyCon` and `KindRep` bindings for each type constructor and its promoted data constructors.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Unboxed sums are not Typeable","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":["typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"While the Typeable machinery introduce in the typeindexed Typeable rework (#11011) is fully capable of representing unboxed sums, we currently don't allow this since it would require that we generate an enormous number of bindings in `GHC.Types`. This is because we need to generate both `TyCon` and `KindRep` bindings for each type constructor and its promoted data constructors.","type_of_failure":"OtherFailure","blocking":[]} >While the Typeable machinery introduce in the typeindexed Typeable rework (#11011) is fully capable of representing unboxed sums, we currently don't allow this since it would require that we generate an enormous number of bindings in `GHC.Types`. This is because we need to generate both `TyCon` and `KindRep` bindings for each type constructor and its promoted data constructors.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Unboxed sums are not Typeable","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":["typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"While the Typeable machinery introduce in the typeindexed Typeable rework (#11011) is fully capable of representing unboxed sums, we currently don't allow this since it would require that we generate an enormous number of bindings in `GHC.Types`. This is because we need to generate both `TyCon` and `KindRep` bindings for each type constructor and its promoted data constructors.","type_of_failure":"OtherFailure","blocking":[]} >8.6.1https://gitlab.haskell.org/ghc/ghc//issues/13261Consider moving Typeable evidence generation wholly back to solver20200511T16:09:24ZBen GamariConsider moving Typeable evidence generation wholly back to solverSince 91c6b1f54aea658b0056caec45655475897f1972 we have generated a set of bindings with each datatype definition which the compiler will refer to when constructing `Typeable` evidence. As described in the commit message, this came with a rather significant performance penalty, especially given that it is paid regardless of whether the code being compiled uses `Typeable`.
The typeindexed Typeable implementation (#11011) augments these bindings with additional information allowing the kind of a type of be reconstructing at runtime (#10343). Unfortunately, this further blows up the cost of associated with Typeable binding generation. Some of the testsuite regressions are hard to swallow to say the least.
While I'm still working out what can be done to reduce this cost, I do wonder whether the generating these bindings at the time of type definition is so wise. Relatively few users make use of Typeable and the cost is not negligible. Moreover, generating bindings for families of tycons (e.g. unboxed sums, which have thousands of type constructors and promoted data constructors) all at once produces a truly massive amount of code (albeit it only has to be done once).
On the other hand, I suppose if Richard's dependent types story comes to fruition then perhaps the weight imposed by generating Typeable bindings at typedefinition time might pull its weight.
Anyways, just idle reflections.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Consider moving Typeable evidence generation wholly back to solver","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Since 91c6b1f54aea658b0056caec45655475897f1972 we have generated a set of bindings with each datatype definition which the compiler will refer to when constructing `Typeable` evidence. As described in the commit message, this came with a rather significant performance penalty, especially given that it is paid regardless of whether the code being compiled uses `Typeable`.\r\n\r\nThe typeindexed Typeable implementation (#11011) augments these bindings with additional information allowing the kind of a type of be reconstructing at runtime (#10343). Unfortunately, this further blows up the cost of associated with Typeable binding generation. Some of the testsuite regressions are hard to swallow to say the least.\r\n\r\nWhile I'm still working out what can be done to reduce this cost, I do wonder whether the generating these bindings at the time of type definition is so wise. Relatively few users make use of Typeable and the cost is not negligible. Moreover, generating bindings for families of tycons (e.g. unboxed sums, which have thousands of type constructors and promoted data constructors) all at once produces a truly massive amount of code (albeit it only has to be done once).\r\n\r\nOn the other hand, I suppose if Richard's dependent types story comes to fruition then perhaps the weight imposed by generating Typeable bindings at typedefinition time might pull its weight.\r\n\r\nAnyways, just idle reflections.","type_of_failure":"OtherFailure","blocking":[]} >Since 91c6b1f54aea658b0056caec45655475897f1972 we have generated a set of bindings with each datatype definition which the compiler will refer to when constructing `Typeable` evidence. As described in the commit message, this came with a rather significant performance penalty, especially given that it is paid regardless of whether the code being compiled uses `Typeable`.
The typeindexed Typeable implementation (#11011) augments these bindings with additional information allowing the kind of a type of be reconstructing at runtime (#10343). Unfortunately, this further blows up the cost of associated with Typeable binding generation. Some of the testsuite regressions are hard to swallow to say the least.
While I'm still working out what can be done to reduce this cost, I do wonder whether the generating these bindings at the time of type definition is so wise. Relatively few users make use of Typeable and the cost is not negligible. Moreover, generating bindings for families of tycons (e.g. unboxed sums, which have thousands of type constructors and promoted data constructors) all at once produces a truly massive amount of code (albeit it only has to be done once).
On the other hand, I suppose if Richard's dependent types story comes to fruition then perhaps the weight imposed by generating Typeable bindings at typedefinition time might pull its weight.
Anyways, just idle reflections.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Consider moving Typeable evidence generation wholly back to solver","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Since 91c6b1f54aea658b0056caec45655475897f1972 we have generated a set of bindings with each datatype definition which the compiler will refer to when constructing `Typeable` evidence. As described in the commit message, this came with a rather significant performance penalty, especially given that it is paid regardless of whether the code being compiled uses `Typeable`.\r\n\r\nThe typeindexed Typeable implementation (#11011) augments these bindings with additional information allowing the kind of a type of be reconstructing at runtime (#10343). Unfortunately, this further blows up the cost of associated with Typeable binding generation. Some of the testsuite regressions are hard to swallow to say the least.\r\n\r\nWhile I'm still working out what can be done to reduce this cost, I do wonder whether the generating these bindings at the time of type definition is so wise. Relatively few users make use of Typeable and the cost is not negligible. Moreover, generating bindings for families of tycons (e.g. unboxed sums, which have thousands of type constructors and promoted data constructors) all at once produces a truly massive amount of code (albeit it only has to be done once).\r\n\r\nOn the other hand, I suppose if Richard's dependent types story comes to fruition then perhaps the weight imposed by generating Typeable bindings at typedefinition time might pull its weight.\r\n\r\nAnyways, just idle reflections.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/12451TemplateHaskell and Data.Typeable  tcIfaceGlobal (local): not found20190707T18:26:34ZmkloczkoTemplateHaskell and Data.Typeable  tcIfaceGlobal (local): not foundThe following code produces an ghc panic error:
```hs
{# LANGUAGE TemplateHaskell #}
{# LANGUAGE ScopedTypeVariables #}
module TH where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Data.Typeable
usingType :: forall a. Typeable a => a > Q [Dec]
usingType _ = do
 Try to get anything using typeRep.
let name = (tyConName $ typeRepTyCon $ typeRep (Proxy :: Proxy a)) `seq` "The name!"
 theF = "The name!"
return [FunD (mkName "theF") [Clause [] (NormalB $ LitE $ StringL name ) []]]
```
```hs
{# LANGUAGE TemplateHaskell #}
module Main where
import TH
data A = A Int
 Changing the argument to (A 3) does not help.
$(usingType (undefined :: A))
main = putStrLn $ theF
```
The error:
```
ghc: panic! (the 'impossible' happened)
(GHC version 8.0.1 for x86_64unknownlinux):
tcIfaceGlobal (local): not found:
$tcA
[r5m0 :> Type constructor ‘A’, r5m3 :> Data constructor ‘A’,
r5m9 :> Identifier ‘A’]
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.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":"TemplateHaskell and Data.Typeable  tcIfaceGlobal (local): not found","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":["TemplateHaskell,","Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following code produces an ghc panic error:\r\n\r\n{{{#!hs\r\n{# LANGUAGE TemplateHaskell #}\r\n{# LANGUAGE ScopedTypeVariables #}\r\n\r\nmodule TH where\r\n\r\nimport Language.Haskell.TH\r\nimport Language.Haskell.TH.Syntax\r\nimport Data.Typeable\r\n\r\n\r\nusingType :: forall a. Typeable a => a > Q [Dec]\r\nusingType _ = do\r\n  Try to get anything using typeRep.\r\n let name = (tyConName $ typeRepTyCon $ typeRep (Proxy :: Proxy a)) `seq` \"The name!\"\r\n  theF = \"The name!\"\r\n return [FunD (mkName \"theF\") [Clause [] (NormalB $ LitE $ StringL name ) []]]\r\n}}}\r\n\r\n{{{#!hs\r\n{# LANGUAGE TemplateHaskell #}\r\n\r\nmodule Main where\r\nimport TH \r\n\r\ndata A = A Int\r\n\r\n Changing the argument to (A 3) does not help.\r\n$(usingType (undefined :: A))\r\n\r\nmain = putStrLn $ theF\r\n}}}\r\n\r\nThe error:\r\n\r\n{{{\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 8.0.1 for x86_64unknownlinux):\r\n\ttcIfaceGlobal (local): not found:\r\n $tcA\r\n [r5m0 :> Type constructor ‘A’, r5m3 :> Data constructor ‘A’,\r\n r5m9 :> Identifier ‘A’]\r\n}}}\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} >The following code produces an ghc panic error:
```hs
{# LANGUAGE TemplateHaskell #}
{# LANGUAGE ScopedTypeVariables #}
module TH where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Data.Typeable
usingType :: forall a. Typeable a => a > Q [Dec]
usingType _ = do
 Try to get anything using typeRep.
let name = (tyConName $ typeRepTyCon $ typeRep (Proxy :: Proxy a)) `seq` "The name!"
 theF = "The name!"
return [FunD (mkName "theF") [Clause [] (NormalB $ LitE $ StringL name ) []]]
```
```hs
{# LANGUAGE TemplateHaskell #}
module Main where
import TH
data A = A Int
 Changing the argument to (A 3) does not help.
$(usingType (undefined :: A))
main = putStrLn $ theF
```
The error:
```
ghc: panic! (the 'impossible' happened)
(GHC version 8.0.1 for x86_64unknownlinux):
tcIfaceGlobal (local): not found:
$tcA
[r5m0 :> Type constructor ‘A’, r5m3 :> Data constructor ‘A’,
r5m9 :> Identifier ‘A’]
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.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":"TemplateHaskell and Data.Typeable  tcIfaceGlobal (local): not found","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":["TemplateHaskell,","Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following code produces an ghc panic error:\r\n\r\n{{{#!hs\r\n{# LANGUAGE TemplateHaskell #}\r\n{# LANGUAGE ScopedTypeVariables #}\r\n\r\nmodule TH where\r\n\r\nimport Language.Haskell.TH\r\nimport Language.Haskell.TH.Syntax\r\nimport Data.Typeable\r\n\r\n\r\nusingType :: forall a. Typeable a => a > Q [Dec]\r\nusingType _ = do\r\n  Try to get anything using typeRep.\r\n let name = (tyConName $ typeRepTyCon $ typeRep (Proxy :: Proxy a)) `seq` \"The name!\"\r\n  theF = \"The name!\"\r\n return [FunD (mkName \"theF\") [Clause [] (NormalB $ LitE $ StringL name ) []]]\r\n}}}\r\n\r\n{{{#!hs\r\n{# LANGUAGE TemplateHaskell #}\r\n\r\nmodule Main where\r\nimport TH \r\n\r\ndata A = A Int\r\n\r\n Changing the argument to (A 3) does not help.\r\n$(usingType (undefined :: A))\r\n\r\nmain = putStrLn $ theF\r\n}}}\r\n\r\nThe error:\r\n\r\n{{{\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 8.0.1 for x86_64unknownlinux):\r\n\ttcIfaceGlobal (local): not found:\r\n $tcA\r\n [r5m0 :> Type constructor ‘A’, r5m3 :> Data constructor ‘A’,\r\n r5m9 :> Identifier ‘A’]\r\n}}}\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/11349[TypeApplications] Create Proxyfree alternatives of functions in base20190707T18:30:48ZIcelandjack[TypeApplications] Create Proxyfree alternatives of functions in baseNow that we have [TypeApplications](https://phabricator.haskell.org/D1138) how about we create a Proxyfree version of functions in base that currently require it:
```hs
tr :: forall a. Typeable a => TypeRep
tr = typeRep @Proxy @a Proxy
symbol :: forall s. KnownSymbol s => String
symbol = symbolVal @s Proxy
nat :: forall n. KnownNat n => Integer
nat = natVal @n Proxy
```
While we're at it let's use [Natural](https://hackage.haskell.org/package/base/docs/NumericNatural.html) as the valuelevel representation of Nat, avoiding `Maybe` in `someNatVal :: Integer > Maybe SomeNat`:
```hs
nat :: forall n. KnownNat n => Natural
nat = natVal @n Proxy
someNatVal :: Natural > SomeNat
someNatVal = ...
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  7.10.3 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  ekmett 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"[TypeApplications] Create Proxyfree alternatives of functions in base","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.3","keywords":["TypeApplications"],"differentials":[],"test_case":"","architecture":"","cc":["ekmett"],"type":"FeatureRequest","description":"Now that we have [https://phabricator.haskell.org/D1138 TypeApplications] how about we create a Proxyfree version of functions in base that currently require it:\r\n\r\n{{{#!hs\r\ntr :: forall a. Typeable a => TypeRep\r\ntr = typeRep @Proxy @a Proxy\r\n\r\nsymbol :: forall s. KnownSymbol s => String\r\nsymbol = symbolVal @s Proxy\r\n\r\nnat :: forall n. KnownNat n => Integer\r\nnat = natVal @n Proxy\r\n}}}\r\n\r\nWhile we're at it let's use [https://hackage.haskell.org/package/base/docs/NumericNatural.html Natural] as the valuelevel representation of Nat, avoiding `Maybe` in `someNatVal :: Integer > Maybe SomeNat`: \r\n\r\n{{{#!hs\r\nnat :: forall n. KnownNat n => Natural\r\nnat = natVal @n Proxy\r\n\r\nsomeNatVal :: Natural > SomeNat\r\nsomeNatVal = ...\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >Now that we have [TypeApplications](https://phabricator.haskell.org/D1138) how about we create a Proxyfree version of functions in base that currently require it:
```hs
tr :: forall a. Typeable a => TypeRep
tr = typeRep @Proxy @a Proxy
symbol :: forall s. KnownSymbol s => String
symbol = symbolVal @s Proxy
nat :: forall n. KnownNat n => Integer
nat = natVal @n Proxy
```
While we're at it let's use [Natural](https://hackage.haskell.org/package/base/docs/NumericNatural.html) as the valuelevel representation of Nat, avoiding `Maybe` in `someNatVal :: Integer > Maybe SomeNat`:
```hs
nat :: forall n. KnownNat n => Natural
nat = natVal @n Proxy
someNatVal :: Natural > SomeNat
someNatVal = ...
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  7.10.3 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Core Libraries 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  ekmett 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"[TypeApplications] Create Proxyfree alternatives of functions in base","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.3","keywords":["TypeApplications"],"differentials":[],"test_case":"","architecture":"","cc":["ekmett"],"type":"FeatureRequest","description":"Now that we have [https://phabricator.haskell.org/D1138 TypeApplications] how about we create a Proxyfree version of functions in base that currently require it:\r\n\r\n{{{#!hs\r\ntr :: forall a. Typeable a => TypeRep\r\ntr = typeRep @Proxy @a Proxy\r\n\r\nsymbol :: forall s. KnownSymbol s => String\r\nsymbol = symbolVal @s Proxy\r\n\r\nnat :: forall n. KnownNat n => Integer\r\nnat = natVal @n Proxy\r\n}}}\r\n\r\nWhile we're at it let's use [https://hackage.haskell.org/package/base/docs/NumericNatural.html Natural] as the valuelevel representation of Nat, avoiding `Maybe` in `someNatVal :: Integer > Maybe SomeNat`: \r\n\r\n{{{#!hs\r\nnat :: forall n. KnownNat n => Natural\r\nnat = natVal @n Proxy\r\n\r\nsomeNatVal :: Natural > SomeNat\r\nsomeNatVal = ...\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >