Skip to content

extend the iterator tutorial + fix zero-size element vec iterators #7736

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

Merged
merged 3 commits into from
Jul 12, 2013
Merged
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
101 changes: 101 additions & 0 deletions doc/tutorial-container.md
Original file line number Diff line number Diff line change
@@ -205,3 +205,104 @@ println(fmt!("last: %?", it.next()));
// the iterator is now fully consumed
assert!(it.next().is_none());
~~~
## Conversion
Iterators offer generic conversion to containers with the `collect` adaptor:
~~~
let xs = [0, 1, 1, 2, 3, 5, 8];
let ys = xs.rev_iter().skip(1).transform(|&x| x * 2).collect::<~[int]>();
assert_eq!(ys, ~[10, 6, 4, 2, 2, 0]);
~~~
The method requires a type hint for the container type, if the surrounding code
does not provide sufficient information.
Containers can provide conversion from iterators through `collect` by
implementing the `FromIterator` trait. For example, the implementation for
vectors is as follows:
~~~
impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
pub fn from_iterator(iterator: &mut T) -> ~[A] {
let (lower, _) = iterator.size_hint();
let mut xs = with_capacity(lower);
for iterator.advance |x| {
xs.push(x);
}
xs
}
}
~~~
### Size hints
The `Iterator` trait provides a `size_hint` default method, returning a lower
bound and optionally on upper bound on the length of the iterator:
~~~
fn size_hint(&self) -> (uint, Option<uint>) { (0, None) }
~~~
The vector implementation of `FromIterator` from above uses the lower bound
to pre-allocate enough space to hold the minimum number of elements the
iterator will yield.
The default implementation is always correct, but it should be overridden if
the iterator can provide better information.
The `ZeroStream` from earlier can provide an exact lower and upper bound:
~~~
/// A stream of N zeroes
struct ZeroStream {
priv remaining: uint
}

impl ZeroStream {
fn new(n: uint) -> ZeroStream {
ZeroStream { remaining: n }
}

fn size_hint(&self) -> (uint, Option<uint>) {
(self.remaining, Some(self.remaining))
}
}

impl Iterator<int> for ZeroStream {
fn next(&mut self) -> Option<int> {
if self.remaining == 0 {
None
} else {
self.remaining -= 1;
Some(0)
}
}
}
~~~
## Double-ended iterators
The `DoubleEndedIterator` trait represents an iterator able to yield elements
from either end of a range. It inherits from the `Iterator` trait and extends
it with the `next_back` function.
A `DoubleEndedIterator` can be flipped with the `invert` adaptor, returning
another `DoubleEndedIterator` with `next` and `next_back` exchanged.
~~~
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter();
println(fmt!("%?", it.next())); // prints `Some(&1)`
println(fmt!("%?", it.next())); // prints `Some(&2)`
println(fmt!("%?", it.next_back())); // prints `Some(&6)`

// prints `5`, `4` and `3`
for it.invert().advance |&x| {
println(fmt!("%?", x))
}
~~~
The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted
version of the standard immutable and mutable vector iterators.
8 changes: 4 additions & 4 deletions src/libextra/bitv.rs
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ impl SmallBitv {
}

#[inline]
pub fn invert(&mut self) { self.bits = !self.bits; }
pub fn negate(&mut self) { self.bits = !self.bits; }
}

struct BigBitv {
@@ -160,7 +160,7 @@ impl BigBitv {
}

#[inline]
pub fn invert(&mut self) { for self.each_storage |w| { *w = !*w } }
pub fn negate(&mut self) { for self.each_storage |w| { *w = !*w } }

#[inline]
pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
@@ -366,9 +366,9 @@ impl Bitv {

/// Invert all bits
#[inline]
pub fn invert(&mut self) {
pub fn negate(&mut self) {
match self.rep {
Small(ref mut b) => b.invert(),
Small(ref mut b) => b.negate(),
Big(ref mut s) => for s.each_storage() |w| { *w = !*w } }
}

2 changes: 1 addition & 1 deletion src/libextra/flatpipes.rs
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion src/libextra/getopts.rs
Original file line number Diff line number Diff line change
@@ -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});
}
2 changes: 1 addition & 1 deletion src/libextra/md4.rs
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion src/libextra/num/bigint.rs
Original file line number Diff line number Diff line change
@@ -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.
7 changes: 3 additions & 4 deletions src/libextra/stats.rs
Original file line number Diff line number Diff line change
@@ -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.
@@ -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);
@@ -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);
2 changes: 1 addition & 1 deletion src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
@@ -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)),
2 changes: 1 addition & 1 deletion src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
@@ -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)
}

22 changes: 11 additions & 11 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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,

@@ -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
}
@@ -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
}
@@ -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()))
}
}
}
@@ -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);
@@ -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,
_ => {
@@ -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 }
}

3 changes: 1 addition & 2 deletions src/librustc/middle/trans/adt.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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(),
}
}

2 changes: 1 addition & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
@@ -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))
}

5 changes: 3 additions & 2 deletions src/libstd/prelude.rs
Original file line number Diff line number Diff line change
@@ -47,8 +47,9 @@ pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Great
pub use char::Char;
pub use container::{Container, Mutable, Map, Set};
pub use hash::Hash;
pub use iter::{Times};
pub use iterator::{Iterator, IteratorUtil, OrdIterator};
pub use iter::Times;
pub use iterator::{Iterator, IteratorUtil, DoubleEndedIterator, DoubleEndedIteratorUtil};
pub use iterator::OrdIterator;
pub use num::{Num, NumCast};
pub use num::{Orderable, Signed, Unsigned, Round};
pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
2 changes: 1 addition & 1 deletion src/libstd/rand.rs
Original file line number Diff line number Diff line change
@@ -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
}
88 changes: 69 additions & 19 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
@@ -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)]
@@ -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] {
@@ -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)
@@ -756,10 +750,13 @@ 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)}
}
}

#[inline]
fn rev_iter(self) -> VecRevIterator<'self, T> {
self.iter().invert()
@@ -1153,7 +1150,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;
}
@@ -1182,7 +1179,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);
}
@@ -1716,7 +1713,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)}
}
}
@@ -2093,7 +2092,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))
}
}
@@ -2102,7 +2105,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))
}
}
@@ -2119,7 +2122,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))
}
}
@@ -2211,7 +2216,6 @@ impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
}
}


#[cfg(test)]
mod tests {
use option::{None, Option, Some};
@@ -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]]);
}
@@ -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);
}
}
3 changes: 1 addition & 2 deletions src/libsyntax/attr.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ use diagnostic::span_handler;
use parse::comments::{doc_comment_style, strip_doc_comment_decoration};

use std::hashmap::HashSet;
use std::vec;
/* Constructors */

pub fn mk_name_value_item_str(name: @str, value: @str)
@@ -256,7 +255,7 @@ pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: &str)

pub fn sort_meta_items(items: &[@ast::meta_item]) -> ~[@ast::meta_item] {
// This is sort of stupid here, converting to a vec of mutables and back
let mut v = vec::to_owned(items);
let mut v = items.to_owned();
do extra::sort::quick_sort(v) |ma, mb| {
get_meta_item_name(*ma) <= get_meta_item_name(*mb)
}
4 changes: 1 addition & 3 deletions src/libsyntax/ext/asm.rs
Original file line number Diff line number Diff line change
@@ -19,8 +19,6 @@ use ext::base::*;
use parse;
use parse::token;

use std::vec;

enum State {
Asm,
Outputs,
@@ -43,7 +41,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
-> base::MacResult {
let p = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(),
vec::to_owned(tts));
tts.to_owned());

let mut asm = @"";
let mut outputs = ~[];
3 changes: 1 addition & 2 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@ use parse;
use parse::token;
use parse::token::{ident_to_str, intern, str_to_ident};

use std::vec;
use std::hashmap::HashMap;

// new-style macro! tt code:
@@ -362,7 +361,7 @@ pub fn get_exprs_from_tts(cx: @ExtCtxt, tts: &[ast::token_tree])
-> ~[@ast::expr] {
let p = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(),
vec::to_owned(tts));
tts.to_owned());
let mut es = ~[];
while *p.token != token::EOF {
if es.len() != 0 {
3 changes: 1 addition & 2 deletions src/libsyntax/ext/log_syntax.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@ use ext::base;
use print;
use parse::token::{get_ident_interner};

use std::vec;
use std::io;

pub fn expand_syntax_ext(cx: @ExtCtxt,
@@ -26,7 +25,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt,
cx.print_backtrace();
io::stdout().write_line(
print::pprust::tt_to_str(
&ast::tt_delim(vec::to_owned(tt)),
&ast::tt_delim(tt.to_owned()),
get_ident_interner()));

//trivial expression
4 changes: 1 addition & 3 deletions src/libsyntax/ext/quote.rs
Original file line number Diff line number Diff line change
@@ -17,8 +17,6 @@ use parse::token::*;
use parse::token;
use parse;

use std::vec;

/**
*
* Quasiquoting works via token trees.
@@ -653,7 +651,7 @@ fn expand_tts(cx: @ExtCtxt,
let p = parse::new_parser_from_tts(
cx.parse_sess(),
cx.cfg(),
vec::to_owned(tts)
tts.to_owned()
);
*p.quote_depth += 1u;
let tts = p.parse_all_token_trees();
4 changes: 1 addition & 3 deletions src/libsyntax/ext/trace_macros.rs
Original file line number Diff line number Diff line change
@@ -16,8 +16,6 @@ use parse::lexer::{new_tt_reader, reader};
use parse::parser::Parser;
use parse::token::keywords;

use std::vec;

pub fn expand_trace_macros(cx: @ExtCtxt,
sp: span,
tt: &[ast::token_tree])
@@ -27,7 +25,7 @@ pub fn expand_trace_macros(cx: @ExtCtxt,
let tt_rdr = new_tt_reader(
copy cx.parse_sess().span_diagnostic,
None,
vec::to_owned(tt)
tt.to_owned()
);
let rdr = tt_rdr as @reader;
let rust_parser = Parser(
5 changes: 2 additions & 3 deletions src/libsyntax/ext/tt/macro_rules.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ use parse::token::{get_ident_interner, special_idents, gensym_ident, ident_to_st
use parse::token::{FAT_ARROW, SEMI, nt_matchers, nt_tt};
use print;

use std::vec;
use std::io;

pub fn add_new_extension(cx: @ExtCtxt,
@@ -82,7 +81,7 @@ pub fn add_new_extension(cx: @ExtCtxt,
io::println(fmt!("%s! { %s }",
cx.str_of(name),
print::pprust::tt_to_str(
&ast::tt_delim(vec::to_owned(arg)),
&ast::tt_delim(arg.to_owned()),
get_ident_interner())));
}

@@ -99,7 +98,7 @@ pub fn add_new_extension(cx: @ExtCtxt,
let arg_rdr = new_tt_reader(
s_d,
None,
vec::to_owned(arg)
arg.to_owned()
) as @reader;
match parse(cx.parse_sess(), cx.cfg(), arg_rdr, *mtcs) {
success(named_matches) => {
14 changes: 6 additions & 8 deletions src/test/run-pass/rcvr-borrowed-to-slice.rs
Original file line number Diff line number Diff line change
@@ -11,19 +11,17 @@
use std::vec;

trait sum {
fn sum(self) -> int;
fn sum_(self) -> int;
}

// Note: impl on a slice
impl<'self> sum for &'self [int] {
fn sum(self) -> int {
let mut sum = 0;
for self.iter().advance |e| { sum += *e; }
return sum;
fn sum_(self) -> int {
self.iter().fold(0, |a, &b| a + b)
}
}

fn call_sum(x: &[int]) -> int { x.sum() }
fn call_sum(x: &[int]) -> int { x.sum_() }

pub fn main() {
let x = ~[1, 2, 3];
@@ -32,12 +30,12 @@ pub fn main() {
assert_eq!(y, 6);

let mut x = ~[1, 2, 3];
let y = x.sum();
let y = x.sum_();
debug!("y==%d", y);
assert_eq!(y, 6);

let x = ~[1, 2, 3];
let y = x.sum();
let y = x.sum_();
debug!("y==%d", y);
assert_eq!(y, 6);
}