[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: docs: fix formatting and add some links

Marge Bot gitlab at gitlab.haskell.org
Sat May 23 01:36:00 UTC 2020



 Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC


Commits:
f31b1311 by Adam Sandberg Ericsson at 2020-05-22T21:35:29-04:00
docs: fix formatting and add some links

[skip ci]

- - - - -
7699a7ab by Andrew Martin at 2020-05-22T21:35:40-04:00
Implement cstringLength# and FinalPtr

This function and its accompanying rule resolve issue #5218.
A future PR to the bytestring library will make the internal
Data.ByteString.Internal.unsafePackAddress compute string length
with cstringLength#. This will improve the status quo because it is
eligible for constant folding.

Additionally, introduce a new data constructor to ForeignPtrContents
named FinalPtr. This additional data constructor, when used in the
IsString instance for ByteString, leads to more Core-to-Core
optimization opportunities, fewer runtime allocations, and smaller
binaries.

Also, this commit re-exports all the functions from GHC.CString
(including cstringLength#) in GHC.Exts. It also adds a new test
driver. This test driver is used to perform substring matches on Core
that is dumped after all the simplifier passes. In this commit, it is
used to check that constant folding of cstringLength# works.

- - - - -
f9d20958 by Ben Gamari at 2020-05-22T21:35:41-04:00
simplCore: Ignore ticks in rule templates

This fixes #17619, where a tick snuck in to the template of a rule,
resulting in a panic during rule matching. The tick in question was
introduced via post-inlining, as discussed in `Note [Simplifying
rules]`. The solution we decided upon was to simply ignore ticks in the
rule template, as discussed in `Note [Tick annotations in RULE
matching]`.

Fixes #18162.
Fixes #17619.

- - - - -
f8f18a40 by John Ericson at 2020-05-22T21:35:46-04:00
Fix #18145 and also avoid needless work with implicit vars

 - `forAllOrNothing` now is monadic, so we can trace whether we bind
   an explicit `forall` or not.

 - #18145 arose because the free vars calculation was needlessly
   complex. It is now greatly simplified.

 - Replaced some other implicit var code with `filterFreeVarsToBind`.

Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com>

- - - - -
a7d31d89 by Ben Gamari at 2020-05-22T21:35:47-04:00
Bump process submodule

Fixes #17926.

- - - - -
c7639bb8 by Ben Gamari at 2020-05-22T21:35:47-04:00
users-guide: Clarify meaning of -haddock flag

Fixes #18206.

- - - - -
f5f3e709 by Ben Gamari at 2020-05-22T21:35:48-04:00
git: Add ignored commits file

This can be used to tell git to ignore bulk renaming commits like the
recently-finished module hierarchy refactoring. Configured with,

    git config blame.ignoreRevsFile .git-ignore-revs

- - - - -


30 changed files:

- + .git-ignore-revs
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Literal.hs
- docs/users_guide/8.12.1-notes.rst
- docs/users_guide/exts/template_haskell.rst
- docs/users_guide/using.rst
- libraries/base/GHC/Exts.hs
- libraries/base/GHC/ForeignPtr.hs
- libraries/ghc-prim/GHC/CString.hs
- libraries/ghc-prim/changelog.md
- libraries/process
- testsuite/.gitignore
- testsuite/driver/testlib.py
- + testsuite/tests/primops/should_gen_core/CStringLength_core.hs
- + testsuite/tests/primops/should_gen_core/CStringLength_core.substr-simpl
- + testsuite/tests/primops/should_gen_core/all.T
- + testsuite/tests/primops/should_run/CStringLength.hs
- + testsuite/tests/primops/should_run/CStringLength.stdout
- testsuite/tests/primops/should_run/all.T
- + testsuite/tests/rename/should_fail/T18145.hs
- + testsuite/tests/rename/should_fail/T18145.stderr
- testsuite/tests/rename/should_fail/all.T


Changes:

=====================================
.git-ignore-revs
=====================================
@@ -0,0 +1,23 @@
+# Configure git to ignore commits listed in this file with:
+#
+#   git config blame.ignoreRevsFile .git-ignore-revs
+
+# Module Hierarchy Renamings
+af332442123878c1b61d236dce46418efcbe8750
+255418da5d264fb2758bc70925adb2094f34adc3
+1941ef4f050c0dfcb68229641fcbbde3a10f1072
+528df8ecb4e2f9c78b1ae4ab7ff8230644e9b643
+18a346a4b5a02b8c62e8eedb91b35c2d8e754b96
+817f93eac4d13f680e8e3e7a25eb403b1864f82e
+1b1067d14b656bbbfa7c47f156ec2700c9751549
+240f5bf6f53515535be5bf3ef7632aa69ae21e3e
+1500f0898e85316c7c97a2f759d83278a072ab0e
+3ca52151881451ce5b3a7740d003e811b586140d
+cf739945b8b28ff463dc44925348f20b3c1f22cb
+da7f74797e8c322006eba385c9cbdce346dd1d43
+6e2d9ee25bce06ae51d2f1cf8df4f7422106a383
+d491a6795d507eabe35d8aec63c534d29f2d305b
+99a9f51bf8207c79241fc0b685fadeb222a61292
+eb6082358cdb5f271a8e4c74044a12f97352c52f
+5119296440e6846c553c72b8a93afc5ecfa576f0
+447864a94a1679b5b079e08bb7208a0005381cef


=====================================
compiler/GHC/Builtin/Names.hs
=====================================
@@ -349,6 +349,7 @@ basicKnownKeyNames
         -- Strings and lists
         unpackCStringName,
         unpackCStringFoldrName, unpackCStringUtf8Name,
+        cstringLengthName,
 
         -- Overloaded lists
         isListClassName,
@@ -1014,10 +1015,11 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey
 
 -- Base strings Strings
 unpackCStringName, unpackCStringFoldrName,
-    unpackCStringUtf8Name, eqStringName :: Name
+    unpackCStringUtf8Name, eqStringName, cstringLengthName :: Name
 unpackCStringName       = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey
 unpackCStringFoldrName  = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey
 unpackCStringUtf8Name   = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey
+cstringLengthName       = varQual gHC_CSTRING (fsLit "cstringLength#") cstringLengthIdKey
 eqStringName            = varQual gHC_BASE (fsLit "eqString")  eqStringIdKey
 
 -- The 'inline' function
@@ -2097,7 +2099,7 @@ wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey,
     unpackCStringUtf8IdKey, unpackCStringAppendIdKey,
     unpackCStringFoldrIdKey, unpackCStringIdKey,
     typeErrorIdKey, divIntIdKey, modIntIdKey,
-    absentSumFieldErrorIdKey :: Unique
+    absentSumFieldErrorIdKey, cstringLengthIdKey :: Unique
 
 wildCardKey                   = mkPreludeMiscIdUnique  0  -- See Note [WildCard binders]
 absentErrorIdKey              = mkPreludeMiscIdUnique  1
@@ -2124,6 +2126,7 @@ voidPrimIdKey                 = mkPreludeMiscIdUnique 21
 typeErrorIdKey                = mkPreludeMiscIdUnique 22
 divIntIdKey                   = mkPreludeMiscIdUnique 23
 modIntIdKey                   = mkPreludeMiscIdUnique 24
+cstringLengthIdKey            = mkPreludeMiscIdUnique 25
 
 concatIdKey, filterIdKey, zipIdKey,
     bindIOIdKey, returnIOIdKey, newStablePtrIdKey,


=====================================
compiler/GHC/Core/Opt/ConstantFold.hs
=====================================
@@ -66,6 +66,7 @@ import qualified Data.ByteString as BS
 import Data.Int
 import Data.Ratio
 import Data.Word
+import Data.Maybe (fromMaybe)
 
 {-
 Note [Constant folding]
@@ -1257,6 +1258,8 @@ builtinRules
                    ru_nargs = 4, ru_try = match_append_lit },
      BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName,
                    ru_nargs = 2, ru_try = match_eq_string },
+     BuiltinRule { ru_name = fsLit "CStringLength", ru_fn = cstringLengthName,
+                   ru_nargs = 1, ru_try = match_cstring_length },
      BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName,
                    ru_nargs = 2, ru_try = \_ _ _ -> match_inline },
      BuiltinRule { ru_name = fsLit "MagicDict", ru_fn = idName magicDictId,
@@ -1477,6 +1480,30 @@ match_eq_string _ id_unf _
 
 match_eq_string _ _ _ _ = Nothing
 
+-----------------------------------------------------------------------
+-- Illustration of this rule:
+--
+-- cstringLength# "foobar"# --> 6
+-- cstringLength# "fizz\NULzz"# --> 4
+--
+-- Nota bene: Addr# literals are suffixed by a NUL byte when they are
+-- compiled to read-only data sections. That's why cstringLength# is
+-- well defined on Addr# literals that do not explicitly have an embedded
+-- NUL byte.
+--
+-- See GHC issue #5218, MR 2165, and bytestring PR 191. This is particularly
+-- helpful when using OverloadedStrings to create a ByteString since the
+-- function computing the length of such ByteStrings can often be constant
+-- folded.
+match_cstring_length :: RuleFun
+match_cstring_length env id_unf _ [lit1]
+  | Just (LitString str) <- exprIsLiteral_maybe id_unf lit1
+    -- If elemIndex returns Just, it has the index of the first embedded NUL
+    -- in the string. If no NUL bytes are present (the common case) then use
+    -- full length of the byte string.
+  = let len = fromMaybe (BS.length str) (BS.elemIndex 0 str)
+     in Just (Lit (mkLitInt (roPlatform env) (fromIntegral len)))
+match_cstring_length _ _ _ _ = Nothing
 
 ---------------------------------------------------
 -- The rule is this:


=====================================
compiler/GHC/Core/Opt/Simplify/Utils.hs
=====================================
@@ -830,6 +830,21 @@ Ticks into the LHS, which makes matching trickier. #10665, #10745.
 Doing this to either side confounds tools like HERMIT, which seek to reason
 about and apply the RULES as originally written. See #10829.
 
+There is, however, one case where we are pretty much /forced/ to transform the
+LHS of a rule: postInlineUnconditionally. For instance, in the case of
+
+    let f = g @Int in f
+
+We very much want to inline f into the body of the let. However, to do so (and
+be able to safely drop f's binding) we must inline into all occurrences of f,
+including those in the LHS of rules.
+
+This can cause somewhat surprising results; for instance, in #18162 we found
+that a rule template contained ticks in its arguments, because
+postInlineUnconditionally substituted in a trivial expression that contains
+ticks. See Note [Tick annotations in RULE matching] in GHC.Core.Rules for
+details.
+
 Note [No eta expansion in stable unfoldings]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 If we have a stable unfolding
@@ -1251,6 +1266,10 @@ it's best to inline it anyway.  We often get a=E; b=a from desugaring,
 with both a and b marked NOINLINE.  But that seems incompatible with
 our new view that inlining is like a RULE, so I'm sticking to the 'active'
 story for now.
+
+NB: unconditional inlining of this sort can introduce ticks in places that
+may seem surprising; for instance, the LHS of rules. See Note [Simplfying
+rules] for details.
 -}
 
 postInlineUnconditionally


=====================================
compiler/GHC/Core/Rules.hs
=====================================
@@ -714,11 +714,15 @@ match :: RuleMatchEnv
       -> CoreExpr               -- Target
       -> Maybe RuleSubst
 
--- We look through certain ticks. See note [Tick annotations in RULE matching]
+-- We look through certain ticks. See Note [Tick annotations in RULE matching]
 match renv subst e1 (Tick t e2)
   | tickishFloatable t
   = match renv subst' e1 e2
   where subst' = subst { rs_binds = rs_binds subst . mkTick t }
+match renv subst (Tick t e1) e2
+  -- Ignore ticks in rule template.
+  | tickishFloatable t
+  =  match renv subst e1 e2
 match _ _ e at Tick{} _
   = pprPanic "Tick in rule" (ppr e)
 
@@ -1016,7 +1020,7 @@ Hence, (a) the guard (not (isLocallyBoundR v2))
 Note [Tick annotations in RULE matching]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-We used to unconditionally look through Notes in both template and
+We used to unconditionally look through ticks in both template and
 expression being matched. This is actually illegal for counting or
 cost-centre-scoped ticks, because we have no place to put them without
 changing entry counts and/or costs. So now we just fail the match in
@@ -1025,6 +1029,11 @@ these cases.
 On the other hand, where we are allowed to insert new cost into the
 tick scope, we can float them upwards to the rule application site.
 
+Moreover, we may encounter ticks in the template of a rule. There are a few
+ways in which these may be introduced (e.g. #18162, #17619). Such ticks are
+ignored by the matcher. See Note [Simplifying rules] in
+GHC.Core.Opt.Simplify.Utils for details.
+
 cf Note [Notes in call patterns] in GHC.Core.Opt.SpecConstr
 
 Note [Matching lets]


=====================================
compiler/GHC/Data/FastString.hs
=====================================
@@ -128,8 +128,9 @@ import Foreign
 import GHC.Conc.Sync    (sharedCAF)
 #endif
 
-import GHC.Base         ( unpackCString#, unpackNBytes# )
-
+#if __GLASGOW_HASKELL__ < 811
+import GHC.Base (unpackCString#,unpackNBytes#)
+#endif
 
 -- | Gives the UTF-8 encoded bytes corresponding to a 'FastString'
 bytesFS :: FastString -> ByteString


=====================================
compiler/GHC/Hs/Lit.hs
=====================================
@@ -53,7 +53,7 @@ data HsLit x
       -- ^ Unboxed character
   | HsString (XHsString x) {- SourceText -} FastString
       -- ^ String
-  | HsStringPrim (XHsStringPrim x) {- SourceText -} ByteString
+  | HsStringPrim (XHsStringPrim x) {- SourceText -} !ByteString
       -- ^ Packed bytes
   | HsInt (XHsInt x)  IntegralLit
       -- ^ Genuinely an Int; arises from


=====================================
compiler/GHC/Rename/HsType.hs
=====================================
@@ -29,7 +29,7 @@ module GHC.Rename.HsType (
         extractHsTysRdrTyVarsDups,
         extractRdrKindSigVars, extractDataDefnKindVars,
         extractHsTvBndrs, extractHsTyArgRdrKiTyVarsDup,
-        forAllOrNothing, nubL, elemRdr
+        forAllOrNothing, nubL
   ) where
 
 import GHC.Prelude
@@ -65,7 +65,7 @@ import GHC.Data.FastString
 import GHC.Data.Maybe
 import qualified GHC.LanguageExtensions as LangExt
 
-import Data.List          ( nubBy, partition, (\\), find )
+import Data.List          ( nubBy, partition, find )
 import Control.Monad      ( unless, when )
 
 #include "HsVersions.h"
@@ -164,13 +164,13 @@ rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> Maybe SDoc
                   -> RnM (a, FreeVars)
 rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside
   = do { check_inferred_vars ctxt inf_err hs_ty
-       ; free_vars <- extractFilteredRdrTyVarsDups hs_ty
+       ; free_vars <- filterInScopeM (extractHsTyRdrTyVarsDups hs_ty)
        ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars
        ; let nwc_rdrs = nubL nwc_rdrs'
-             implicit_bndrs = case scoping of
-               AlwaysBind       -> tv_rdrs
-               BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs
-               NeverBind        -> []
+       ; implicit_bndrs <- case scoping of
+           AlwaysBind       -> pure tv_rdrs
+           BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs
+           NeverBind        -> pure []
        ; rnImplicitBndrs implicit_bndrs $ \ vars ->
     do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty
        ; (res, fvs2) <- thing_inside wcs vars hs_ty'
@@ -178,7 +178,7 @@ rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside
 
 rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars)
 rnHsWcType ctxt (HsWC { hswc_body = hs_ty })
-  = do { free_vars <- extractFilteredRdrTyVars hs_ty
+  = do { free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty)
        ; (nwc_rdrs, _) <- partition_nwcs free_vars
        ; (wcs, hs_ty', fvs) <- rnWcBody ctxt nwc_rdrs hs_ty
        ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = hs_ty' }
@@ -278,22 +278,6 @@ extraConstraintWildCardsAllowed env
       StandaloneKindSigCtx {} -> False  -- See Note [Wildcards in standalone kind signatures] in GHC/Hs/Decls
       _                   -> False
 
--- | Finds free type and kind variables in a type,
---     without duplicates, and
---     without variables that are already in scope in LocalRdrEnv
---   NB: this includes named wildcards, which look like perfectly
---       ordinary type variables at this point
-extractFilteredRdrTyVars :: LHsType GhcPs -> RnM FreeKiTyVarsNoDups
-extractFilteredRdrTyVars hs_ty = filterInScopeM (extractHsTyRdrTyVars hs_ty)
-
--- | Finds free type and kind variables in a type,
---     with duplicates, but
---     without variables that are already in scope in LocalRdrEnv
---   NB: this includes named wildcards, which look like perfectly
---       ordinary type variables at this point
-extractFilteredRdrTyVarsDups :: LHsType GhcPs -> RnM FreeKiTyVarsWithDups
-extractFilteredRdrTyVarsDups hs_ty = filterInScopeM (extractHsTyRdrTyVarsDups hs_ty)
-
 -- | When the NamedWildCards extension is enabled, partition_nwcs
 -- removes type variables that start with an underscore from the
 -- FreeKiTyVars in the argument and returns them in a separate list.
@@ -340,9 +324,12 @@ rnHsSigType :: HsDocContext
 -- that cannot have wildcards
 rnHsSigType ctx level inf_err (HsIB { hsib_body = hs_ty })
   = do { traceRn "rnHsSigType" (ppr hs_ty)
-       ; vars <- extractFilteredRdrTyVarsDups hs_ty
+       ; rdr_env <- getLocalRdrEnv
        ; check_inferred_vars ctx inf_err hs_ty
-       ; rnImplicitBndrs (forAllOrNothing (isLHsForAllTy hs_ty) vars) $ \ vars ->
+       ; vars0 <- forAllOrNothing (isLHsForAllTy hs_ty)
+           $ filterInScope rdr_env
+           $ extractHsTyRdrTyVarsDups hs_ty
+       ; rnImplicitBndrs vars0 $ \ vars ->
     do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty
 
        ; return ( HsIB { hsib_ext = vars
@@ -361,7 +348,7 @@ rnHsSigType ctx level inf_err (HsIB { hsib_body = hs_ty })
 -- therefore an indication that the user is trying to be fastidious, so
 -- we don't implicitly bind any variables.
 
--- | See Note [forall-or-nothing rule]. This tiny little function is used
+-- | See @Note [forall-or-nothing rule]@. This tiny little function is used
 -- (rather than its small body inlined) to indicate that we are implementing
 -- that rule.
 forAllOrNothing :: Bool
@@ -372,10 +359,14 @@ forAllOrNothing :: Bool
                 --  we want to bring both 'a' and 'b' into scope, hence False
                 -> FreeKiTyVarsWithDups
                 -- ^ Free vars of the type
-                -> FreeKiTyVarsWithDups
-forAllOrNothing True  _   = []
-forAllOrNothing False fvs = fvs
-
+                -> RnM FreeKiTyVarsWithDups
+forAllOrNothing has_outer_forall fvs = case has_outer_forall of
+  True -> do
+    traceRn "forAllOrNothing" $ text "has explicit outer forall"
+    pure []
+  False -> do
+    traceRn "forAllOrNothing" $ text "no explicit forall. implicit binders:" <+> ppr fvs
+    pure fvs
 
 rnImplicitBndrs :: FreeKiTyVarsWithDups
                 -- ^ Surface-syntax free vars that we will implicitly bind.
@@ -878,21 +869,20 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside
 
        ; let -- See Note [bindHsQTyVars examples] for what
              -- all these various things are doing
-             bndrs, kv_occs, implicit_kvs :: [Located RdrName]
+             bndrs, implicit_kvs :: [Located RdrName]
              bndrs        = map hsLTyVarLocName hs_tv_bndrs
-             kv_occs      = nubL (bndr_kv_occs ++ body_kv_occs)
-                                 -- Make sure to list the binder kvs before the
-                                 -- body kvs, as mandated by
-                                 -- Note [Ordering of implicit variables]
-             implicit_kvs = filter_occs bndrs kv_occs
+             implicit_kvs = nubL $ filterFreeVarsToBind bndrs $
+               bndr_kv_occs ++ body_kv_occs
              del          = deleteBys eqLocated
-             all_bound_on_lhs = null ((body_kv_occs `del` bndrs) `del` bndr_kv_occs)
+             body_remaining = (body_kv_occs `del` bndrs) `del` bndr_kv_occs
+             all_bound_on_lhs = null body_remaining
 
        ; traceRn "checkMixedVars3" $
-           vcat [ text "kv_occs" <+> ppr kv_occs
-                , text "bndrs"   <+> ppr hs_tv_bndrs
+           vcat [ text "bndrs"   <+> ppr hs_tv_bndrs
                 , text "bndr_kv_occs"   <+> ppr bndr_kv_occs
-                , text "wubble" <+> ppr ((kv_occs \\ bndrs) \\ bndr_kv_occs)
+                , text "body_kv_occs"   <+> ppr body_kv_occs
+                , text "implicit_kvs"   <+> ppr implicit_kvs
+                , text "body_remaining" <+> ppr body_remaining
                 ]
 
        ; implicit_kv_nms <- mapM (newTyVarNameRn mb_assoc) implicit_kvs
@@ -904,17 +894,6 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside
                               , hsq_explicit  = rn_bndrs })
                       all_bound_on_lhs } }
 
-  where
-    filter_occs :: [Located RdrName]   -- Bound here
-                -> [Located RdrName]   -- Potential implicit binders
-                -> [Located RdrName]   -- Final implicit binders
-    -- Filter out any potential implicit binders that are either
-    -- already in scope, or are explicitly bound in the same HsQTyVars
-    filter_occs bndrs occs
-      = filterOut is_in_scope occs
-      where
-        is_in_scope locc = locc `elemRdr` bndrs
-
 {- Note [bindHsQTyVars examples]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Suppose we have
@@ -943,7 +922,7 @@ Then:
 * Order is not important in these lists.  All we are doing is
   bring Names into scope.
 
-Finally, you may wonder why filter_occs removes in-scope variables
+Finally, you may wonder why filterFreeVarsToBind removes in-scope variables
 from bndr/body_kv_occs.  How can anything be in scope?  Answer:
 HsQTyVars is /also/ used (slightly oddly) for Haskell-98 syntax
 ConDecls
@@ -1654,9 +1633,15 @@ type FreeKiTyVarsWithDups = FreeKiTyVars
 -- | A 'FreeKiTyVars' list that contains no duplicate variables.
 type FreeKiTyVarsNoDups   = FreeKiTyVars
 
+-- | Filter out any type and kind variables that are already in scope in the
+-- the supplied LocalRdrEnv. Note that this includes named wildcards, which
+-- look like perfectly ordinary type variables at this point.
 filterInScope :: LocalRdrEnv -> FreeKiTyVars -> FreeKiTyVars
 filterInScope rdr_env = filterOut (inScope rdr_env . unLoc)
 
+-- | Filter out any type and kind variables that are already in scope in the
+-- the environment's LocalRdrEnv. Note that this includes named wildcards,
+-- which look like perfectly ordinary type variables at this point.
 filterInScopeM :: FreeKiTyVars -> RnM FreeKiTyVars
 filterInScopeM vars
   = do { rdr_env <- getLocalRdrEnv
@@ -1812,12 +1797,13 @@ extract_hs_tv_bndrs :: [LHsTyVarBndr flag GhcPs]
 --     'a' is bound by the forall
 --     'b' is a free type variable
 --     'e' is a free kind variable
-extract_hs_tv_bndrs tv_bndrs acc_vars body_vars
-  | null tv_bndrs = body_vars ++ acc_vars
-  | otherwise = filterOut (`elemRdr` tv_bndr_rdrs) (bndr_vars ++ body_vars) ++ acc_vars
+extract_hs_tv_bndrs tv_bndrs acc_vars body_vars = new_vars ++ acc_vars
+  where
+    new_vars
+      | null tv_bndrs = body_vars
+      | otherwise = filterFreeVarsToBind tv_bndr_rdrs $ bndr_vars ++ body_vars
     -- NB: delete all tv_bndr_rdrs from bndr_vars as well as body_vars.
     -- See Note [Kind variable scoping]
-  where
     bndr_vars = extract_hs_tv_bndrs_kvs tv_bndrs
     tv_bndr_rdrs = map hsLTyVarLocName tv_bndrs
 
@@ -1848,5 +1834,16 @@ extract_tv tv acc =
 nubL :: Eq a => [Located a] -> [Located a]
 nubL = nubBy eqLocated
 
-elemRdr :: Located RdrName -> [Located RdrName] -> Bool
-elemRdr x = any (eqLocated x)
+-- | Filter out any potential implicit binders that are either
+-- already in scope, or are explicitly bound in the binder.
+filterFreeVarsToBind :: FreeKiTyVars
+                     -- ^ Explicitly bound here
+                     -> FreeKiTyVarsWithDups
+                     -- ^ Potential implicit binders
+                     -> FreeKiTyVarsWithDups
+                     -- ^ Final implicit binders
+filterFreeVarsToBind bndrs = filterOut is_in_scope
+    -- Make sure to list the binder kvs before the body kvs, as mandated by
+    -- Note [Ordering of implicit variables]
+  where
+    is_in_scope locc = any (eqLocated locc) bndrs


=====================================
compiler/GHC/Rename/Module.hs
=====================================
@@ -59,7 +59,7 @@ import GHC.Types.Basic  ( pprRuleName, TypeOrKind(..) )
 import GHC.Data.FastString
 import GHC.Types.SrcLoc as SrcLoc
 import GHC.Driver.Session
-import GHC.Utils.Misc   ( debugIsOn, filterOut, lengthExceeds, partitionWith )
+import GHC.Utils.Misc   ( debugIsOn, lengthExceeds, partitionWith )
 import GHC.Driver.Types ( HscEnv, hsc_dflags )
 import GHC.Data.List.SetOps ( findDupsEq, removeDups, equivClasses )
 import GHC.Data.Graph.Directed ( SCC, flattenSCC, flattenSCCs, Node(..)
@@ -664,7 +664,9 @@ rnClsInstDecl (ClsInstDecl { cid_poly_ty = inst_ty, cid_binds = mbinds
 
 rnFamInstEqn :: HsDocContext
              -> AssocTyFamInfo
-             -> [Located RdrName]    -- Kind variables from the equation's RHS
+             -> [Located RdrName]
+             -- ^ Kind variables from the equation's RHS to be implicitly bound
+             -- if no explicit forall.
              -> FamInstEqn GhcPs rhs
              -> (HsDocContext -> rhs -> RnM (rhs', FreeVars))
              -> RnM (FamInstEqn GhcRn rhs', FreeVars)
@@ -683,20 +685,36 @@ rnFamInstEqn doc atfi rhs_kvars
              -- Use the "...Dups" form because it's needed
              -- below to report unused binder on the LHS
 
-         -- Implicitly bound variables, empty if we have an explicit 'forall'.
-         -- See Note [forall-or-nothing rule] in GHC.Rename.HsType.
-       ; let imp_vars = nubL $ forAllOrNothing (isJust mb_bndrs) pat_kity_vars_with_dups
-       ; imp_var_names <- mapM (newTyVarNameRn mb_cls) imp_vars
-
        ; let bndrs = fromMaybe [] mb_bndrs
-             bnd_vars = map hsLTyVarLocName bndrs
-             payload_kvars = filterOut (`elemRdr` (bnd_vars ++ imp_vars)) rhs_kvars
-             -- Make sure to filter out the kind variables that were explicitly
-             -- bound in the type patterns.
-       ; payload_kvar_names <- mapM (newTyVarNameRn mb_cls) payload_kvars
 
-         -- all names not bound in an explicit forall
-       ; let all_imp_var_names = imp_var_names ++ payload_kvar_names
+         -- all_imp_vars represent the implicitly bound type variables. This is
+         -- empty if we have an explicit `forall` (see
+         -- Note [forall-or-nothing rule] in GHC.Rename.HsType), which means
+         -- ignoring:
+         --
+         -- - pat_kity_vars_with_dups, the variables mentioned in the LHS of
+         --   the equation, and
+         -- - rhs_kvars, the kind variables mentioned in an outermost kind
+         --   signature on the RHS of the equation. (See
+         --   Note [Implicit quantification in type synonyms] in
+         --   GHC.Rename.HsType for why these are implicitly quantified in the
+         --   absence of an explicit forall).
+         --
+         -- For example:
+         --
+         -- @
+         -- type family F a b
+         -- type instance forall a b c. F [(a, b)] c = a -> b -> c
+         --   -- all_imp_vars = []
+         -- type instance F [(a, b)] c = a -> b -> c
+         --   -- all_imp_vars = [a, b, c]
+         -- @
+       ; all_imp_vars <- forAllOrNothing (isJust mb_bndrs) $
+           -- No need to filter out explicit binders (the 'mb_bndrs = Just
+           -- explicit_bndrs' case) because there must be none if we're going
+           -- to implicitly bind anything, per the previous comment.
+           nubL $ pat_kity_vars_with_dups ++ rhs_kvars
+       ; all_imp_var_names <- mapM (newTyVarNameRn mb_cls) all_imp_vars
 
              -- All the free vars of the family patterns
              -- with a sensible binding location
@@ -2096,14 +2114,14 @@ rnConDecl decl@(ConDeclGADT { con_names   = names
           -- That order governs the order the implicitly-quantified type
           -- variable, and hence the order needed for visible type application
           -- See #14808.
-              free_tkvs = extractHsTvBndrs explicit_tkvs $
-                          extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty])
+        ; implicit_bndrs <- forAllOrNothing explicit_forall
+            $ extractHsTvBndrs explicit_tkvs
+            $ extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty])
 
-              ctxt    = ConDeclCtx new_names
+        ; let ctxt    = ConDeclCtx new_names
               mb_ctxt = Just (inHsDocContext ctxt)
 
-        ; traceRn "rnConDecl" (ppr names $$ ppr free_tkvs $$ ppr explicit_forall )
-        ; rnImplicitBndrs (forAllOrNothing explicit_forall free_tkvs) $ \ implicit_tkvs ->
+        ; rnImplicitBndrs implicit_bndrs $ \ implicit_tkvs ->
           bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs ->
     do  { (new_cxt, fvs1)    <- rnMbContext ctxt mcxt
         ; (new_args, fvs2)   <- rnConDeclDetails (unLoc (head new_names)) ctxt args


=====================================
compiler/GHC/ThToHs.hs
=====================================
@@ -6,6 +6,7 @@
 This module converts Template Haskell syntax into Hs syntax
 -}
 
+{-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE DeriveFunctor #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE ScopedTypeVariables #-}
@@ -1232,8 +1233,7 @@ cvtLit (CharPrimL c)   = do { force c; return $ HsCharPrim NoSourceText c }
 cvtLit (StringL s)     = do { let { s' = mkFastString s }
                             ; force s'
                             ; return $ HsString (quotedSourceText s) s' }
-cvtLit (StringPrimL s) = do { let { s' = BS.pack s }
-                            ; force s'
+cvtLit (StringPrimL s) = do { let { !s' = BS.pack s }
                             ; return $ HsStringPrim NoSourceText s' }
 cvtLit (BytesPrimL (Bytes fptr off sz)) = do
   let bs = unsafePerformIO $ withForeignPtr fptr $ \ptr ->


=====================================
compiler/GHC/Types/Literal.hs
=====================================
@@ -114,7 +114,7 @@ data Literal
                                 -- See Note [Types of LitNumbers] below for the
                                 -- Type field.
 
-  | LitString  ByteString       -- ^ A string-literal: stored and emitted
+  | LitString !ByteString       -- ^ A string-literal: stored and emitted
                                 -- UTF-8 encoded, we'll arrange to decode it
                                 -- at runtime.  Also emitted with a @\'\\0\'@
                                 -- terminator. Create with 'mkLitString'


=====================================
docs/users_guide/8.12.1-notes.rst
=====================================
@@ -79,12 +79,15 @@ Language
 * GHC now consistently does eager instantiation during type inference.
   As a consequence, visible type application (VTA) now only works when
   the head of the application is:
+
   * A variable
   * An expression with a type signature
-  For example `(let x = blah in id) @Bool True` no longer typechecks.
-  You should write `let x = blah in id @Bool True` instead.
 
-  This change prepares the way for Quick Look impredicativity.
+  For example ``(let x = blah in id) @Bool True`` no longer typechecks.
+  You should write ``let x = blah in id @Bool True`` instead.
+
+  This change prepares the way for `Quick Look impredicativity
+  <https://gitlab.haskell.org/ghc/ghc/issues/18126>`_.
 
 * GHC now allows users to manually define the specificity of type variable
   binders. By marking a variable with braces ``{tyvar}`` or ``{tyvar :: kind}``,
@@ -110,60 +113,65 @@ Runtime system
 Template Haskell
 ~~~~~~~~~~~~~~~~
 
- - Implement the Overloaded Quotations proposal (#246). The type of all quotation
-   forms have now been generalised in terms of a minimal interface necessary for the
-   implementation rather than the overapproximation of the ``Q`` monad.
+- Implement the `Overloaded Quotations proposal (#246) <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst>`_.
+  The type of all quotation forms have now been generalised in terms of a
+  minimal interface necessary (the ``Quote`` type class) for the
+  implementation rather than the overapproximation of the ``Q`` monad.
 
- - Template Haskell quotes now handle fixity declarations in ``let`` and
-   ``where`` bindings properly. Previously, such fixity declarations would
-   be dropped when quoted due to a Template Haskell bug.
+- Template Haskell quotes now handle fixity declarations in ``let`` and
+  ``where`` bindings properly. Previously, such fixity declarations would
+  be dropped when quoted due to a Template Haskell bug.
 
- - The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested
-   splices do not lead directly to compile-time evaluation. (!2288)
+- The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested
+  splices do not lead directly to compile-time evaluation. (Merge request
+  `!2288 <https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2288>`_)
 
 Arrow notation
 ~~~~~~~~~~~~~~
 
- - When combined with :extension:`Arrows`, the :extension:`LambdaCase` extension
-   now additionally allows ``\case`` syntax to be used as a command in ``proc``
-   notation.
+- When combined with :extension:`Arrows`, the :extension:`LambdaCase` extension
+  now additionally allows ``\case`` syntax to be used as a command in ``proc``
+  notation.
 
- - When combined with :extension:`Arrows`, the effects of the
-   :extension:`BlockArguments` extension now also apply to applications of
-   arrow control operators in ``(|`` banana brackets ``|)``: ::
+- When combined with :extension:`Arrows`, the effects of the
+  :extension:`BlockArguments` extension now also apply to applications of
+  arrow control operators in ``(|`` banana brackets ``|)``: ::
 
-     (| untilA (increment -< x + y) do
-          within 0.5 -< x
-          ... |)
+    (| untilA (increment -< x + y) do
+         within 0.5 -< x
+         ... |)
 
 ``ghc-prim`` library
 ~~~~~~~~~~~~~~~~~~~~
 
+- Add a known-key ``cstringLength#`` to ``GHC.CString`` that is eligible
+  for constant folding by a built-in rule.
+
 ``ghc`` library
 ~~~~~~~~~~~~~~~
 
- - The type of the ``getAnnotations`` function has changed to better reflect
-   the fact that it returns two different kinds of annotations, those on
-   names and those on modules: ::
+- The type of the ``getAnnotations`` function has changed to better reflect
+  the fact that it returns two different kinds of annotations, those on
+  names and those on modules: ::
 
-      getAnnotations :: Typeable a
-                     => ([Word8] -> a) -> ModGuts
-                     -> CoreM (ModuleEnv [a], NameEnv [a])
+     getAnnotations :: Typeable a
+                    => ([Word8] -> a) -> ModGuts
+                    -> CoreM (ModuleEnv [a], NameEnv [a])
 
- - The meaning of the ``hs_fixds`` field of ``HsGroup`` has changed slightly.
-   It now only contains fixity signatures defined for top-level declarations
-   and class methods defined *outside* of the class itself. Previously,
-   ``hs_fixds`` would also contain fixity signatures for class methods defined
-   *inside* the class, such as the fixity signature for ``m`` in the following
-   example: ::
+- The meaning of the ``hs_fixds`` field of ``HsGroup`` has changed slightly.
+  It now only contains fixity signatures defined for top-level declarations
+  and class methods defined *outside* of the class itself. Previously,
+  ``hs_fixds`` would also contain fixity signatures for class methods defined
+  *inside* the class, such as the fixity signature for ``m`` in the following
+  example: ::
 
-     class C a where
-       infixl 4 `m`
-       m :: a -> a -> a
+    class C a where
+      infixl 4 `m`
+      m :: a -> a -> a
 
-   If you wish to attain the previous behavior of ``hs_fixds``, use the new
-   ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity
-   signatures, including those for class methods defined inside classes.
+  If you wish to attain the previous behavior of ``hs_fixds``, use the new
+  ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity
+  signatures, including those for class methods defined inside classes.
 
 - The ``Exception`` module was boiled down acknowledging the existence of
   the ``exceptions`` dependency. In particular, the ``ExceptionMonad``
@@ -176,6 +184,15 @@ Arrow notation
 ``base`` library
 ~~~~~~~~~~~~~~~~
 
+- ``ForeignPtrContents`` has a new nullary data constructor ``FinalPtr``.
+  ``FinalPtr`` is intended for turning a primitive string literal into a
+  ``ForeignPtr``.  Unlike ``PlainForeignPtr``, ``FinalPtr`` does not have
+  a finalizer. Replacing ``PlainForeignPtr`` that has ``NoFinalizers`` with
+  ``FinalPtr`` reduces allocations, reduces the size of compiled binaries,
+  and unlocks important Core-to-Core optimizations. ``FinalPtr`` will be used
+  in an upcoming ``bytestring`` release to improve the performance of
+  ``ByteString`` literals created with ``OverloadedStrings``.
+
 Build system
 ~~~~~~~~~~~~
 
@@ -196,7 +213,7 @@ for further change information.
     libraries/containers/containers/containers.cabal:   Dependency of ``ghc`` library
     libraries/deepseq/deepseq.cabal:         Dependency of ``ghc`` library
     libraries/directory/directory.cabal:     Dependency of ``ghc`` library
-    libraries/exceptions/exceptions.cabal:   Dependency of ``haskeline`` library
+    libraries/exceptions/exceptions.cabal:   Dependency of ``ghc`` and ``haskeline`` library
     libraries/filepath/filepath.cabal:       Dependency of ``ghc`` library
     compiler/ghc.cabal:                      The compiler itself
     libraries/ghci/ghci.cabal:               The REPL interface


=====================================
docs/users_guide/exts/template_haskell.rst
=====================================
@@ -74,7 +74,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
    that declaration splices are not allowed anywhere except at top level
    (outside any other declarations).
 
-   The ``Q`` monad is a monad defined in ``Language.Haskell.TH.Syntax`` which
+   The ``Q`` monad is a monad defined in :th-ref:`Language.Haskell.TH.Syntax.` which
    supports several useful operations during code generation such as reporting
    errors or looking up identifiers in the environment.
 
@@ -92,9 +92,10 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
    -  ``[p| ... |]``, where the "..." is a pattern; the quotation has
       type ``Quote m => m Pat``.
 
-   The ``Quote`` type class is the minimal interface necessary to implement
-   the desugaring of quotations. The ``Q`` monad is an instance of ``Quote`` but
-   contains many more operations which are not needed for defining quotations.
+   The ``Quote`` type class (:th-ref:`Language.Haskell.TH.Syntax.Quote`) is
+   the minimal interface necessary to implement the desugaring of quotations.
+   The ``Q`` monad is an instance of ``Quote`` but contains many more
+   operations which are not needed for defining quotations.
 
    See :ref:`pts-where` for using partial type signatures in quotations.
 
@@ -402,7 +403,7 @@ Using Template Haskell
 ----------------------
 
 -  The data types and monadic constructor functions for Template Haskell
-   are in the library ``Language.Haskell.TH.Syntax``.
+   are in the library :th-ref:`Language.Haskell.TH.Syntax.`.
 
 -  You can only run a function at compile time if it is imported from
    another module. That is, you can't define a function in a module, and
@@ -645,7 +646,7 @@ Here are the salient features
    (Only the first two are described in the paper.)
 
 -  A quoter is a value of type
-   ``Language.Haskell.TH.Quote.QuasiQuoter``, which is defined thus: ::
+   :th-ref:`Language.Haskell.TH.Quote.QuasiQuoter`, which is defined thus: ::
 
        data QuasiQuoter = QuasiQuoter { quoteExp  :: String -> Q Exp,
                                         quotePat  :: String -> Q Pat,


=====================================
docs/users_guide/using.rst
=====================================
@@ -1136,10 +1136,11 @@ Haddock
    single: haddock
 
 .. ghc-flag:: -haddock
-    :shortdesc: Make the parser more strict about Haddock comments.
+    :shortdesc: With this flag GHC will parse Haddock comments and include them
+      in the interface file it produces.
     :type: dynamic
     :reverse: -no-haddock
-    :category: misc
+    :category: haddock
 
     By default, GHC ignores Haddock comments (``-- | ...`` and ``-- ^ ...``)
     and does not check that they're associated with a valid term, such as a


=====================================
libraries/base/GHC/Exts.hs
=====================================
@@ -54,6 +54,14 @@ module GHC.Exts
         -- * Overloaded string literals
         IsString(..),
 
+        -- * CString
+        unpackCString#,
+        unpackAppendCString#,
+        unpackFoldrCString#,
+        unpackCStringUtf8#,
+        unpackNBytes#,
+        cstringLength#,
+
         -- * Debugging
         breakpoint, breakpointCond,
 


=====================================
libraries/base/GHC/ForeignPtr.hs
=====================================
@@ -23,11 +23,13 @@
 
 module GHC.ForeignPtr
   (
+        -- * Types
         ForeignPtr(..),
         ForeignPtrContents(..),
         Finalizers(..),
         FinalizerPtr,
         FinalizerEnvPtr,
+        -- * Create
         newForeignPtr_,
         mallocForeignPtr,
         mallocPlainForeignPtr,
@@ -35,15 +37,20 @@ module GHC.ForeignPtr
         mallocPlainForeignPtrBytes,
         mallocForeignPtrAlignedBytes,
         mallocPlainForeignPtrAlignedBytes,
+        newConcForeignPtr,
+        -- * Add Finalizers
         addForeignPtrFinalizer,
         addForeignPtrFinalizerEnv,
-        touchForeignPtr,
+        addForeignPtrConcFinalizer,
+        -- * Conversion
         unsafeForeignPtrToPtr,
         castForeignPtr,
         plusForeignPtr,
-        newConcForeignPtr,
-        addForeignPtrConcFinalizer,
+        -- * Finalization
+        touchForeignPtr,
         finalizeForeignPtr
+        -- * Commentary
+        -- $commentary
   ) where
 
 import Foreign.Storable
@@ -86,15 +93,121 @@ data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
         -- object, because that ensures that whatever the finalizer is
         -- attached to is kept alive.
 
+-- | Functions called when a 'ForeignPtr' is finalized. Note that
+-- C finalizers and Haskell finalizers cannot be mixed.
 data Finalizers
   = NoFinalizers
+    -- ^ No finalizer. If there is no intent to add a finalizer at
+    -- any point in the future, consider 'FinalPtr' or 'PlainPtr' instead
+    -- since these perform fewer allocations.
   | CFinalizers (Weak# ())
+    -- ^ Finalizers are all C functions.
   | HaskellFinalizers [IO ()]
+    -- ^ Finalizers are all Haskell functions.
 
+-- | Controls finalization of a 'ForeignPtr', that is, what should happen
+-- if the 'ForeignPtr' becomes unreachable. Visually, these data constructors
+-- are appropriate in these scenarios:
+--
+-- >                           Memory backing pointer is
+-- >                            GC-Managed   Unmanaged
+-- > Finalizer functions are: +------------+-----------------+
+-- >                 Allowed  | MallocPtr  | PlainForeignPtr |
+-- >                          +------------+-----------------+
+-- >              Prohibited  | PlainPtr   | FinalPtr        |
+-- >                          +------------+-----------------+
 data ForeignPtrContents
   = PlainForeignPtr !(IORef Finalizers)
-  | MallocPtr      (MutableByteArray# RealWorld) !(IORef Finalizers)
-  | PlainPtr       (MutableByteArray# RealWorld)
+    -- ^ The pointer refers to unmanaged memory that was allocated by
+    -- a foreign function (typically using @malloc@). The finalizer
+    -- frequently calls the C function @free@ or some variant of it.
+  | FinalPtr
+    -- ^ The pointer refers to unmanaged memory that should not be freed when
+    -- the 'ForeignPtr' becomes unreachable. Functions that add finalizers
+    -- to a 'ForeignPtr' throw exceptions when the 'ForeignPtr' is backed by
+    -- 'PlainPtr'Most commonly, this is used with @Addr#@ literals.
+    -- See Note [Why FinalPtr].
+    --
+    -- @since 4.15
+  | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers)
+    -- ^ The pointer refers to a byte array.
+    -- The 'MutableByteArray#' field means that the 'MutableByteArray#' is
+    -- reachable (by GC) whenever the 'ForeignPtr' is reachable. When the
+    -- 'ForeignPtr' becomes unreachable, the runtime\'s normal GC recovers
+    -- the memory backing it. Here, the finalizer function intended to be used
+    -- to @free()@ any ancilliary *unmanaged* memory pointed to by the
+    -- 'MutableByteArray#'. See the @zlib@ library for an example of this use.
+    --
+    -- 1. Invariant: The 'Addr#' in the parent 'ForeignPtr' is an interior
+    --    pointer into this 'MutableByteArray#'.
+    -- 2. Invariant: The 'MutableByteArray#' is pinned, so the 'Addr#' does not
+    --    get invalidated by the GC moving the byte array.
+    -- 3. Invariant: A 'MutableByteArray#' must not be associated with more than
+    --    one set of finalizers. For example, this is sound:
+    --
+    --    > incrGood :: ForeignPtr Word8 -> ForeignPtr Word8
+    --    > incrGood (ForeignPtr p (MallocPtr m f)) = ForeignPtr (plusPtr p 1) (MallocPtr m f)
+    --
+    --    But this is unsound:
+    --
+    --    > incrBad :: ForeignPtr Word8 -> IO (ForeignPtr Word8)
+    --    > incrBad (ForeignPtr p (MallocPtr m _)) = do
+    --    >   f <- newIORef NoFinalizers
+    --    >   pure (ForeignPtr p (MallocPtr m f))
+  | PlainPtr (MutableByteArray# RealWorld)
+    -- ^ The pointer refers to a byte array. Finalization is not
+    -- supported. This optimizes @MallocPtr@ by avoiding the allocation
+    -- of a @MutVar#@ when it is known that no one will add finalizers to
+    -- the @ForeignPtr at . Functions that add finalizers to a 'ForeignPtr'
+    -- throw exceptions when the 'ForeignPtr' is backed by 'PlainPtr'.
+    -- The invariants that apply to 'MallocPtr' apply to 'PlainPtr' as well.
+
+-- Note [Why FinalPtr]
+--
+-- FinalPtr exists as an optimization for foreign pointers created
+-- from Addr# literals. Most commonly, this happens in the bytestring
+-- library, where the combination of OverloadedStrings and a rewrite
+-- rule overloads String literals as ByteString literals. See the
+-- rule "ByteString packChars/packAddress" in
+-- bytestring:Data.ByteString.Internal. Prior to the
+-- introduction of FinalPtr, bytestring used PlainForeignPtr (in
+-- Data.ByteString.Internal.unsafePackAddress) to handle such literals.
+-- With O2 optimization, the resulting Core from a GHC patched with a
+-- known-key cstringLength# function but without FinalPtr looked like:
+--
+--   RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
+--   stringOne1 = "hello beautiful world"#
+--   RHS size: {terms: 11, types: 17, coercions: 0, joins: 0/0}
+--   stringOne
+--     = case newMutVar# NoFinalizers realWorld# of
+--       { (# ipv_i7b6, ipv1_i7b7 #) ->
+--       PS stringOne1 (PlainForeignPtr ipv1_i7b7) 0# 21#
+--       }
+--
+-- After the introduction of FinalPtr, the bytestring library was modified
+-- so that the resulting Core was instead:
+--
+--   RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
+--   stringOne1 = "hello beautiful world"#
+--   RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0}
+--   stringOne = PS stringOne1 FinalPtr 0# 21#
+--
+-- This improves performance in three ways:
+--
+-- 1. More optimization opportunities. GHC is willing to inline the FinalPtr
+--    variant of stringOne into its use sites. This means the offset and length
+--    are eligible for case-of-known-literal. Previously, this never happened.
+-- 2. Smaller binaries. Setting up the thunk to call newMutVar# required
+--    machine instruction in the generated code. On x86_64, FinalPtr reduces
+--    the size of binaries by about 450 bytes per ByteString literal.
+-- 3. Smaller memory footprint. Previously, every ByteString literal resulted
+--    in the allocation of a MutVar# and a PlainForeignPtr data constructor.
+--    These both hang around until the ByteString goes out of scope. FinalPtr
+--    eliminates both of these sources of allocations. The MutVar# is not
+--    allocated because FinalPtr does not allow it, and the data constructor
+--    is not allocated because FinalPtr is a nullary data constructor.
+--
+-- For more discussion of FinalPtr, see GHC MR #2165 and bytestring PR #191.
 
 -- | @since 2.01
 instance Eq (ForeignPtr a) where
@@ -259,7 +372,7 @@ addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO ()
 addForeignPtrFinalizer (FunPtr fp) (ForeignPtr p c) = case c of
   PlainForeignPtr r -> insertCFinalizer r fp 0# nullAddr# p ()
   MallocPtr     _ r -> insertCFinalizer r fp 0# nullAddr# p c
-  _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer"
+  _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer"
 
 -- Note [MallocPtr finalizers] (#10904)
 --
@@ -277,7 +390,7 @@ addForeignPtrFinalizerEnv ::
 addForeignPtrFinalizerEnv (FunPtr fp) (Ptr ep) (ForeignPtr p c) = case c of
   PlainForeignPtr r -> insertCFinalizer r fp 1# ep p ()
   MallocPtr     _ r -> insertCFinalizer r fp 1# ep p c
-  _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer"
+  _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer"
 
 addForeignPtrConcFinalizer :: ForeignPtr a -> IO () -> IO ()
 -- ^This function adds a finalizer to the given @ForeignPtr at .  The
@@ -319,7 +432,7 @@ addForeignPtrConcFinalizer_ f@(MallocPtr fo r) finalizer = do
     finalizer' = unIO (foreignPtrFinalizer r >> touch f)
 
 addForeignPtrConcFinalizer_ _ _ =
-  errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer"
+  errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer or a final pointer"
 
 insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
 insertHaskellFinalizer r f = do
@@ -345,6 +458,8 @@ insertCFinalizer r fp flag ep p val = do
       -- replaced the content of r before calling finalizeWeak#.
       (# s1, _ #) -> unIO (insertCFinalizer r fp flag ep p val) s1
 
+-- Read the weak reference from an IORef Finalizers, creating it if necessary.
+-- Throws an exception if HaskellFinalizers is encountered.
 ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak
 ensureCFinalizerWeak ref@(IORef (STRef r#)) value = do
   fin <- readIORef ref
@@ -370,6 +485,7 @@ noMixingError = errorWithoutStackTrace $
    "GHC.ForeignPtr: attempt to mix Haskell and C finalizers " ++
    "in the same ForeignPtr"
 
+-- Swap out the finalizers with NoFinalizers and then run them.
 foreignPtrFinalizer :: IORef Finalizers -> IO ()
 foreignPtrFinalizer r = do
   fs <- atomicSwapIORef r NoFinalizers
@@ -455,13 +571,53 @@ plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
 plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c
 
 -- | Causes the finalizers associated with a foreign pointer to be run
--- immediately.
+-- immediately. The foreign pointer must not be used again after this
+-- function is called.
 finalizeForeignPtr :: ForeignPtr a -> IO ()
-finalizeForeignPtr (ForeignPtr _ (PlainPtr _)) = return () -- no effect
-finalizeForeignPtr (ForeignPtr _ foreignPtr) = foreignPtrFinalizer refFinalizers
-        where
-                refFinalizers = case foreignPtr of
-                        (PlainForeignPtr ref) -> ref
-                        (MallocPtr     _ ref) -> ref
-                        PlainPtr _            ->
-                            errorWithoutStackTrace "finalizeForeignPtr PlainPtr"
+finalizeForeignPtr (ForeignPtr _ c) = case c of
+  PlainForeignPtr ref -> foreignPtrFinalizer ref
+  MallocPtr _ ref -> foreignPtrFinalizer ref
+  _ -> errorWithoutStackTrace "finalizeForeignPtr PlainPtr"
+
+{- $commentary
+
+This is a high-level overview of how 'ForeignPtr' works.
+The implementation of 'ForeignPtr' must accomplish several goals:
+
+1. Invoke a finalizer once a foreign pointer becomes unreachable.
+2. Support augmentation of finalizers, i.e. 'addForeignPtrFinalizer'.
+   As a motivating example, suppose that the payload of a foreign
+   pointer is C struct @bar@ that has an optionally NULL pointer field
+   @foo@ to an unmanaged heap object. Initially, @foo@ is NULL, and
+   later the program uses @malloc@, initializes the object, and assigns
+   @foo@ the address returned by @malloc at . When the foreign pointer
+   becomes unreachable, it is now necessary to first @free@ the object
+   pointed to by @foo@ and then invoke whatever finalizer was associated
+   with @bar at . That is, finalizers must be invoked in the opposite order
+   they are added.
+3. Allow users to invoke a finalizer promptly if they know that the
+   foreign pointer is unreachable, i.e. 'finalizeForeignPtr'.
+
+How can these goals be accomplished? Goal 1 suggests that weak references
+and finalizers (via 'Weak#' and 'mkWeak#') are necessary. But how should
+they be used and what should their key be?  Certainly not 'ForeignPtr' or
+'ForeignPtrContents'. See the warning in "GHC.Weak" about weak pointers with
+lifted (non-primitive) keys. The two finalizer-supporting data constructors of
+'ForeignPtr' have an @'IORef' 'Finalizers'@ (backed by 'MutVar#') field.
+This gets used in two different ways depending on the kind of finalizer:
+
+* 'HaskellFinalizers': The first @addForeignPtrConcFinalizer_@ call uses
+  'mkWeak#' to attach the finalizer @foreignPtrFinalizer@ to the 'MutVar#'.
+  The resulting 'Weak#' is discarded (see @addForeignPtrConcFinalizer_@).
+  Subsequent calls to @addForeignPtrConcFinalizer_@ (goal 2) just add
+  finalizers onto the list in the 'HaskellFinalizers' data constructor.
+* 'CFinalizers': The first 'addForeignPtrFinalizer' call uses
+  'mkWeakNoFinalizer#' to create a 'Weak#'. The 'Weak#' is preserved in the
+  'CFinalizers' data constructor. Both the first call and subsequent
+  calls (goal 2) use 'addCFinalizerToWeak#' to attach finalizers to the
+  'Weak#' itself. Also, see Note [MallocPtr finalizers] for discussion of
+  the key and value of this 'Weak#'.
+
+In either case, the runtime invokes the appropriate finalizers when the
+'ForeignPtr' becomes unreachable.
+-}


=====================================
libraries/ghc-prim/GHC/CString.hs
=====================================
@@ -1,5 +1,4 @@
-{-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns #-}
-
+{-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns, UnliftedFFITypes #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  GHC.CString
@@ -18,7 +17,7 @@
 
 module GHC.CString (
         unpackCString#, unpackAppendCString#, unpackFoldrCString#,
-        unpackCStringUtf8#, unpackNBytes#
+        unpackCStringUtf8#, unpackNBytes#, cstringLength#
     ) where
 
 import GHC.Types
@@ -174,3 +173,17 @@ unpackNBytes#  addr len# = unpack [] (len# -# 1#)
          case indexCharOffAddr# addr i# of
             ch -> unpack (C# ch : acc) (i# -# 1#)
 
+-- The return type is not correct here. We really want CSize,
+-- but that type is defined in base. However, CSize should always
+-- match the size of a machine word (I hope), so this is probably
+-- alright on all platforms that GHC supports.
+foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int#
+
+-- | Compute the length of a NUL-terminated string. This address
+-- must refer to immutable memory. GHC includes a built-in rule for
+-- constant folding when the argument is a statically-known literal.
+-- That is, a core-to-core pass reduces the expression
+-- @cstringLength# "hello"#@ to the constant @5#@.
+cstringLength# :: Addr# -> Int#
+{-# INLINE[0] cstringLength# #-}
+cstringLength# = c_strlen


=====================================
libraries/ghc-prim/changelog.md
=====================================
@@ -1,3 +1,11 @@
+## 0.6.2 (edit as necessary)
+
+- Shipped with GHC 8.12.1
+
+- Add known-key `cstringLength#` to `GHC.CString`. This is just the
+  C function `strlen`, but a built-in rewrite rule allows GHC to
+  compute the result at compile time when the argument is known.
+
 ## 0.6.1 (edit as necessary)
 
 - Shipped with GHC 8.10.1


=====================================
libraries/process
=====================================
@@ -1 +1 @@
-Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc
+Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01


=====================================
testsuite/.gitignore
=====================================
@@ -43,6 +43,7 @@ Thumbs.db
 *.prof.sample.normalised
 *.run.stdout
 *.run.stderr
+*.dump-simpl
 
 *.hp
 tests/**/*.ps


=====================================
testsuite/driver/testlib.py
=====================================
@@ -1344,6 +1344,26 @@ def compile_grep_asm(name: TestName,
     # no problems found, this test passed
     return passed()
 
+def compile_grep_core(name: TestName,
+                      way: WayName,
+                      extra_hc_opts: str
+                      ) -> PassFail:
+    print('Compile only, extra args = ', extra_hc_opts)
+    result = simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, False, False)
+
+    if badResult(result):
+        return result
+
+    expected_pat_file = find_expected_file(name, 'substr-simpl')
+    actual_core_file = add_suffix(name, 'dump-simpl')
+
+    if not grep_output(join_normalisers(normalise_errmsg),
+                       expected_pat_file, actual_core_file):
+        return failBecause('simplified core mismatch')
+
+    # no problems found, this test passed
+    return passed()
+
 # -----------------------------------------------------------------------------
 # Compile-and-run tests
 


=====================================
testsuite/tests/primops/should_gen_core/CStringLength_core.hs
=====================================
@@ -0,0 +1,11 @@
+{-# language MagicHash #-}
+
+module CStringLengthCore
+  ( ozymandias
+  ) where
+
+import GHC.Exts
+
+ozymandias :: Int
+ozymandias =
+  I# (cstringLength# "I met a traveller from an antique land"#)


=====================================
testsuite/tests/primops/should_gen_core/CStringLength_core.substr-simpl
=====================================
@@ -0,0 +1 @@
+I# 38#


=====================================
testsuite/tests/primops/should_gen_core/all.T
=====================================
@@ -0,0 +1 @@
+test('CStringLength_core', normal, compile_grep_core, [''])


=====================================
testsuite/tests/primops/should_run/CStringLength.hs
=====================================
@@ -0,0 +1,33 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+import GHC.Exts
+
+main :: IO ()
+main = do
+  putStr "A: "
+  print $
+    I# (cstringLength# "hello_world"#)
+    ==
+    naiveStrlen "hello_world"# 0
+  putStr "B: "
+  print $
+    I# (cstringLength# "aaaaaaaaaaaaa\x00b"#)
+    ==
+    naiveStrlen "aaaaaaaaaaaaa\x00b"# 0
+  putStr "C: "
+  print $
+    I# (cstringLength# "cccccccccccccccccc\x00b"#)
+    ==
+    naiveStrlen "cccccccccccccccccc\x00b"# 0
+  putStr "D: "
+  print $
+    I# (cstringLength# "araña\NULb"#)
+    ==
+    naiveStrlen "araña\NULb"# 0
+
+naiveStrlen :: Addr# -> Int -> Int
+naiveStrlen addr !n = case indexWord8OffAddr# addr 0# of
+  0## -> n
+  _ -> naiveStrlen (plusAddr# addr 1#) (n + 1)


=====================================
testsuite/tests/primops/should_run/CStringLength.stdout
=====================================
@@ -0,0 +1,4 @@
+A: True
+B: True
+C: True
+D: True


=====================================
testsuite/tests/primops/should_run/all.T
=====================================
@@ -29,3 +29,4 @@ test('CmpWord16', normal, compile_and_run, [''])
 test('ShrinkSmallMutableArrayA', normal, compile_and_run, [''])
 test('ShrinkSmallMutableArrayB', normal, compile_and_run, [''])
 test('T14664', normal, compile_and_run, [''])
+test('CStringLength', normal, compile_and_run, ['-O2'])


=====================================
testsuite/tests/rename/should_fail/T18145.hs
=====================================
@@ -0,0 +1,17 @@
+{-# LANGUAGE ExplicitForAll #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DataKinds #-}
+
+module T18145 where
+
+type family A :: k
+type instance forall. A = Nothing :: Maybe a -- 'a' should be out of scope
+
+class Foo x where
+  type B x :: Maybe a
+  type forall x. B x = Nothing :: Maybe a -- 'a' should be out of scope
+
+instance Foo [x] where
+  type forall. B [x] = Nothing :: Maybe a -- 'a' should be out of scope


=====================================
testsuite/tests/rename/should_fail/T18145.stderr
=====================================
@@ -0,0 +1,6 @@
+
+T18145.hs:10:44: error: Not in scope: type variable ‘a’
+
+T18145.hs:14:41: error: Not in scope: type variable ‘a’
+
+T18145.hs:17:41: error: Not in scope: type variable ‘a’


=====================================
testsuite/tests/rename/should_fail/all.T
=====================================
@@ -153,3 +153,4 @@ test('T16504', normal, compile_fail, [''])
 test('T14548', normal, compile_fail, [''])
 test('T16610', normal, compile_fail, [''])
 test('T17593', normal, compile_fail, [''])
+test('T18145', normal, compile_fail, [''])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be3a978b1677f0a70af033d9699bdffb106e3506...f5f3e7091dc281a48fd7c29862052d3f8475a793

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be3a978b1677f0a70af033d9699bdffb106e3506...f5f3e7091dc281a48fd7c29862052d3f8475a793
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/20200522/1875cb9f/attachment-0001.html>


More information about the ghc-commits mailing list