Skip to content

Account for possible 0-sized elements in vector iterators #7738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libextra/flatpipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ pub mod flatteners {
T: Decodable<D>>(
buf: &[u8])
-> T {
let buf = vec::to_owned(buf);
let buf = buf.to_owned();
let buf_reader = @BufReader::new(buf);
let reader = buf_reader as @Reader;
let mut deser: D = FromReader::from_reader(reader);
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/getopts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
}
i += 1;
}
return Ok(Matches {opts: vec::to_owned(opts),
return Ok(Matches {opts: opts.to_owned(),
vals: vals,
free: free});
}
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/md4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn md4(msg: &[u8]) -> Quad {
let orig_len: u64 = (msg.len() * 8u) as u64;

// pad message
let mut msg = vec::append(vec::to_owned(msg), [0x80u8]);
let mut msg = vec::append(msg.to_owned(), [0x80u8]);
let mut bitlen = orig_len + 8u64;
while (bitlen + 64u64) % 512u64 > 0u64 {
msg.push(0u8);
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/num/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ impl BigUint {
/// Creates and initializes an BigUint.

pub fn from_slice(slice: &[BigDigit]) -> BigUint {
return BigUint::new(vec::to_owned(slice));
return BigUint::new(slice.to_owned());
}

/// Creates and initializes an BigUint.
Expand Down
7 changes: 3 additions & 4 deletions src/libextra/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use sort;
use std::cmp;
use std::io;
use std::num;
use std::vec;

// NB: this can probably be rewritten in terms of num::Num
// to be less f64-specific.
Expand Down Expand Up @@ -200,13 +199,13 @@ impl<'self> Stats for &'self [f64] {
}

fn percentile(self, pct: f64) -> f64 {
let mut tmp = vec::to_owned(self);
let mut tmp = self.to_owned();
sort::tim_sort(tmp);
percentile_of_sorted(tmp, pct)
}

fn quartiles(self) -> (f64,f64,f64) {
let mut tmp = vec::to_owned(self);
let mut tmp = self.to_owned();
sort::tim_sort(tmp);
let a = percentile_of_sorted(tmp, 25.0);
let b = percentile_of_sorted(tmp, 50.0);
Expand Down Expand Up @@ -251,7 +250,7 @@ priv fn percentile_of_sorted(sorted_samples: &[f64],
///
/// See: http://en.wikipedia.org/wiki/Winsorising
pub fn winsorize(samples: &mut [f64], pct: f64) {
let mut tmp = vec::to_owned(samples);
let mut tmp = samples.to_owned();
sort::tim_sort(tmp);
let lo = percentile_of_sorted(tmp, pct);
let hi = percentile_of_sorted(tmp, 100.0-pct);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ pub fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt,
let item_doc = lookup_item(id, cdata.data);
let path = {
let item_path = item_path(item_doc);
vec::to_owned(item_path.init())
item_path.init().to_owned()
};
match decode_inlined_item(cdata, tcx, copy path, item_doc) {
Some(ref ii) => csearch::found((/*bad*/copy *ii)),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1659,7 +1659,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {

let writer_bytes: &mut ~[u8] = wr.bytes;

vec::to_owned(metadata_encoding_version) +
metadata_encoding_version.to_owned() +
flate::deflate_bytes(*writer_bytes)
}

Expand Down
22 changes: 11 additions & 11 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
match cx.tcx.def_map.find(&pat_id) {
Some(&def_variant(_, id)) => {
if variant(id) == *ctor_id {
Some(vec::to_owned(r.tail()))
Some(r.tail().to_owned())
} else {
None
}
Expand Down Expand Up @@ -522,7 +522,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
_ => fail!("type error")
};
if match_ {
Some(vec::to_owned(r.tail()))
Some(r.tail().to_owned())
} else {
None
}
Expand Down Expand Up @@ -569,7 +569,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
_ => fail!("type error")
};
if match_ {
Some(vec::to_owned(r.tail()))
Some(r.tail().to_owned())
} else {
None
}
Expand All @@ -579,7 +579,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
Some(args) => args,
None => vec::from_elem(arity, wild())
};
Some(vec::append(args, vec::to_owned(r.tail())))
Some(vec::append(args, r.tail()))
}
def_variant(_, _) => None,

Expand All @@ -591,7 +591,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
Some(args) => new_args = args,
None => new_args = vec::from_elem(arity, wild())
}
Some(vec::append(new_args, vec::to_owned(r.tail())))
Some(vec::append(new_args, r.tail()))
}
_ => None
}
Expand All @@ -609,7 +609,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
_ => wild()
}
});
Some(vec::append(args, vec::to_owned(r.tail())))
Some(vec::append(args, r.tail()))
} else {
None
}
Expand Down Expand Up @@ -640,7 +640,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
_ => wild()
}
}).collect();
Some(vec::append(args, vec::to_owned(r.tail())))
Some(vec::append(args, r.tail()))
}
}
}
Expand Down Expand Up @@ -676,14 +676,14 @@ pub fn specialize(cx: &MatchCheckCtxt,
single => true,
_ => fail!("type error")
};
if match_ { Some(vec::to_owned(r.tail())) } else { None }
if match_ { Some(r.tail().to_owned()) } else { None }
}
pat_range(lo, hi) => {
let (c_lo, c_hi) = match *ctor_id {
val(ref v) => ((/*bad*/copy *v), (/*bad*/copy *v)),
range(ref lo, ref hi) =>
((/*bad*/copy *lo), (/*bad*/copy *hi)),
single => return Some(vec::to_owned(r.tail())),
single => return Some(r.tail().to_owned()),
_ => fail!("type error")
};
let v_lo = eval_const_expr(cx.tcx, lo);
Expand All @@ -693,7 +693,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
let m2 = compare_const_vals(&c_hi, &v_hi);
match (m1, m2) {
(Some(val1), Some(val2)) if val1 >= 0 && val2 <= 0 => {
Some(vec::to_owned(r.tail()))
Some(r.tail().to_owned())
},
(Some(_), Some(_)) => None,
_ => {
Expand Down Expand Up @@ -734,7 +734,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
}

pub fn default(cx: &MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> {
if is_wild(cx, r[0]) { Some(vec::to_owned(r.tail())) }
if is_wild(cx, r[0]) { Some(r.tail().to_owned()) }
else { None }
}

Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
use std::container::Map;
use std::libc::c_ulonglong;
use std::option::{Option, Some, None};
use std::vec;

use lib::llvm::{ValueRef, True, IntEQ, IntNE};
use middle::trans::_match;
Expand Down Expand Up @@ -219,7 +218,7 @@ fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct {
size: machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64,
align: machine::llalign_of_min(cx, llty_rec) /*bad*/as u64,
packed: packed,
fields: vec::to_owned(tys)
fields: tys.to_owned(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3782,7 +3782,7 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
}

ast_map::node_variant(ref variant, _, path) => {
vec::append_one(vec::to_owned(path.init()),
vec::append_one(path.init().to_owned(),
ast_map::path_name((*variant).node.name))
}

Expand Down
2 changes: 1 addition & 1 deletion src/libstd/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ impl<R: Rng> RngUtil for R {

/// Shuffle a vec
fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T] {
let mut m = vec::to_owned(values);
let mut m = values.to_owned();
self.shuffle_mut(m);
m
}
Expand Down
86 changes: 68 additions & 18 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use ptr::RawPtr;
use rt::global_heap::malloc_raw;
use rt::global_heap::realloc_raw;
use sys;
use sys::size_of;
use uint;
use unstable::intrinsics;
#[cfg(stage0)]
Expand Down Expand Up @@ -91,11 +90,6 @@ pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
}
}

/// Creates a new unique vector with the same contents as the slice
pub fn to_owned<T:Copy>(t: &[T]) -> ~[T] {
from_fn(t.len(), |i| copy t[i])
}

/// Creates a new vector with a capacity of `capacity`
#[cfg(stage0)]
pub fn with_capacity<T>(capacity: uint) -> ~[T] {
Expand All @@ -114,7 +108,7 @@ pub fn with_capacity<T>(capacity: uint) -> ~[T] {
vec
} else {
let alloc = capacity * sys::nonzero_size_of::<T>();
let ptr = malloc_raw(alloc + size_of::<raw::VecRepr>()) as *mut raw::VecRepr;
let ptr = malloc_raw(alloc + sys::size_of::<raw::VecRepr>()) as *mut raw::VecRepr;
(*ptr).unboxed.alloc = alloc;
(*ptr).unboxed.fill = 0;
cast::transmute(ptr)
Expand Down Expand Up @@ -756,7 +750,9 @@ 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.offset(self.len()),
VecIterator{ptr: p,
end: cast::transmute(p as uint + self.len() *
sys::nonzero_size_of::<T>()),
lifetime: cast::transmute(p)}
}
}
Expand Down Expand Up @@ -1153,7 +1149,7 @@ impl<T> OwnedVector<T> for ~[T] {
::at_vec::raw::reserve_raw(td, ptr, n);
} else {
let alloc = n * sys::nonzero_size_of::<T>();
*ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
*ptr = realloc_raw(*ptr as *mut c_void, alloc + sys::size_of::<raw::VecRepr>())
as *mut raw::VecRepr;
(**ptr).unboxed.alloc = alloc;
}
Expand Down Expand Up @@ -1182,7 +1178,7 @@ impl<T> OwnedVector<T> for ~[T] {
::at_vec::raw::reserve_raw(td, ptr, n);
} else {
let alloc = n * sys::nonzero_size_of::<T>();
let size = alloc + size_of::<raw::VecRepr>();
let size = alloc + sys::size_of::<raw::VecRepr>();
if alloc / sys::nonzero_size_of::<T>() != n || size < alloc {
fail!("vector size is too large: %u", n);
}
Expand Down Expand Up @@ -1716,7 +1712,9 @@ 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.offset(self.len()),
VecMutIterator{ptr: p,
end: cast::transmute(p as uint + self.len() *
sys::nonzero_size_of::<T>()),
lifetime: cast::transmute(p)}
}
}
Expand Down Expand Up @@ -2093,7 +2091,11 @@ macro_rules! iterator {
None
} else {
let old = self.ptr;
self.ptr = self.ptr.offset(1);
// purposefully don't use 'ptr.offset' because for
// vectors with 0-size elements this would return the
// same pointer.
self.ptr = cast::transmute(self.ptr as uint +
sys::nonzero_size_of::<T>());
Some(cast::transmute(old))
}
}
Expand All @@ -2102,7 +2104,7 @@ macro_rules! iterator {
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let diff = (self.end as uint) - (self.ptr as uint);
let exact = diff / size_of::<$elem>();
let exact = diff / sys::nonzero_size_of::<$elem>();
(exact, Some(exact))
}
}
Expand All @@ -2119,7 +2121,9 @@ macro_rules! double_ended_iterator {
if self.end == self.ptr {
None
} else {
self.end = self.end.offset(-1);
// See above for why 'ptr.offset' isn't used
self.end = cast::transmute(self.end as uint -
sys::nonzero_size_of::<T>());
Some(cast::transmute(self.end))
}
}
Expand Down Expand Up @@ -2676,19 +2680,19 @@ mod tests {
let mut results: ~[~[int]];

results = ~[];
for each_permutation([]) |v| { results.push(to_owned(v)); }
for each_permutation([]) |v| { results.push(v.to_owned()); }
assert_eq!(results, ~[~[]]);

results = ~[];
for each_permutation([7]) |v| { results.push(to_owned(v)); }
for each_permutation([7]) |v| { results.push(v.to_owned()); }
assert_eq!(results, ~[~[7]]);

results = ~[];
for each_permutation([1,1]) |v| { results.push(to_owned(v)); }
for each_permutation([1,1]) |v| { results.push(v.to_owned()); }
assert_eq!(results, ~[~[1,1],~[1,1]]);

results = ~[];
for each_permutation([5,2,0]) |v| { results.push(to_owned(v)); }
for each_permutation([5,2,0]) |v| { results.push(v.to_owned()); }
assert!(results ==
~[~[5,2,0],~[5,0,2],~[2,5,0],~[2,0,5],~[0,5,2],~[0,2,5]]);
}
Expand Down Expand Up @@ -3375,4 +3379,50 @@ mod tests {

assert_eq!(values, [2, 3, 5, 6, 7]);
}

#[deriving(Eq)]
struct Foo;

#[test]
fn test_iter_zero_sized() {
let mut v = ~[Foo, Foo, Foo];
assert_eq!(v.len(), 3);
let mut cnt = 0;

for v.iter().advance |f| {
assert!(*f == Foo);
cnt += 1;
}
assert_eq!(cnt, 3);

for v.slice(1, 3).iter().advance |f| {
assert!(*f == Foo);
cnt += 1;
}
assert_eq!(cnt, 5);

for v.mut_iter().advance |f| {
assert!(*f == Foo);
cnt += 1;
}
assert_eq!(cnt, 8);

for v.consume_iter().advance |f| {
assert!(f == Foo);
cnt += 1;
}
assert_eq!(cnt, 11);

let xs = ~[Foo, Foo, Foo];
assert_eq!(fmt!("%?", xs.slice(0, 2).to_owned()), ~"~[{}, {}]");

let xs: [Foo, ..3] = [Foo, Foo, Foo];
assert_eq!(fmt!("%?", xs.slice(0, 2).to_owned()), ~"~[{}, {}]");
cnt = 0;
for xs.iter().advance |f| {
assert!(*f == Foo);
cnt += 1;
}
assert!(cnt == 3);
}
}
Loading