about summary refs log tree commit diff
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-09-27 05:50:33 +0200
committerblake2-ppc <blake2-ppc>2013-09-27 06:06:13 +0200
commitc0e1c09783422870e4d6e5862459d45036bb24d7 (patch)
treeeb2dcc83402cf43699fe40dec080b348a39248db
parent48499c7494d47f505a640157816cea2690b8d407 (diff)
downloadrust-c0e1c09783422870e4d6e5862459d45036bb24d7.tar.gz
rust-c0e1c09783422870e4d6e5862459d45036bb24d7.zip
std::vec: Use a valid value as lifetime dummy in iterator
The current implementation uses `&v[0]` for the lifetime struct field,
but that is a dangling pointer for iterators derived from zero-length
slices.

Example:

    let v: [int, ..0] = [];  println!("{:?}", v.iter())

    std::vec::VecIterator<,int>{ptr: (0x7f3768626100 as *()), end: (0x7f3768626100 as *()), lifetime: &139875951207128}

To replace this parameter, use a field of type `Option<&'self ()>`
that is simply initialized with `None`, but still allows the iterator to
have a lifetime parameter.
-rw-r--r--src/libstd/vec.rs12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index e54717053e9..cf020c8f651 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -932,11 +932,11 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
             if sys::size_of::<T>() == 0 {
                 VecIterator{ptr: p,
                             end: (p as uint + self.len()) as *T,
-                            lifetime: cast::transmute(p)}
+                            lifetime: None}
             } else {
                 VecIterator{ptr: p,
                             end: p.offset(self.len() as int),
-                            lifetime: cast::transmute(p)}
+                            lifetime: None}
             }
         }
     }
@@ -1940,11 +1940,11 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
             if sys::size_of::<T>() == 0 {
                 VecMutIterator{ptr: p,
                                end: (p as uint + self.len()) as *mut T,
-                               lifetime: cast::transmute(p)}
+                               lifetime: None}
             } else {
                 VecMutIterator{ptr: p,
                                end: p.offset(self.len() as int),
-                               lifetime: cast::transmute(p)}
+                               lifetime: None}
             }
         }
     }
@@ -2389,7 +2389,7 @@ impl<'self, T> RandomAccessIterator<&'self T> for VecIterator<'self, T> {
 pub struct VecIterator<'self, T> {
     priv ptr: *T,
     priv end: *T,
-    priv lifetime: &'self T // FIXME: #5922
+    priv lifetime: Option<&'self ()> // FIXME: #5922
 }
 iterator!{impl VecIterator -> &'self T}
 double_ended_iterator!{impl VecIterator -> &'self T}
@@ -2407,7 +2407,7 @@ impl<'self, T> Clone for VecIterator<'self, T> {
 pub struct VecMutIterator<'self, T> {
     priv ptr: *mut T,
     priv end: *mut T,
-    priv lifetime: &'self mut T // FIXME: #5922
+    priv lifetime: Option<&'self mut ()> // FIXME: #5922
 }
 iterator!{impl VecMutIterator -> &'self mut T}
 double_ended_iterator!{impl VecMutIterator -> &'self mut T}