From d6e583ab1038ffe2706e5ecdc96a3da207f87c16 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 3 Mar 2013 14:49:44 -0800 Subject: [PATCH 1/9] std: remove an unnecessary copy from workcache --- src/libstd/workcache.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index 1dd7bfd75db8f..c46c2d17ed0c6 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -174,7 +174,7 @@ pub impl Database { let k = json_encode(&(fn_name, declared_inputs)); match self.db_cache.find(&k) { None => None, - Some(&v) => Some(json_decode(copy v)) + Some(v) => Some(json_decode(*v)) } } From ac4016ff992bde67b37448200abdc84680d49d72 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 3 Mar 2013 07:52:06 -0800 Subject: [PATCH 2/9] rustdoc: Remove a unused variable warning --- src/librustdoc/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 21c0393f68f6f..187ddcc015261 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -262,7 +262,7 @@ fn should_find_pandoc() { output_format: PandocHtml, .. default_config(&Path("test")) }; - let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |prog, _| { + let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| { ProgramOutput { status: 0, out: ~"pandoc 1.8.2.1", err: ~"" } }; let result = maybe_find_pandoc(&config, None, mock_program_output); From 431e756fd72df1c092e71f6e605e82385a9c6881 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 3 Mar 2013 09:01:28 -0800 Subject: [PATCH 3/9] rustdoc: change paragraphs fn to take &str --- src/librustdoc/desc_to_brief_pass.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index b4d990ccdd24c..963715796e65a 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -142,7 +142,7 @@ fn parse_desc(desc: ~str) -> Option<~str> { } fn first_sentence(s: ~str) -> Option<~str> { - let paras = paragraphs(copy s); + let paras = paragraphs(s); if !paras.is_empty() { let first_para = vec::head(paras); Some(str::replace(first_sentence_(first_para), ~"\n", ~" ")) @@ -182,7 +182,7 @@ fn first_sentence_(s: ~str) -> ~str { } } -fn paragraphs(s: ~str) -> ~[~str] { +fn paragraphs(s: &str) -> ~[~str] { let lines = str::lines_any(s); let mut whitespace_lines = 0; let mut accum = ~""; From 359bb3e10bb022aabc5bfc60e48d3dfffc2ee62c Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sat, 2 Mar 2013 21:49:50 -0800 Subject: [PATCH 4/9] core: convert vec::{head,head_opt} to return references --- src/libcore/vec.rs | 52 +++++++++++++++++++++++----- src/librust/rust.rc | 12 ++++--- src/librustdoc/config.rs | 2 +- src/librustdoc/desc_to_brief_pass.rs | 24 ++++++------- src/librustdoc/unindent_pass.rs | 2 +- src/test/run-pass/zip-same-length.rs | 7 ++-- 6 files changed, 68 insertions(+), 31 deletions(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index ab5f04ace79c0..20aadd79d12ef 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -211,7 +211,16 @@ pub pure fn build_sized_opt<A>(size: Option<uint>, // Accessors /// Returns the first element of a vector -pub pure fn head<T:Copy>(v: &[const T]) -> T { v[0] } +pub pure fn head<T>(v: &r/[T]) -> &r/T { + if v.len() == 0 { fail!(~"last_unsafe: empty vector") } + &v[0] +} + +/// Returns `Some(x)` where `x` is the first element of the slice `v`, +/// or `None` if the vector is empty. +pub pure fn head_opt<T>(v: &r/[T]) -> Option<&r/T> { + if v.len() == 0 { None } else { Some(&v[0]) } +} /// Returns a vector containing all but the first element of a slice pub pure fn tail<T:Copy>(v: &[const T]) -> ~[T] { @@ -1692,7 +1701,6 @@ impl<T> Container for &[const T] { } pub trait CopyableVector<T> { - pure fn head(&self) -> T; pure fn init(&self) -> ~[T]; pure fn last(&self) -> T; pure fn slice(&self, start: uint, end: uint) -> ~[T]; @@ -1701,10 +1709,6 @@ pub trait CopyableVector<T> { /// Extension methods for vectors impl<T:Copy> CopyableVector<T> for &[const T] { - /// Returns the first element of a vector - #[inline] - pure fn head(&self) -> T { head(*self) } - /// Returns all but the last elemnt of a vector #[inline] pure fn init(&self) -> ~[T] { init(*self) } @@ -1726,7 +1730,9 @@ impl<T:Copy> CopyableVector<T> for &[const T] { pub trait ImmutableVector<T> { pure fn view(&self, start: uint, end: uint) -> &self/[T]; - pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; + pure fn head(&self) -> &self/T; + pure fn head_opt(&self) -> Option<&self/T>; + pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U]; pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U]; fn map_r<U>(&self, f: fn(x: &T) -> U) -> ~[U]; @@ -1743,6 +1749,14 @@ impl<T> ImmutableVector<T> for &[T] { slice(*self, start, end) } + /// Returns the first element of a vector, failing if the vector is empty. + #[inline] + pure fn head(&self) -> &self/T { head(*self) } + + /// Returns the first element of a vector + #[inline] + pure fn head_opt(&self) -> Option<&self/T> { head_opt(*self) } + /// Reduce a vector from right to left #[inline] pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { @@ -2570,8 +2584,28 @@ mod tests { #[test] fn test_head() { - let a = ~[11, 12]; - assert (head(a) == 11); + let mut a = ~[11]; + assert a.head() == &11; + a = ~[11, 12]; + assert a.head() == &11; + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_head_empty() { + let a: ~[int] = ~[]; + a.head(); + } + + #[test] + fn test_head_opt() { + let mut a = ~[]; + assert a.head_opt() == None; + a = ~[11]; + assert a.head_opt().unwrap() == &11; + a = ~[11, 12]; + assert a.head_opt().unwrap() == &11; } #[test] diff --git a/src/librust/rust.rc b/src/librust/rust.rc index 37e0f874b40dc..235ed6412a356 100644 --- a/src/librust/rust.rc +++ b/src/librust/rust.rc @@ -130,7 +130,7 @@ fn cmd_help(args: &[~str]) -> ValidUsage { UsgExec(commandline) => { let words = str::words(commandline); let (prog, args) = (words.head(), words.tail()); - run::run_program(prog, args); + run::run_program(*prog, args); } } Valid @@ -186,7 +186,10 @@ fn do_command(command: &Command, args: &[~str]) -> ValidUsage { Exec(commandline) => { let words = str::words(commandline); let (prog, prog_args) = (words.head(), words.tail()); - let exitstatus = run::run_program(prog, prog_args + args); + let exitstatus = run::run_program( + *prog, + vec::append(vec::from_slice(prog_args), args) + ); os::set_exit_status(exitstatus); Valid } @@ -221,11 +224,12 @@ fn usage() { } pub fn main() { - let args = os::args().tail(); + let os_args = os::args(); + let args = os_args.tail(); if !args.is_empty() { for commands.each |command| { - if command.cmd == args.head() { + if command.cmd == *args.head() { let result = do_command(command, args.tail()); if result.is_valid() { return; } } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 187ddcc015261..58316110b64ed 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -132,7 +132,7 @@ pub fn parse_config_( match getopts::getopts(args, opts) { result::Ok(matches) => { if matches.free.len() == 1 { - let input_crate = Path(vec::head(matches.free)); + let input_crate = Path(copy *matches.free.head()); config_from_opts(&input_crate, &matches, program_output) } else if matches.free.is_empty() { result::Err(~"no crates specified") diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 963715796e65a..3a4cd9e1379f9 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -144,14 +144,14 @@ fn parse_desc(desc: ~str) -> Option<~str> { fn first_sentence(s: ~str) -> Option<~str> { let paras = paragraphs(s); if !paras.is_empty() { - let first_para = vec::head(paras); - Some(str::replace(first_sentence_(first_para), ~"\n", ~" ")) + let first_para = paras.head(); + Some(str::replace(first_sentence_(*first_para), ~"\n", ~" ")) } else { None } } -fn first_sentence_(s: ~str) -> ~str { +fn first_sentence_(s: &str) -> ~str { let mut dotcount = 0; // The index of the character following a single dot. This allows // Things like [0..1) to appear in the brief description @@ -169,16 +169,16 @@ fn first_sentence_(s: ~str) -> ~str { } }; match idx { - Some(idx) if idx > 2u => { - str::slice(s, 0u, idx - 1u) - } - _ => { - if str::ends_with(s, ~".") { - str::slice(s, 0u, str::len(s)) - } else { - copy s + Some(idx) if idx > 2u => { + str::from_slice(str::view(s, 0, idx - 1)) + } + _ => { + if str::ends_with(s, ~".") { + str::from_slice(s) + } else { + str::from_slice(s) + } } - } } } diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs index d5b9756faa5e2..5fafcf392bec6 100644 --- a/src/librustdoc/unindent_pass.rs +++ b/src/librustdoc/unindent_pass.rs @@ -78,7 +78,7 @@ fn unindent(s: &str) -> ~str { }; if !lines.is_empty() { - let unindented = ~[str::trim(vec::head(lines))] + let unindented = ~[lines.head().trim()] + do vec::tail(lines).map |line| { if str::is_whitespace(*line) { copy *line diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs index 1ade9e8246fdd..29b58cd643115 100644 --- a/src/test/run-pass/zip-same-length.rs +++ b/src/test/run-pass/zip-same-length.rs @@ -10,7 +10,6 @@ // In this case, the code should compile and should // succeed at runtime -use core::vec::{head, last, same_length, zip}; fn enum_chars(start: u8, end: u8) -> ~[char] { assert start < end; @@ -33,8 +32,8 @@ pub fn main() { let chars = enum_chars(a, j); let ints = enum_uints(k, l); - let ps = zip(chars, ints); + let ps = vec::zip(chars, ints); - assert (head(ps) == ('a', 1u)); - assert (last(ps) == (j as char, 10u)); + assert (ps.head() == &('a', 1u)); + assert (ps.last() == (j as char, 10u)); } From 5ae06ae9dea2f1dac157193b702f640e2216a5a9 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 3 Mar 2013 07:22:40 -0800 Subject: [PATCH 5/9] core: convert vec::{tail,tailn} to return references --- src/libcore/vec.rs | 57 +++++++++++++++++--------- src/librustc/middle/check_match.rs | 65 ++++++++++++++++++------------ src/librustc/middle/trans/cabi.rs | 8 ++-- src/librustdoc/unindent_pass.rs | 2 +- 4 files changed, 84 insertions(+), 48 deletions(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 20aadd79d12ef..98316066fd176 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -223,17 +223,10 @@ pub pure fn head_opt<T>(v: &r/[T]) -> Option<&r/T> { } /// Returns a vector containing all but the first element of a slice -pub pure fn tail<T:Copy>(v: &[const T]) -> ~[T] { - slice(v, 1u, len(v)).to_vec() -} +pub pure fn tail<T>(v: &r/[T]) -> &r/[T] { slice(v, 1, v.len()) } -/** - * Returns a vector containing all but the first `n` \ - * elements of a slice - */ -pub pure fn tailn<T:Copy>(v: &[const T], n: uint) -> ~[T] { - slice(v, n, len(v)).to_vec() -} +/// Returns a vector containing all but the first `n` elements of a slice +pub pure fn tailn<T>(v: &r/[T], n: uint) -> &r/[T] { slice(v, n, v.len()) } /// Returns a vector containing all but the last element of a slice pub pure fn init<T:Copy>(v: &[const T]) -> ~[T] { @@ -1704,7 +1697,6 @@ pub trait CopyableVector<T> { pure fn init(&self) -> ~[T]; pure fn last(&self) -> T; pure fn slice(&self, start: uint, end: uint) -> ~[T]; - pure fn tail(&self) -> ~[T]; } /// Extension methods for vectors @@ -1722,16 +1714,14 @@ impl<T:Copy> CopyableVector<T> for &[const T] { pure fn slice(&self, start: uint, end: uint) -> ~[T] { slice(*self, start, end).to_vec() } - - /// Returns all but the first element of a vector - #[inline] - pure fn tail(&self) -> ~[T] { tail(*self) } } pub trait ImmutableVector<T> { pure fn view(&self, start: uint, end: uint) -> &self/[T]; pure fn head(&self) -> &self/T; pure fn head_opt(&self) -> Option<&self/T>; + pure fn tail(&self) -> &self/[T]; + pure fn tailn(&self, n: uint) -> &self/[T]; pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U]; pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U]; @@ -1757,6 +1747,14 @@ impl<T> ImmutableVector<T> for &[T] { #[inline] pure fn head_opt(&self) -> Option<&self/T> { head_opt(*self) } + /// Returns all but the first element of a vector + #[inline] + pure fn tail(&self) -> &self/[T] { tail(*self) } + + /// Returns all but the first `n' elements of a vector + #[inline] + pure fn tailn(&self, n: uint) -> &self/[T] { tailn(*self, n) } + /// Reduce a vector from right to left #[inline] pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { @@ -2611,10 +2609,33 @@ mod tests { #[test] fn test_tail() { let mut a = ~[11]; - assert (tail(a) == ~[]); - + assert a.tail() == &[]; a = ~[11, 12]; - assert (tail(a) == ~[12]); + assert a.tail() == &[12]; + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_tail_empty() { + let a: ~[int] = ~[]; + a.tail(); + } + + #[test] + fn test_tailn() { + let mut a = ~[11, 12, 13]; + assert a.tailn(0) == &[11, 12, 13]; + a = ~[11, 12, 13]; + assert a.tailn(2) == &[13]; + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_tailn_empty() { + let a: ~[int] = ~[]; + a.tailn(2); } #[test] diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 51cb305ab028e..7dd31374fc677 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -265,7 +265,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful { Some(ref ctor) => { match is_useful(cx, vec::filter_map(m, |r| default(cx, r)), - vec::tail(v)) { + v.tail()) { useful_ => useful(left_ty, (/*bad*/copy *ctor)), ref u => (/*bad*/copy *u) } @@ -281,7 +281,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful { pub fn is_useful_specialized(cx: @MatchCheckCtxt, m: matrix, - +v: &[@pat], + v: &[@pat], +ctor: ctor, arity: uint, lty: ty::t) @@ -475,7 +475,7 @@ pub fn wild() -> @pat { } pub fn specialize(cx: @MatchCheckCtxt, - +r: &[@pat], + r: &[@pat], ctor_id: ctor, arity: uint, left_ty: ty::t) @@ -485,13 +485,17 @@ pub fn specialize(cx: @MatchCheckCtxt, match r0 { pat{id: pat_id, node: n, span: pat_span} => match n { - pat_wild => Some(vec::append(vec::from_elem(arity, wild()), - vec::tail(r))), + pat_wild => { + Some(vec::append(vec::from_elem(arity, wild()), r.tail())) + } pat_ident(_, _, _) => { match cx.tcx.def_map.find(&pat_id) { Some(def_variant(_, id)) => { - if variant(id) == ctor_id { Some(vec::tail(r)) } - else { None } + if variant(id) == ctor_id { + Some(vec::from_slice(r.tail())) + } else { + None + } } Some(def_const(did)) => { let const_expr = @@ -506,10 +510,20 @@ pub fn specialize(cx: @MatchCheckCtxt, single => true, _ => fail!(~"type error") }; - if match_ { Some(vec::tail(r)) } else { None } + if match_ { + Some(vec::from_slice(r.tail())) + } else { + None + } + } + _ => { + Some( + vec::append( + vec::from_elem(arity, wild()), + r.tail() + ) + ) } - _ => Some(vec::append(vec::from_elem(arity, wild()), - vec::tail(r))) } } pat_enum(_, args) => { @@ -519,7 +533,7 @@ pub fn specialize(cx: @MatchCheckCtxt, Some(args) => args, None => vec::from_elem(arity, wild()) }; - Some(vec::append(args, vec::tail(r))) + Some(vec::append(args, vec::from_slice(r.tail()))) } def_variant(_, _) => None, def_struct(*) => { @@ -529,7 +543,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::tail(r))) + Some(vec::append(new_args, vec::from_slice(r.tail()))) } _ => None } @@ -545,7 +559,7 @@ pub fn specialize(cx: @MatchCheckCtxt, _ => wild() } }); - Some(vec::append(args, vec::tail(r))) + Some(vec::append(args, vec::from_slice(r.tail()))) } pat_struct(_, ref flds, _) => { // Is this a struct or an enum variant? @@ -560,7 +574,7 @@ pub fn specialize(cx: @MatchCheckCtxt, _ => wild() } }); - Some(vec::append(args, vec::tail(r))) + Some(vec::append(args, vec::from_slice(r.tail()))) } else { None } @@ -587,13 +601,14 @@ pub fn specialize(cx: @MatchCheckCtxt, _ => wild() } }); - Some(vec::append(args, vec::tail(r))) + Some(vec::append(args, vec::from_slice(r.tail()))) } } } - pat_tup(args) => Some(vec::append(args, vec::tail(r))), - pat_box(a) | pat_uniq(a) | pat_region(a) => - Some(vec::append(~[a], vec::tail(r))), + pat_tup(args) => Some(vec::append(args, r.tail())), + pat_box(a) | pat_uniq(a) | pat_region(a) => { + Some(vec::append(~[a], r.tail())) + } pat_lit(expr) => { let e_v = eval_const_expr(cx.tcx, expr); let match_ = match ctor_id { @@ -605,21 +620,21 @@ pub fn specialize(cx: @MatchCheckCtxt, single => true, _ => fail!(~"type error") }; - if match_ { Some(vec::tail(r)) } else { None } + if match_ { Some(vec::from_slice(r.tail())) } 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::tail(r)), + single => return Some(vec::from_slice(r.tail())), _ => fail!(~"type error") }; let v_lo = eval_const_expr(cx.tcx, lo), v_hi = eval_const_expr(cx.tcx, hi); let match_ = compare_const_vals(c_lo, v_lo) >= 0 && compare_const_vals(c_hi, v_hi) <= 0; - if match_ { Some(vec::tail(r)) } else { None } + if match_ { Some(vec::from_slice(r.tail())) } else { None } } pat_vec(elems, tail) => { match ctor_id { @@ -630,10 +645,10 @@ pub fn specialize(cx: @MatchCheckCtxt, vec::append(elems, vec::from_elem( arity - num_elements, wild() )), - vec::tail(r) + vec::from_slice(r.tail()) )) } else if num_elements == arity { - Some(vec::append(elems, vec::tail(r))) + Some(vec::append(elems, r.tail())) } else { None } @@ -645,8 +660,8 @@ pub fn specialize(cx: @MatchCheckCtxt, } } -pub fn default(cx: @MatchCheckCtxt, r: ~[@pat]) -> Option<~[@pat]> { - if is_wild(cx, r[0]) { Some(vec::tail(r)) } +pub fn default(cx: @MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> { + if is_wild(cx, r[0]) { Some(vec::from_slice(r.tail())) } else { None } } diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index bbc19cf86eaac..1d7314f751870 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -71,8 +71,8 @@ pub impl FnType { let llretptr = GEPi(bcx, llargbundle, [0u, n]); let llretloc = Load(bcx, llretptr); llargvals = ~[llretloc]; - atys = vec::tail(atys); - attrs = vec::tail(attrs); + atys = vec::from_slice(atys.tail()); + attrs = vec::from_slice(attrs.tail()); } while i < n { @@ -131,8 +131,8 @@ pub impl FnType { let mut attrs = /*bad*/copy self.attrs; let mut j = 0u; let llretptr = if self.sret { - atys = vec::tail(atys); - attrs = vec::tail(attrs); + atys = vec::from_slice(atys.tail()); + attrs = vec::from_slice(attrs.tail()); j = 1u; get_param(llwrapfn, 0u) } else if self.ret_ty.cast { diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs index 5fafcf392bec6..06595a23d9612 100644 --- a/src/librustdoc/unindent_pass.rs +++ b/src/librustdoc/unindent_pass.rs @@ -79,7 +79,7 @@ fn unindent(s: &str) -> ~str { if !lines.is_empty() { let unindented = ~[lines.head().trim()] - + do vec::tail(lines).map |line| { + + do lines.tail().map |line| { if str::is_whitespace(*line) { copy *line } else { From d60747a24839c50165b0e2ea35592a7cb008f69b Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 3 Mar 2013 08:06:31 -0800 Subject: [PATCH 6/9] core: convert vec::{init,initn} to return references --- src/libcore/vec.rs | 70 ++++++++++++++++++++++---------- src/librustc/metadata/decoder.rs | 8 ++-- src/librustc/middle/ty.rs | 2 +- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 98316066fd176..2884d44861072 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -229,9 +229,11 @@ pub pure fn tail<T>(v: &r/[T]) -> &r/[T] { slice(v, 1, v.len()) } pub pure fn tailn<T>(v: &r/[T], n: uint) -> &r/[T] { slice(v, n, v.len()) } /// Returns a vector containing all but the last element of a slice -pub pure fn init<T:Copy>(v: &[const T]) -> ~[T] { - assert len(v) != 0u; - slice(v, 0u, len(v) - 1u).to_vec() +pub pure fn init<T>(v: &r/[T]) -> &r/[T] { slice(v, 0, v.len() - 1) } + +/// Returns a vector containing all but the last `n' elements of a slice +pub pure fn initn<T>(v: &r/[T], n: uint) -> &r/[T] { + slice(v, 0, v.len() - n) } /// Returns the last element of the slice `v`, failing if the slice is empty. @@ -1694,17 +1696,12 @@ impl<T> Container for &[const T] { } pub trait CopyableVector<T> { - pure fn init(&self) -> ~[T]; pure fn last(&self) -> T; pure fn slice(&self, start: uint, end: uint) -> ~[T]; } /// Extension methods for vectors -impl<T:Copy> CopyableVector<T> for &[const T] { - /// Returns all but the last elemnt of a vector - #[inline] - pure fn init(&self) -> ~[T] { init(*self) } - +impl<T: Copy> CopyableVector<T> for &[const T] { /// Returns the last element of a `v`, failing if the vector is empty. #[inline] pure fn last(&self) -> T { last(*self) } @@ -1722,6 +1719,8 @@ pub trait ImmutableVector<T> { pure fn head_opt(&self) -> Option<&self/T>; pure fn tail(&self) -> &self/[T]; pure fn tailn(&self, n: uint) -> &self/[T]; + pure fn init(&self) -> &self/[T]; + pure fn initn(&self, n: uint) -> &self/[T]; pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U]; pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U]; @@ -1755,6 +1754,14 @@ impl<T> ImmutableVector<T> for &[T] { #[inline] pure fn tailn(&self, n: uint) -> &self/[T] { tailn(*self, n) } + /// Returns all but the last elemnt of a vector + #[inline] + pure fn init(&self) -> &self/[T] { init(*self) } + + /// Returns all but the last `n' elemnts of a vector + #[inline] + pure fn initn(&self, n: uint) -> &self/[T] { initn(*self, n) } + /// Reduce a vector from right to left #[inline] pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { @@ -2638,6 +2645,38 @@ mod tests { a.tailn(2); } + #[test] + fn test_init() { + let mut a = ~[11]; + assert a.init() == &[]; + a = ~[11, 12]; + assert a.init() == &[11]; + } + + #[init] + #[should_fail] + #[ignore(cfg(windows))] + fn test_init_empty() { + let a: ~[int] = ~[]; + a.init(); + } + + #[test] + fn test_initn() { + let mut a = ~[11, 12, 13]; + assert a.initn(0) == &[11, 12, 13]; + a = ~[11, 12, 13]; + assert a.initn(2) == &[11]; + } + + #[init] + #[should_fail] + #[ignore(cfg(windows))] + fn test_initn_empty() { + let a: ~[int] = ~[]; + a.initn(2); + } + #[test] fn test_last() { let mut n = last_opt(~[]); @@ -3317,12 +3356,6 @@ mod tests { assert (v2[1] == 10); } - #[test] - fn test_init() { - let v = init(~[1, 2, 3]); - assert v == ~[1, 2]; - } - #[test] fn test_split() { fn f(x: &int) -> bool { *x == 3 } @@ -3387,13 +3420,6 @@ mod tests { (~[], ~[1, 2, 3]); } - #[test] - #[should_fail] - #[ignore(cfg(windows))] - fn test_init_empty() { - init::<int>(~[]); - } - #[test] fn test_concat() { assert concat(~[~[1], ~[2,3]]) == ~[1, 2, 3]; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index aa18c1eb450bd..0bf1fc3870449 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -558,7 +558,10 @@ pub fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt, -> csearch::found_ast { debug!("Looking up item: %d", id); let item_doc = lookup_item(id, cdata.data); - let path = vec::init(item_path(intr, item_doc)); + let path = { + let item_path = item_path(intr, item_doc); + vec::from_slice(item_path.init()) + }; match decode_inlined_item(cdata, tcx, path, item_doc) { Some(ref ii) => csearch::found((/*bad*/copy *ii)), None => { @@ -566,8 +569,7 @@ pub fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt, Some(did) => { let did = translate_def_id(cdata, did); let parent_item = lookup_item(did.node, cdata.data); - match decode_inlined_item(cdata, tcx, path, - parent_item) { + match decode_inlined_item(cdata, tcx, path, parent_item) { Some(ref ii) => csearch::found_parent(did, (/*bad*/copy *ii)), None => csearch::not_found } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 644b2c5145441..12a2011ad2560 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3815,7 +3815,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::init(*path), + vec::append_one(vec::from_slice(vec::init(*path)), ast_map::path_name((*variant).node.name)) } From 8f263dd0238ff85943a794bd3214ffa64b764a64 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 3 Mar 2013 08:50:20 -0800 Subject: [PATCH 7/9] rustc: remove some copies --- src/librustc/metadata/creader.rs | 2 +- src/librustc/metadata/loader.rs | 13 +++++++------ src/librustc/middle/astencode.rs | 2 +- src/librustc/middle/check_match.rs | 6 +++--- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index c7c81d0b1c06c..0776611342a3b 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -65,7 +65,7 @@ struct cache_entry { metas: @~[@ast::meta_item] } -fn dump_crates(+crate_cache: @mut ~[cache_entry]) { +fn dump_crates(crate_cache: @mut ~[cache_entry]) { debug!("resolved crates:"); for crate_cache.each |entry| { debug!("cnum: %?", entry.cnum); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index da7f3635c0e24..0fdea7abebf33 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -84,11 +84,12 @@ fn libname(cx: Context) -> (~str, ~str) { (str::from_slice(dll_prefix), str::from_slice(dll_suffix)) } -fn find_library_crate_aux(cx: Context, - (prefix, suffix): (~str, ~str), - filesearch: filesearch::FileSearch) -> - Option<(~str, @~[u8])> { - let crate_name = crate_name_from_metas(/*bad*/copy cx.metas); +fn find_library_crate_aux( + cx: Context, + (prefix, suffix): (~str, ~str), + filesearch: filesearch::FileSearch +) -> Option<(~str, @~[u8])> { + let crate_name = crate_name_from_metas(cx.metas); let prefix: ~str = prefix + *crate_name + ~"-"; let suffix: ~str = /*bad*/copy suffix; @@ -140,7 +141,7 @@ fn find_library_crate_aux(cx: Context, } } -pub fn crate_name_from_metas(+metas: &[@ast::meta_item]) -> @~str { +pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @~str { let name_items = attr::find_meta_items_by_name(metas, ~"name"); match vec::last_opt(name_items) { Some(i) => { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 016daf3ac9f5f..cf88a0eb90240 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -105,7 +105,7 @@ pub fn encode_inlined_item(ecx: @e::EncodeContext, pub fn decode_inlined_item(cdata: @cstore::crate_metadata, tcx: ty::ctxt, maps: Maps, - +path: ast_map::path, + path: ast_map::path, par_doc: ebml::Doc) -> Option<ast::inlined_item> { let dcx = @DecodeContext { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 7dd31374fc677..f43fd75864903 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -71,7 +71,7 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) { arm.pats); } - check_arms(cx, (/*bad*/copy *arms)); + check_arms(cx, *arms); /* Check for exhaustiveness */ // Check for empty enum, because is_useful only works on inhabited // types. @@ -108,12 +108,12 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) { } // Check for unreachable patterns -pub fn check_arms(cx: @MatchCheckCtxt, arms: ~[arm]) { +pub fn check_arms(cx: @MatchCheckCtxt, arms: &[arm]) { let mut seen = ~[]; for arms.each |arm| { for arm.pats.each |pat| { let v = ~[*pat]; - match is_useful(cx, copy seen, v) { + match is_useful(cx, &seen, v) { not_useful => { cx.tcx.sess.span_err(pat.span, ~"unreachable pattern"); } From a18bf8c67d99385ce4db6083ed8d4368c5b6ccfe Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 3 Mar 2013 11:44:11 -0800 Subject: [PATCH 8/9] rustc: minor code cleanup --- src/librustc/metadata/loader.rs | 2 +- src/librustc/middle/check_match.rs | 16 ++++++++-------- src/librustc/middle/pat_util.rs | 2 +- src/librustdoc/config.rs | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 0fdea7abebf33..76080ece3d869 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -97,7 +97,7 @@ fn find_library_crate_aux( filesearch::search(filesearch, |path| { debug!("inspecting file %s", path.to_str()); let f: ~str = path.filename().get(); - if !(str::starts_with(f, prefix) && str::ends_with(f, suffix)) { + if !(f.starts_with(prefix) && f.ends_with(suffix)) { debug!("skipping %s, doesn't look like %s*%s", path.to_str(), prefix, suffix); option::None::<()> diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index f43fd75864903..f9f655d50218f 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -133,7 +133,7 @@ pub fn raw_pat(p: @pat) -> @pat { pub fn check_exhaustive(cx: @MatchCheckCtxt, sp: span, pats: ~[@pat]) { assert(!pats.is_empty()); - let ext = match is_useful(cx, vec::map(pats, |p| ~[*p]), ~[wild()]) { + let ext = match is_useful(cx, &pats.map(|p| ~[*p]), ~[wild()]) { not_useful => { // This is good, wildcard pattern isn't reachable return; @@ -165,7 +165,7 @@ pub fn check_exhaustive(cx: @MatchCheckCtxt, sp: span, pats: ~[@pat]) { ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { match *ctor { vec(n) => Some(@fmt!("vectors of length %u", n)), - _ => None + _ => None } } _ => None @@ -205,10 +205,10 @@ pub enum ctor { // Note: is_useful doesn't work on empty types, as the paper notes. // So it assumes that v is non-empty. -pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful { +pub fn is_useful(cx: @MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { if m.len() == 0u { return useful_; } if m[0].len() == 0u { return not_useful; } - let real_pat = match vec::find(m, |r| r[0].id != 0) { + let real_pat = match m.find(|r| r[0].id != 0) { Some(r) => r[0], None => v[0] }; let left_ty = if real_pat.id == 0 { ty::mk_nil(cx.tcx) } @@ -264,7 +264,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful { } Some(ref ctor) => { match is_useful(cx, - vec::filter_map(m, |r| default(cx, r)), + &m.filter_mapped(|r| default(cx, *r)), v.tail()) { useful_ => useful(left_ty, (/*bad*/copy *ctor)), ref u => (/*bad*/copy *u) @@ -280,7 +280,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful { } pub fn is_useful_specialized(cx: @MatchCheckCtxt, - m: matrix, + m: &matrix, v: &[@pat], +ctor: ctor, arity: uint, @@ -288,7 +288,7 @@ pub fn is_useful_specialized(cx: @MatchCheckCtxt, -> useful { let ms = m.filter_mapped(|r| specialize(cx, *r, ctor, arity, lty)); let could_be_useful = is_useful( - cx, ms, specialize(cx, v, ctor, arity, lty).get()); + cx, &ms, specialize(cx, v, ctor, arity, lty).get()); match could_be_useful { useful_ => useful(lty, ctor), ref u => (/*bad*/copy *u) @@ -347,7 +347,7 @@ pub fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool { } pub fn missing_ctor(cx: @MatchCheckCtxt, - m: matrix, + m: &matrix, left_ty: ty::t) -> Option<ctor> { match ty::get(left_ty).sty { diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index df9b9aa137464..77ad7df531978 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -26,7 +26,7 @@ pub fn pat_id_map(dm: resolve::DefMap, pat: @pat) -> PatIdMap { do pat_bindings(dm, pat) |_bm, p_id, _s, n| { map.insert(path_to_ident(n), p_id); }; - return map; + map } pub fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: @pat) -> bool { diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 58316110b64ed..83ef5a6f3a855 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -130,18 +130,18 @@ pub fn parse_config_( let args = args.tail(); let opts = vec::unzip(opts()).first(); match getopts::getopts(args, opts) { - result::Ok(matches) => { + Ok(matches) => { if matches.free.len() == 1 { - let input_crate = Path(copy *matches.free.head()); + let input_crate = Path(*matches.free.head()); config_from_opts(&input_crate, &matches, program_output) } else if matches.free.is_empty() { - result::Err(~"no crates specified") + Err(~"no crates specified") } else { - result::Err(~"multiple crates specified") + Err(~"multiple crates specified") } } - result::Err(f) => { - result::Err(getopts::fail_str(f)) + Err(f) => { + Err(getopts::fail_str(f)) } } } From 743cfce7032e3b0649c22bf1c397280192bf9e95 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Tue, 5 Mar 2013 19:39:18 -0800 Subject: [PATCH 9/9] core: convert vec::{last,last_opt} to return references --- src/libcore/vec.rs | 61 +++++++++++++++--------- src/librustc/metadata/creader.rs | 4 +- src/librustc/metadata/loader.rs | 4 +- src/librustc/middle/resolve.rs | 14 +++--- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 14 +++--- src/librustpkg/util.rs | 8 ++-- src/libstd/bigint.rs | 4 +- src/libstd/json.rs | 2 +- src/libstd/priority_queue.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/attr.rs | 2 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/test/bench/task-perf-alloc-unwind.rs | 2 +- src/test/run-pass/zip-same-length.rs | 2 +- 15 files changed, 74 insertions(+), 51 deletions(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 2884d44861072..1be0daf21ba94 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -212,7 +212,7 @@ pub pure fn build_sized_opt<A>(size: Option<uint>, /// Returns the first element of a vector pub pure fn head<T>(v: &r/[T]) -> &r/T { - if v.len() == 0 { fail!(~"last_unsafe: empty vector") } + if v.len() == 0 { fail!(~"head: empty vector") } &v[0] } @@ -237,18 +237,15 @@ pub pure fn initn<T>(v: &r/[T], n: uint) -> &r/[T] { } /// Returns the last element of the slice `v`, failing if the slice is empty. -pub pure fn last<T:Copy>(v: &[const T]) -> T { - if len(v) == 0u { fail!(~"last_unsafe: empty vector") } - v[len(v) - 1u] +pub pure fn last<T>(v: &r/[T]) -> &r/T { + if v.len() == 0 { fail!(~"last: empty vector") } + &v[v.len() - 1] } -/** - * Returns `Some(x)` where `x` is the last element of the slice `v`, - * or `none` if the vector is empty. - */ -pub pure fn last_opt<T:Copy>(v: &[const T]) -> Option<T> { - if len(v) == 0u { return None; } - Some(v[len(v) - 1u]) +/// Returns `Some(x)` where `x` is the last element of the slice `v`, or +/// `None` if the vector is empty. +pub pure fn last_opt<T>(v: &r/[T]) -> Option<&r/T> { + if v.len() == 0 { None } else { Some(&v[v.len() - 1]) } } /// Return a slice that points into another slice. @@ -1696,16 +1693,11 @@ impl<T> Container for &[const T] { } pub trait CopyableVector<T> { - pure fn last(&self) -> T; pure fn slice(&self, start: uint, end: uint) -> ~[T]; } /// Extension methods for vectors impl<T: Copy> CopyableVector<T> for &[const T] { - /// Returns the last element of a `v`, failing if the vector is empty. - #[inline] - pure fn last(&self) -> T { last(*self) } - /// Returns a copy of the elements from [`start`..`end`) from `v`. #[inline] pure fn slice(&self, start: uint, end: uint) -> ~[T] { @@ -1721,6 +1713,8 @@ pub trait ImmutableVector<T> { pure fn tailn(&self, n: uint) -> &self/[T]; pure fn init(&self) -> &self/[T]; pure fn initn(&self, n: uint) -> &self/[T]; + pure fn last(&self) -> &self/T; + pure fn last_opt(&self) -> Option<&self/T>; pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U]; pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U]; @@ -1762,6 +1756,14 @@ impl<T> ImmutableVector<T> for &[T] { #[inline] pure fn initn(&self, n: uint) -> &self/[T] { initn(*self, n) } + /// Returns the last element of a `v`, failing if the vector is empty. + #[inline] + pure fn last(&self) -> &self/T { last(*self) } + + /// Returns the last element of a `v`, failing if the vector is empty. + #[inline] + pure fn last_opt(&self) -> Option<&self/T> { last_opt(*self) } + /// Reduce a vector from right to left #[inline] pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { @@ -2679,12 +2681,27 @@ mod tests { #[test] fn test_last() { - let mut n = last_opt(~[]); - assert (n.is_none()); - n = last_opt(~[1, 2, 3]); - assert (n == Some(3)); - n = last_opt(~[1, 2, 3, 4, 5]); - assert (n == Some(5)); + let mut a = ~[11]; + assert a.last() == &11; + a = ~[11, 12]; + assert a.last() == &12; + } + + #[test] + #[should_fail] + fn test_last_empty() { + let a: ~[int] = ~[]; + a.last(); + } + + #[test] + fn test_last_opt() { + let mut a = ~[]; + assert a.last_opt() == None; + a = ~[11]; + assert a.last_opt().unwrap() == &11; + a = ~[11, 12]; + assert a.last_opt().unwrap() == &12; } #[test] diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 0776611342a3b..ff26000af9749 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -81,7 +81,9 @@ fn warn_if_multiple_versions(e: @mut Env, if crate_cache.len() != 0u { let name = loader::crate_name_from_metas( - /*bad*/copy *crate_cache.last().metas); + *crate_cache[crate_cache.len() - 1].metas + ); + let (matches, non_matches) = partition(crate_cache.map_to_vec(|&entry| { let othername = loader::crate_name_from_metas( diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 76080ece3d869..d45cefdbf081f 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -143,9 +143,9 @@ fn find_library_crate_aux( pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @~str { let name_items = attr::find_meta_items_by_name(metas, ~"name"); - match vec::last_opt(name_items) { + match name_items.last_opt() { Some(i) => { - match attr::get_meta_item_value_str(i) { + match attr::get_meta_item_value_str(*i) { Some(n) => n, // FIXME (#2406): Probably want a warning here since the user // is using the wrong type of meta item. diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 004d5ee14ad5b..49898885a6603 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1438,7 +1438,7 @@ pub impl Resolver { type_value_ns => AnyNS }; - let source_ident = full_path.idents.last(); + let source_ident = *full_path.idents.last(); let subclass = @SingleImport(binding, source_ident, ns); @@ -4087,7 +4087,7 @@ pub impl Resolver { // First, check to see whether the name is a primitive type. if path.idents.len() == 1 { - let name = path.idents.last(); + let name = *path.idents.last(); match self.primitive_type_table .primitive_types @@ -4110,7 +4110,7 @@ pub impl Resolver { debug!("(resolving type) resolved `%s` to \ type %?", *self.session.str_of( - path.idents.last()), + *path.idents.last()), def); result_def = Some(def); } @@ -4296,7 +4296,7 @@ pub impl Resolver { path.span, fmt!("not an enum variant: %s", *self.session.str_of( - path.idents.last()))); + *path.idents.last()))); } None => { self.session.span_err(path.span, @@ -4418,7 +4418,7 @@ pub impl Resolver { namespace); } - return self.resolve_identifier(path.idents.last(), + return self.resolve_identifier(*path.idents.last(), namespace, check_ribs, path.span); @@ -4552,7 +4552,7 @@ pub impl Resolver { } } - let name = path.idents.last(); + let name = *path.idents.last(); match self.resolve_definition_of_name_in_module(containing_module, name, namespace, @@ -4601,7 +4601,7 @@ pub impl Resolver { } } - let name = path.idents.last(); + let name = *path.idents.last(); match self.resolve_definition_of_name_in_module(containing_module, name, namespace, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 76c62919dfa0b..1926b2f2e5df7 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2207,7 +2207,7 @@ pub fn register_fn_fuller(ccx: @CrateContext, ast_map::path_to_str(path, ccx.sess.parse_sess.interner)); let ps = if attr::attrs_contains_name(attrs, "no_mangle") { - path_elt_to_str(path.last(), ccx.sess.parse_sess.interner) + path_elt_to_str(*path.last(), ccx.sess.parse_sess.interner) } else { mangle_exported_name(ccx, /*bad*/copy path, node_type) }; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index da8e27ba4fffa..61d0594d2274f 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -792,12 +792,14 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) match arg.pat.node { ast::pat_ident(_, path, _) => { // XXX: This is wrong; it should work for multiple bindings. - let mdnode = create_var(tg, - context.node, - *cx.sess.str_of(path.idents.last()), - filemd.node, - loc.line as int, - tymd.node); + let mdnode = create_var( + tg, + context.node, + *cx.sess.str_of(*path.idents.last()), + filemd.node, + loc.line as int, + tymd.node + ); let mdval = @Metadata { node: mdnode, diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 57d456f1bbf07..d7428ae15e7ef 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -57,7 +57,7 @@ pub fn parse_name(id: ~str) -> result::Result<~str, ~str> { } } - result::Ok(parts.last()) + result::Ok(copy *parts.last()) } struct ListenerFn { @@ -516,9 +516,11 @@ pub fn get_pkg(id: ~str, return result::Err(~"package not found"); } - result::Ok(sort::merge_sort(possibs, |v1, v2| { + let possibs = sort::merge_sort(possibs, |v1, v2| { v1.vers <= v2.vers - }).last()) + }); + + result::Ok(copy *possibs.last()) } pub fn add_pkg(pkg: &Package) -> bool { diff --git a/src/libstd/bigint.rs b/src/libstd/bigint.rs index 5a0928e6a1182..e8836c5866284 100644 --- a/src/libstd/bigint.rs +++ b/src/libstd/bigint.rs @@ -346,7 +346,7 @@ pub impl BigUint { } let mut shift = 0; - let mut n = other.data.last(); + let mut n = *other.data.last(); while n < (1 << BigDigit::bits - 2) { n <<= 1; shift += 1; @@ -384,7 +384,7 @@ pub impl BigUint { } let an = vec::slice(a.data, a.data.len() - n, a.data.len()); - let bn = b.data.last(); + let bn = *b.data.last(); let mut d = ~[]; let mut carry = 0; for vec::rev_each(an) |elt| { diff --git a/src/libstd/json.rs b/src/libstd/json.rs index d1a65517aad0f..7993f15f622c8 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -759,7 +759,7 @@ pub fn Decoder(json: Json) -> Decoder { priv impl Decoder { fn peek(&self) -> &self/Json { if self.stack.len() == 0 { self.stack.push(&self.json); } - vec::last(self.stack) + self.stack[self.stack.len() - 1] } fn pop(&self) -> &self/Json { diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index 4b92bd7543a7d..2a2c655cca9ee 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -197,7 +197,7 @@ mod tests { let mut sorted = merge_sort(data, le); let mut heap = from_vec(data); while !heap.is_empty() { - assert *heap.top() == sorted.last(); + assert heap.top() == sorted.last(); assert heap.pop() == sorted.pop(); } } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 680101e673c95..ba683004aeec7 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -31,7 +31,7 @@ pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner) } -pub pure fn path_to_ident(p: @path) -> ident { vec::last(p.idents) } +pub pure fn path_to_ident(p: @path) -> ident { copy *p.idents.last() } pub pure fn local_def(id: node_id) -> def_id { ast::def_id { crate: local_crate, node: id } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 7739a862432ee..fb7143f7c1438 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -229,7 +229,7 @@ fn last_meta_item_by_name(items: &[@ast::meta_item], name: &str) -> Option<@ast::meta_item> { let items = attr::find_meta_items_by_name(items, name); - vec::last_opt(items) + items.last_opt().map(|item| **item) } pub fn last_meta_item_value_str_by_name(items: &[@ast::meta_item], name: &str) diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 79264f7adf034..116ecc37d2e18 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -167,7 +167,7 @@ pub fn tt_next_token(r: @mut TtReader) -> TokenAndSpan { while r.cur.idx >= r.cur.readme.len() { /* done with this set; pop or repeat? */ if ! r.cur.dotdotdoted - || r.repeat_idx.last() == r.repeat_len.last() - 1 { + || { *r.repeat_idx.last() == *r.repeat_len.last() - 1 } { match r.cur.up { None => { diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 05781b20a9b3f..4a372d016f9cf 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -93,7 +93,7 @@ fn recurse_or_fail(depth: int, st: Option<State>) { fn_box: || @Cons((), fn_box()), tuple: (@Cons((), st.tuple.first()), ~Cons((), @*st.tuple.second())), - vec: st.vec + ~[@Cons((), st.vec.last())], + vec: st.vec + ~[@Cons((), *st.vec.last())], res: r(@Cons((), st.res._l)) } } diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs index 29b58cd643115..fdb6989b7bb37 100644 --- a/src/test/run-pass/zip-same-length.rs +++ b/src/test/run-pass/zip-same-length.rs @@ -35,5 +35,5 @@ pub fn main() { let ps = vec::zip(chars, ints); assert (ps.head() == &('a', 1u)); - assert (ps.last() == (j as char, 10u)); + assert (ps.last() == &(j as char, 10u)); }