Open doyougnu opened 2 years ago
In GHC.Types.Name.Occurrence
we have the decoder ring:
-- These derived variables have a prefix that no Haskell value could have
mkDataConWrapperOcc = mk_simple_deriv varName "$W"
mkWorkerOcc = mk_simple_deriv varName "$w"
mkMatcherOcc = mk_simple_deriv varName "$m"
mkBuilderOcc = mk_simple_deriv varName "$b"
mkDefaultMethodOcc = mk_simple_deriv varName "$dm"
mkClassOpAuxOcc = mk_simple_deriv varName "$c"
mkDictOcc = mk_simple_deriv varName "$d"
mkIPOcc = mk_simple_deriv varName "$i"
mkSpecOcc = mk_simple_deriv varName "$s"
mkForeignExportOcc = mk_simple_deriv varName "$f"
mkRepEqOcc = mk_simple_deriv tvName "$r" -- In RULES involving Coercible
mkClassDataConOcc = mk_simple_deriv dataName "C:" -- Data con for a class
mkNewTyCoOcc = mk_simple_deriv tcName "N:" -- Coercion for newtypes
mkInstTyCoOcc = mk_simple_deriv tcName "D:" -- Coercion for type functions
mkEqPredCoOcc = mk_simple_deriv tcName "$co"
Aha $c
is a derived name that is either a data con or a auxillary binding from a type class. That is, I think mkClassOpAuxOcc
is make TypeClass operator auxillary occurrence
. Looks like I forgot an important bit in the decoder ring:
-- Used in derived instances for the names of auxiliary bindings.
-- See Note [Auxiliary binders] in GHC.Tc.Deriv.Generate.
mkCon2TagOcc = mk_simple_deriv varName "$con2tag_"
mkTag2ConOcc = mk_simple_deriv varName "$tag2con_"
mkMaxTagOcc = mk_simple_deriv varName "$maxtag_"
mkDataTOcc = mk_simple_deriv varName "$t"
mkDataCOcc = mk_simple_deriv varName "$c"
$c
is unique in that its overloaded then. I wonder why that's the case (and if it matters)
$l
is a late lambda lift from STG:
-- | Hides away distracting bookkeeping while lambda lifting into a 'LiftM'
-- monad.
module GHC.Stg.Lift.Monad (
...
-- | Similarly to 'withSubstBndr', this function takes a set of variables to
-- abstract over, the binder to lift (and generate a fresh, substituted name
-- for) and a continuation in which that fresh, lifted binder is in scope.
--
-- It takes care of all the details involved with copying and adjusting the
-- binder and fresh name generation.
withLiftedBndr :: DIdSet -> Id -> (Id -> LiftM a) -> LiftM a
withLiftedBndr abs_ids bndr inner = do
let str = fsLit "$l" `appendFS` occNameFS (getOccName bndr)
let ty = mkLamTypes (dVarSetElems abs_ids) (idType bndr)
bndr' <-
-- See Note [transferPolyIdInfo] in GHC.Types.Id. We need to do this at least
-- for arity information.
transferPolyIdInfo bndr (dVarSetElems abs_ids)
<$> mkSysLocalM str ManyTy ty
LiftM $ RWS.local
(\e -> e
{ e_subst = extendSubst bndr bndr' $ extendInScope bndr' $ e_subst e
, e_expansions = extendVarEnv (e_expansions e) bndr abs_ids
})
(unwrapLiftM (inner bndr'))
Another good but out of date reference: https://www.scs.stanford.edu/11au-cs240h/notes/ghc-slides.html#(29)
gd
stands for given dictionary
and will be seen with GADT use: https://youtu.be/kyI9fjtgN7w?si=FCJWMImEAtYNK8eo&t=4442
$p
is from a superclass:
module GHC.Types.Name.Occurrence (
...
mkSuperDictAuxOcc :: Int -> OccName -> OccName
mkSuperDictAuxOcc index cls_tc_occ
= mk_deriv varName "$cp" [fsLit $ show index, occNameFS cls_tc_occ]
mkSuperDictSelOcc :: Int -- ^ Index of superclass, e.g. 3
-> OccName -- ^ Class, e.g. @Ord@
-> OccName -- ^ Derived 'Occname', e.g. @$p3Ord@
mkSuperDictSelOcc index cls_tc_occ
= mk_deriv varName "$p" [fsLit $ show index, occNameFS cls_tc_occ]
also see this ticket https://gitlab.haskell.org/ghc/ghc/-/issues/3781#note_535482
also see this ticket on the performance impacts on type classes: https://gitlab.haskell.org/ghc/ghc/-/issues/24679 basically GHC never unboxes type class dictionaries (which makes sense) but this can lead to slow downs if the specializer doesn't actually specialize
from the proposal