Skip to content

GHC allows implicit parameters with unlifted/unboxed types

I was looking at tcExpr for implicit parameters:

tcExpr e@(HsIPVar _ x) res_ty
  = do {   {- Implicit parameters must have a *tau-type* not a
              type scheme.  We enforce this by creating a fresh
              type variable as its type.  (Because res_ty may not
              be a tau-type.) -}
         ip_ty <- newOpenFlexiTyVarTy
       ; let ip_name = mkStrLitTy (hsIPNameFS x)
       ; ipClass <- tcLookupClass ipClassName
       ; ip_var <- emitWantedEvVar origin (mkClassPred ipClass [ip_name, ip_ty])
       ; tcWrapResult e
                   (fromDict ipClass ip_name ip_ty (HsVar noExtField (noLocA ip_var)))
                   ip_ty res_ty }

Here we allow an implicit parameter of type alpha :: TYPE kappa. That seems odd to me; after all, we have:

class IP (x :: Symbol) a | x -> a where
  ip :: a

so a must surely be lifted, as it's the type of a class method.

The following program compiles but fails Core Lint:

foo () = (?p :: Int#)
*** Core Lint errors : in result of Desugar (before optimization) ***

    Kind application error in type `?p::Int#'
      Function kind = Symbol -> * -> Constraint
      Arg types = ["p", Int#]
    Fun: * -> Constraint
         Int# :: TYPE 'IntRep

    Kind application error in type `?p::Int#'
      Function kind = Symbol -> * -> Constraint
      Arg types = ["p", Int#]
    Fun: * -> Constraint
         Int# :: TYPE 'IntRep


    Kind application error in type `?p::Int#'
      Function kind = Symbol -> * -> Constraint
      Arg types = ["p", Int#]
    Fun: * -> Constraint
         Int# :: TYPE 'IntRep

    Bad axiom application (check_ki1 N:IP[0] <"p">_N <Int#>_N
                                     TYPE 'IntRep
                                     a_aOe
                                     *)
      N:IP[0] <"p">_N <Int#>_N


    Bad axiom application (check_ki2 N:IP[0] <"p">_N <Int#>_N
                                     TYPE 'IntRep
                                     a_aOe
                                     *)
      N:IP[0] <"p">_N <Int#>_N

*** Offending Program ***
foo :: (?p::Int#) => () -> Int#
[LclIdX]
foo
  = \ ($dIP_aOl :: ?p::Int#) ->
      let {
        $dIP_aOg :: ?p::Int#
        [LclId]
        $dIP_aOg = $dIP_aOl } in
      letrec {
        foo_aBH :: () -> Int#
        [LclId]
        foo_aBH
          = \ (ds_dOP :: ()) ->
              case ds_dOP of wild_00 { () ->
              break<0>()
              $dIP_aOg `cast` (N:IP[0] <"p">_N <Int#>_N :: (?p::Int#) ~R# Int#)
              }; } in
      foo_aBH
Edited by sheaf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information