Repository: toml-rs/toml (language: rust)

Issue:
NLL future-compat warning on nightly
Latest nightly has [enabled the NLL migration mode for Edition 2015 code](https://github.com/rust-lang/rust/pull/59114), this is triggering a couple of warnings (that will become errors in the future) in `toml_edit` 0.1.3:

```
warning[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
  --> /home/travis/.cargo/registry/src/github.com-1ecc6299db9ec823/toml_edit-0.1.3/src/index.rs:55:65
   |
44 |       fn index_or_insert<'v>(&self, v: &'v mut Item) -> &'v mut Item {
   |                          -- lifetime `'v` defined here
45 | /         match *v {
46 | |             Item::ArrayOfTables(ref mut vec) => {
47 | |                 vec.values.get_mut(*self).expect("index out of bounds")
48 | |             }
49 | |             Item::Value(ref mut a) if a.is_array() => a
   | |                         --------- mutable borrow occurs here
...  |
55 | |             _ => panic!("cannot access index {} in {:?}", self, v),
   | |                                                                 ^ immutable borrow occurs here
56 | |         }
   | |_________- returning this value requires that `v.0` is borrowed for `'v`
   |
   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future

warning[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
  --> /home/travis/.cargo/registry/src/github.com-1ecc6299db9ec823/toml_edit-0.1.3/src/index.rs:88:63
   |
70 |       fn index_or_insert<'v>(&self, v: &'v mut Item) -> &'v mut Item {
   |                          -- lifetime `'v` defined here
...
77 | /         match *v {
78 | |             Item::Table(ref mut t) => t.entry(self).or_insert(Item::None),
79 | |             Item::Value(ref mut v) if v.is_inline_table() => {
   | |                         --------- mutable borrow occurs here
80 | |                 &mut v
...  |
88 | |             _ => panic!("cannot access key {} in {:?}", self, v),
   | |                                                               ^ immutable borrow occurs here
89 | |         }
   | |_________- returning this value requires that `v.0` is borrowed for `'v`
   |
   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
```


Discussion / hints:

Fix patch:
diff --git a/src/formatted.rs b/src/formatted.rs
index bbcee534..5f438867 100644
--- a/src/formatted.rs
+++ b/src/formatted.rs
@@ -11,7 +11,7 @@ pub(crate) fn decorate_array(array: &mut Array) {
     for (i, val) in array
         .values
         .iter_mut()
-        .filter_map(|i| i.as_value_mut())
+        .filter_map(Item::as_value_mut)
         .enumerate()
     {
         // [value1, value2, value3]
diff --git a/src/index.rs b/src/index.rs
index 7e2f663b..8874fb48 100644
--- a/src/index.rs
+++ b/src/index.rs
@@ -48,7 +48,7 @@ impl Index for usize {
                 .values
                 .get_mut(*self)
                 .expect("index out of bounds"),
-            _ => panic!("cannot access index {} in {:?}", self, v),
+            _ => panic!("cannot access index {}", self),
         }
     }
 }
@@ -81,7 +81,7 @@ impl Index for str {
                     .or_insert(to_table_key_value(self, Item::None))
                     .value
             }
-            _ => panic!("cannot access key {} in {:?}", self, v),
+            _ => panic!("cannot access key {}", self),
         }
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index dd6dc6bb..f090d3e8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -72,7 +72,6 @@
 //!
 //! [test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84
 extern crate chrono;
-#[macro_use]
 extern crate combine;
 extern crate linked_hash_map;
 
diff --git a/src/parser/array.rs b/src/parser/array.rs
index 9cc9a579..db953270 100644
--- a/src/parser/array.rs
+++ b/src/parser/array.rs
@@ -60,7 +60,7 @@ parse!(array_values() -> (Vec<Value>, bool, &'a str), {
 });
 
 parse!(array_value() -> Value, {
-    try((
+    attempt((
         ws_comment_newline(),
         value(),
         ws_comment_newline(),
diff --git a/src/parser/datetime.rs b/src/parser/datetime.rs
index 4584e33b..370d7932 100644
--- a/src/parser/datetime.rs
+++ b/src/parser/datetime.rs
@@ -51,7 +51,7 @@ parse!(date_time() -> value::DateTime, {
             }),
         // Local Time
         recognize(partial_time())
-            .and_then(|s: &str| s.parse::<chrono::NaiveTime>())
+            .and_then(str::parse)
             .message("While parsing a Time")
             .map(value::DateTime::LocalTime)
     )
@@ -64,7 +64,7 @@ parse!(date_time() -> value::DateTime, {
 // date-mday      = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31 based on month/year
 parse!(full_date() -> &'a str, {
     recognize((
-        try((repeat(4, digit()), char('-'))),
+        attempt((repeat(4, digit()), char('-'))),
         repeat(2, digit()),
         char('-'),
         repeat(2, digit()),
@@ -78,24 +78,24 @@ parse!(full_date() -> &'a str, {
 // time-secfrac   = "." 1*DIGIT
 parse!(partial_time() -> (), {
     (
-        try((
+        attempt((
             repeat(2, digit()),
             char(':'),
         )),
         repeat(2, digit()),
         char(':'),
         repeat(2, digit()),
-        optional(try(char('.')).and(skip_many1(digit()))),
+        optional(attempt(char('.')).and(skip_many1(digit()))),
     ).map(|_| ())
 });
 
 // time-offset    = "Z" / time-numoffset
 // time-numoffset = ( "+" / "-" ) time-hour ":" time-minute
 parse!(time_offset() -> (), {
-    try(char('Z')).map(|_| ())
+    attempt(char('Z')).map(|_| ())
         .or(
             (
-                try(choice([char('+'), char('-')])),
+                attempt(choice([char('+'), char('-')])),
                 repeat(2, digit()),
                 char(':'),
                 repeat(2, digit()),
diff --git a/src/parser/inline_table.rs b/src/parser/inline_table.rs
index a17e3f6d..32b942ec 100644
--- a/src/parser/inline_table.rs
+++ b/src/parser/inline_table.rs
@@ -62,7 +62,7 @@ parse!(inline_table_keyvals() -> (&'a str, Vec<(InternalString, TableKeyValue)>)
 
 parse!(keyval() -> (InternalString, TableKeyValue), {
     (
-        try((ws(), key(), ws())),
+        attempt((ws(), key(), ws())),
         char(KEYVAL_SEP),
         (ws(), value(), ws()),
     ).map(|(k, _, v)| {
diff --git a/src/parser/numbers.rs b/src/parser/numbers.rs
index f59f613f..c9107118 100644
--- a/src/parser/numbers.rs
+++ b/src/parser/numbers.rs
@@ -68,7 +68,7 @@ parse!(exp() -> &'a str, {
 // float = integer ( frac / ( frac exp ) / exp )
 parse!(parse_float() -> &'a str, {
     recognize((
-        try((parse_integer(), look_ahead(one_of("eE.".chars())))),
+        attempt((parse_integer(), look_ahead(one_of("eE.".chars())))),
         choice((
             exp(),
             (
diff --git a/src/parser/strings.rs b/src/parser/strings.rs
index 7c453824..028b010b 100644
--- a/src/parser/strings.rs
+++ b/src/parser/strings.rs
@@ -127,7 +127,7 @@ parse!(ml_basic_char() -> char, {
 // (including newlines) up to the next non-whitespace
 // character or closing delimiter.
 parse!(try_eat_escaped_newline() -> (), {
-    skip_many(try((
+    skip_many(attempt((
         char(ESCAPE),
         ws(),
         ws_newlines(),
diff --git a/src/parser/table.rs b/src/parser/table.rs
index 40adbe87..194d6162 100644
--- a/src/parser/table.rs
+++ b/src/parser/table.rs
@@ -84,7 +84,7 @@ parser! {
 
 pub(crate) fn duplicate_key(path: &[Key], i: usize) -> CustomError {
     assert!(i < path.len());
-    let header: Vec<&str> = path[..i].iter().map(|key| key.raw()).collect();
+    let header: Vec<&str> = path[..i].iter().map(Key::raw).collect();
     CustomError::DuplicateKey {
         key: path[i].raw().into(),
         table: format!("[{}]", header.join(".")),
diff --git a/src/parser/trivia.rs b/src/parser/trivia.rs
index 2b5d0424..7434d580 100644
--- a/src/parser/trivia.rs
+++ b/src/parser/trivia.rs
@@ -33,7 +33,7 @@ const COMMENT_START_SYMBOL: char = '#';
 // comment = comment-start-symbol *non-eol
 parse!(comment() -> &'a str, {
     recognize((
-        try(char(COMMENT_START_SYMBOL)),
+        attempt(char(COMMENT_START_SYMBOL)),
         take_while(is_non_eol),
     ))
 });
diff --git a/src/table.rs b/src/table.rs
index 7cd9cf6e..1c55d11e 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -260,7 +260,7 @@ impl Item {
 
     /// Casts `self` to integer.
     pub fn as_integer(&self) -> Option<i64> {
-        self.as_value().and_then(|v| v.as_integer())
+        self.as_value().and_then(Value::as_integer)
     }
 
     /// Returns true iff `self` is an integer.
@@ -270,7 +270,7 @@ impl Item {
 
     /// Casts `self` to float.
     pub fn as_float(&self) -> Option<f64> {
-        self.as_value().and_then(|v| v.as_float())
+        self.as_value().and_then(Value::as_float)
     }
 
     /// Returns true iff `self` is a float.
@@ -280,7 +280,7 @@ impl Item {
 
     /// Casts `self` to boolean.
     pub fn as_bool(&self) -> Option<bool> {
-        self.as_value().and_then(|v| v.as_bool())
+        self.as_value().and_then(Value::as_bool)
     }
 
     /// Returns true iff `self` is a boolean.
@@ -290,7 +290,7 @@ impl Item {
 
     /// Casts `self` to str.
     pub fn as_str(&self) -> Option<&str> {
-        self.as_value().and_then(|v| v.as_str())
+        self.as_value().and_then(Value::as_str)
     }
 
     /// Returns true iff `self` is a string.
@@ -300,7 +300,7 @@ impl Item {
 
     /// Casts `self` to date-time.
     pub fn as_date_time(&self) -> Option<&DateTime> {
-        self.as_value().and_then(|v| v.as_date_time())
+        self.as_value().and_then(Value::as_date_time)
     }
 
     /// Returns true iff `self` is a date-time.
@@ -310,12 +310,12 @@ impl Item {
 
     /// Casts `self` to array.
     pub fn as_array(&self) -> Option<&Array> {
-        self.as_value().and_then(|v| v.as_array())
+        self.as_value().and_then(Value::as_array)
     }
 
     /// Casts `self` to mutable array.
     pub fn as_array_mut(&mut self) -> Option<&mut Array> {
-        self.as_value_mut().and_then(|v| v.as_array_mut())
+        self.as_value_mut().and_then(Value::as_array_mut)
     }
 
     /// Returns true iff `self` is an array.
@@ -325,12 +325,12 @@ impl Item {
 
     /// Casts `self` to inline table.
     pub fn as_inline_table(&self) -> Option<&InlineTable> {
-        self.as_value().and_then(|v| v.as_inline_table())
+        self.as_value().and_then(Value::as_inline_table)
     }
 
     /// Casts `self` to mutable inline table.
     pub fn as_inline_table_mut(&mut self) -> Option<&mut InlineTable> {
-        self.as_value_mut().and_then(|v| v.as_inline_table_mut())
+        self.as_value_mut().and_then(Value::as_inline_table_mut)
     }
 
     /// Returns true iff `self` is an inline table.
diff --git a/src/value.rs b/src/value.rs
index f6b2feb1..f4ed11a6 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -96,7 +96,7 @@ impl Array {
 
     /// Returns an iterator over all values.
     pub fn iter(&self) -> ArrayIter {
-        Box::new(self.values.iter().filter_map(|i| i.as_value()))
+        Box::new(self.values.iter().filter_map(Item::as_value))
     }
 
     /// Appends a new value.


Test patch: