diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-08-06 17:15:43 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-08-06 23:41:20 -0400 |
| commit | f23fb19ee508515912e136c948a0242cc88a2d4e (patch) | |
| tree | f83ee05e78fd9ea5560c03529c5c9860d576a061 /src/libstd | |
| parent | 8f9bbc476d9e4403bc5cd1edfe4a651bd341e811 (diff) | |
vec: avoid `ptrtoint`/`inttoptr` in the iterators
This results in throwing away alias analysis information, because LLVM does *not* implement reasoning about these conversions yet. We specialize zero-size types since a `getelementptr` offset will return us the same pointer, making it broken as a simple counter.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/vec.rs | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 0259b547ab3..8dbfb3ec543 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -849,10 +849,15 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn iter(self) -> VecIterator<'self, T> { unsafe { let p = vec::raw::to_ptr(self); - VecIterator{ptr: p, - end: (p as uint + self.len() * - sys::nonzero_size_of::<T>()) as *T, - lifetime: cast::transmute(p)} + if sys::size_of::<T>() == 0 { + VecIterator{ptr: p, + end: (p as uint + self.len()) as *T, + lifetime: cast::transmute(p)} + } else { + VecIterator{ptr: p, + end: p.offset(self.len() as int), + lifetime: cast::transmute(p)} + } } } @@ -1826,10 +1831,15 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { fn mut_iter(self) -> VecMutIterator<'self, T> { unsafe { let p = vec::raw::to_mut_ptr(self); - VecMutIterator{ptr: p, - end: (p as uint + self.len() * - sys::nonzero_size_of::<T>()) as *mut T, - lifetime: cast::transmute(p)} + if sys::size_of::<T>() == 0 { + VecMutIterator{ptr: p, + end: (p as uint + self.len()) as *mut T, + lifetime: cast::transmute(p)} + } else { + VecMutIterator{ptr: p, + end: p.offset(self.len() as int), + lifetime: cast::transmute(p)} + } } } |
