Repository: Geal/nom (rust)

Issue:
`fold_many1` (and some others) now requires `Clone` attribute
- Rust version : 1.36
- nom version : 5.0

`fold_many1` now requires init/return value to have `Clone`, which is annoying when it can be a complex type (and you don't want to clone it).

It was not the case with nom 4.

## Test case

```rust
struct TypeWithoutClone {
    pub a: u32,
}

named!(multi<&[u8], Vec<TypeWithoutClone>>,
    fold_many1!( tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
        acc.push( TypeWithoutClone{ a: 0 } );
        acc
    })
);
```

Nom 4 build: no error

Nom 5 build:
```
error[E0277]: the trait bound `TypeWithoutClone: std::clone::Clone` is not satisfied
  --> src/lib.rs:14:1
   |
14 | / named!(multi<&[u8], Vec<TypeWithoutClone>>,
15 | |     fold_many1!( tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
16 | |         acc.push( TypeWithoutClone{ a: 0 } );
17 | |         acc
18 | |     })
19 | | );
   | |__^ the trait `std::clone::Clone` is not implemented for `TypeWithoutClone`
   |
   = note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<TypeWithoutClone>`
   = note: required by `nom::multi::fold_many1c`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
```


Pull request description:
Remove Clone trait bound from fold parsers
<!--
Hello, and thank you for submitting a pull request to nom!

First, please note that, for family reasons, I have limited time to work on
nom, so following the advice here will make sure I will quickly understand
your work and be able to merge it early.
Second, if I don't get to work on your PR quickly, that does not mean I won't
include it later. Major version releases happen once a year, and a lot of
interesting work is merged for the occasion. So I will get back to you :)

## Prerequisites

Please provide the following information with this pull request:

- related issue number (I need some context to understand a PR with a lot of
code, except for documentation typos)
- a test case reproducing the issue. You can write it in [issues.rs](https://github.com/Geal/nom/blob/master/tests/issues.rs)
- if adding a new combinator, please add code documentation and some unit tests
in the same file. Also, please update the [combinator list](https://github.com/Geal/nom/blob/master/doc/choosing_a_combinator.md)

## Code style

This project follows a [code style](https://github.com/Geal/nom/blob/master/rustfmt.toml)
checked by [rustfmt][https://github.com/rust-lang-nursery/rustfmt].

Please avoid cosmetic fixes unrelated to the pull request. Keeping the changes
as small as possible increase your chances of getting this merged quickly.

## Rebasing

To make sure the changes will work properly once merged into the master branch
(which might have changed while you were working on your PR), please
[rebase your PR on master](https://git-scm.com/book/en/v2/Git-Branching-Rebasing).

## Squashing the commits

If the pull request include a lot of small commits used for testing, debugging,
or correcting previous work, it might be useful to
[squash the commits](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History)
to make the code easier to merge.
-->
This PR fixes #1008.

It removes the `R: Clone` bound for the initial acculumators of the `fold_*` family of nom parsers. This is accomplished by using a supplier function `FnMut() -> R` that returns a new accumulator instead of needing the parser to clone a new one.

This allows `fold_*` to be used even if the resulting type is not cloneable. Cloning the accumulator is still possible if desired but must be done by the supplier function.

This is a breaking change but migration is relatively easy as the intial accumulator can simply be wrapped in a closure/be replaced by a function reference.

Patch:
diff --git a/benches/arithmetic.rs b/benches/arithmetic.rs
index d4d7647..6912f41 100644
--- a/benches/arithmetic.rs
+++ b/benches/arithmetic.rs
@@ -1,7 +1,5 @@
-extern crate nom;
 #[macro_use]
 extern crate criterion;
-extern crate jemallocator;
 
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
diff --git a/benches/http.rs b/benches/http.rs
index c61f173..4145d4a 100644
--- a/benches/http.rs
+++ b/benches/http.rs
@@ -1,8 +1,5 @@
 #![cfg_attr(rustfmt, rustfmt_skip)]
 
-extern crate criterion;
-extern crate jemallocator;
-
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
 
@@ -70,7 +67,7 @@ fn is_version(c: u8) -> bool {
   c >= b'0' && c <= b'9' || c == b'.'
 }
 
-fn request_line(input: &[u8]) -> IResult<&[u8], Request> {
+fn request_line(input: &[u8]) -> IResult<&[u8], Request<'_>> {
   let (input, method) = take_while1(is_token)(input)?;
   let (input, _) = take_while1(is_space)(input)?;
   let (input, uri) = take_while1(is_not_space)(input)?;
@@ -96,7 +93,7 @@ fn message_header_value(input: &[u8]) -> IResult<&[u8], &[u8]> {
   Ok((input, data))
 }
 
-fn message_header(input: &[u8]) -> IResult<&[u8], Header> {
+fn message_header(input: &[u8]) -> IResult<&[u8], Header<'_>> {
   let (input, name) = take_while1(is_token)(input)?;
   let (input, _) = char(':')(input)?;
   let (input, value) = many1(message_header_value)(input)?;
@@ -104,7 +101,7 @@ fn message_header(input: &[u8]) -> IResult<&[u8], Header> {
   Ok((input, Header{ name, value }))
 }
 
-fn request(input: &[u8]) -> IResult<&[u8], (Request, Vec<Header>)> {
+fn request(input: &[u8]) -> IResult<&[u8], (Request<'_>, Vec<Header<'_>>)> {
   let (input, req) = request_line(input)?;
   let (input, h) = many1(message_header)(input)?;
   let (input, _) = line_ending(input)?;
@@ -113,7 +110,7 @@ fn request(input: &[u8]) -> IResult<&[u8], (Request, Vec<Header>)> {
 }
 
 
-fn parse(data: &[u8]) -> Option<Vec<(Request, Vec<Header>)>> {
+fn parse(data: &[u8]) -> Option<Vec<(Request<'_>, Vec<Header<'_>>)>> {
   let mut buf = &data[..];
   let mut v = Vec::new();
   loop {
diff --git a/benches/ini.rs b/benches/ini.rs
index 160eee9..b2f651b 100644
--- a/benches/ini.rs
+++ b/benches/ini.rs
@@ -1,6 +1,3 @@
-extern crate criterion;
-extern crate jemallocator;
-
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
 
diff --git a/benches/ini_str.rs b/benches/ini_str.rs
index 044f679..7df6219 100644
--- a/benches/ini_str.rs
+++ b/benches/ini_str.rs
@@ -1,6 +1,3 @@
-extern crate criterion;
-extern crate jemallocator;
-
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
 
diff --git a/benches/json.rs b/benches/json.rs
index 8579594..f2df030 100644
--- a/benches/json.rs
+++ b/benches/json.rs
@@ -1,7 +1,5 @@
-extern crate nom;
 #[macro_use]
 extern crate criterion;
-extern crate jemallocator;
 
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
diff --git a/benches/number.rs b/benches/number.rs
index 16f7400..802ad4d 100644
--- a/benches/number.rs
+++ b/benches/number.rs
@@ -1,7 +1,5 @@
-extern crate nom;
 #[macro_use]
 extern crate criterion;
-extern crate jemallocator;
 
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
diff --git a/examples/json.rs b/examples/json.rs
index 09ff21a..f9e9a57 100644
--- a/examples/json.rs
+++ b/examples/json.rs
@@ -1,8 +1,5 @@
 #![cfg(feature = "alloc")]
 
-extern crate jemallocator;
-extern crate nom;
-
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
 
diff --git a/examples/s_expression.rs b/examples/s_expression.rs
index 77b2cc6..7030970 100644
--- a/examples/s_expression.rs
+++ b/examples/s_expression.rs
@@ -4,9 +4,6 @@
 
 #![cfg(feature = "alloc")]
 
-extern crate jemallocator;
-extern crate nom;
-
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
 
diff --git a/examples/string.rs b/examples/string.rs
index 73c5d3e..f89d3d1 100644
--- a/examples/string.rs
+++ b/examples/string.rs
@@ -11,9 +11,6 @@
 
 #![cfg(feature = "alloc")]
 
-extern crate jemallocator;
-extern crate nom;
-
 #[global_allocator]
 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
 
@@ -148,7 +145,7 @@ where
     // Our parser function– parses a single string fragment
     parse_fragment,
     // Our init value, an empty string
-    String::new(),
+    String::new,
     // Our folding function. For each fragment, append the fragment to the
     // string.
     |mut string, fragment| {
diff --git a/src/bytes/complete.rs b/src/bytes/complete.rs
index 892edc4..ef5340e 100644
--- a/src/bytes/complete.rs
+++ b/src/bytes/complete.rs
@@ -448,6 +448,44 @@ where
   }
 }
 
+/// Returns the non empty input slice up to the first occurrence of the pattern.
+///
+/// It doesn't consume the pattern. It will return `Err(Err::Error((_, ErrorKind::TakeUntil)))`
+/// if the pattern wasn't met.
+/// # Example
+/// ```rust
+/// # #[macro_use] extern crate nom;
+/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
+/// use nom::bytes::complete::take_until1;
+///
+/// fn until_eof(s: &str) -> IResult<&str, &str> {
+///   take_until1("eof")(s)
+/// }
+///
+/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
+/// assert_eq!(until_eof("hello, world"), Err(Err::Error(Error::new("hello, world", ErrorKind::TakeUntil))));
+/// assert_eq!(until_eof(""), Err(Err::Error(Error::new("", ErrorKind::TakeUntil))));
+/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
+/// assert_eq!(until_eof("eof"), Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil))));
+/// ```
+pub fn take_until1<T, Input, Error: ParseError<Input>>(
+  tag: T,
+) -> impl Fn(Input) -> IResult<Input, Input, Error>
+where
+  Input: InputTake + FindSubstring<T>,
+  T: InputLength + Clone,
+{
+  move |i: Input| {
+    let t = tag.clone();
+    let res: IResult<_, _, Error> = match i.find_substring(t) {
+      None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
+      Some(0) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
+      Some(index) => Ok(i.take_split(index)),
+    };
+    res
+  }
+}
+
 /// Matches a byte string with escaped characters.
 ///
 /// * The first argument matches the normal characters (it must not accept the control character)
diff --git a/src/bytes/streaming.rs b/src/bytes/streaming.rs
index a166545..a703d56 100644
--- a/src/bytes/streaming.rs
+++ b/src/bytes/streaming.rs
@@ -472,6 +472,51 @@ where
   }
 }
 
+/// Returns the non empty input slice up to the first occurrence of the pattern.
+///
+/// It doesn't consume the pattern.
+///
+/// # Streaming Specific
+/// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't
+/// contain the pattern or if the input is smaller than the pattern.
+/// # Example
+/// ```rust
+/// # #[macro_use] extern crate nom;
+/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
+/// use nom::bytes::streaming::take_until1;
+///
+/// fn until_eof(s: &str) -> IResult<&str, &str> {
+///   take_until1("eof")(s)
+/// }
+///
+/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
+/// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown)));
+/// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown)));
+/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
+/// assert_eq!(until_eof("eof"),  Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil))));
+/// ```
+pub fn take_until1<T, Input, Error: ParseError<Input>>(
+  tag: T,
+) -> impl Fn(Input) -> IResult<Input, Input, Error>
+where
+  Input: InputTake + InputLength + FindSubstring<T>,
+  T: Clone,
+{
+  move |i: Input| {
+    let t = tag.clone();
+
+    let res: IResult<_, _, Error> = match i.find_substring(t) {
+      None => Err(Err::Incomplete(Needed::Unknown)),
+      Some(0) => Err(Err::Error(Error::from_error_kind(
+          i,
+          ErrorKind::TakeUntil,
+      ))),
+      Some(index) => Ok(i.take_split(index)),
+    };
+    res
+  }
+}
+
 /// Matches a byte string with escaped characters.
 ///
 /// * The first argument matches the normal characters (it must not accept the control character)
diff --git a/src/internal.rs b/src/internal.rs
index d3f62dd..7712925 100644
--- a/src/internal.rs
+++ b/src/internal.rs
@@ -176,7 +176,7 @@ impl<E> fmt::Display for Err<E>
 where
   E: fmt::Debug,
 {
-  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     match self {
       Err::Incomplete(Needed::Size(u)) => write!(f, "Parsing requires {} bytes/chars", u),
       Err::Incomplete(Needed::Unknown) => write!(f, "Parsing requires more data"),
diff --git a/src/lib.rs b/src/lib.rs
index 0bbf88c..a0a5a09 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -386,9 +386,7 @@
 extern crate alloc;
 #[cfg(doctest)]
 extern crate doc_comment;
-#[cfg(feature = "lexical")]
-extern crate lexical_core;
-extern crate memchr;
+
 #[cfg(nightly)]
 extern crate test;
 
diff --git a/src/multi/mod.rs b/src/multi/mod.rs
index 99061d5..b00568c 100644
--- a/src/multi/mod.rs
+++ b/src/multi/mod.rs
@@ -596,7 +596,7 @@ where
 /// the results using a given function and initial value.
 /// # Arguments
 /// * `f` The parser to apply.
-/// * `init` The initial value.
+/// * `init` A function returning the initial value.
 /// * `g` The function that combines a result of `f` with
 ///       the current accumulator.
 /// ```rust
@@ -608,7 +608,7 @@ where
 /// fn parser(s: &str) -> IResult<&str, Vec<&str>> {
 ///   fold_many0(
 ///     tag("abc"),
-///     Vec::new(),
+///     Vec::new,
 ///     |mut acc: Vec<_>, item| {
 ///       acc.push(item);
 ///       acc
@@ -621,20 +621,20 @@ where
 /// assert_eq!(parser("123123"), Ok(("123123", vec![])));
 /// assert_eq!(parser(""), Ok(("", vec![])));
 /// ```
-pub fn fold_many0<I, O, E, F, G, R>(
+pub fn fold_many0<I, O, E, F, G, H, R>(
   mut f: F,
-  init: R,
+  mut init: H,
   mut g: G,
 ) -> impl FnMut(I) -> IResult<I, R, E>
 where
   I: Clone + PartialEq,
   F: Parser<I, O, E>,
   G: FnMut(R, O) -> R,
+  H: FnMut() -> R,
   E: ParseError<I>,
-  R: Clone,
 {
   move |i: I| {
-    let mut res = init.clone();
+    let mut res = init();
     let mut input = i;
 
     loop {
@@ -666,7 +666,7 @@ where
 /// once.
 /// # Arguments
 /// * `f` The parser to apply.
-/// * `init` The initial value.
+/// * `init` A function returning the initial value.
 /// * `g` The function that combines a result of `f` with
 ///       the current accumulator.
 /// ```rust
@@ -678,7 +678,7 @@ where
 /// fn parser(s: &str) -> IResult<&str, Vec<&str>> {
 ///   fold_many1(
 ///     tag("abc"),
-///     Vec::new(),
+///     Vec::new,
 ///     |mut acc: Vec<_>, item| {
 ///       acc.push(item);
 ///       acc
@@ -691,21 +691,21 @@ where
 /// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Many1))));
 /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Many1))));
 /// ```
-pub fn fold_many1<I, O, E, F, G, R>(
+pub fn fold_many1<I, O, E, F, G, H, R>(
   mut f: F,
-  init: R,
+  mut init: H,
   mut g: G,
 ) -> impl FnMut(I) -> IResult<I, R, E>
 where
   I: Clone + PartialEq,
   F: Parser<I, O, E>,
   G: FnMut(R, O) -> R,
+  H: FnMut() -> R,
   E: ParseError<I>,
-  R: Clone,
 {
   move |i: I| {
     let _i = i.clone();
-    let init = init.clone();
+    let init = init();
     match f.parse(_i) {
       Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))),
       Err(e) => Err(e),
@@ -745,7 +745,7 @@ where
 /// * `m` The minimum number of iterations.
 /// * `n` The maximum number of iterations.
 /// * `f` The parser to apply.
-/// * `init` The initial value.
+/// * `init` A function returning the initial value.
 /// * `g` The function that combines a result of `f` with
 ///       the current accumulator.
 /// ```rust
@@ -759,7 +759,7 @@ where
 ///     0,
 ///     2,
 ///     tag("abc"),
-///     Vec::new(),
+///     Vec::new,
 ///     |mut acc: Vec<_>, item| {
 ///       acc.push(item);
 ///       acc
@@ -773,22 +773,22 @@ where
 /// assert_eq!(parser(""), Ok(("", vec![])));
 /// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));
 /// ```
-pub fn fold_many_m_n<I, O, E, F, G, R>(
+pub fn fold_many_m_n<I, O, E, F, G, H, R>(
   min: usize,
   max: usize,
   mut parse: F,
-  init: R,
+  mut init: H,
   mut fold: G,
 ) -> impl FnMut(I) -> IResult<I, R, E>
 where
   I: Clone + PartialEq,
   F: Parser<I, O, E>,
   G: FnMut(R, O) -> R,
+  H: FnMut() -> R,
   E: ParseError<I>,
-  R: Clone,
 {
   move |mut input: I| {
-    let mut acc = init.clone();
+    let mut acc = init();
     for count in 0..max {
       match parse.parse(input.clone()) {
         Ok((tail, value)) => {


Test patch:
diff --git a/src/bytes/tests.rs b/src/bytes/tests.rs
index d6ad7e5..159c4b4 100644
--- a/src/bytes/tests.rs
+++ b/src/bytes/tests.rs
@@ -1,22 +1,18 @@
-#[cfg(feature = "alloc")]
-use crate::branch::alt;
-#[cfg(feature = "alloc")]
-use crate::bytes::complete::tag;
-#[cfg(feature = "alloc")]
-use crate::bytes::complete::{escaped, escaped_transform};
 use crate::character::is_alphabetic;
 use crate::character::streaming::{
   alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit,
   multispace1 as multispace, oct_digit1 as oct_digit, space1 as space,
 };
-#[cfg(feature = "alloc")]
-use crate::combinator::{map, value};
 use crate::error::ErrorKind;
 use crate::internal::{Err, IResult, Needed};
 #[cfg(feature = "alloc")]
-use crate::lib::std::string::String;
-#[cfg(feature = "alloc")]
-use crate::lib::std::vec::Vec;
+use crate::{
+  branch::alt,
+  bytes::complete::{escaped, escaped_transform, tag},
+  combinator::{map, value},
+  lib::std::string::String,
+  lib::std::vec::Vec,
+};
 
 #[test]
 fn is_a() {
diff --git a/src/multi/tests.rs b/src/multi/tests.rs
index 0ce46d2..2a96f84 100644
--- a/src/multi/tests.rs
+++ b/src/multi/tests.rs
@@ -422,10 +422,10 @@ fn fold_many0_test() {
     acc
   }
   fn multi(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
-    fold_many0(tag("abcd"), Vec::new(), fold_into_vec)(i)
+    fold_many0(tag("abcd"), Vec::new, fold_into_vec)(i)
   }
   fn multi_empty(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
-    fold_many0(tag(""), Vec::new(), fold_into_vec)(i)
+    fold_many0(tag(""), Vec::new, fold_into_vec)(i)
   }
 
   assert_eq!(multi(&b"abcdef"[..]), Ok((&b"ef"[..], vec![&b"abcd"[..]])));
@@ -454,7 +454,7 @@ fn fold_many1_test() {
     acc
   }
   fn multi(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
-    fold_many1(tag("abcd"), Vec::new(), fold_into_vec)(i)
+    fold_many1(tag("abcd"), Vec::new, fold_into_vec)(i)
   }
 
   let a = &b"abcdef"[..];
@@ -481,7 +481,7 @@ fn fold_many_m_n_test() {
     acc
   }
   fn multi(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
-    fold_many_m_n(2, 4, tag("Abcd"), Vec::new(), fold_into_vec)(i)
+    fold_many_m_n(2, 4, tag("Abcd"), Vec::new, fold_into_vec)(i)
   }
 
   let a = &b"Abcdef"[..];
diff --git a/tests/arithmetic.rs b/tests/arithmetic.rs
index 393c7e7..5b627a9 100644
--- a/tests/arithmetic.rs
+++ b/tests/arithmetic.rs
@@ -1,5 +1,3 @@
-extern crate nom;
-
 use nom::{
   branch::alt,
   bytes::complete::tag,
@@ -39,7 +37,7 @@ fn term(i: &str) -> IResult<&str, i64> {
 
   fold_many0(
     pair(alt((char('*'), char('/'))), factor),
-    init,
+    move || init,
     |acc, (op, val): (char, i64)| {
       if op == '*' {
         acc * val
@@ -55,7 +53,7 @@ fn expr(i: &str) -> IResult<&str, i64> {
 
   fold_many0(
     pair(alt((char('+'), char('-'))), term),
-    init,
+    move || init,
     |acc, (op, val): (char, i64)| {
       if op == '+' {
         acc + val
diff --git a/tests/arithmetic_ast.rs b/tests/arithmetic_ast.rs
index 9852f6c..ca15110 100644
--- a/tests/arithmetic_ast.rs
+++ b/tests/arithmetic_ast.rs
@@ -1,5 +1,3 @@
-extern crate nom;
-
 use std::fmt;
 use std::fmt::{Debug, Display, Formatter};
 
@@ -33,7 +31,7 @@ pub enum Oper {
 }
 
 impl Display for Expr {
-  fn fmt(&self, format: &mut Formatter) -> fmt::Result {
+  fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
     use self::Expr::*;
     match *self {
       Value(val) => write!(format, "{}", val),
@@ -47,7 +45,7 @@ impl Display for Expr {
 }
 
 impl Debug for Expr {
-  fn fmt(&self, format: &mut Formatter) -> fmt::Result {
+  fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
     use self::Expr::*;
     match *self {
       Value(val) => write!(format, "{}", val),
diff --git a/tests/css.rs b/tests/css.rs
index 5b1e79a..ad3d72b 100644
--- a/tests/css.rs
+++ b/tests/css.rs
@@ -1,5 +1,3 @@
-extern crate nom;
-
 use nom::bytes::complete::{tag, take_while_m_n};
 use nom::combinator::map_res;
 use nom::sequence::tuple;
diff --git a/tests/fnmut.rs b/tests/fnmut.rs
index 1314967..b1486cb 100644
--- a/tests/fnmut.rs
+++ b/tests/fnmut.rs
@@ -1,5 +1,3 @@
-extern crate nom;
-
 use nom::{
   bytes::complete::tag,
   multi::{many0, many0_count},
diff --git a/tests/json.rs b/tests/json.rs
index 5b30c74..e8a06fd 100644
--- a/tests/json.rs
+++ b/tests/json.rs
@@ -1,5 +1,4 @@
 #![cfg(feature = "alloc")]
-extern crate nom;
 
 use nom::{
   branch::alt,
@@ -83,7 +82,7 @@ fn character(input: &str) -> IResult<&str, char> {
 fn string(input: &str) -> IResult<&str, String> {
   delimited(
     char('"'),
-    fold_many0(character, String::new(), |mut string, c| {
+    fold_many0(character, String::new, |mut string, c| {
       string.push(c);
       string
     }),
diff --git a/tests/mp4.rs b/tests/mp4.rs
index ff60b3d..852bf29 100644
--- a/tests/mp4.rs
+++ b/tests/mp4.rs
@@ -247,7 +247,7 @@ fn brand_name(input: &[u8]) -> IResult<&[u8], &str> {
   map_res(take(4_usize), str::from_utf8)(input)
 }
 
-fn filetype_parser(input: &[u8]) -> IResult<&[u8], FileType> {
+fn filetype_parser(input: &[u8]) -> IResult<&[u8], FileType<'_>> {
   let (i, name) = brand_name(input)?;
   let (i, version) = take(4_usize)(i)?;
   let (i, brands) = many0(brand_name)(i)?;
diff --git a/tests/multiline.rs b/tests/multiline.rs
index fa8cbf4..7378b9e 100644
--- a/tests/multiline.rs
+++ b/tests/multiline.rs
@@ -1,5 +1,3 @@
-extern crate nom;
-
 use nom::{
   character::complete::{alphanumeric1 as alphanumeric, line_ending as eol},
   multi::many0,
diff --git a/tests/reborrow_fold.rs b/tests/reborrow_fold.rs
index d356176..486617e 100644
--- a/tests/reborrow_fold.rs
+++ b/tests/reborrow_fold.rs
@@ -23,7 +23,7 @@ fn atom<'a>(_tomb: &'a mut ()) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], Stri
 fn list<'a>(i: &'a [u8], tomb: &'a mut ()) -> IResult<&'a [u8], String> {
   delimited(
     char('('),
-    fold_many0(atom(tomb), String::new(), |acc: String, next: String| {
+    fold_many0(atom(tomb), String::new, |acc: String, next: String| {
       acc + next.as_str()
     }),
     char(')'),