From 8fc15b5ac4475a4f29277eef3250e78b66e5f222 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 14 Aug 2015 14:35:17 -0400 Subject: [PATCH] Update tendril to avoid double borrow. This double borrow is detected by the latest Nightly builds. --- src/fmt.rs | 2 +- src/tendril.rs | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/fmt.rs b/src/fmt.rs index b9c5881..feb49f5 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -156,7 +156,7 @@ pub unsafe trait SubsetOf: Format /// Indicates a format which corresponds to a Rust slice type, /// representing exactly the same invariants. -pub unsafe trait SliceFormat: Format { +pub unsafe trait SliceFormat: Format + Sized { type Slice: ?Sized + Slice; } diff --git a/src/tendril.rs b/src/tendril.rs index 7cb7ce1..b007f36 100644 --- a/src/tendril.rs +++ b/src/tendril.rs @@ -1178,15 +1178,35 @@ impl Tendril #[inline] pub fn pop_front_char<'a>(&'a mut self) -> Option { unsafe { - let mut it = F::char_indices(self.as_byte_slice()); - it.next().map(|(_, c)| { - if let Some((n, _)) = it.next() { - self.unsafe_pop_front(n as u32); - } else { - self.clear(); + let next_char; // first char in iterator + let mut skip = 0; // number of bytes to skip, or 0 to clear + + { // <--+ + // | Creating an iterator borrows self, so introduce a + // +- scope to contain the borrow (that way we can mutate + // self below, after this scope exits). + + let mut iter = F::char_indices(self.as_byte_slice()); + match iter.next() { + Some((_, c)) => { + next_char = Some(c); + if let Some((n, _)) = iter.next() { + skip = n as u32; + } + } + None => { + next_char = None; + } } - c - }) + } + + if skip != 0 { + self.unsafe_pop_front(skip); + } else { + self.clear(); + } + + next_char } }