Skip to content

Commit 743cfce

Browse files
committed
core: convert vec::{last,last_opt} to return references
1 parent a18bf8c commit 743cfce

File tree

15 files changed

+74
-51
lines changed

15 files changed

+74
-51
lines changed

src/libcore/vec.rs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ pub pure fn build_sized_opt<A>(size: Option<uint>,
212212

213213
/// Returns the first element of a vector
214214
pub pure fn head<T>(v: &r/[T]) -> &r/T {
215-
if v.len() == 0 { fail!(~"last_unsafe: empty vector") }
215+
if v.len() == 0 { fail!(~"head: empty vector") }
216216
&v[0]
217217
}
218218
@@ -237,18 +237,15 @@ pub pure fn initn<T>(v: &r/[T], n: uint) -> &r/[T] {
237237
}
238238
239239
/// Returns the last element of the slice `v`, failing if the slice is empty.
240-
pub pure fn last<T:Copy>(v: &[const T]) -> T {
241-
if len(v) == 0u { fail!(~"last_unsafe: empty vector") }
242-
v[len(v) - 1u]
240+
pub pure fn last<T>(v: &r/[T]) -> &r/T {
241+
if v.len() == 0 { fail!(~"last: empty vector") }
242+
&v[v.len() - 1]
243243
}
244244
245-
/**
246-
* Returns `Some(x)` where `x` is the last element of the slice `v`,
247-
* or `none` if the vector is empty.
248-
*/
249-
pub pure fn last_opt<T:Copy>(v: &[const T]) -> Option<T> {
250-
if len(v) == 0u { return None; }
251-
Some(v[len(v) - 1u])
245+
/// Returns `Some(x)` where `x` is the last element of the slice `v`, or
246+
/// `None` if the vector is empty.
247+
pub pure fn last_opt<T>(v: &r/[T]) -> Option<&r/T> {
248+
if v.len() == 0 { None } else { Some(&v[v.len() - 1]) }
252249
}
253250
254251
/// Return a slice that points into another slice.
@@ -1696,16 +1693,11 @@ impl<T> Container for &[const T] {
16961693
}
16971694

16981695
pub trait CopyableVector<T> {
1699-
pure fn last(&self) -> T;
17001696
pure fn slice(&self, start: uint, end: uint) -> ~[T];
17011697
}
17021698

17031699
/// Extension methods for vectors
17041700
impl<T: Copy> CopyableVector<T> for &[const T] {
1705-
/// Returns the last element of a `v`, failing if the vector is empty.
1706-
#[inline]
1707-
pure fn last(&self) -> T { last(*self) }
1708-
17091701
/// Returns a copy of the elements from [`start`..`end`) from `v`.
17101702
#[inline]
17111703
pure fn slice(&self, start: uint, end: uint) -> ~[T] {
@@ -1721,6 +1713,8 @@ pub trait ImmutableVector<T> {
17211713
pure fn tailn(&self, n: uint) -> &self/[T];
17221714
pure fn init(&self) -> &self/[T];
17231715
pure fn initn(&self, n: uint) -> &self/[T];
1716+
pure fn last(&self) -> &self/T;
1717+
pure fn last_opt(&self) -> Option<&self/T>;
17241718
pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U;
17251719
pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U];
17261720
pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U];
@@ -1762,6 +1756,14 @@ impl<T> ImmutableVector<T> for &[T] {
17621756
#[inline]
17631757
pure fn initn(&self, n: uint) -> &self/[T] { initn(*self, n) }
17641758

1759+
/// Returns the last element of a `v`, failing if the vector is empty.
1760+
#[inline]
1761+
pure fn last(&self) -> &self/T { last(*self) }
1762+
1763+
/// Returns the last element of a `v`, failing if the vector is empty.
1764+
#[inline]
1765+
pure fn last_opt(&self) -> Option<&self/T> { last_opt(*self) }
1766+
17651767
/// Reduce a vector from right to left
17661768
#[inline]
17671769
pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U {
@@ -2679,12 +2681,27 @@ mod tests {
26792681

26802682
#[test]
26812683
fn test_last() {
2682-
let mut n = last_opt(~[]);
2683-
assert (n.is_none());
2684-
n = last_opt(~[1, 2, 3]);
2685-
assert (n == Some(3));
2686-
n = last_opt(~[1, 2, 3, 4, 5]);
2687-
assert (n == Some(5));
2684+
let mut a = ~[11];
2685+
assert a.last() == &11;
2686+
a = ~[11, 12];
2687+
assert a.last() == &12;
2688+
}
2689+
2690+
#[test]
2691+
#[should_fail]
2692+
fn test_last_empty() {
2693+
let a: ~[int] = ~[];
2694+
a.last();
2695+
}
2696+
2697+
#[test]
2698+
fn test_last_opt() {
2699+
let mut a = ~[];
2700+
assert a.last_opt() == None;
2701+
a = ~[11];
2702+
assert a.last_opt().unwrap() == &11;
2703+
a = ~[11, 12];
2704+
assert a.last_opt().unwrap() == &12;
26882705
}
26892706

26902707
#[test]

src/librustc/metadata/creader.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ fn warn_if_multiple_versions(e: @mut Env,
8181

8282
if crate_cache.len() != 0u {
8383
let name = loader::crate_name_from_metas(
84-
/*bad*/copy *crate_cache.last().metas);
84+
*crate_cache[crate_cache.len() - 1].metas
85+
);
86+
8587
let (matches, non_matches) =
8688
partition(crate_cache.map_to_vec(|&entry| {
8789
let othername = loader::crate_name_from_metas(

src/librustc/metadata/loader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ fn find_library_crate_aux(
143143

144144
pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @~str {
145145
let name_items = attr::find_meta_items_by_name(metas, ~"name");
146-
match vec::last_opt(name_items) {
146+
match name_items.last_opt() {
147147
Some(i) => {
148-
match attr::get_meta_item_value_str(i) {
148+
match attr::get_meta_item_value_str(*i) {
149149
Some(n) => n,
150150
// FIXME (#2406): Probably want a warning here since the user
151151
// is using the wrong type of meta item.

src/librustc/middle/resolve.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,7 @@ pub impl Resolver {
14381438
type_value_ns => AnyNS
14391439
};
14401440
1441-
let source_ident = full_path.idents.last();
1441+
let source_ident = *full_path.idents.last();
14421442
let subclass = @SingleImport(binding,
14431443
source_ident,
14441444
ns);
@@ -4087,7 +4087,7 @@ pub impl Resolver {
40874087

40884088
// First, check to see whether the name is a primitive type.
40894089
if path.idents.len() == 1 {
4090-
let name = path.idents.last();
4090+
let name = *path.idents.last();
40914091

40924092
match self.primitive_type_table
40934093
.primitive_types
@@ -4110,7 +4110,7 @@ pub impl Resolver {
41104110
debug!("(resolving type) resolved `%s` to \
41114111
type %?",
41124112
*self.session.str_of(
4113-
path.idents.last()),
4113+
*path.idents.last()),
41144114
def);
41154115
result_def = Some(def);
41164116
}
@@ -4296,7 +4296,7 @@ pub impl Resolver {
42964296
path.span,
42974297
fmt!("not an enum variant: %s",
42984298
*self.session.str_of(
4299-
path.idents.last())));
4299+
*path.idents.last())));
43004300
}
43014301
None => {
43024302
self.session.span_err(path.span,
@@ -4418,7 +4418,7 @@ pub impl Resolver {
44184418
namespace);
44194419
}
44204420
4421-
return self.resolve_identifier(path.idents.last(),
4421+
return self.resolve_identifier(*path.idents.last(),
44224422
namespace,
44234423
check_ribs,
44244424
path.span);
@@ -4552,7 +4552,7 @@ pub impl Resolver {
45524552
}
45534553
}
45544554

4555-
let name = path.idents.last();
4555+
let name = *path.idents.last();
45564556
match self.resolve_definition_of_name_in_module(containing_module,
45574557
name,
45584558
namespace,
@@ -4601,7 +4601,7 @@ pub impl Resolver {
46014601
}
46024602
}
46034603

4604-
let name = path.idents.last();
4604+
let name = *path.idents.last();
46054605
match self.resolve_definition_of_name_in_module(containing_module,
46064606
name,
46074607
namespace,

src/librustc/middle/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2207,7 +2207,7 @@ pub fn register_fn_fuller(ccx: @CrateContext,
22072207
ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
22082208
22092209
let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
2210-
path_elt_to_str(path.last(), ccx.sess.parse_sess.interner)
2210+
path_elt_to_str(*path.last(), ccx.sess.parse_sess.interner)
22112211
} else {
22122212
mangle_exported_name(ccx, /*bad*/copy path, node_type)
22132213
};

src/librustc/middle/trans/debuginfo.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -792,12 +792,14 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span)
792792
match arg.pat.node {
793793
ast::pat_ident(_, path, _) => {
794794
// XXX: This is wrong; it should work for multiple bindings.
795-
let mdnode = create_var(tg,
796-
context.node,
797-
*cx.sess.str_of(path.idents.last()),
798-
filemd.node,
799-
loc.line as int,
800-
tymd.node);
795+
let mdnode = create_var(
796+
tg,
797+
context.node,
798+
*cx.sess.str_of(*path.idents.last()),
799+
filemd.node,
800+
loc.line as int,
801+
tymd.node
802+
);
801803
802804
let mdval = @Metadata {
803805
node: mdnode,

src/librustpkg/util.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub fn parse_name(id: ~str) -> result::Result<~str, ~str> {
5757
}
5858
}
5959

60-
result::Ok(parts.last())
60+
result::Ok(copy *parts.last())
6161
}
6262

6363
struct ListenerFn {
@@ -516,9 +516,11 @@ pub fn get_pkg(id: ~str,
516516
return result::Err(~"package not found");
517517
}
518518

519-
result::Ok(sort::merge_sort(possibs, |v1, v2| {
519+
let possibs = sort::merge_sort(possibs, |v1, v2| {
520520
v1.vers <= v2.vers
521-
}).last())
521+
});
522+
523+
result::Ok(copy *possibs.last())
522524
}
523525

524526
pub fn add_pkg(pkg: &Package) -> bool {

src/libstd/bigint.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ pub impl BigUint {
346346
}
347347

348348
let mut shift = 0;
349-
let mut n = other.data.last();
349+
let mut n = *other.data.last();
350350
while n < (1 << BigDigit::bits - 2) {
351351
n <<= 1;
352352
shift += 1;
@@ -384,7 +384,7 @@ pub impl BigUint {
384384
}
385385

386386
let an = vec::slice(a.data, a.data.len() - n, a.data.len());
387-
let bn = b.data.last();
387+
let bn = *b.data.last();
388388
let mut d = ~[];
389389
let mut carry = 0;
390390
for vec::rev_each(an) |elt| {

src/libstd/json.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ pub fn Decoder(json: Json) -> Decoder {
759759
priv impl Decoder {
760760
fn peek(&self) -> &self/Json {
761761
if self.stack.len() == 0 { self.stack.push(&self.json); }
762-
vec::last(self.stack)
762+
self.stack[self.stack.len() - 1]
763763
}
764764

765765
fn pop(&self) -> &self/Json {

src/libstd/priority_queue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ mod tests {
197197
let mut sorted = merge_sort(data, le);
198198
let mut heap = from_vec(data);
199199
while !heap.is_empty() {
200-
assert *heap.top() == sorted.last();
200+
assert heap.top() == sorted.last();
201201
assert heap.pop() == sorted.pop();
202202
}
203203
}

src/libsyntax/ast_util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner)
3131
}
3232

3333

34-
pub pure fn path_to_ident(p: @path) -> ident { vec::last(p.idents) }
34+
pub pure fn path_to_ident(p: @path) -> ident { copy *p.idents.last() }
3535

3636
pub pure fn local_def(id: node_id) -> def_id {
3737
ast::def_id { crate: local_crate, node: id }

src/libsyntax/attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ fn last_meta_item_by_name(items: &[@ast::meta_item], name: &str)
229229
-> Option<@ast::meta_item> {
230230

231231
let items = attr::find_meta_items_by_name(items, name);
232-
vec::last_opt(items)
232+
items.last_opt().map(|item| **item)
233233
}
234234

235235
pub fn last_meta_item_value_str_by_name(items: &[@ast::meta_item], name: &str)

src/libsyntax/ext/tt/transcribe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub fn tt_next_token(r: @mut TtReader) -> TokenAndSpan {
167167
while r.cur.idx >= r.cur.readme.len() {
168168
/* done with this set; pop or repeat? */
169169
if ! r.cur.dotdotdoted
170-
|| r.repeat_idx.last() == r.repeat_len.last() - 1 {
170+
|| { *r.repeat_idx.last() == *r.repeat_len.last() - 1 } {
171171

172172
match r.cur.up {
173173
None => {

src/test/bench/task-perf-alloc-unwind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ fn recurse_or_fail(depth: int, st: Option<State>) {
9393
fn_box: || @Cons((), fn_box()),
9494
tuple: (@Cons((), st.tuple.first()),
9595
~Cons((), @*st.tuple.second())),
96-
vec: st.vec + ~[@Cons((), st.vec.last())],
96+
vec: st.vec + ~[@Cons((), *st.vec.last())],
9797
res: r(@Cons((), st.res._l))
9898
}
9999
}

src/test/run-pass/zip-same-length.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ pub fn main() {
3535
let ps = vec::zip(chars, ints);
3636

3737
assert (ps.head() == &('a', 1u));
38-
assert (ps.last() == (j as char, 10u));
38+
assert (ps.last() == &(j as char, 10u));
3939
}

0 commit comments

Comments
 (0)