From 4571175568bcce1544d7c6da5e38841cb2377735 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 12 Mar 2012 18:26:31 -0700 Subject: [PATCH] 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. --- src/libstd/list.rs | 12 +++++------- src/rustc/middle/resolve.rs | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 9f4254f20c4..a33ba0b647a 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -40,13 +40,13 @@ Apply function `f` to each element of `v`, starting from the first. When function `f` returns true then an option containing the element is returned. If `f` matches no elements then none is returned. "] -fn find(ls: list, f: fn(T) -> option) - -> option { +fn find(ls: list, f: fn(T) -> bool) -> option { let ls = ls; loop { alt ls { cons(hd, tl) { - alt f(hd) { none { ls = *tl; } some(rs) { ret some(rs); } } + if f(hd) { ret some(hd); } + ls = *tl; } nil { ret none; } } @@ -195,16 +195,14 @@ mod tests { #[test] fn test_find_success() { - fn match(&&i: int) -> option { - ret if i == 2 { option::some(i) } else { option::none:: }; - } + fn match(&&i: int) -> bool { ret i == 2; } let l = from_vec([0, 1, 2]); assert (list::find(l, match) == option::some(2)); } #[test] fn test_find_fail() { - fn match(&&_i: int) -> option { ret option::none::; } + fn match(&&_i: int) -> bool { ret false; } let l = from_vec([0, 1, 2]); let empty = list::nil::; assert (list::find(l, match) == option::none::); diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index 56d2cc973a0..9c6ebe8ee1b 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -1469,6 +1469,24 @@ fn is_exported(e: env, i: ident, m: @indexed_mod) -> bool { || e.resolve_unexported; } +// A list search function. Applies `f` to each element of `v`, starting from +// the first. When `f` returns `some(x)`, `list_search` returns `some(x)`. If +// `f` returns `none` for every element, `list_search` returns `none`. +fn list_search(ls: list, f: fn(T) -> option) + -> option { + let ls = ls; + loop { + alt ls { + cons(hd, tl) { + let result = f(hd); + if !is_none(result) { ret result; } + ls = *tl; + } + nil { ret none; } + } + }; +} + fn lookup_in_local_mod(e: env, node_id: node_id, sp: span, id: ident, ns: namespace, dr: dir) -> option { 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, alt info.index.find(id) { none { } some(lst) { - let found = list::find(lst, bind lookup_in_mie(e, _, ns)); + let found = list_search(lst, bind lookup_in_mie(e, _, ns)); if !is_none(found) { ret found; } @@ -2072,7 +2090,7 @@ fn check_exports(e: @env) { e.sess.span_fatal(sp, #fmt("undefined id %s in an export", id)); } some(ms) { - let maybe_id = list::find(ms) {|m| + let maybe_id = list_search(ms) {|m| alt m { mie_item(@{node: item_enum(_, _), id, _}) { some(id) } _ { none }