Skip to content

Non-unique Uniques in Prep output

In the output of the Prep stage, some definitions get eta-expanded with type parameters. These type parameters seem to have Unique values that are not, in fact, unique across the module.

To wit, try the following input:

{-# LANGUAGE NoImplicitPrelude #-}
module UniqueTyVar where

foo :: a -> a
foo x = x

bar :: a -> a
bar = foo

Compile it and dump Prep output:

$ ghc -fforce-recomp -dppr-debug -ddump-prep -dno-typeable-binds UniqueTyVar.hs
==================== CorePrep ====================
Result size of CorePrep
  = {terms: 9, types: 11, coercions: 0, joins: 0/0}

-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
main:UniqueTyVar.foo{v r2}
  :: forall (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}).
     (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})
     -> (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})
[GblId, Arity=1, Str=<1L>, Unf=OtherCon []]
main:UniqueTyVar.foo{v r2}
  = \ (@(a{tv agu} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}))
      (x{v sj7} [Occ=Once1]
         :: (a{tv agu} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})) ->
      (x{v sj7} Just 'ghc-prim:GHC.Types.Many{(w) d 65I} [lid] :: (a{tv agu} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}))

-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
main:UniqueTyVar.bar{v r1}
  :: forall (a{tv a3} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}).
     (a{tv a3} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})
     -> (a{tv a3} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})
[GblId, Arity=1, Str=<1L>, Unf=OtherCon []]
main:UniqueTyVar.bar{v r1}
  = \ (@(a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}))
      (eta_B0{v} [Occ=Once1]
         :: (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})) ->
      (main:UniqueTyVar.foo{v r2} Just 'ghc-prim:GHC.Types.Many{(w) d 65I} [gid] :: forall (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}).
                                                                                    (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})
                                                                                    -> (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}))
        @(a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O})
        (eta_B0{v} Just 'ghc-prim:GHC.Types.Many{(w) d 65I} [lid] :: (a{tv a4} Nothing [tv] :: ghc-prim:GHC.Types.Type{(w) tc 32O}))

Cleaned up a bit, we have:

main:UniqueTyVar.foo{v r2} :: forall a{tv a4}. a{tv a4} -> a{tv a4}

main:UniqueTyVar.bar{v r1} :: forall a{tv a3}. a{tv a3} -> a{tv a3}
main:UniqueTyVar.bar{v r1}
  = \ @(a{tv a4} :: Type) (eta_B0{v} :: a{tv a4}) ->
      main:UniqueTyVar.foo{v r2} 
        @a{tv a4}
        eta_B0{v}

Note that the type of foo and the definition of bar both binds a (type) variable with the same unique a{tv a4}.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information