From 0a10b9dc9c9d35379a8d35d060fd351ab9c567a8 Mon Sep 17 00:00:00 2001 From: Piotr Czarnecki Date: Wed, 24 Sep 2014 19:38:15 +0100 Subject: [PATCH] Fix free lifetime vars in HashMap's iterators --- src/libstd/collections/hashmap/table.rs | 20 ++++++++++++++----- .../hashmap-iter-value-lifetime.rs | 20 +++++++++++++++++++ src/test/compile-fail/hashmap-lifetimes.rs | 17 ++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/hashmap-iter-value-lifetime.rs create mode 100644 src/test/compile-fail/hashmap-lifetimes.rs diff --git a/src/libstd/collections/hashmap/table.rs b/src/libstd/collections/hashmap/table.rs index 87a5cc1484a..f542326d8bc 100644 --- a/src/libstd/collections/hashmap/table.rs +++ b/src/libstd/collections/hashmap/table.rs @@ -663,7 +663,8 @@ impl RawTable { raw: self.first_bucket_raw(), hashes_end: unsafe { self.hashes.offset(self.capacity as int) - } + }, + marker: marker::ContravariantLifetime, } } @@ -682,8 +683,14 @@ impl RawTable { } pub fn into_iter(self) -> MoveEntries { + let RawBuckets { raw, hashes_end, .. } = self.raw_buckets(); + // Replace the marker regardless of lifetime bounds on parameters. MoveEntries { - iter: self.raw_buckets(), + iter: RawBuckets { + raw: raw, + hashes_end: hashes_end, + marker: marker::ContravariantLifetime, + }, table: self, } } @@ -695,7 +702,8 @@ impl RawTable { RevMoveBuckets { raw: raw_bucket.offset(self.capacity as int), hashes_end: raw_bucket.hash, - elems_left: self.size + elems_left: self.size, + marker: marker::ContravariantLifetime, } } } @@ -704,7 +712,8 @@ impl RawTable { /// this interface is safe, it's not used outside this module. struct RawBuckets<'a, K, V> { raw: RawBucket, - hashes_end: *mut u64 + hashes_end: *mut u64, + marker: marker::ContravariantLifetime<'a>, } impl<'a, K, V> Iterator> for RawBuckets<'a, K, V> { @@ -730,7 +739,8 @@ impl<'a, K, V> Iterator> for RawBuckets<'a, K, V> { struct RevMoveBuckets<'a, K, V> { raw: RawBucket, hashes_end: *mut u64, - elems_left: uint + elems_left: uint, + marker: marker::ContravariantLifetime<'a>, } impl<'a, K, V> Iterator<(K, V)> for RevMoveBuckets<'a, K, V> { diff --git a/src/test/compile-fail/hashmap-iter-value-lifetime.rs b/src/test/compile-fail/hashmap-iter-value-lifetime.rs new file mode 100644 index 00000000000..d9d7705fef6 --- /dev/null +++ b/src/test/compile-fail/hashmap-iter-value-lifetime.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , 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); +} diff --git a/src/test/compile-fail/hashmap-lifetimes.rs b/src/test/compile-fail/hashmap-lifetimes.rs new file mode 100644 index 00000000000..5bd6c73df1a --- /dev/null +++ b/src/test/compile-fail/hashmap-lifetimes.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , 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 +}