[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Various Hadrian bootstrapping fixes

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Wed Aug 31 01:13:06 UTC 2022



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


Commits:
0154bc80 by sheaf at 2022-08-30T06:05:41-04:00
Various Hadrian bootstrapping fixes

  - Don't always produce a distribution archive (#21629)
  - Use correct executable names for ghc-pkg and hsc2hs on windows
    (we were missing the .exe file extension)
  - Fix a bug where we weren't using the right archive format on Windows
    when unpacking the bootstrap sources.

Fixes #21629

- - - - -
451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00
ci: Attempt using normal submodule cloning strategy

We do not use any recursively cloned submodules, and this protects us
from flaky upstream remotes.

Fixes #22121

- - - - -
9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00
Fix typo in Any docs: stray "--"

- - - - -
3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00
Fix typo in Any docs: syntatic -> syntactic

- - - - -
5a944e82 by Simon Peyton Jones at 2022-08-30T21:12:49-04:00
Add a missing trimArityType

This buglet was exposed by #22114, a consequence of my earlier
refactoring of arity for join points.

- - - - -


8 changed files:

- .gitlab-ci.yml
- .gitlab/ci.sh
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- hadrian/bootstrap/bootstrap.py
- libraries/ghc-prim/GHC/Types.hs
- + testsuite/tests/simplCore/should_compile/T22114.hs
- testsuite/tests/simplCore/should_compile/all.T


Changes:

=====================================
.gitlab-ci.yml
=====================================
@@ -17,7 +17,7 @@ variables:
   # Overridden by individual jobs
   CONFIGURE_ARGS: ""
 
-  GIT_SUBMODULE_STRATEGY: "recursive"
+  GIT_SUBMODULE_STRATEGY: "normal"
 
   # Makes ci.sh isolate CABAL_DIR
   HERMETIC: "YES"


=====================================
.gitlab/ci.sh
=====================================
@@ -377,8 +377,8 @@ function cleanup_submodules() {
     # On Windows submodules can inexplicably get into funky states where git
     # believes that the submodule is initialized yet its associated repository
     # is not valid. Avoid failing in this case with the following insanity.
-    git submodule sync --recursive || git submodule deinit --force --all
-    git submodule update --init --recursive
+    git submodule sync || git submodule deinit --force --all
+    git submodule update --init
     git submodule foreach git clean -xdf
   else
     info "Not cleaning submodules, not in a git repo"


=====================================
compiler/GHC/Core/Opt/Arity.hs
=====================================
@@ -873,24 +873,49 @@ exprEtaExpandArity opts e
 *                                                                      *
 ********************************************************************* -}
 
-findRhsArity :: ArityOpts -> RecFlag -> Id -> CoreExpr -> Arity -> SafeArityType
+findRhsArity :: ArityOpts -> RecFlag -> Id -> CoreExpr
+             -> (Bool, SafeArityType)
 -- This implements the fixpoint loop for arity analysis
 -- See Note [Arity analysis]
--- If findRhsArity e = (n, is_bot) then
---  (a) any application of e to <n arguments will not do much work,
---      so it is safe to expand e  ==>  (\x1..xn. e x1 .. xn)
---  (b) if is_bot=True, then e applied to n args is guaranteed bottom
 --
--- Returns an ArityType that is guaranteed trimmed to typeArity of 'bndr'
+-- The Bool is True if the returned arity is greater than (exprArity rhs)
+--     so the caller should do eta-expansion
+-- That Bool is never True for join points, which are never eta-expanded
+--
+-- Returns an SafeArityType that is guaranteed trimmed to typeArity of 'bndr'
 --         See Note [Arity trimming]
-findRhsArity opts is_rec bndr rhs old_arity
-  = case is_rec of
-      Recursive    -> go 0 botArityType
-      NonRecursive -> step init_env
+
+findRhsArity opts is_rec bndr rhs
+  | isJoinId bndr
+  = (False, join_arity_type)
+    -- False: see Note [Do not eta-expand join points]
+    -- But do return the correct arity and bottom-ness, because
+    -- these are used to set the bndr's IdInfo (#15517)
+    -- Note [Invariants on join points] invariant 2b, in GHC.Core
+
+  | otherwise
+  = (arity_increased, non_join_arity_type)
+    -- arity_increased: eta-expand if we'll get more lambdas
+    -- to the top of the RHS
   where
+    old_arity = exprArity rhs
+
     init_env :: ArityEnv
     init_env = findRhsArityEnv opts (isJoinId bndr)
 
+    -- Non-join-points only
+    non_join_arity_type = case is_rec of
+                             Recursive    -> go 0 botArityType
+                             NonRecursive -> step init_env
+    arity_increased = arityTypeArity non_join_arity_type > old_arity
+
+    -- Join-points only
+    -- See Note [Arity for non-recursive join bindings]
+    -- and Note [Arity for recursive join bindings]
+    join_arity_type = case is_rec of
+                         Recursive    -> go 0 botArityType
+                         NonRecursive -> trimArityType ty_arity (cheapArityType rhs)
+
     ty_arity     = typeArity (idType bndr)
     id_one_shots = idDemandOneShots bndr
 
@@ -1076,6 +1101,117 @@ But /only/ for called-once demands.  Suppose we had
 Now we don't want to eta-expand f1 to have 3 args; only two.
 Nor, in the case of f2, do we want to push that error call under
 a lambda.  Hence the takeWhile in combineWithDemandDoneShots.
+
+Note [Do not eta-expand join points]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Similarly to CPR (see Note [Don't w/w join points for CPR] in
+GHC.Core.Opt.WorkWrap), a join point stands well to gain from its outer binding's
+eta-expansion, and eta-expanding a join point is fraught with issues like how to
+deal with a cast:
+
+    let join $j1 :: IO ()
+             $j1 = ...
+             $j2 :: Int -> IO ()
+             $j2 n = if n > 0 then $j1
+                              else ...
+
+    =>
+
+    let join $j1 :: IO ()
+             $j1 = (\eta -> ...)
+                     `cast` N:IO :: State# RealWorld -> (# State# RealWorld, ())
+                                 ~  IO ()
+             $j2 :: Int -> IO ()
+             $j2 n = (\eta -> if n > 0 then $j1
+                                       else ...)
+                     `cast` N:IO :: State# RealWorld -> (# State# RealWorld, ())
+                                 ~  IO ()
+
+The cast here can't be pushed inside the lambda (since it's not casting to a
+function type), so the lambda has to stay, but it can't because it contains a
+reference to a join point. In fact, $j2 can't be eta-expanded at all. Rather
+than try and detect this situation (and whatever other situations crop up!), we
+don't bother; again, any surrounding eta-expansion will improve these join
+points anyway, since an outer cast can *always* be pushed inside. By the time
+CorePrep comes around, the code is very likely to look more like this:
+
+    let join $j1 :: State# RealWorld -> (# State# RealWorld, ())
+             $j1 = (...) eta
+             $j2 :: Int -> State# RealWorld -> (# State# RealWorld, ())
+             $j2 = if n > 0 then $j1
+                            else (...) eta
+
+Note [Arity for recursive join bindings]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+  f x = joinrec j 0 = \ a b c -> (a,x,b)
+                j n = j (n-1)
+        in j 20
+
+Obviously `f` should get arity 4.  But it's a bit tricky:
+
+1. Remember, we don't eta-expand join points; see
+   Note [Do not eta-expand join points].
+
+2. But even though we aren't going to eta-expand it, we still want `j` to get
+   idArity=4, via the findRhsArity fixpoint.  Then when we are doing findRhsArity
+   for `f`, we'll call arityType on f's RHS:
+    - At the letrec-binding for `j` we'll whiz up an arity-4 ArityType
+      for `j` (See Note [arityType for non-recursive let-bindings]
+      in GHC.Core.Opt.Arity)b
+    - At the occurrence (j 20) that arity-4 ArityType will leave an arity-3
+      result.
+
+3. All this, even though j's /join-arity/ (stored in the JoinId) is 1.
+   This is is the Main Reason that we want the idArity to sometimes be
+   larger than the join-arity c.f. Note [Invariants on join points] item 2b
+   in GHC.Core.
+
+4. Be very careful of things like this (#21755):
+     g x = let j 0 = \y -> (x,y)
+               j n = expensive n `seq` j (n-1)
+           in j x
+   Here we do /not/ want eta-expand `g`, lest we duplicate all those
+   (expensive n) calls.
+
+   But it's fine: the findRhsArity fixpoint calculation will compute arity-1
+   for `j` (not arity 2); and that's just what we want. But we do need that
+   fixpoint.
+
+   Historical note: an earlier version of GHC did a hack in which we gave
+   join points an ArityType of ABot, but that did not work with this #21755
+   case.
+
+5. arityType does not usually expect to encounter free join points;
+   see GHC.Core.Opt.Arity Note [No free join points in arityType].
+   But consider
+          f x = join    j1 y = .... in
+                joinrec j2 z = ...j1 y... in
+                j2 v
+
+   When doing findRhsArity on `j2` we'll encounter the free `j1`.
+   But that is fine, because we aren't going to eta-expand `j2`;
+   we just want to know its arity.  So we have a flag am_no_eta,
+   switched on when doing findRhsArity on a join point RHS. If
+   the flag is on, we allow free join points, but not otherwise.
+
+
+Note [Arity for non-recursive join bindings]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [Arity for recursive join bindings] deals with recursive join
+bindings. But what about /non-recursive/ones?  If we just call
+findRhsArity, it will call arityType.  And that can be expensive when
+we have deeply nested join points:
+  join j1 x1 = join j2 x2 = join j3 x3 = blah3
+                            in blah2
+               in blah1
+(e.g. test T18698b).
+
+So we call cheapArityType instead.  It's good enough for practical
+purposes.
+
+(Side note: maybe we should use cheapArity for the RHS of let bindings
+in the main arityType function.)
 -}
 
 


=====================================
compiler/GHC/Core/Opt/Simplify/Utils.hs
=====================================
@@ -102,6 +102,14 @@ bindContextLevel :: BindContext -> TopLevelFlag
 bindContextLevel (BC_Let top_lvl _) = top_lvl
 bindContextLevel (BC_Join {})       = NotTopLevel
 
+bindContextRec :: BindContext -> RecFlag
+bindContextRec (BC_Let _ rec_flag)  = rec_flag
+bindContextRec (BC_Join rec_flag _) = rec_flag
+
+isJoinBC :: BindContext -> Bool
+isJoinBC (BC_Let {})  = False
+isJoinBC (BC_Join {}) = True
+
 
 {- *********************************************************************
 *                                                                      *
@@ -1776,39 +1784,26 @@ Wrinkles
 tryEtaExpandRhs :: SimplEnv -> BindContext -> OutId -> OutExpr
                 -> SimplM (ArityType, OutExpr)
 -- See Note [Eta-expanding at let bindings]
--- If tryEtaExpandRhs rhs = (n, is_bot, rhs') then
---   (a) rhs' has manifest arity n
---   (b) if is_bot is True then rhs' applied to n args is guaranteed bottom
-tryEtaExpandRhs env (BC_Join is_rec _) bndr rhs
-  = assertPpr (isJoinId bndr) (ppr bndr) $
-    return (arity_type, rhs)
-    -- Note [Do not eta-expand join points]
-    -- But do return the correct arity and bottom-ness, because
-    -- these are used to set the bndr's IdInfo (#15517)
-    -- Note [Invariants on join points] invariant 2b, in GHC.Core
-  where
-    -- See Note [Arity for non-recursive join bindings]
-    -- and Note [Arity for recursive join bindings]
-    arity_type = case is_rec of
-                   NonRecursive -> cheapArityType rhs
-                   Recursive    -> findRhsArity (seArityOpts env) Recursive
-                                                bndr rhs (exprArity rhs)
-
-tryEtaExpandRhs env (BC_Let _ is_rec) bndr rhs
-  | seEtaExpand env         -- Provided eta-expansion is on
-  , new_arity > old_arity   -- And the current manifest arity isn't enough
+tryEtaExpandRhs env bind_cxt bndr rhs
+  | do_eta_expand           -- If the current manifest arity isn't enough
+                            --    (never true for join points)
+  , seEtaExpand env         -- and eta-expansion is on
   , wantEtaExpansion rhs
-  = do { tick (EtaExpansion bndr)
+  = -- Do eta-expansion.
+    assertPpr( not (isJoinBC bind_cxt) ) (ppr bndr) $
+       -- assert: this never happens for join points; see GHC.Core.Opt.Arity
+       --         Note [Do not eta-expand join points]
+    do { tick (EtaExpansion bndr)
        ; return (arity_type, etaExpandAT in_scope arity_type rhs) }
 
   | otherwise
   = return (arity_type, rhs)
+
   where
     in_scope   = getInScope env
-    old_arity  = exprArity rhs
     arity_opts = seArityOpts env
-    arity_type = findRhsArity arity_opts is_rec bndr rhs old_arity
-    new_arity  = arityTypeArity arity_type
+    is_rec     = bindContextRec bind_cxt
+    (do_eta_expand, arity_type) = findRhsArity arity_opts is_rec bndr rhs
 
 wantEtaExpansion :: CoreExpr -> Bool
 -- Mostly True; but False of PAPs which will immediately eta-reduce again
@@ -1894,117 +1889,6 @@ But note that this won't eta-expand, say
 Does it matter not eta-expanding such functions?  I'm not sure.  Perhaps
 strictness analysis will have less to bite on?
 
-Note [Do not eta-expand join points]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Similarly to CPR (see Note [Don't w/w join points for CPR] in
-GHC.Core.Opt.WorkWrap), a join point stands well to gain from its outer binding's
-eta-expansion, and eta-expanding a join point is fraught with issues like how to
-deal with a cast:
-
-    let join $j1 :: IO ()
-             $j1 = ...
-             $j2 :: Int -> IO ()
-             $j2 n = if n > 0 then $j1
-                              else ...
-
-    =>
-
-    let join $j1 :: IO ()
-             $j1 = (\eta -> ...)
-                     `cast` N:IO :: State# RealWorld -> (# State# RealWorld, ())
-                                 ~  IO ()
-             $j2 :: Int -> IO ()
-             $j2 n = (\eta -> if n > 0 then $j1
-                                       else ...)
-                     `cast` N:IO :: State# RealWorld -> (# State# RealWorld, ())
-                                 ~  IO ()
-
-The cast here can't be pushed inside the lambda (since it's not casting to a
-function type), so the lambda has to stay, but it can't because it contains a
-reference to a join point. In fact, $j2 can't be eta-expanded at all. Rather
-than try and detect this situation (and whatever other situations crop up!), we
-don't bother; again, any surrounding eta-expansion will improve these join
-points anyway, since an outer cast can *always* be pushed inside. By the time
-CorePrep comes around, the code is very likely to look more like this:
-
-    let join $j1 :: State# RealWorld -> (# State# RealWorld, ())
-             $j1 = (...) eta
-             $j2 :: Int -> State# RealWorld -> (# State# RealWorld, ())
-             $j2 = if n > 0 then $j1
-                            else (...) eta
-
-Note [Arity for recursive join bindings]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-  f x = joinrec j 0 = \ a b c -> (a,x,b)
-                j n = j (n-1)
-        in j 20
-
-Obviously `f` should get arity 4.  But it's a bit tricky:
-
-1. Remember, we don't eta-expand join points; see
-   Note [Do not eta-expand join points].
-
-2. But even though we aren't going to eta-expand it, we still want `j` to get
-   idArity=4, via the findRhsArity fixpoint.  Then when we are doing findRhsArity
-   for `f`, we'll call arityType on f's RHS:
-    - At the letrec-binding for `j` we'll whiz up an arity-4 ArityType
-      for `j` (See Note [arityType for non-recursive let-bindings]
-      in GHC.Core.Opt.Arity)b
-    - At the occurrence (j 20) that arity-4 ArityType will leave an arity-3
-      result.
-
-3. All this, even though j's /join-arity/ (stored in the JoinId) is 1.
-   This is is the Main Reason that we want the idArity to sometimes be
-   larger than the join-arity c.f. Note [Invariants on join points] item 2b
-   in GHC.Core.
-
-4. Be very careful of things like this (#21755):
-     g x = let j 0 = \y -> (x,y)
-               j n = expensive n `seq` j (n-1)
-           in j x
-   Here we do /not/ want eta-expand `g`, lest we duplicate all those
-   (expensive n) calls.
-
-   But it's fine: the findRhsArity fixpoint calculation will compute arity-1
-   for `j` (not arity 2); and that's just what we want. But we do need that
-   fixpoint.
-
-   Historical note: an earlier version of GHC did a hack in which we gave
-   join points an ArityType of ABot, but that did not work with this #21755
-   case.
-
-5. arityType does not usually expect to encounter free join points;
-   see GHC.Core.Opt.Arity Note [No free join points in arityType].
-   But consider
-          f x = join    j1 y = .... in
-                joinrec j2 z = ...j1 y... in
-                j2 v
-
-   When doing findRhsArity on `j2` we'll encounter the free `j1`.
-   But that is fine, because we aren't going to eta-expand `j2`;
-   we just want to know its arity.  So we have a flag am_no_eta,
-   switched on when doing findRhsArity on a join point RHS. If
-   the flag is on, we allow free join points, but not otherwise.
-
-
-Note [Arity for non-recursive join bindings]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Note [Arity for recursive join bindings] deals with recursive join
-bindings. But what about /non-recursive/ones?  If we just call
-findRhsArity, it will call arityType.  And that can be expensive when
-we have deeply nested join points:
-  join j1 x1 = join j2 x2 = join j3 x3 = blah3
-                            in blah2
-               in blah1
-(e.g. test T18698b).
-
-So we call cheapArityType instead.  It's good enough for practical
-purposes.
-
-(Side note: maybe we should use cheapArity for the RHS of let bindings
-in the main arityType function.)
-
 
 ************************************************************************
 *                                                                      *


=====================================
hadrian/bootstrap/bootstrap.py
=====================================
@@ -86,14 +86,17 @@ class Compiler:
 
         self.ghc_path = ghc_path.resolve()
 
+        exe = ''
+        if platform.system() == 'Windows': exe = '.exe'
+
         info = self._get_ghc_info()
         self.version = info['Project version']
         #self.lib_dir = Path(info['LibDir'])
         #self.ghc_pkg_path = (self.lib_dir / 'bin' / 'ghc-pkg').resolve()
-        self.ghc_pkg_path = (self.ghc_path.parent / 'ghc-pkg').resolve()
+        self.ghc_pkg_path = (self.ghc_path.parent / ('ghc-pkg' + exe)).resolve()
         if not self.ghc_pkg_path.is_file():
             raise TypeError(f'ghc-pkg {self.ghc_pkg_path} is not a file')
-        self.hsc2hs_path = (self.ghc_path.parent / 'hsc2hs').resolve()
+        self.hsc2hs_path = (self.ghc_path.parent / ('hsc2hs' + exe)).resolve()
         if not self.hsc2hs_path.is_file():
             raise TypeError(f'hsc2hs {self.hsc2hs_path} is not a file')
 
@@ -367,6 +370,11 @@ def main() -> None:
                         help='path to GHC')
     parser.add_argument('-s', '--bootstrap-sources', type=Path,
                         help='Path to prefetched bootstrap sources tarball')
+    parser.add_argument('--archive', dest='want_archive', action='store_true',
+                       help='produce a Hadrian distribution archive (default)')
+    parser.add_argument('--no-archive', dest='want_archive', action='store_false',
+                       help='do not produce a Hadrian distribution archive')
+    parser.set_defaults(want_archive=True)
 
     subparsers = parser.add_subparsers(dest="command")
 
@@ -381,6 +389,9 @@ def main() -> None:
 
     ghc = None
 
+    sources_fmt = 'gztar' # The archive format for the bootstrap sources archive.
+    if platform.system() == 'Windows': sources_fmt = 'zip'
+
     if args.deps is None:
       if args.bootstrap_sources is None:
         # find appropriate plan in the same directory as the script
@@ -390,7 +401,7 @@ def main() -> None:
       # We have a tarball with all the required information, unpack it and use for further
       elif args.bootstrap_sources is not None and args.command != 'list-sources':
         print(f'Unpacking {args.bootstrap_sources} to {TARBALLS}')
-        shutil.unpack_archive(args.bootstrap_sources.resolve(), TARBALLS, 'gztar')
+        shutil.unpack_archive(args.bootstrap_sources.resolve(), TARBALLS, sources_fmt)
         args.deps = TARBALLS / 'plan-bootstrap.json'
         print(f"using plan-bootstrap.json ({args.deps}) from {args.bootstrap_sources}")
       else:
@@ -428,10 +439,7 @@ def main() -> None:
 
         shutil.copyfile(args.deps, rootdir / 'plan-bootstrap.json')
 
-        fmt = 'gztar'
-        if platform.system() == 'Windows': fmt = 'zip'
-
-        archivename = shutil.make_archive(args.output, fmt, root_dir=rootdir)
+        archivename = shutil.make_archive(args.output, sources_fmt, root_dir=rootdir)
 
         print(f"""
 Bootstrap sources saved to {archivename}
@@ -475,21 +483,21 @@ Alternatively, you could use `bootstrap.py -w {ghc.ghc_path} -d {args.deps} fetc
         bootstrap(info, ghc)
         hadrian_path = (BINDIR / 'hadrian').resolve()
 
-        archive = make_archive(hadrian_path)
-
         print(dedent(f'''
             Bootstrapping finished!
 
             The resulting hadrian executable can be found at
 
                 {hadrian_path}
+        '''))
 
-            It has been archived for distribution in
-
-                {archive}
+        if args.want_archive:
+            dist_archive = make_archive(hadrian_path)
+            print(dedent(f'''
+                The Hadrian executable has been archived for distribution in
 
-            You can use this executable to build GHC.
-        '''))
+                    {dist_archive}
+            '''))
     else:
       print(f"No such command: {args.command}")
 


=====================================
libraries/ghc-prim/GHC/Types.hs
=====================================
@@ -143,7 +143,7 @@ data Symbol
 
 -- | The type constructor 'Any' is type to which you can unsafely coerce any
 -- lifted type, and back. More concretely, for a lifted type @t@ and
--- value @x :: t@, -- @unsafeCoerce (unsafeCoerce x :: Any) :: t@ is equivalent
+-- value @x :: t@, @unsafeCoerce (unsafeCoerce x :: Any) :: t@ is equivalent
 -- to @x at .
 --
 type family Any :: k where { }
@@ -165,7 +165,7 @@ type family Any :: k where { }
 -- ==== __Examples__
 --
 -- Unless the OverloadedLists extension is enabled, list literals are
--- syntatic sugar for repeated applications of @:@ and @[]@.
+-- syntactic sugar for repeated applications of @:@ and @[]@.
 --
 -- >>> 1:2:3:4:[] == [1,2,3,4]
 -- True


=====================================
testsuite/tests/simplCore/should_compile/T22114.hs
=====================================
@@ -0,0 +1,17 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module T22114 where
+
+import Data.Kind (Type)
+
+value :: [Int] -> () -> Maybe Bool
+value = valu
+  where valu [0] = valuN
+        valu _   = \_ -> Nothing
+
+type family T :: Type where
+  T = () -> Maybe Bool
+
+valuN :: T
+valuN = valuN


=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -428,3 +428,4 @@ test('T21948', [grep_errmsg(r'^ Arity=5') ], compile, ['-O -ddump-simpl'])
 test('T21763', only_ways(['optasm']), compile, ['-O2 -ddump-rules'])
 test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules'])
 test('T22028', normal, compile, ['-O -ddump-rule-firings'])
+test('T22114', normal, compile, ['-O'])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6aada809cd75dc229a3b7a62e79aa4a1624358e2...5a944e820a429c4208317f1171c6dfde29ad82b7

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6aada809cd75dc229a3b7a62e79aa4a1624358e2...5a944e820a429c4208317f1171c6dfde29ad82b7
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/20220830/5b48c846/attachment-0001.html>


More information about the ghc-commits mailing list