| 
1 |  | -{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}  | 
2 | 1 | {-# OPTIONS_HADDOCK prune #-}  | 
3 | 2 | {-# LANGUAGE Trustworthy #-}  | 
4 | 3 | 
 
  | 
@@ -1095,6 +1094,7 @@ splitWith p (Chunk c0 cs0) = comb [] (S.splitWith p c0) cs0  | 
1095 | 1094 |         comb acc [s] Empty        = [revChunks (s:acc)]  | 
1096 | 1095 |         comb acc [s] (Chunk c cs) = comb (s:acc) (S.splitWith p c) cs  | 
1097 | 1096 |         comb acc (s:ss) cs        = revChunks (s:acc) : comb [] ss cs  | 
 | 1097 | +        comb _ [] _ = error "Strict splitWith returned [] for nonempty input"  | 
1098 | 1098 | {-# INLINE splitWith #-}  | 
1099 | 1099 | 
 
  | 
1100 | 1100 | -- | /O(n)/ Break a 'ByteString' into pieces separated by the byte  | 
@@ -1122,6 +1122,7 @@ split w (Chunk c0 cs0) = comb [] (S.split w c0) cs0  | 
1122 | 1122 |         comb acc [s] Empty        = [revChunks (s:acc)]  | 
1123 | 1123 |         comb acc [s] (Chunk c cs) = comb (s:acc) (S.split w c) cs  | 
1124 | 1124 |         comb acc (s:ss) cs        = revChunks (s:acc) : comb [] ss cs  | 
 | 1125 | +        comb _ [] _ = error "Strict split returned [] for nonempty input"  | 
1125 | 1126 | {-# INLINE split #-}  | 
1126 | 1127 | 
 
  | 
1127 | 1128 | -- | The 'group' function takes a ByteString and returns a list of  | 
@@ -1441,16 +1442,22 @@ zipWith _ Empty     _  = []  | 
1441 | 1442 | zipWith _ _      Empty = []  | 
1442 | 1443 | zipWith f (Chunk a as) (Chunk b bs) = go a as b bs  | 
1443 | 1444 |   where  | 
1444 |  | -    go x xs y ys = f (S.unsafeHead x) (S.unsafeHead y)  | 
1445 |  | -                 : to (S.unsafeTail x) xs (S.unsafeTail y) ys  | 
1446 |  | - | 
1447 |  | -    to x Empty         _ _             | S.null x       = []  | 
1448 |  | -    to _ _             y Empty         | S.null y       = []  | 
1449 |  | -    to x xs            y ys            | not (S.null x)  | 
1450 |  | -                                      && not (S.null y) = go x  xs y  ys  | 
1451 |  | -    to x xs            _ (Chunk y' ys) | not (S.null x) = go x  xs y' ys  | 
1452 |  | -    to _ (Chunk x' xs) y ys            | not (S.null y) = go x' xs y  ys  | 
1453 |  | -    to _ (Chunk x' xs) _ (Chunk y' ys)                  = go x' xs y' ys  | 
 | 1445 | +    -- This loop is written in a slightly awkward way but ensures we  | 
 | 1446 | +    -- don't have to allocate any 'Chunk' objects to pass to a recursive  | 
 | 1447 | +    -- call.  We have in some sense performed SpecConstr manually.  | 
 | 1448 | +    go !x xs !y ys = let  | 
 | 1449 | +      -- Creating a thunk for reading one byte would  | 
 | 1450 | +      -- be wasteful, so we evaluate these eagerly.  | 
 | 1451 | +      -- See also #558 for a similar issue with uncons.  | 
 | 1452 | +      !xHead = S.unsafeHead x  | 
 | 1453 | +      !yHead = S.unsafeHead y  | 
 | 1454 | +      in f xHead yHead : to (S.unsafeTail x) xs (S.unsafeTail y) ys  | 
 | 1455 | + | 
 | 1456 | +    to !x xs !y ys  | 
 | 1457 | +      | Chunk x' xs' <- chunk x xs  | 
 | 1458 | +      , Chunk y' ys' <- chunk y ys  | 
 | 1459 | +      = go x' xs' y' ys'  | 
 | 1460 | +      | otherwise = []  | 
1454 | 1461 | 
 
  | 
1455 | 1462 | -- | A specialised version of `zipWith` for the common case of a  | 
1456 | 1463 | -- simultaneous map over two ByteStrings, to build a 3rd.  | 
 | 
0 commit comments