Skip to content

Draft: Another attempt at introducing hsExprType

Zubin requested to merge wz1000/ghc:wip/hs-expr-type-2 into master

Here is an attempt to implement hsExprType using the power of the new XRec extension point introduced in !3428 (closed).

This is largely based on the code from !2182 (closed).

I've slightly generalized HsWrap and CoPat to be pass polymorphic, so that can be converted to use non GHC passes. Without this, we would be unable to get the types of all subexpressions of something guarded by a HsWrap.

I've also added a new type family NoGhcTcNonGhc to allow custom passes to override the result of NoGhcTc. Otherwise, it is impossible to have a custom pass that largely shares the instances of GhcPass p.

For example, while implementing conversion for Match GhcTc to With Typed GhcTc, we get

convertMatch :: Match GhcTc body -> Match CustomPass body'
matchType (Match ext (ctxt :: HsMatchContext (NoGhcTc GhcTc)) ...) = Match ext (ctxt' :: HsMatchContext (NoGhcTc CustomPass)) ...

-- HsMatchContext contains a field `mc_fun :: LIdP p`
-- If we have IdP CustomPass = Var
-- and as NoGhcTc GhcTc = GhcRn, NoGhcTc CustomPass = CustomPass
-- we now need to conjure up a `Var` from `Name`. Clearly this is not ideal.
-- If we instead allow CustomPass to override its NoGhcTc instance, such that
-- NoGhcTc CustomPass = CustomPassRn, we can work around this issue.

-- Thus, we have

type family NoGhcTc (p :: Type) where
    -- this way, GHC can figure out that the result is a GhcPass
  NoGhcTc (GhcPass pass) = GhcPass (NoGhcTcPass pass)
  NoGhcTc other          = NoGhcTcNonGhc other

-- | Allows passes other than GhcPass to customize the result of NoGhcTc
type family NoGhcTcNonGhc (p :: Type)

One big question that remains is how to get the type of a HsWrap expression.

hsExprType' (XExpr (WrapExpr (HsWrap wrap x))) = (error "??? fill this in", XExpr (WrapExpr (HsWrap wrap x')))
  where (ty, x') = hsExprType' x

Related tickets: #17331, #15320, #16804, #12706

TODO:

  • Can anything be done about HsTcBracketOut?
  • Make .hie file generation use this mechanism
  • Tests
Edited by Andreas Klebinger

Merge request reports