Repository: Marwes/combine (language: rust)

Issue:
Reset count state after extending the iterator
When working on a parser, I started to get `attempt to subtract with overflow` panic coming from the Count combinator:

```
thread 'tests_std::test_nested_count_overflow' panicked at 'attempt to subtract with overflow', /home/blake/src/combine/src/parser/repeat.rs:50:23
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:221
   4: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:477
   5: std::panicking::continue_panic_fmt
             at libstd/panicking.rs:391
   6: rust_begin_unwind
             at libstd/panicking.rs:326
   7: core::panicking::panic_fmt
             at libcore/panicking.rs:77
   8: core::panicking::panic
             at libcore/panicking.rs:52
   9: <combine::parser::repeat::Count<F, P> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/repeat.rs:50
  10: combine::parser::ParseMode::parse_consumed
             at ./src/parser/mod.rs:1025
  11: <combine::parser::sequence::ThenPartial<P, F> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/mod.rs:374
             at ./src/parser/sequence.rs:660
  12: <combine::parser::repeat::Iter<'a, P, S, M> as core::iter::iterator::Iterator>::next
             at ./src/parser/mod.rs:334
             at ./src/parser/mod.rs:58
             at ./src/parser/mod.rs:960
             at ./src/parser/mod.rs:354
             at ./src/parser/mod.rs:334
             at ./src/parser/repeat.rs:340
  13: <&'a mut I as core::iter::iterator::Iterator>::next
             at libcore/iter/iterator.rs:2562
  14: <core::iter::Take<I> as core::iter::iterator::Iterator>::next
             at libcore/iter/mod.rs:2366
  15: <core::iter::Inspect<I, F> as core::iter::iterator::Iterator>::next
             at libcore/iter/mod.rs:3066
  16: <alloc::vec::Vec<T>>::extend_desugared
             at liballoc/vec.rs:1980
  17: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::spec_extend
             at liballoc/vec.rs:1877
  18: <alloc::vec::Vec<T> as core::iter::traits::Extend<T>>::extend
             at liballoc/vec.rs:1841
  19: <combine::parser::repeat::Count<F, P> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/repeat.rs:48
  20: combine::parser::ParseMode::parse_consumed
             at ./src/parser/mod.rs:1025
  21: <combine::parser::sequence::ThenPartial<P, F> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/mod.rs:374
             at ./src/parser/sequence.rs:660
  22: combine::parser::sequence::<impl combine::parser::Parser for (A, B)>::parse_mode_impl
             at ./src/parser/mod.rs:334
             at ./src/parser/sequence.rs:189
  23: <combine::parser::combinator::Map<P, F> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/mod.rs:334
             at ./src/parser/combinator.rs:237
  24: combine::parser::Parser::parse_stream_consumed
             at ./src/parser/mod.rs:334
             at ./src/parser/mod.rs:58
             at ./src/parser/mod.rs:225
  25: combine::parser::Parser::parse
             at ./src/parser/mod.rs:206
             at ./src/parser/mod.rs:174
  26: parser::tests_std::test_nested_count_overflow
             at tests/parser.rs:589
  27: parser::tests_std::test_nested_count_overflow::{{closure}}
             at tests/parser.rs:574
  28: core::ops::function::FnOnce::call_once
             at libcore/ops/function.rs:238
  29: <F as alloc::boxed::FnBox<A>>::call_box
             at libtest/lib.rs:1461
             at libcore/ops/function.rs:238
             at liballoc/boxed.rs:646
  30: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:103
```

I'm not sure exactly what's happening, but it seems that the *count ref is being preserved between `count` combinator calls. The attached PR makes my parser not panic anymore, and the attached test pass, but I'm a little puzzled why the *count state is being preserved between calls. Any help or insight would be really appreciated.

Thanks so much for the great library, it's been really great so far!
Reset count state after extending the iterator
When working on a parser, I started to get `attempt to subtract with overflow` panic coming from the Count combinator:

```
thread 'tests_std::test_nested_count_overflow' panicked at 'attempt to subtract with overflow', /home/blake/src/combine/src/parser/repeat.rs:50:23
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:221
   4: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:477
   5: std::panicking::continue_panic_fmt
             at libstd/panicking.rs:391
   6: rust_begin_unwind
             at libstd/panicking.rs:326
   7: core::panicking::panic_fmt
             at libcore/panicking.rs:77
   8: core::panicking::panic
             at libcore/panicking.rs:52
   9: <combine::parser::repeat::Count<F, P> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/repeat.rs:50
  10: combine::parser::ParseMode::parse_consumed
             at ./src/parser/mod.rs:1025
  11: <combine::parser::sequence::ThenPartial<P, F> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/mod.rs:374
             at ./src/parser/sequence.rs:660
  12: <combine::parser::repeat::Iter<'a, P, S, M> as core::iter::iterator::Iterator>::next
             at ./src/parser/mod.rs:334
             at ./src/parser/mod.rs:58
             at ./src/parser/mod.rs:960
             at ./src/parser/mod.rs:354
             at ./src/parser/mod.rs:334
             at ./src/parser/repeat.rs:340
  13: <&'a mut I as core::iter::iterator::Iterator>::next
             at libcore/iter/iterator.rs:2562
  14: <core::iter::Take<I> as core::iter::iterator::Iterator>::next
             at libcore/iter/mod.rs:2366
  15: <core::iter::Inspect<I, F> as core::iter::iterator::Iterator>::next
             at libcore/iter/mod.rs:3066
  16: <alloc::vec::Vec<T>>::extend_desugared
             at liballoc/vec.rs:1980
  17: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::spec_extend
             at liballoc/vec.rs:1877
  18: <alloc::vec::Vec<T> as core::iter::traits::Extend<T>>::extend
             at liballoc/vec.rs:1841
  19: <combine::parser::repeat::Count<F, P> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/repeat.rs:48
  20: combine::parser::ParseMode::parse_consumed
             at ./src/parser/mod.rs:1025
  21: <combine::parser::sequence::ThenPartial<P, F> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/mod.rs:374
             at ./src/parser/sequence.rs:660
  22: combine::parser::sequence::<impl combine::parser::Parser for (A, B)>::parse_mode_impl
             at ./src/parser/mod.rs:334
             at ./src/parser/sequence.rs:189
  23: <combine::parser::combinator::Map<P, F> as combine::parser::Parser>::parse_mode_impl
             at ./src/parser/mod.rs:334
             at ./src/parser/combinator.rs:237
  24: combine::parser::Parser::parse_stream_consumed
             at ./src/parser/mod.rs:334
             at ./src/parser/mod.rs:58
             at ./src/parser/mod.rs:225
  25: combine::parser::Parser::parse
             at ./src/parser/mod.rs:206
             at ./src/parser/mod.rs:174
  26: parser::tests_std::test_nested_count_overflow
             at tests/parser.rs:589
  27: parser::tests_std::test_nested_count_overflow::{{closure}}
             at tests/parser.rs:574
  28: core::ops::function::FnOnce::call_once
             at libcore/ops/function.rs:238
  29: <F as alloc::boxed::FnBox<A>>::call_box
             at libtest/lib.rs:1461
             at libcore/ops/function.rs:238
             at liballoc/boxed.rs:646
  30: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:103
```

I'm not sure exactly what's happening, but it seems that the *count ref is being preserved between `count` combinator calls. The attached PR makes my parser not panic anymore, and the attached test pass, but I'm a little puzzled why the *count state is being preserved between calls. Any help or insight would be really appreciated.

Thanks so much for the great library, it's been really great so far!


Discussion / hints:

Fix patch:
diff --git a/benches/http.rs b/benches/http.rs
index 4abff343..9be42f8a 100644
--- a/benches/http.rs
+++ b/benches/http.rs
@@ -80,7 +80,8 @@ where
         take_while1(is_horizontal_space),
         take_while1(|c| c != b'\r' && c != b'\n'),
         end_of_line(),
-    ).map(|(_, line, _)| line);
+    )
+        .map(|(_, line, _)| line);
 
     struct_parser!(Header {
         name: take_while1(is_token),
@@ -109,7 +110,8 @@ where
         end_of_line(),
         many(message_header()),
         end_of_line(),
-    ).map(|(request, _, headers, _)| (request, headers));
+    )
+        .map(|(request, _, headers, _)| (request, headers));
 
     request.parse(input)
 }
diff --git a/benches/json.rs b/benches/json.rs
index ed28d0e9..be6f11cc 100644
--- a/benches/json.rs
+++ b/benches/json.rs
@@ -97,7 +97,8 @@ where
                 n * 10.0f64.powi(e as i32)
             }
             None => n,
-        })).expected("number")
+        }))
+    .expected("number")
 }
 
 fn json_char<I>() -> impl Parser<Input = I, Output = char>
@@ -210,9 +211,10 @@ fn json_test() {
             ("true", Bool(true)),
             ("false", Bool(false)),
             ("null", Null),
-        ].into_iter()
-            .map(|(k, v)| (k.to_string(), v))
-            .collect(),
+        ]
+        .into_iter()
+        .map(|(k, v)| (k.to_string(), v))
+        .collect(),
     );
     match result {
         Ok(result) => assert_eq!(result, (expected, "")),
diff --git a/benches/mp4.rs b/benches/mp4.rs
index a415d7ca..2ddfa4cf 100644
--- a/benches/mp4.rs
+++ b/benches/mp4.rs
@@ -42,13 +42,14 @@ fn parse_mp4(data: &[u8]) -> Result<(Vec<MP4Box>, &[u8]), ParseError<&[u8]>> {
         brand_name(),
         take(4),
         many(brand_name()),
-    ).map(|(_, m, v, c)| {
-        MP4Box::Ftyp(FileType {
-            major_brand: m,
-            major_brand_version: v,
-            compatible_brands: c,
-        })
-    });
+    )
+        .map(|(_, m, v, c)| {
+            MP4Box::Ftyp(FileType {
+                major_brand: m,
+                major_brand_version: v,
+                compatible_brands: c,
+            })
+        });
 
     let mp4_box = take(4)
         .map(BigEndian::read_u32)
diff --git a/examples/async.rs b/examples/async.rs
index 5e9c8e2d..717a1646 100644
--- a/examples/async.rs
+++ b/examples/async.rs
@@ -23,7 +23,7 @@ use combine::parser::byte::digit;
 use combine::parser::range::{range, recognize, take};
 use combine::stream::easy;
 use combine::stream::{PartialStream, RangeStream, StreamErrorFor};
-use combine::{skip_many, Parser, skip_many1};
+use combine::{skip_many, skip_many1, Parser};
 
 pub struct LanguageServerDecoder {
     state: AnyPartialState,
@@ -58,9 +58,11 @@ where
 {
     let content_length = range(&b"Content-Length: "[..])
         .with(recognize(skip_many1(digit())).and_then(|digits: &[u8]| {
-            str::from_utf8(digits).unwrap().parse::<usize>()
-                                // Convert the error from `.parse` into an error combine understands
-                                .map_err(StreamErrorFor::<I>::other)
+            str::from_utf8(digits)
+                .unwrap()
+                .parse::<usize>()
+                // Convert the error from `.parse` into an error combine understands
+                .map_err(StreamErrorFor::<I>::other)
         }))
         .map(move |x| {
             content_length_parses.set(content_length_parses.get() + 1);
@@ -74,9 +76,10 @@ where
             skip_many(range(&b"\r\n"[..])),
             content_length,
             range(&b"\r\n\r\n"[..]).map(|_| ()),
-        ).then_partial(|&mut (_, message_length, _)| {
-            take(message_length).map(|bytes: &[u8]| bytes.to_owned())
-        }),
+        )
+            .then_partial(|&mut (_, message_length, _)| {
+                take(message_length).map(|bytes: &[u8]| bytes.to_owned())
+            }),
     )
 }
 
@@ -95,15 +98,18 @@ impl Decoder for LanguageServerDecoder {
             // expected if end of input is unexpectedly reached
             easy::Stream(PartialStream(&src[..])),
             &mut self.state,
-        ).map_err(|err| {
+        )
+        .map_err(|err| {
             // Since err contains references into `src` we must replace these before
             // we can return an error or call `split_to` to remove the input we
             // just consumed
-            let err = err.map_range(|r| {
-                str::from_utf8(r)
-                    .ok()
-                    .map_or_else(|| format!("{:?}", r), |s| s.to_string())
-            }).map_position(|p| p.translate_position(&src[..]));
+            let err = err
+                .map_range(|r| {
+                    str::from_utf8(r)
+                        .ok()
+                        .map_or_else(|| format!("{:?}", r), |s| s.to_string())
+                })
+                .map_position(|p| p.translate_position(&src[..]));
             format!("{}\nIn input: `{}`", err, str::from_utf8(src).unwrap())
         })?;
 
diff --git a/examples/date.rs b/examples/date.rs
index 46192f7c..039a228f 100644
--- a/examples/date.rs
+++ b/examples/date.rs
@@ -83,14 +83,15 @@ where
         choice([char('-'), char('+')]),
         two_digits(),
         optional(optional(char(':')).with(two_digits())),
-    ).map(|(sign, hour, minute)| {
-        let offset = hour * 60 + minute.unwrap_or(0);
-        if sign == '-' {
-            -offset
-        } else {
-            offset
-        }
-    });
+    )
+        .map(|(sign, hour, minute)| {
+            let offset = hour * 60 + minute.unwrap_or(0);
+            if sign == '-' {
+                -offset
+            } else {
+                offset
+            }
+        });
 
     utc.or(offset)
 }
@@ -108,14 +109,15 @@ where
         two_digits(),
         char('-'),
         two_digits(),
-    ).map(|(year, _, month, _, day)| {
-        // Its ok to just unwrap since we only parsed digits
-        Date {
-            year: year.parse().unwrap(),
-            month: month,
-            day: day,
-        }
-    })
+    )
+        .map(|(year, _, month, _, day)| {
+            // Its ok to just unwrap since we only parsed digits
+            Date {
+                year: year.parse().unwrap(),
+                month: month,
+                day: day,
+            }
+        })
 }
 
 /// Parses a time
@@ -132,15 +134,16 @@ where
         char(':'),
         two_digits(),
         time_zone(),
-    ).map(|(hour, _, minute, _, second, time_zone)| {
-        // Its ok to just unwrap since we only parsed digits
-        Time {
-            hour: hour,
-            minute: minute,
-            second: second,
-            time_zone: time_zone,
-        }
-    })
+    )
+        .map(|(hour, _, minute, _, second, time_zone)| {
+            // Its ok to just unwrap since we only parsed digits
+            Time {
+                hour: hour,
+                minute: minute,
+                second: second,
+                time_zone: time_zone,
+            }
+        })
 }
 
 /// Parses a date time according to ISO8601
@@ -223,6 +226,8 @@ where
 {
     let mut text = String::new();
     read.read_to_string(&mut text).map_err(Error::Io)?;
-    date_time().parse(State::new(&*text)).map_err(Error::Parse)?;
+    date_time()
+        .parse(State::new(&*text))
+        .map_err(Error::Parse)?;
     Ok(())
 }
diff --git a/examples/ini.rs b/examples/ini.rs
index 925b13f6..cb357e70 100644
--- a/examples/ini.rs
+++ b/examples/ini.rs
@@ -49,7 +49,8 @@ where
         many1(satisfy(|c| c != '=' && c != '[' && c != ';')),
         token('='),
         many1(satisfy(|c| c != '\n' && c != ';')),
-    ).map(|(key, _, value)| (key, value))
+    )
+        .map(|(key, _, value)| (key, value))
         .message("while parsing property")
 }
 
@@ -82,7 +83,8 @@ where
         between(token('['), token(']'), many(satisfy(|c| c != ']'))),
         whitespace(),
         properties(),
-    ).map(|(name, _, properties)| (name, properties))
+    )
+        .map(|(name, _, properties)| (name, properties))
         .message("while parsing section")
 }
 
diff --git a/src/error.rs b/src/error.rs
index e460fd15..32273ff6 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -14,9 +14,7 @@ use stream::StreamOnce;
 macro_rules! ctry {
     ($result:expr) => {
         match $result {
-            $crate::error::FastResult::ConsumedOk(x) => {
-                (x, $crate::error::Consumed::Consumed(()))
-            }
+            $crate::error::FastResult::ConsumedOk(x) => (x, $crate::error::Consumed::Consumed(())),
             $crate::error::FastResult::EmptyOk(x) => (x, $crate::error::Consumed::Empty(())),
             $crate::error::FastResult::ConsumedErr(err) => {
                 return $crate::error::FastResult::ConsumedErr(err.into())
diff --git a/src/lib.rs b/src/lib.rs
index 8eed8009..88bc6c71 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -788,17 +788,11 @@ pub mod combinator {
 }
 
 #[doc(hidden)]
-#[deprecated(
-    since = "3.0.0",
-    note = "Please use the `parser::char` module instead"
-)]
+#[deprecated(since = "3.0.0", note = "Please use the `parser::char` module instead")]
 pub use parser::char;
 
 #[doc(hidden)]
-#[deprecated(
-    since = "3.0.0",
-    note = "Please use the `parser::byte` module instead"
-)]
+#[deprecated(since = "3.0.0", note = "Please use the `parser::byte` module instead")]
 pub use parser::byte;
 
 #[doc(hidden)]
@@ -911,11 +905,9 @@ mod std_tests {
         I: Stream<Item = char>,
         I::Error: ParseError<I::Item, I::Range, I::Position>,
     {
-        let (s, input) = try!(
-            many1::<String, _>(digit())
-                .expected("integer")
-                .parse_stream(input)
-        );
+        let (s, input) = try!(many1::<String, _>(digit())
+            .expected("integer")
+            .parse_stream(input));
         let mut n = 0;
         for c in s.chars() {
             n = n * 10 + (c as i64 - '0' as i64);
diff --git a/src/parser/byte.rs b/src/parser/byte.rs
index c3048f0e..bbda743f 100644
--- a/src/parser/byte.rs
+++ b/src/parser/byte.rs
@@ -5,12 +5,12 @@ use lib::marker::PhantomData;
 
 use self::ascii::AsciiChar;
 
-use Parser;
 use combinator::{satisfy, skip_many, token, tokens, Expected, Satisfy, SkipMany, Token};
 use error::{ConsumedResult, Info, ParseError, StreamError, Tracked};
-use parser::ParseMode;
 use parser::sequence::With;
+use parser::ParseMode;
 use stream::{uncons_range, FullRangeStream, RangeStream, Stream, StreamOnce};
+use Parser;
 
 use error::FastResult::*;
 
@@ -727,9 +727,9 @@ pub mod num {
     #[cfg(test)]
     mod tests {
         use super::*;
-        use stream::IteratorStream;
         use stream::buffered::BufferedStream;
         use stream::state::State;
+        use stream::IteratorStream;
 
         #[test]
         fn no_rangestream() {
diff --git a/src/parser/char.rs b/src/parser/char.rs
index c6228100..35d4c79c 100644
--- a/src/parser/char.rs
+++ b/src/parser/char.rs
@@ -1,11 +1,11 @@
 //! Module containing parsers specialized on character streams.
 
-use Parser;
 use combinator::{satisfy, skip_many, token, tokens, Expected, Satisfy, SkipMany, Token};
 use error::{ConsumedResult, ParseError, Tracked};
 use lib::marker::PhantomData;
 use parser::sequence::With;
 use stream::{Stream, StreamOnce};
+use Parser;
 
 /// Parses a character and succeeds if the character is equal to `c`.
 ///
diff --git a/src/parser/choice.rs b/src/parser/choice.rs
index 5ab56e26..aaf09037 100644
--- a/src/parser/choice.rs
+++ b/src/parser/choice.rs
@@ -443,7 +443,8 @@ where
         None => I::Error::from_error(
             input.position(),
             StreamError::message_static_message("parser choice is empty"),
-        ).into(),
+        )
+        .into(),
         Some(mut prev_err) => {
             if prev_err.offset != ErrorOffset(1) {
                 let offset = prev_err.offset;
diff --git a/src/parser/function.rs b/src/parser/function.rs
index 4f1c8fe1..0c5fcfe3 100644
--- a/src/parser/function.rs
+++ b/src/parser/function.rs
@@ -2,9 +2,9 @@
 
 use lib::marker::PhantomData;
 
-use Parser;
 use error::{ConsumedResult, ParseResult};
 use stream::Stream;
+use Parser;
 
 impl<'a, I: Stream, O> Parser for FnMut(&mut I) -> ParseResult<O, I> + 'a {
     type Input = I;
diff --git a/src/parser/repeat.rs b/src/parser/repeat.rs
index 61c600d6..d985546d 100644
--- a/src/parser/repeat.rs
+++ b/src/parser/repeat.rs
@@ -14,49 +14,9 @@ use {ErrorOffset, Parser};
 
 use error::FastResult::*;
 
+parser!{
 #[derive(Copy, Clone)]
-pub struct Count<F, P> {
-    parser: P,
-    count: usize,
-    _marker: PhantomData<fn() -> F>,
-}
-
-impl<P, F> Parser for Count<F, P>
-where
-    P: Parser,
-    F: Extend<P::Output> + Default,
-{
-    type Input = P::Input;
-    type Output = F;
-    type PartialState = (usize, F, P::PartialState);
-
-    parse_mode!();
-    #[inline]
-    fn parse_mode_impl<M>(
-        &mut self,
-        mode: M,
-        input: &mut Self::Input,
-        state: &mut Self::PartialState,
-    ) -> ConsumedResult<Self::Output, Self::Input>
-    where
-        M: ParseMode,
-    {
-        let (ref mut count, ref mut elements, ref mut child_state) = *state;
-        let mut iter = self.parser.by_ref().partial_iter(mode, input, child_state);
-
-        elements.extend(
-            iter.by_ref()
-                .take(self.count - *count)
-                .inspect(|_| *count += 1),
-        );
-
-        iter.into_result_fast(elements)
-    }
-
-    fn add_error(&mut self, error: &mut Tracked<<Self::Input as StreamOnce>::Error>) {
-        self.parser.add_error(error)
-    }
-}
+pub struct Count;
 
 /// Parses `parser` from zero up to `count` times.
 ///
@@ -73,16 +33,15 @@ where
 /// # }
 /// ```
 #[inline(always)]
-pub fn count<F, P>(count: usize, parser: P) -> Count<F, P>
-where
+pub fn count[F, P](count: usize, parser: P)(P::Input) -> F
+where [
     P: Parser,
     F: Extend<P::Output> + Default,
+]
 {
-    Count {
-        parser,
-        count: count,
-        _marker: PhantomData,
-    }
+    count_min_max(0, *count, parser)
+}
+
 }
 
 parser!{
@@ -710,11 +669,10 @@ where
         let rest = match *parsed_one {
             Some(rest) => rest,
             None => {
-                let (first, rest) = ctry!(self.parser.parse_mode(
-                    mode,
-                    input,
-                    &mut child_state.B.state
-                ));
+                let (first, rest) =
+                    ctry!(self
+                        .parser
+                        .parse_mode(mode, input, &mut child_state.B.state));
                 elements.extend(Some(first));
                 rest
             }
@@ -896,11 +854,10 @@ where
         let rest = match *parsed_one {
             Some(rest) => rest,
             None => {
-                let (first, rest) = ctry!(self.parser.parse_mode(
-                    mode,
-                    input,
-                    &mut child_state.B.state
-                ));
+                let (first, rest) =
+                    ctry!(self
+                        .parser
+                        .parse_mode(mode, input, &mut child_state.B.state));
                 elements.extend(Some(first));
                 rest
             }
diff --git a/src/stream/mod.rs b/src/stream/mod.rs
index aeb44c8d..3e9c1262 100644
--- a/src/stream/mod.rs
+++ b/src/stream/mod.rs
@@ -139,7 +139,8 @@ impl<I> Stream for I
 where
     I: StreamOnce + Positioned + Resetable,
     I::Error: ParseError<I::Item, I::Range, I::Position>,
-{}
+{
+}
 
 #[inline]
 pub fn uncons<I>(input: &mut I) -> ConsumedResult<I::Item, I>


Test patch:
diff --git a/tests/async.rs b/tests/async.rs
index 0ac6eeb8..989acf95 100644
--- a/tests/async.rs
+++ b/tests/async.rs
@@ -138,7 +138,8 @@ where
         .map(|x| {
             println!("Decoded `{}`", x);
             x
-        }).collect()
+        })
+        .collect()
         .wait()
 }
 
diff --git a/tests/parser.rs b/tests/parser.rs
index c8b6174f..a3337e7a 100644
--- a/tests/parser.rs
+++ b/tests/parser.rs
@@ -6,7 +6,7 @@ use combine::parser::combinator::{attempt, no_partial, not_followed_by};
 use combine::parser::error::unexpected;
 use combine::parser::item::{any, eof, position, token, value, Token};
 use combine::parser::range::{self, range};
-use combine::parser::repeat::{count_min_max, many, sep_by, sep_end_by1, skip_until, take_until};
+use combine::parser::repeat::{count, count_min_max, many, sep_by, sep_end_by1, skip_until, take_until};
 use combine::Parser;
 
 #[test]
@@ -43,6 +43,8 @@ fn not_followed_by_does_not_consume_any_input() {
 #[cfg(feature = "std")]
 mod tests_std {
     use super::*;
+    use combine::parser::byte::{alpha_num, bytes};
+    use combine::parser::byte::num::be_u32;
     use combine::parser::char::{char, digit, letter};
     use combine::stream::easy::{Error, Errors, ParseError};
     use combine::stream::state::{SourcePosition, State};
@@ -542,7 +544,8 @@ mod tests_std {
         let mut parser = many::<Vec<_>, _>(position().and(choice((
             ident("aa").skip(string(";")),
             choice((ident("bb"), ident("cc"))),
-        )))).skip(string("."));
+        ))))
+        .skip(string("."));
 
         assert_eq!(
             parser.easy_parse("c").map_err(|err| err.errors),
@@ -567,4 +570,24 @@ mod tests_std {
             ]),
         );
     }
+
+    #[test]
+    fn test_nested_count_overflow() {
+        let key = || count::<Vec<_>, _>(64, alpha_num());
+        let value_bytes = || be_u32()
+            .then_partial(|&mut size| count::<Vec<_>, _>(size as usize, any()));
+        let value_messages = (be_u32(), be_u32())
+            .then_partial(|&mut (_body_size, message_count)| {
+                count::<Vec<_>, _>(message_count as usize, value_bytes())
+            });
+        let put = (bytes(b"PUT"), key())
+            .map(|(_, key)| key)
+            .and(value_messages);
+
+        let parser = || put.map(|(_, messages)| messages);
+
+        let command = &b"PUTkey\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x04\xDE\xAD\xBE\xEF\x00\x00\x00\x02\xBE\xEF"[..];
+        let result = parser().parse(command).unwrap();
+        assert_eq!(2, result.0.len());
+    }
 }