diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index be402f317a1fb02487df6f271e0dddceb1877134..8f1ff7d1a01e21d87f969331b3194a879d3e931e 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -451,12 +451,20 @@ fn push_slow(&v: [const T]/~, +initval: T) { } } +// Unchecked vector indexing +#[inline(always)] +unsafe fn ref(v: [const T]/&, i: uint) -> T { + unpack_slice(v) {|p, _len| + *ptr::offset(p, i) + } +} + #[inline(always)] fn push_all(&v: [const T]/~, rhs: [const T]/&) { reserve(v, v.len() + rhs.len()); for uint::range(0u, rhs.len()) {|i| - push(v, rhs[i]); + push(v, unsafe { ref(rhs, i) }) } } @@ -464,19 +472,9 @@ fn push_all(&v: [const T]/~, rhs: [const T]/&) { #[inline(always)] pure fn append(lhs: [T]/&, rhs: [const T]/&) -> [T]/~ { let mut v = []/~; - let mut i = 0u; - while i < lhs.len() { - unsafe { // This is impure, but it appears pure to the caller. - push(v, lhs[i]); - } - i += 1u; - } - i = 0u; - while i < rhs.len() { - unsafe { // This is impure, but it appears pure to the caller. - push(v, rhs[i]); - } - i += 1u; + unchecked { + push_all(v, lhs); + push_all(v, rhs); } ret v; } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 798dc6aee9b42c871eb3ddec0e5addf161751bf3..26495e233fff6e5093e1ea338721f834560488f7 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -1234,6 +1234,12 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool { } accum } + ty_fn(fty) { + alt fty.proto { + proto_bare | proto_any | proto_block { false } + _ { true } + } + } _ { true } }; diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index 9ea0ad51feb119e381f9f4ff36cbda38ae2e8fa9..9e1f88690d11bd50239804e5b1d2a207e8133566 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -22,6 +22,8 @@ fn main(argv: [str]/~) { #bench[shift_push]; #bench[read_line]; #bench[str_set]; + #bench[vec_append]; + #bench[vec_push_all]; } fn run_test(name: str, test: fn()) { @@ -72,3 +74,34 @@ fn str_set() { } } } + +fn vec_append() { + let r = rand::rng(); + + let mut v = []/~; + for uint::range(0, 1500) {|i| + let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i); + if r.gen_bool() { + v += rv; + } + else { + v = rv + v; + } + } +} + +fn vec_push_all() { + let r = rand::rng(); + + let mut v = []/~; + for uint::range(0, 1500) {|i| + let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i); + if r.gen_bool() { + vec::push_all(v, rv); + } + else { + v <-> rv; + vec::push_all(v, rv); + } + } +}