[Git][ghc/ghc][master] Add missing primop documentation (#18454)

Marge Bot gitlab at gitlab.haskell.org
Fri Aug 28 06:22:43 UTC 2020



 Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
c6f50cea by Krzysztof Gogolewski at 2020-08-28T02:22:36-04:00
Add missing primop documentation (#18454)

- Add three pseudoops to primops.txt.pp, so that Haddock renders
  the documentation
- Update comments
- Remove special case for "->" - it's no longer exported from GHC.Prim
- Remove reference to Note [Compiling GHC.Prim] - the ad-hoc fix is no
  longer there after updates to levity polymorphism.
- Document GHC.Prim
- Remove the comment that lazy is levity-polymorphic.
  As far as I can tell, it never was: in 80e399639,
  only the unfolding was given an open type variable.
- Remove haddock hack in GHC.Magic - no longer neccessary after
  adding realWorld# to primops.txt.pp.

- - - - -


8 changed files:

- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Unique/Supply.hs
- libraries/ghc-prim/GHC/Magic.hs
- utils/genprimopcode/Main.hs
- utils/genprimopcode/Parser.y


Changes:

=====================================
compiler/GHC/Builtin/Utils.hs
=====================================
@@ -257,9 +257,6 @@ primOpId op = primOpIds ! primOpTag op
             Export lists for pseudo-modules (GHC.Prim)
 *                                                                      *
 ************************************************************************
-
-GHC.Prim "exports" all the primops and primitive types, some
-wired-in Ids.
 -}
 
 ghcPrimExports :: [IfaceExport]


=====================================
compiler/GHC/Builtin/primops.txt.pp
=====================================
@@ -15,14 +15,86 @@
 --
 -- It should first be preprocessed.
 --
+-- Note in particular that Haskell block-style comments are not recognized
+-- here, so stick to '--' (even for Notes spanning multiple lines).
+
+-- Note [GHC.Prim]
+-- ~~~~~~~~~~~~~~~
+-- GHC.Prim is a special module:
+--
+-- * It can be imported by any module (import GHC.Prim).
+--   However, in the future we might change which functions are primitives
+--   and which are defined in Haskell.
+--   Users should import GHC.Exts, which reexports GHC.Prim and is more stable.
+--   In particular, we might move some of the primops to 'foreign import prim'
+--   (see ticket #16929 and Note [When do out-of-line primops go in primops.txt.pp])
+--
+-- * It provides primitives of three sorts:
+--   - primitive types such as Int64#, MutableByteArray#
+--   - primops such as (+#), newTVar#, touch#
+--   - pseudoops such as realWorld#, nullAddr#
+--
+-- * The pseudoops are described in Note [ghcPrimIds (aka pseudoops)]
+--   in GHC.Types.Id.Make.
+--
+-- * The primitives (primtypes, primops, pseudoops) cannot be defined in
+--   source Haskell.
+--   There is no GHC/Prim.hs file with definitions.
+--   Instead, we support importing GHC.Prim by manually defining its
+--   ModIface (see Iface.Load.ghcPrimIface).
+--
+-- * The primitives are listed in this file, primops.txt.pp.
+--   It goes through CPP, which creates primops.txt.
+--   It is then consumed by the utility program genprimopcode, which produces
+--   the following three types of files.
+--
+--   1. The files with extension .hs-incl.
+--      They can be found by grepping for hs-incl.
+--      They are #included in compiler sources.
+--
+--      One of them, primop-data-decl.hs-incl, defines the PrimOp type:
+--        data PrimOp
+--         = IntAddOp
+--         | IntSubOp
+--         | CharGtOp
+--         | CharGeOp
+--         | ...
+--
+--      The remaining files define properties of the primops
+--      by pattern matching, for example:
+--        primOpFixity IntAddOp = Just (Fixity NoSourceText 6 InfixL)
+--        primOpFixity IntSubOp = Just (Fixity NoSourceText 6 InfixL)
+--        ...
+--      This includes fixity, has-side-effects, commutability,
+--      IDs used to generate Uniques etc.
+--
+--      Additionally, we pattern match on PrimOp when generating Cmm in
+--      GHC/StgToCmm/Prim.hs.
+--
+--   2. The dummy Prim.hs file, which is used for Haddock and
+--      contains descriptions taken from primops.txt.pp.
+--      All definitions are replaced by placeholders.
+--      See Note [GHC.Prim Docs] in genprimopcode.
+--
+--   3. The module PrimopWrappers.hs, which wraps every call for GHCi;
+--      see Note [Primop wrappers] in GHC.Builtin.Primops for details.
+--
+-- * This file does not list internal-only equality types
+--   (GHC.Builtin.Types.Prim.unexposedPrimTyCons and coercionToken#
+--   in GHC.Types.Id.Make) which are defined but not exported from GHC.Prim.
+--   Every export of GHC.Prim should be in listed in this file.
+--
+-- * The primitive types should be listed in primTyCons in Builtin.Types.Prim
+--   in addition to primops.txt.pp.
+--   (This task should be delegated to genprimopcode in the future.)
+--
+--
+--
 -- Information on how PrimOps are implemented and the steps necessary to
 -- add a new one can be found in the Commentary:
 --
 --  https://gitlab.haskell.org/ghc/ghc/wikis/commentary/prim-ops
 --
--- Note in particular that Haskell block-style comments are not recognized
--- here, so stick to '--' (even for Notes spanning multiple lines).
-
 -- This file is divided into named sections, each containing or more
 -- primop entries. Section headers have the format:
 --
@@ -76,7 +148,6 @@ defaults
    vector           = []
    deprecated_msg   = {}      -- A non-empty message indicates deprecation
 
-
 -- Note [When do out-of-line primops go in primops.txt.pp]
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 --
@@ -189,19 +260,6 @@ section "The word size story."
 #define WORD64 Word#
 #endif
 
--- This type won't be exported directly (since there is no concrete
--- syntax for this sort of export) so we'll have to manually patch
--- export lists in both GHC and Haddock.
-primtype FUN m a b
-  {The builtin function type, written in infix form as {\tt a # m -> b}.
-   Values of this type are functions taking inputs of type {\tt a} and
-   producing outputs of type {\tt b}. The multiplicity of the input is
-   {\tt m}.
-
-   Note that {\tt FUN m a b} permits levity-polymorphism in both {\tt a} and
-   {\tt b}, so that types like {\tt Int\# -> Int\#} can still be well-kinded.
-  }
-
 ------------------------------------------------------------------------
 section "Char#"
         {Operations on 31-bit characters.}
@@ -3377,6 +3435,37 @@ section "Etc"
         {Miscellaneous built-ins}
 ------------------------------------------------------------------------
 
+primtype FUN m a b
+  {The builtin function type, written in infix form as {\tt a # m -> b}.
+   Values of this type are functions taking inputs of type {\tt a} and
+   producing outputs of type {\tt b}. The multiplicity of the input is
+   {\tt m}.
+
+   Note that {\tt FUN m a b} permits levity-polymorphism in both {\tt a} and
+   {\tt b}, so that types like {\tt Int\# -> Int\#} can still be well-kinded.
+  }
+
+pseudoop "realWorld#"
+   State# RealWorld
+   { The token used in the implementation of the IO monad as a state monad.
+     It does not pass any information at runtime.
+     See also {\tt GHC.Magic.runRW\#}. }
+
+pseudoop "void#"
+   (# #)
+   { This is an alias for the unboxed unit tuple constructor.
+     In earlier versions of GHC, {\tt void\#} was a value
+     of the primitive type {\tt Void\#}, which is now defined to be {\tt (\# \#)}.
+   }
+   with deprecated_msg = { Use an unboxed unit tuple instead }
+
+pseudoop "magicDict"
+   a
+   { {\tt magicDict} is a special-purpose placeholder value.
+     It is used internally by modules such as {\tt GHC.TypeNats} to cast a typeclass
+     dictionary with a single method. It is eliminated by a rule during compilation.
+     For the details, see Note [magicDictId magic] in GHC. }
+
 primtype Proxy# a
    { The type constructor {\tt Proxy#} is used to bear witness to some
    type variable. It's used when you want to pass around proxy values


=====================================
compiler/GHC/Iface/Load.hs
=====================================
@@ -915,6 +915,7 @@ findAndReadIface doc_str mod wanted_mod_with_insts hi_boot_file
                      nest 4 (text "reason:" <+> doc_str)])
 
        -- Check for GHC.Prim, and return its static interface
+       -- See Note [GHC.Prim] in primops.txt.pp.
        -- TODO: make this check a function
        if mod `installedModuleEq` gHC_PRIM
            then do
@@ -1059,6 +1060,7 @@ initExternalPackageState home_unit
 *********************************************************
 -}
 
+-- See Note [GHC.Prim] in primops.txt.pp.
 ghcPrimIface :: ModIface
 ghcPrimIface
   = empty_iface {
@@ -1071,7 +1073,7 @@ ghcPrimIface
   where
     empty_iface = emptyFullModIface gHC_PRIM
 
-    -- The fixities listed here for @`seq`@ or @->@ should match
+    -- The fixity listed here for @`seq`@ should match
     -- those in primops.txt.pp (from which Haddock docs are generated).
     fixities = (getOccName seqId, Fixity NoSourceText 0 InfixR)
              : mapMaybe mkFixity allThePrimOps


=====================================
compiler/GHC/Types/Id/Make.hs
=====================================
@@ -118,7 +118,8 @@ Note [ghcPrimIds (aka pseudoops)]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The ghcPrimIds
 
-  * Are exported from GHC.Prim
+  * Are exported from GHC.Prim (see ghcPrimExports, used in ghcPrimInterface)
+    See Note [GHC.Prim] in primops.txt.pp for the remaining items in GHC.Prim.
 
   * Can't be defined in Haskell, and hence no Haskell binding site,
     but have perfectly reasonable unfoldings in Core
@@ -141,7 +142,17 @@ The magicIds
   * May or may not have a CompulsoryUnfolding.
 
   * But have some special behaviour that can't be done via an
-    unfolding from an interface file
+    unfolding from an interface file.
+
+  * May have IdInfo that differs from what would be imported from GHC.Magic.hi.
+    For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic].
+
+  The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed
+  in magicIds: they have special behavior but they can be known-key and
+  not wired-in.
+  runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in
+  Simplifier, Note [Linting of runRW#].
+  inline: see Note [inlineId magic]
 -}
 
 wiredInIds :: [Id]
@@ -1402,12 +1413,12 @@ These Ids can't be defined in Haskell.  They could be defined in
 unfoldings in the wired-in GHC.Prim interface file, but we'd have to
 ensure that they were definitely, definitely inlined, because there is
 no curried identifier for them.  That's what mkCompulsoryUnfolding
-does.  If we had a way to get a compulsory unfolding from an interface
-file, we could do that, but we don't right now.
+does. Alternatively, we could add the definitions to mi_decls of ghcPrimIface
+but it's not clear if this would be simpler.
 
-The type variables we use here are "open" type variables: this means
-they can unify with both unlifted and lifted types.  Hence we provide
-another gun with which to shoot yourself in the foot.
+coercionToken# is not listed in ghcPrimIds, since its type uses (~#)
+which is not supposed to be used in expressions (GHC throws an assertion
+failure when trying.)
 -}
 
 nullAddrName, seqName,
@@ -1422,6 +1433,7 @@ magicDictName     = mkWiredInIdName gHC_PRIM  (fsLit "magicDict")      magicDict
 coerceName        = mkWiredInIdName gHC_PRIM  (fsLit "coerce")         coerceKey          coerceId
 proxyName         = mkWiredInIdName gHC_PRIM  (fsLit "proxy#")         proxyHashKey       proxyHashId
 
+-- Names listed in magicIds; see Note [magicIds]
 lazyIdName, oneShotName, noinlineIdName :: Name
 lazyIdName        = mkWiredInIdName gHC_MAGIC (fsLit "lazy")           lazyIdKey          lazyId
 oneShotName       = mkWiredInIdName gHC_MAGIC (fsLit "oneShot")        oneShotKey         oneShotId
@@ -1598,7 +1610,7 @@ See also: Note [User-defined RULES for seq] in GHC.Core.Opt.Simplify.
 
 Note [lazyId magic]
 ~~~~~~~~~~~~~~~~~~~
-lazy :: forall a?. a? -> a?   (i.e. works for unboxed types too)
+lazy :: forall a. a -> a
 
 'lazy' is used to make sure that a sub-expression, and its free variables,
 are truly used call-by-need, with no code motion.  Key examples:
@@ -1616,7 +1628,7 @@ are truly used call-by-need, with no code motion.  Key examples:
 Implementing 'lazy' is a bit tricky:
 
 * It must not have a strictness signature: by being a built-in Id,
-  all the info about lazyId comes from here, not from GHC.Base.hi.
+  all the info about lazyId comes from here, not from GHC.Magic.hi.
   This is important, because the strictness analyser will spot it as
   strict!
 
@@ -1777,7 +1789,7 @@ voidPrimId  = pcMiscPrelId voidPrimIdName unboxedUnitTy
 voidArgId :: Id       -- Local lambda-bound :: Void#
 voidArgId = mkSysLocal (fsLit "void") voidArgIdKey Many unboxedUnitTy
 
-coercionTokenId :: Id         -- :: () ~ ()
+coercionTokenId :: Id         -- :: () ~# ()
 coercionTokenId -- See Note [Coercion tokens] in "GHC.CoreToStg"
   = pcMiscPrelId coercionTokenName
                  (mkTyConApp eqPrimTyCon [liftedTypeKind, liftedTypeKind, unitTy, unitTy])
@@ -1786,8 +1798,3 @@ coercionTokenId -- See Note [Coercion tokens] in "GHC.CoreToStg"
 pcMiscPrelId :: Name -> Type -> IdInfo -> Id
 pcMiscPrelId name ty info
   = mkVanillaGlobalWithInfo name ty info
-    -- We lie and say the thing is imported; otherwise, we get into
-    -- a mess with dependency analysis; e.g., core2stg may heave in
-    -- random calls to GHCbase.unpackPS__.  If GHCbase is the module
-    -- being compiled, then it's just a matter of luck if the definition
-    -- will be in "the right place" to be in scope.


=====================================
compiler/GHC/Types/Unique/Supply.hs
=====================================
@@ -180,7 +180,7 @@ The magic `inline` function does two things
 
 * It helps ensure that 'm' really does inline.
 
-Note that 'inline' evaporates in phase 0.  See Note [inlineIdMagic]
+Note that 'inline' evaporates in phase 0.  See Note [inlineId magic]
 in GHC.Core.Opt.ConstantFold.match_inline.
 
 The INLINE pragma on multiShotIO is very important, else the


=====================================
libraries/ghc-prim/GHC/Magic.hs
=====================================
@@ -1,8 +1,6 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE Trustworthy #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE MagicHash #-}
-{-# LANGUAGE UnboxedTuples #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE PolyKinds #-}
 {-# LANGUAGE ScopedTypeVariables #-}
@@ -32,13 +30,8 @@ module GHC.Magic ( inline, noinline, lazy, oneShot, runRW# ) where
 
 -- Here import TYPE explicitly from GHC.Types and not from GHC.Prim. This is
 -- because TYPE is not exported by the source Haskell module generated by
--- genprimops which Haddock will typecheck.
--- Likewise, realWorld# is not generated by genprimops so we use CPP and only
--- import/use it when not building haddock docs.
-#if !defined(__HADDOCK_VERSION__)
-import GHC.Prim (realWorld#)
-#endif
-import GHC.Prim (State#, RealWorld)
+-- genprimops which Haddock will typecheck (#15935).
+import GHC.Prim (State#, realWorld#, RealWorld)
 import GHC.Types (RuntimeRep, TYPE)
 
 -- | The call @inline f@ arranges that @f@ is inlined, regardless of
@@ -83,8 +76,6 @@ noinline x = x
 --
 -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in
 -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'.
---
--- Like 'seq', the argument of 'lazy' can have an unboxed type.
 lazy :: a -> a
 lazy x = x
 -- Implementation note: its strictness and unfolding are over-ridden
@@ -124,8 +115,4 @@ runRW# :: forall (r :: RuntimeRep) (o :: TYPE r).
           (State# RealWorld -> o) -> o
 -- See Note [runRW magic] in GHC.CoreToStg.Prep.
 {-# NOINLINE runRW# #-}  -- runRW# is inlined manually in CorePrep
-#if !defined(__HADDOCK_VERSION__)
 runRW# m = m realWorld#
-#else
-runRW# = runRW#   -- The realWorld# is too much for haddock
-#endif


=====================================
utils/genprimopcode/Main.hs
=====================================
@@ -1,5 +1,7 @@
 ------------------------------------------------------------------
 -- A primop-table mangling program                              --
+--
+-- See Note [GHC.Prim] in primops.txt.pp for details.
 ------------------------------------------------------------------
 
 module Main where
@@ -293,8 +295,6 @@ gen_hs_source (Info defaults entries) =
            hdr (PrimOpSpec { name = n })                         = wrapOp n ++ ","
            hdr (PrimVecOpSpec { name = n })                      = wrapOp n ++ ","
            hdr (PseudoOpSpec { name = n })                       = wrapOp n ++ ","
-           hdr (PrimTypeSpec { ty = TyApp (TyCon "->") _ })      = ""
-                  -- GHC lacks the syntax to explicitly export "->"
            hdr (PrimTypeSpec { ty = TyApp (TyCon n) _ })         = wrapOp n ++ ","
            hdr (PrimTypeSpec {})                                 = error $ "Illegal type spec"
            hdr (PrimVecTypeSpec { ty = TyApp (VecTyCon n _) _ }) = wrapOp n ++ ","
@@ -398,8 +398,6 @@ keep GHC's renamer and typechecker happy enough for what Haddock
 needs.  Our main plan is to say
         foo :: <type>
         foo = foo
-We have to silence GHC's complaints about unboxed-top-level declarations
-with an ad-hoc fix in GHC.Tc.Gen.Bind: see Note [Compiling GHC.Prim] in GHC.Tc.Gen.Bind.
 
 That works for all the primitive functions except tagToEnum#.
 If we generate the binding


=====================================
utils/genprimopcode/Parser.y
=====================================
@@ -163,6 +163,7 @@ paT : pTycon ppTs     { TyApp $1 $2 }
 
 pUnboxedTupleTy :: { Ty }
 pUnboxedTupleTy : '(#' pCommaTypes '#)' { TyUTup $2 }
+                | '(#' '#)' { TyUTup [] }
 
 pCommaTypes :: { [Ty] }
 pCommaTypes : pType ',' pCommaTypes { $1 : $3 }



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6f50cea42a9ffc947bf4243986663cc820b0ec8

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6f50cea42a9ffc947bf4243986663cc820b0ec8
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200828/08cd7972/attachment-0001.html>


More information about the ghc-commits mailing list