Change:
Sorry, I'm not sure how to describe this very well in a sentence. I am able to mutably borrow the innermost values of a , delete the values, then reference them after they were deleted. This code compiles, runs, and barfs out strange numbers.
Little bit shorter example, without mutable borrows. But still fails to freeze :
nominating for 1.0 P-backcompat-lang
though this may be a library issue
weird This code is also valid: This is because the hashmap iterator just wraps the rawtable iterator, which just defers to the RawBuckets iterator, which is just a wrapper around two *mut's. That is, literally none of these iterators actually borrows the hashmap. Presumably this is fixable by taking a useless reference somewhere. The other thing I'm seeing is that there's , but the signature for Hashmap's iterator function is . How is this lifetime being elided? Is it doing the same thing as , or is something else happening? CC
Yep, it's eliding !
So there's two bugs here: the iterator doesn't borrow the map, and the references are being yielded as .
Assigning P-backcompat-libs, 1.0
thanks for fixing this! Great job!

Discussion:
raw: self.first_bucket_raw(), hashes_end: unsafe { self.hashes.offset(self.capacity as int) <del> } </del> <ins> }, marker: marker::ContravariantLifetime, </ins> } }

} pub fn into_iter(self) -> MoveEntries<K, V> { <ins> let RawBuckets { raw, hashes_end, .. } = self.raw_buckets(); // Replace the marker regardless of lifetime bounds on parameters. </ins> MoveEntries { <del> iter: self.raw_buckets(), </del> <ins> iter: RawBuckets { raw: raw, hashes_end: hashes_end, marker: marker::ContravariantLifetime, }, </ins> table: self, } }

RevMoveBuckets { raw: raw_bucket.offset(self.capacity as int), hashes_end: raw_bucket.hash, <del> elems_left: self.size </del> <ins> elems_left: self.size, marker:     marker::ContravariantLifetime, </ins> } } }

/// this interface is safe, it's not used outside this module. struct RawBuckets<'a, K, V> { raw: RawBucket<K, V>, <del> hashes_end: *mut u64 </del> <ins> hashes_end: *mut u64, marker: marker::ContravariantLifetime<'a>, </ins> } impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {

struct RevMoveBuckets<'a, K, V> { raw: RawBucket<K, V>, hashes_end: *mut u64, <del> elems_left: uint </del> <ins> elems_left: uint, marker: marker::ContravariantLifetime<'a>, </ins> } impl<'a, K, V> Iterator<(K, V)> for RevMoveBuckets<'a, K, V> {

<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn main() { let mut my_stuff = std::collections::HashMap::new(); my_stuff.insert(0i, 42i); let (_, thing) = my_stuff.iter().next().unwrap(); my_stuff.clear(); //~ ERROR cannot borrow println!("{}", *thing); } </ins>

<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn main() { let mut my_stuff = std::collections::HashMap::new(); my_stuff.insert(0i, 42i); let mut it = my_stuff.iter(); my_stuff.swap(1, 43); //~ ERROR cannot borrow } </ins>