Skip to content

Commit 4571175

Browse files
committed
stdlib: Make list::find do what the docs say it does.
Talked on #rust about this change, got approval from graydon and brson. Will bring up tomorrow at meeting to verify.
1 parent 3de30f4 commit 4571175

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

src/libstd/list.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ Apply function `f` to each element of `v`, starting from the first.
4040
When function `f` returns true then an option containing the element
4141
is returned. If `f` matches no elements then none is returned.
4242
"]
43-
fn find<T: copy, U: copy>(ls: list<T>, f: fn(T) -> option<U>)
44-
-> option<U> {
43+
fn find<T: copy>(ls: list<T>, f: fn(T) -> bool) -> option<T> {
4544
let ls = ls;
4645
loop {
4746
alt ls {
4847
cons(hd, tl) {
49-
alt f(hd) { none { ls = *tl; } some(rs) { ret some(rs); } }
48+
if f(hd) { ret some(hd); }
49+
ls = *tl;
5050
}
5151
nil { ret none; }
5252
}
@@ -195,16 +195,14 @@ mod tests {
195195

196196
#[test]
197197
fn test_find_success() {
198-
fn match(&&i: int) -> option<int> {
199-
ret if i == 2 { option::some(i) } else { option::none::<int> };
200-
}
198+
fn match(&&i: int) -> bool { ret i == 2; }
201199
let l = from_vec([0, 1, 2]);
202200
assert (list::find(l, match) == option::some(2));
203201
}
204202

205203
#[test]
206204
fn test_find_fail() {
207-
fn match(&&_i: int) -> option<int> { ret option::none::<int>; }
205+
fn match(&&_i: int) -> bool { ret false; }
208206
let l = from_vec([0, 1, 2]);
209207
let empty = list::nil::<int>;
210208
assert (list::find(l, match) == option::none::<int>);

src/rustc/middle/resolve.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,24 @@ fn is_exported(e: env, i: ident, m: @indexed_mod) -> bool {
14691469
|| e.resolve_unexported;
14701470
}
14711471

1472+
// A list search function. Applies `f` to each element of `v`, starting from
1473+
// the first. When `f` returns `some(x)`, `list_search` returns `some(x)`. If
1474+
// `f` returns `none` for every element, `list_search` returns `none`.
1475+
fn list_search<T: copy, U: copy>(ls: list<T>, f: fn(T) -> option<U>)
1476+
-> option<U> {
1477+
let ls = ls;
1478+
loop {
1479+
alt ls {
1480+
cons(hd, tl) {
1481+
let result = f(hd);
1482+
if !is_none(result) { ret result; }
1483+
ls = *tl;
1484+
}
1485+
nil { ret none; }
1486+
}
1487+
};
1488+
}
1489+
14721490
fn lookup_in_local_mod(e: env, node_id: node_id, sp: span, id: ident,
14731491
ns: namespace, dr: dir) -> option<def> {
14741492
let info = e.mod_map.get(node_id);
@@ -1479,7 +1497,7 @@ fn lookup_in_local_mod(e: env, node_id: node_id, sp: span, id: ident,
14791497
alt info.index.find(id) {
14801498
none { }
14811499
some(lst) {
1482-
let found = list::find(lst, bind lookup_in_mie(e, _, ns));
1500+
let found = list_search(lst, bind lookup_in_mie(e, _, ns));
14831501
if !is_none(found) {
14841502
ret found;
14851503
}
@@ -2072,7 +2090,7 @@ fn check_exports(e: @env) {
20722090
e.sess.span_fatal(sp, #fmt("undefined id %s in an export", id));
20732091
}
20742092
some(ms) {
2075-
let maybe_id = list::find(ms) {|m|
2093+
let maybe_id = list_search(ms) {|m|
20762094
alt m {
20772095
mie_item(@{node: item_enum(_, _), id, _}) { some(id) }
20782096
_ { none }

0 commit comments

Comments
 (0)