[Git][ghc/ghc][wip/T18927] More changes, committing so that we see a segfault

Sebastian Graf (@sgraf812) gitlab at gitlab.haskell.org
Tue Nov 15 11:00:10 UTC 2022



Sebastian Graf pushed to branch wip/T18927 at Glasgow Haskell Compiler / GHC


Commits:
07a4f966 by Sebastian Graf at 2022-11-15T11:32:26+01:00
More changes, committing so that we see a segfault

- - - - -


5 changed files:

- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Data/SArr.hs
- compiler/GHC/Types/Demand.hs


Changes:

=====================================
compiler/GHC/Core/Opt/DmdAnal.hs
=====================================
@@ -40,10 +40,11 @@ import GHC.Utils.Misc
 import GHC.Utils.Panic
 import GHC.Utils.Panic.Plain
 import GHC.Data.Maybe         ( isJust )
+import GHC.Data.SArr (SArr, Slice)
+import qualified GHC.Data.SArr as SArr
 import GHC.Builtin.PrimOps
 import GHC.Builtin.Types.Prim ( realWorldStatePrimTy )
 import GHC.Types.Unique.Set
-import GHC.Exts ( IsList(..) )
 
 import GHC.Utils.Trace
 _ = pprTrace -- Tired of commenting out the import all the time
@@ -445,8 +446,8 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt bndrs rhs])
           | DataAlt _ <- alt
           -- See Note [Demand on the scrutinee of a product case]
           -- See Note [Demand on case-alternative binders]
-          , (!scrut_sd, fld_dmds') <- addCaseBndrDmd case_bndr_sd (fromList fld_dmds)
-          , let !bndrs' = setBndrsDemandInfo bndrs fld_dmds'
+          , (!scrut_sd, fld_dmds') <- addCaseBndrDmd case_bndr_sd (SArr.fromList fld_dmds)
+          , let !bndrs' = setBndrsDemandInfo bndrs (SArr.slice fld_dmds')
           = (bndrs', scrut_sd)
           | otherwise
           -- __DEFAULT and literal alts. Simply add demands and discard the
@@ -560,26 +561,26 @@ dmdAnalSumAlt env dmd case_bndr (Alt con bndrs rhs)
         -- See Note [Demand on case-alternative binders]
         -- we can't use the scrut_sd, because it says 'Prod' and we'll use
         -- topSubDmd anyway for scrutinees of sum types.
-        (!_scrut_sd, dmds') = addCaseBndrDmd case_bndr_sd dmds
+        (!_scrut_sd, dmds') = addCaseBndrDmd case_bndr_sd (SArr.fromList dmds)
         -- Do not put a thunk into the Alt
-        !new_ids            = setBndrsDemandInfo bndrs dmds'
+        !new_ids            = setBndrsDemandInfo bndrs (SArr.slice dmds')
   = WithDmdType alt_ty (Alt con new_ids rhs')
 
 -- Precondition: The SubDemand is not a Call
 -- See Note [Demand on the scrutinee of a product case]
 -- and Note [Demand on case-alternative binders]
 addCaseBndrDmd :: SubDemand -- On the case binder
-               -> [Demand]  -- On the fields of the constructor
-               -> (SubDemand, [Demand])
+               -> SArr Demand  -- On the fields of the constructor
+               -> (SubDemand, SArr Demand)
                             -- SubDemand on the case binder incl. field demands
                             -- and final demands for the components of the constructor
 addCaseBndrDmd case_sd fld_dmds
   | Just (_, ds) <- viewProd (length fld_dmds) scrut_sd
-  = (scrut_sd, toList ds)
+  = (scrut_sd, ds)
   | otherwise
   = pprPanic "was a call demand" (ppr case_sd $$ ppr fld_dmds) -- See the Precondition
   where
-    scrut_sd = case_sd `plusSubDmd` mkProd Unboxed (fromList fld_dmds)
+    scrut_sd = case_sd `plusSubDmd` mkProd Unboxed fld_dmds
 
 {-
 Note [Analysing with absent demand]
@@ -1344,10 +1345,10 @@ conservative thing and refrain from strictifying a dfun's argument
 dictionaries.
 -}
 
-setBndrsDemandInfo :: HasCallStack => [Var] -> [Demand] -> [Var]
+setBndrsDemandInfo :: HasCallStack => [Var] -> Slice Demand -> [Var]
 setBndrsDemandInfo (b:bs) ds
   | isTyVar b = b : setBndrsDemandInfo bs ds
-setBndrsDemandInfo (b:bs) (d:ds) =
+setBndrsDemandInfo (b:bs) (d SArr.:<| ds) =
     let !new_info = setIdDemandInfo b d
         !vars = setBndrsDemandInfo bs ds
     in new_info : vars


=====================================
compiler/GHC/Core/Opt/SpecConstr.hs
=====================================
@@ -57,6 +57,7 @@ import GHC.Types.Unique.FM
 
 import GHC.Data.Maybe     ( orElse, catMaybes, isJust, isNothing )
 import GHC.Data.Pair
+import qualified GHC.Data.SArr as SArr
 import GHC.Data.FastString
 
 import GHC.Utils.Misc
@@ -69,7 +70,7 @@ import GHC.Utils.Trace
 
 import GHC.Builtin.Names ( specTyConKey )
 
-import GHC.Exts( SpecConstrAnnotation(..), IsList(..) )
+import GHC.Exts( SpecConstrAnnotation(..) )
 import GHC.Serialized   ( deserializeWithData )
 
 import Control.Monad    ( zipWithM )
@@ -1836,19 +1837,19 @@ calcSpecInfo fn (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs
     set_dmds (v:vs) ds@(d:ds') | isTyVar v = v                   : set_dmds vs ds
                                | otherwise = setIdDemandInfo v d : set_dmds vs ds'
 
-    dmd_env = go emptyVarEnv fn_dmds val_pats
+    dmd_env = go emptyVarEnv (SArr.slice $ SArr.fromList fn_dmds) val_pats
 
-    go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv
+    go :: DmdEnv -> SArr.Slice Demand -> [CoreExpr] -> DmdEnv
     -- We've filtered out all the type patterns already
-    go env (d:ds) (pat : pats)     = go (go_one env d pat) ds pats
-    go env _      _                = env
+    go env (d SArr.:<| ds) (pat : pats)     = go (go_one env d pat) ds pats
+    go env _               _                = env
 
     go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv
     go_one env d          (Var v) = extendVarEnv_C plusDmd env v d
     go_one env (_n :* cd) e -- NB: _n does not have to be strict
       | (Var _, args) <- collectArgs e
       , Just (_b, ds) <- viewProd (length args) cd -- TODO: We may want to look at boxity _b, though...
-      = go env (toList ds) args
+      = go env (SArr.slice ds) args
     go_one env _  _ = env
 
 


=====================================
compiler/GHC/Core/Opt/WorkWrap/Utils.hs
=====================================
@@ -51,6 +51,8 @@ import GHC.Data.FastString
 import GHC.Data.Maybe
 import GHC.Data.OrdList
 import GHC.Data.List.SetOps
+import GHC.Data.SArr (SArr)
+import qualified GHC.Data.SArr as SArr
 
 import GHC.Builtin.Types ( tupleDataCon )
 
@@ -554,7 +556,7 @@ data UnboxingDecision s
   -- ^ We ran out of strictness info. Leave untouched.
   | DropAbsent
   -- ^ The argument/field was absent. Drop it.
-  | Unbox !DataConPatContext [s]
+  | Unbox !DataConPatContext !(SArr s)
   -- ^ The argument is used strictly or the returned product was constructed, so
   -- unbox it.
   -- The 'DataConPatContext' carries the bits necessary for
@@ -581,7 +583,7 @@ wantToUnboxArg fam_envs ty (n :* sd)
   , Just (Unboxed, ds) <- viewProd arity sd -- See Note [Boxity Analysis]
   -- NB: No strictness or evaluatedness checks here. That is done by
   -- 'finaliseBoxity'!
-  = Unbox (DataConPatContext dc tc_args co) (toList ds)
+  = Unbox (DataConPatContext dc tc_args co) ds
 
   | otherwise
   = StopUnboxing
@@ -605,7 +607,7 @@ wantToUnboxResult fam_envs ty cpr
   -- Deactivates CPR worker/wrapper splits on constructors with non-linear
   -- arguments, for the moment, because they require unboxed tuple with variable
   -- multiplicity fields.
-  = Unbox (DataConPatContext dc tc_args co) arg_cprs
+  = Unbox (DataConPatContext dc tc_args co) (SArr.fromList arg_cprs)
 
   | otherwise
   = StopUnboxing
@@ -965,7 +967,7 @@ mkWWstr_one opts arg =
 
 unbox_one_arg :: WwOpts
           -> Var
-          -> [Demand]
+          -> SArr Demand
           -> DataConPatContext
           -> UniqSM (Bool, [Var], CoreExpr -> CoreExpr, CoreExpr)
 unbox_one_arg opts arg_var ds
@@ -975,7 +977,7 @@ unbox_one_arg opts arg_var ds
        ; let ex_name_fss = map getOccFS $ dataConExTyCoVars dc
              (ex_tvs', arg_ids) =
                dataConRepFSInstPat (ex_name_fss ++ repeat ww_prefix) pat_bndrs_uniqs (idMult arg_var) dc tc_args
-             arg_ids' = zipWithEqual "unbox_one_arg" setIdDemandInfo arg_ids ds
+             arg_ids' = zipWithEqual "unbox_one_arg" (flip setIdDemandInfo) (toList ds) arg_ids
              unbox_fn = mkUnpackCase (Var arg_var) co (idMult arg_var)
                                      dc (ex_tvs' ++ arg_ids')
        ; (_, worker_args, wrap_fn, wrap_args) <- mkWWstr opts (ex_tvs' ++ arg_ids')
@@ -1284,7 +1286,7 @@ findTypeShape fam_envs ty
          -- don't matter.
          -- We really do encounter existentials here, see
          -- Note [Which types are unboxed?] for an example.
-       = TsProd (map (go rec_tc) (dubiousDataConInstArgTys con tc_args))
+       = TsProd (fromList $ map (go rec_tc) (dubiousDataConInstArgTys con tc_args))
 
        | Just (ty', _) <- instNewTyCon_maybe tc tc_args
        , Just rec_tc <- checkRecTc rec_tc tc
@@ -1449,7 +1451,7 @@ finaliseBoxity env in_inl_fun ty dmd = go NotMarkedStrict ty dmd
           -- See Note [Do not unbox class dictionaries]
           , in_inl_fun == NotInsideInlineableFun || not (isClassPred ty)
           -- See Note [mkWWstr and unsafeCoerce]
-          , ds `lengthIs` dataConRepArity dc
+          , length ds == dataConRepArity dc
           , let arg_tys = dubiousDataConInstArgTys dc tc_args
           -> -- pprTrace "finaliseBoxity:Unbox" (ppr ty $$ ppr dmd $$ ppr ds) $
              n :* (mkProd Unboxed $! zip_go_with_marks dc arg_tys ds)
@@ -1458,9 +1460,9 @@ finaliseBoxity env in_inl_fun ty dmd = go NotMarkedStrict ty dmd
 
     -- See Note [Unboxing evaluated arguments]
     zip_go_with_marks dc arg_tys ds = case dataConWrapId_maybe dc of
-      Nothing -> fromList $ strictZipWith  (go NotMarkedStrict)          arg_tys ds
+      Nothing -> SArr.zipWith (go NotMarkedStrict) (fromList arg_tys) ds
                     -- Shortcut when DataCon worker=wrapper
-      Just _  -> fromList $ strictZipWith3 go  (dataConRepStrictness dc) arg_tys ds
+      Just _  -> SArr.zipWith3 go (fromList $ dataConRepStrictness dc) (fromList arg_tys) ds
 
 {-
 ************************************************************************
@@ -1541,7 +1543,7 @@ mkWWcpr_one :: WwOpts -> Id -> Cpr -> UniqSM CprWwResultOne
 mkWWcpr_one opts res_bndr cpr
   | assert (not (isTyVar res_bndr) ) True
   , Unbox dcpc arg_cprs <- wantToUnboxResult (wo_fam_envs opts) (idType res_bndr) cpr
-  = unbox_one_result opts res_bndr arg_cprs dcpc
+  = unbox_one_result opts res_bndr (SArr.toList arg_cprs) dcpc
   | otherwise
   = return (False, unitOL res_bndr, varToCoreExpr res_bndr, nop_fn)
 


=====================================
compiler/GHC/Data/SArr.hs
=====================================
@@ -1,4 +1,5 @@
 {-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
+{-# OPTIONS_GHC -ddump-simpl -ddump-to-file #-}
 {-# LANGUAGE MagicHash           #-}
 {-# LANGUAGE UnboxedTuples       #-}
 {-# LANGUAGE RankNTypes          #-}
@@ -16,20 +17,24 @@ module GHC.Data.SArr (
       -- * Indexing
       get, unsafeGet, (!),
       -- * Construction
-      take, drop, replicate,
+      fromList, toList, take, drop, replicate,
       -- * Slicing
       Slice(Empty,(:<|),(:|>)), slice, toSArr, takeS, dropS,
       -- * Other operations
-      all, map, zipWith
+      all, map, zipWith, zipWith3
   ) where
 
-import Prelude hiding (replicate, drop, take, head, init, map, all, zipWith)
+import Prelude hiding (replicate, drop, take, head, init, map, all, zipWith, zipWith3)
 import qualified Prelude
 
 import qualified Data.List as List
 import qualified GHC.Exts as Exts
+import qualified GHC.Utils.Binary as Binary
 import GHC.ST
-import GHC.Stack
+import GHC.Utils.Misc
+import GHC.Utils.Outputable
+
+import Data.Maybe
 
 -- | A general-purpose array type that is strict in its elements and the
 -- combinators of which enjoy list fusion.
@@ -63,7 +68,7 @@ instance Show a => Show (SArr a) where
   showsPrec p arr = showParen (p >= 10) $
     showString "fromList " . shows (toList arr)
 
-die :: String -> String -> a
+die :: HasDebugCallStack => String -> String -> a
 die fun problem = error (fun ++ ": " ++ problem)
 {-# NOINLINE die #-}
 
@@ -117,7 +122,7 @@ createSmallArrayN (Exts.I# n) x f = runST $ ST $ \s ->
 {-# INLINE createSmallArrayN #-}
 
 createSmallArray
-  :: a
+  :: HasDebugCallStack => a
   -> (forall s. Exts.SmallMutableArray# s a -> USTL s (Exts.SmallMutableArray# s a))
   -> SArr a
 createSmallArray x f = runST $ ST $ \s ->
@@ -128,6 +133,7 @@ createSmallArray x f = runST $ ST $ \s ->
       !s3                   = Exts.shrinkSmallMutableArray# sma' n s2
       !(# s4, sa   #)       = Exts.unsafeFreezeSmallArray# sma' s3
       -- !_                    = trace ("create: " ++ show (Exts.I# n) ++ show (Exts.I# m)) ()
+      !()                   = foldr seq () (SArr sa)
   in (# s4, SArr sa #)
 {-# INLINE createSmallArray #-}
 
@@ -163,11 +169,11 @@ ifoldrUST f b as s = ifoldr c z as b s
     z = Exts.oneShot $ \(Exts.I# i) -> Exts.oneShot $ \b s -> (# s, b, i #)
 {-# INLINE ifoldrUST #-}
 
-dieFromList :: a
+dieFromList :: HasDebugCallStack => a
 dieFromList = die "fromList" "uninitialized element"
 {-# NOINLINE dieFromList #-}
 
-fromList :: [a] -> SArr a
+fromList :: HasDebugCallStack => [a] -> SArr a
 fromList l =
   createSmallArray dieFromList $ Exts.oneShot $ \sma ->
     ifoldrUST (\(Exts.I# i) a sma' s -> a `seq` writeResize i a sma' s) sma l
@@ -175,11 +181,11 @@ fromList l =
 -- we need [2], otherwise FB's (and their builds) will be rewritten back to
 -- list producing functions and we can't fuse away the ifoldr
 
-dieWriteResize :: a
+dieWriteResize :: HasDebugCallStack => a
 dieWriteResize = die "writeResize" "uninitialized element"
 {-# NOINLINE dieWriteResize #-}
 
-writeResize :: Exts.Int# -> a -> Exts.SmallMutableArray# s a -> UST s (Exts.SmallMutableArray# s a)
+writeResize :: HasDebugCallStack => Exts.Int# -> a -> Exts.SmallMutableArray# s a -> UST s (Exts.SmallMutableArray# s a)
 writeResize i a sma s =
   let !(# s1, n #) = Exts.getSizeofSmallMutableArray# sma s -- TODO: cache this
       !(# s2, sma' #)
@@ -190,19 +196,19 @@ writeResize i a sma s =
   in (# s3, sma' #)
 {-# NOINLINE writeResize #-}
 
-dieFromListN :: HasCallStack => a
+dieFromListN :: HasDebugCallStack => a
 dieFromListN = die "fromListN" "uninitialized element"
 {-# NOINLINE dieFromListN #-}
 
-fromListN :: HasCallStack => Int -> [a] -> SArr a
+fromListN :: HasDebugCallStack => Int -> [a] -> SArr a
 fromListN n l =
   createSmallArrayN n dieFromListN $ Exts.oneShot $ \sma s ->
     case ifoldrUST (\(Exts.I# i) a _sma s -> a `seq` (# Exts.writeSmallArray# sma i a s, sma #)) sma l s of
       (# s', _sma, _n #) -> (# s', sma #)
 {-# INLINE [2] fromListN #-}
 
-toList :: SArr a -> [a]
-toList arr = Prelude.map (\i -> unsafeGet i arr) [0..length arr-1]
+toList :: HasDebugCallStack => SArr a -> [a]
+toList arr = Prelude.map (\i -> fromJust $ get i arr) [0..length arr-1]
 {-# INLINE [2] toList #-}
 
 len :: SArr a -> Int
@@ -213,14 +219,19 @@ all :: (a -> Bool) -> SArr a -> Bool
 all cond = List.all cond . toList
 {-# INLINE [2] all #-}
 
-map :: (a -> b) -> SArr a -> SArr b
-map f a = fromList $ Prelude.map f (toList a)
+map :: HasDebugCallStack => (a -> b) -> SArr a -> SArr b
+map f = fromList . Prelude.map f . toList
 {-# INLINE [2] map #-}
 
 zipWith :: (a -> b -> c) -> SArr a -> SArr b -> SArr c
 zipWith f a b = fromListN (min (len a) (len b)) $ Prelude.zipWith f (toList a) (toList b)
 {-# INLINE [2] zipWith #-}
 
+zipWith3 :: HasDebugCallStack => (a -> b -> c -> d) -> SArr a -> SArr b -> SArr c -> SArr d
+zipWith3 f a b c = fromListN (len a `min` len b `min` len c) $
+  Prelude.zipWith3 f (toList a) (toList b) (toList c)
+{-# INLINE [2] zipWith3 #-}
+
 instance Eq a => Eq (SArr a) where
   a1 == a2 = len a1 == len a2 && and (Prelude.map (\i -> a1 ! i == a2 ! i) [0..len a1])
 
@@ -238,9 +249,9 @@ fromListA l =
 
 {-# RULES
 "toList/fromList"  forall xs.    toList (fromList xs)     = xs
-"toList/fromListN" forall n xs.  toList (fromListN n xs)  = xs
+"toList/fromListN" forall n xs.  toList (fromListN n xs)  = List.take n xs
 "fromList/toList"  forall arr.   fromList (toList arr)    = arr
-"fromListN/toList" forall n arr. fromListN n (toList arr) = arr
+-- "fromListN/toList" forall n arr. fromListN n (toList arr) = arr -- Unsafe: What if n != len arr? We need the copy here
 "len/fromListN"    forall n arr. len (fromListN n arr)    = n
 #-}
 
@@ -383,3 +394,10 @@ pattern a :<| rest <- (head -> Just (a, rest))
 pattern (:|>) :: Slice a -> a -> Slice a
 pattern rest :|> a <- (init -> Just (rest, a))
 {-# COMPLETE Empty, (:|>) #-}
+
+instance Binary.Binary a => Binary.Binary (SArr a) where
+  put_ bh a = Binary.put_ bh (toList a)
+  get bh    = fromList <$> Binary.get bh
+
+instance Outputable a => Outputable (SArr a) where
+  ppr = ppr . toList


=====================================
compiler/GHC/Types/Demand.hs
=====================================
@@ -93,8 +93,6 @@ import GHC.Data.Maybe   ( orElse )
 import GHC.Data.SArr ( SArr, Slice(..), slice )
 import qualified GHC.Data.SArr as SArr
 
-import GHC.Exts ( IsList(..) )
-
 import GHC.Core.Type    ( Type )
 import GHC.Core.TyCon   ( isNewTyCon, isClassTyCon )
 import GHC.Core.DataCon ( splitDataProductType_maybe )
@@ -737,9 +735,9 @@ mkProd :: Boxity -> SArr Demand -> SubDemand
 mkProd b ds
   | SArr.all (== AbsDmd) ds = Poly b C_00
   | SArr.all (== BotDmd) ds = Poly b C_10
-  | dmd@(n :* Poly Boxed m):<|_ <- slice ds  -- don't rewrite P(L!L)
-  , n == m                           -- don't rewrite P(1L)
-  , SArr.all (== dmd) ds                  -- don't rewrite P(L,A)
+  | dmd@(n :* Poly Boxed m) :<| _ <- slice ds -- don't rewrite P(L!L)
+  , n == m                                    -- don't rewrite P(1L)
+  , SArr.all (== dmd) ds                      -- don't rewrite P(L,A)
   = Poly b n
   | otherwise          = Prod b ds
 
@@ -944,7 +942,7 @@ strictifyDictDmd :: Type -> Demand -> Demand
 strictifyDictDmd ty (n :* Prod b ds)
   | not (isAbs n)
   , Just field_tys <- as_non_newtype_dict ty
-  = C_1N :* mkProd b (SArr.zipWith strictifyDictDmd (fromList field_tys) ds)
+  = C_1N :* mkProd b (SArr.zipWith strictifyDictDmd (SArr.fromList field_tys) ds)
       -- main idea: ensure it's strict
   where
     -- | Return a TyCon and a list of field types if the given
@@ -1954,7 +1952,7 @@ dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd
 -- demands into the constructor arguments.
 dmdTransformDataConSig :: Arity -> DmdTransformer
 dmdTransformDataConSig arity sd = case go arity sd of
-  Just dmds -> DmdType emptyDmdEnv (toList dmds) topDiv
+  Just dmds -> DmdType emptyDmdEnv (SArr.toList dmds) topDiv
   Nothing   -> nopDmdType -- Not saturated
   where
     go 0 sd             = snd <$> viewProd arity sd
@@ -2154,7 +2152,7 @@ kill_usage_sd _   sd          = sd
 data TypeShape -- See Note [Trimming a demand to a type]
                --     in GHC.Core.Opt.DmdAnal
   = TsFun TypeShape
-  | TsProd [TypeShape]
+  | TsProd (SArr TypeShape)
   | TsUnk
 
 trimToType :: Demand -> TypeShape -> Demand
@@ -2165,8 +2163,7 @@ trimToType (n :* sd) ts
   = n :* go sd ts
   where
     go (Prod b ds) (TsProd tss)
-      | length ds == length tss' = mkProd b (SArr.zipWith trimToType ds tss') where
-        tss' = fromList tss
+      | length ds == length tss = mkProd b (SArr.zipWith trimToType ds tss) where
     go (Call n sd) (TsFun ts)    = mkCall n (go sd ts)
     go sd at Poly{}   _             = sd
     go _           _             = topSubDmd
@@ -2178,7 +2175,7 @@ trimBoxity BotDmd    = BotDmd
 trimBoxity (n :* sd) = n :* go sd
   where
     go (Poly _ n)  = Poly Boxed n
-    go (Prod _ ds) = mkProd Boxed (SArr.map trimBoxity ds)
+    go (Prod _ ds) | !_ <- foldr seq () ds = pprTrace "test" empty $ pprTrace "trimBoxity" (ppr ds $$ ppr (SArr.map trimBoxity ds)) $ Prod Boxed (SArr.map trimBoxity ds)
     go (Call n sd) = mkCall n $ go sd
 
 {-
@@ -2336,7 +2333,7 @@ instance Outputable DmdSig where
 instance Outputable TypeShape where
   ppr TsUnk        = text "TsUnk"
   ppr (TsFun ts)   = text "TsFun" <> parens (ppr ts)
-  ppr (TsProd tss) = parens (hsep $ punctuate comma $ map ppr tss)
+  ppr (TsProd tss) = parens (hsep $ punctuate comma $ map ppr $ SArr.toList tss)
 
 instance Binary Card where
   put_ bh C_00 = putByte bh 0



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

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/07a4f966a58d35fae29431448af7accc2b969a10
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/20221115/fb30a7d7/attachment-0001.html>


More information about the ghc-commits mailing list