auto merge of #10854 : Kimundi/rust/result_compose_map_mutate_or, r=alexcrichton

This implements parts of the changes to `Option` I proposed and discussed in this thread: https://mail.mozilla.org/pipermail/rust-dev/2013-November/006254.html, and on IRC.

In short, the string "default" should not be used in any context that has nothing to do with the `std::default::Default` trait.

This PR consists of this change:
- Renamed `map_default -> map_or` and `mutate_default -> mutate_or_set`.
This commit is contained in:
bors 2014-01-07 17:56:32 -08:00
commit a121f7bab3
18 changed files with 43 additions and 44 deletions

View File

@ -191,7 +191,7 @@ impl<T> DList<T> {
/// Remove the last Node and return it, or None if the list is empty
#[inline]
fn pop_back_node(&mut self) -> Option<~Node<T>> {
self.list_tail.resolve().map_default(None, |tail| {
self.list_tail.resolve().map_or(None, |tail| {
self.length -= 1;
self.list_tail = tail.prev;
match tail.prev.resolve() {

View File

@ -100,7 +100,7 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> GlobIterator {
root.push(pat_root.get_ref());
}
let root_len = pat_root.map_default(0u, |p| p.as_vec().len());
let root_len = pat_root.map_or(0u, |p| p.as_vec().len());
let dir_patterns = pattern.slice_from(root_len.min(&pattern.len()))
.split_terminator(is_sep).map(|s| Pattern::new(s)).to_owned_vec();
@ -314,7 +314,7 @@ impl Pattern {
*/
pub fn matches_path(&self, path: &Path) -> bool {
// FIXME (#9639): This needs to handle non-utf8 paths
path.as_str().map_default(false, |s| {
path.as_str().map_or(false, |s| {
self.matches(s)
})
}
@ -332,7 +332,7 @@ impl Pattern {
*/
pub fn matches_path_with(&self, path: &Path, options: MatchOptions) -> bool {
// FIXME (#9639): This needs to handle non-utf8 paths
path.as_str().map_default(false, |s| {
path.as_str().map_or(false, |s| {
self.matches_with(s, options)
})
}

View File

@ -697,7 +697,7 @@ impl BigUint {
#[inline]
pub fn new(v: ~[BigDigit]) -> BigUint {
// omit trailing zeros
let new_len = v.iter().rposition(|n| *n != 0).map_default(0, |p| p + 1);
let new_len = v.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
if new_len == v.len() { return BigUint { data: v }; }
let mut v = v;

View File

@ -122,7 +122,7 @@ impl<T: Writer> Terminal<T> {
let inf = ti.unwrap();
let nc = if inf.strings.find_equiv(&("setaf")).is_some()
&& inf.strings.find_equiv(&("setab")).is_some() {
inf.numbers.find_equiv(&("colors")).map_default(0, |&n| n)
inf.numbers.find_equiv(&("colors")).map_or(0, |&n| n)
} else { 0 };
return Ok(Terminal {out: out, ti: inf, num_colors: nc});
@ -215,7 +215,7 @@ impl<T: Writer> Terminal<T> {
cap = self.ti.strings.find_equiv(&("op"));
}
}
let s = cap.map_default(Err(~"can't find terminfo capability `sgr0`"), |op| {
let s = cap.map_or(Err(~"can't find terminfo capability `sgr0`"), |op| {
expand(*op, [], &mut Variables::new())
});
if s.is_ok() {

View File

@ -820,7 +820,7 @@ impl<K: TotalOrd, V> TreeNode<K, V> {
// Remove left horizontal link by rotating right
fn skew<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
if node.left.as_ref().map_default(false, |x| x.level == node.level) {
if node.left.as_ref().map_or(false, |x| x.level == node.level) {
let mut save = node.left.take_unwrap();
swap(&mut node.left, &mut save.right); // save.right now None
swap(node, &mut save);
@ -831,8 +831,8 @@ fn skew<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
// Remove dual horizontal link by rotating left and increasing level of
// the parent
fn split<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
if node.right.as_ref().map_default(false,
|x| x.right.as_ref().map_default(false, |y| y.level == node.level)) {
if node.right.as_ref().map_or(false,
|x| x.right.as_ref().map_or(false, |y| y.level == node.level)) {
let mut save = node.right.take_unwrap();
swap(&mut node.right, &mut save.left); // save.left now None
save.level += 1;
@ -938,8 +938,8 @@ fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
};
if rebalance {
let left_level = save.left.as_ref().map_default(0, |x| x.level);
let right_level = save.right.as_ref().map_default(0, |x| x.level);
let left_level = save.left.as_ref().map_or(0, |x| x.level);
let right_level = save.right.as_ref().map_or(0, |x| x.level);
// re-balance, if necessary
if left_level < save.level - 1 || right_level < save.level - 1 {

View File

@ -927,7 +927,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
// check legality of moving out of the enum
// x @ Foo(..) is legal, but x @ Foo(y) isn't.
if sub.map_default(false, |p| pat_contains_bindings(def_map, p)) {
if sub.map_or(false, |p| pat_contains_bindings(def_map, p)) {
tcx.sess.span_err(
p.span,
"cannot bind by-move with sub-bindings");

View File

@ -300,8 +300,8 @@ impl DeadVisitor {
fn symbol_is_live(&mut self, id: ast::NodeId,
ctor_id: Option<ast::NodeId>) -> bool {
if self.live_symbols.contains(&id)
|| ctor_id.map_default(false,
|ctor| self.live_symbols.contains(&ctor)) {
|| ctor_id.map_or(false,
|ctor| self.live_symbols.contains(&ctor)) {
return true;
}
// If it's a type whose methods are live, then it's live, too.

View File

@ -256,7 +256,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
_ => true,
};
let tr = ty::impl_trait_ref(self.tcx, local_def(item.id));
let public_trait = tr.map_default(false, |tr| {
let public_trait = tr.map_or(false, |tr| {
!is_local(tr.def_id) ||
self.exported_items.contains(&tr.def_id.node)
});

View File

@ -165,7 +165,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
// See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
fcx.infcx().type_error_message_str_with_expected(pat.span,
|expected, actual| {
expected.map_default(~"", |e| {
expected.map_or(~"", |e| {
format!("mismatched types: expected `{}` but found {}",
e, actual)})},
Some(expected), ~"a structure pattern",
@ -214,7 +214,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
// See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
fcx.infcx().type_error_message_str_with_expected(pat.span,
|expected, actual| {
expected.map_default(~"", |e| {
expected.map_or(~"", |e| {
format!("mismatched types: expected `{}` but found {}",
e, actual)})},
Some(expected), ~"an enum or structure pattern",
@ -530,7 +530,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
// See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
fcx.infcx().type_error_message_str_with_expected(pat.span,
|expected, actual| {
expected.map_default(~"", |e| {
expected.map_or(~"", |e| {
format!("mismatched types: expected `{}` but found {}",
e, actual)})},
Some(expected), ~"a structure pattern",
@ -578,7 +578,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
};
// See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
fcx.infcx().type_error_message_str_with_expected(pat.span, |expected, actual| {
expected.map_default(~"", |e| {
expected.map_or(~"", |e| {
format!("mismatched types: expected `{}` but found {}",
e, actual)})}, Some(expected), ~"tuple", Some(&type_error));
fcx.write_error(pat.id);
@ -628,7 +628,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
fcx.infcx().type_error_message_str_with_expected(
pat.span,
|expected, actual| {
expected.map_default(~"", |e| {
expected.map_or(~"", |e| {
format!("mismatched types: expected `{}` but found {}",
e, actual)})},
Some(expected),
@ -687,7 +687,7 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
fcx.infcx().type_error_message_str_with_expected(
span,
|expected, actual| {
expected.map_default(~"", |e| {
expected.map_or(~"", |e| {
format!("mismatched types: expected `{}` but found {}",
e, actual)})},
Some(expected),

View File

@ -141,7 +141,7 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
// Substitute the values of the type parameters that may
// appear in the bound.
let trait_ref = substs.as_ref().map_default(trait_ref, |substs| {
let trait_ref = substs.as_ref().map_or(trait_ref, |substs| {
debug!("about to subst: {}, {}",
trait_ref.repr(tcx), substs.repr(tcx));
trait_ref.subst(tcx, *substs)
@ -334,7 +334,7 @@ fn search_for_vtable(vcx: &VtableContext,
let trait_impls = tcx.trait_impls.borrow();
trait_impls.get()
.find(&trait_ref.def_id)
.map_default(@RefCell::new(~[]), |x| *x)
.map_or(@RefCell::new(~[]), |x| *x)
};
// impls is the list of all impls in scope for trait_ref.
let impls = impls.borrow();

View File

@ -747,13 +747,13 @@ impl InferCtxt {
err: Option<&ty::type_err>) {
debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
let error_str = err.map_default(~"", |t_err| {
let error_str = err.map_or(~"", |t_err| {
format!(" ({})", ty::type_err_to_str(self.tcx, t_err))
});
let resolved_expected = expected_ty.map(|e_ty| {
self.resolve_type_vars_if_possible(e_ty)
});
if !resolved_expected.map_default(false, |e| { ty::type_is_error(e) }) {
if !resolved_expected.map_or(false, |e| { ty::type_is_error(e) }) {
match resolved_expected {
None => self.tcx.sess.span_err(sp,
format!("{}{}", mk_msg(None, actual_ty), error_str)),

View File

@ -384,7 +384,7 @@ fn executable_exists(repo: &Path, short_name: &str) -> bool {
fn test_executable_exists(repo: &Path, short_name: &str) -> bool {
debug!("test_executable_exists: repo = {}, short_name = {}", repo.display(), short_name);
let exec = built_test_in_workspace(&CrateId::new(short_name), repo);
exec.map_default(false, |exec| exec.exists() && is_rwx(&exec))
exec.map_or(false, |exec| exec.exists() && is_rwx(&exec))
}
fn remove_executable_file(p: &CrateId, workspace: &Path) {
@ -600,8 +600,8 @@ fn test_install_valid() {
let lib = installed_library_in_workspace(&temp_pkg_id.path, temp_workspace);
debug!("lib = {:?}", lib);
assert!(lib.as_ref().map_default(false, |l| l.exists()));
assert!(lib.as_ref().map_default(false, |l| is_rwx(l)));
assert!(lib.as_ref().map_or(false, |l| l.exists()));
assert!(lib.as_ref().map_or(false, |l| is_rwx(l)));
// And that the test and bench executables aren't installed
assert!(!target_test_in_workspace(&temp_pkg_id, temp_workspace).exists());
@ -652,8 +652,8 @@ fn test_install_valid_external() {
let lib = installed_library_in_workspace(&temp_pkg_id.path, temp_workspace);
debug!("lib = {:?}", lib);
assert!(lib.as_ref().map_default(false, |l| l.exists()));
assert!(lib.as_ref().map_default(false, |l| is_rwx(l)));
assert!(lib.as_ref().map_or(false, |l| l.exists()));
assert!(lib.as_ref().map_or(false, |l| is_rwx(l)));
// And that the test and bench executables aren't installed
assert!(!target_test_in_workspace(&temp_pkg_id, temp_workspace).exists());
@ -947,7 +947,7 @@ fn rustpkg_clean_no_arg() {
assert_built_executable_exists(&tmp, "foo");
command_line_test([~"clean"], &package_dir);
let res = built_executable_in_workspace(&CrateId::new("foo"), &tmp);
assert!(!res.as_ref().map_default(false, |m| m.exists()));
assert!(!res.as_ref().map_or(false, |m| m.exists()));
}
#[test]

View File

@ -72,7 +72,7 @@ impl GetAddrInfoRequest {
ai_next: null(),
}
});
let hint_ptr = hint.as_ref().map_default(null(), |x| x as *uvll::addrinfo);
let hint_ptr = hint.as_ref().map_or(null(), |x| x as *uvll::addrinfo);
let mut req = Request::new(uvll::UV_GETADDRINFO);
return match unsafe {

View File

@ -1600,8 +1600,8 @@ impl<'a, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'a, A, T,
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let (flo, fhi) = self.frontiter.as_ref().map_default((0, Some(0)), |it| it.size_hint());
let (blo, bhi) = self.backiter.as_ref().map_default((0, Some(0)), |it| it.size_hint());
let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
let lo = flo.saturating_add(blo);
match (self.iter.size_hint(), fhi, bhi) {
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(&b)),

View File

@ -164,7 +164,7 @@ impl<T> Option<T> {
/// Applies a function to the contained value or returns a default.
#[inline]
pub fn map_default<U>(self, def: U, f: |T| -> U) -> U {
pub fn map_or<U>(self, def: U, f: |T| -> U) -> U {
match self { None => def, Some(t) => f(t) }
}
@ -179,7 +179,7 @@ impl<T> Option<T> {
/// Apply a function to the contained value or set it to a default.
/// Returns true if the contained value was mutated, or false if set to the default.
pub fn mutate_default(&mut self, def: T, f: |T| -> T) -> bool {
pub fn mutate_or_set(&mut self, def: T, f: |T| -> T) -> bool {
if self.is_some() {
*self = Some(f(self.take_unwrap()));
true
@ -695,12 +695,12 @@ mod tests {
let mut x = Some(3i);
assert!(x.mutate(|i| i+1));
assert_eq!(x, Some(4i));
assert!(x.mutate_default(0, |i| i+1));
assert!(x.mutate_or_set(0, |i| i+1));
assert_eq!(x, Some(5i));
x = None;
assert!(!x.mutate(|i| i+1));
assert_eq!(x, None);
assert!(!x.mutate_default(0i, |i| i+1));
assert!(!x.mutate_or_set(0i, |i| i+1));
assert_eq!(x, Some(0i));
}

View File

@ -255,7 +255,7 @@ impl GenericPathUnsafe for Path {
// if me is verbatim, we need to pre-normalize the new path
let path_ = if is_verbatim(me) { Path::normalize__(path, None) }
else { None };
let pathlen = path_.as_ref().map_default(path.len(), |p| p.len());
let pathlen = path_.as_ref().map_or(path.len(), |p| p.len());
let mut s = str::with_capacity(me.repr.len() + 1 + pathlen);
s.push_str(me.repr);
let plen = me.prefix_len();

View File

@ -314,12 +314,11 @@ fn highlight_lines(cm: &codemap::CodeMap,
fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) {
for ei in sp.expn_info.iter() {
let ss = ei.callee.span.as_ref().map_default(~"", |span| cm.span_to_str(*span));
let ss = ei.callee.span.as_ref().map_or(~"", |span| cm.span_to_str(*span));
let (pre, post) = match ei.callee.format {
codemap::MacroAttribute => ("#[", "]"),
codemap::MacroBang => ("", "!")
};
print_diagnostic(ss, note,
format!("in expansion of {}{}{}", pre, ei.callee.name, post));
let ss = cm.span_to_str(ei.call_site);

View File

@ -402,7 +402,7 @@ impl Parser {
fn tokens_to_str(tokens: &[token::Token]) -> ~str {
let mut i = tokens.iter();
// This might be a sign we need a connect method on Iterator.
let b = i.next().map_default(~"", |t| Parser::token_to_str(t));
let b = i.next().map_or(~"", |t| Parser::token_to_str(t));
i.fold(b, |b,a| b + "`, `" + Parser::token_to_str(a))
}
if edible.contains(&self.token) {
@ -467,7 +467,7 @@ impl Parser {
pub fn commit_stmt(&mut self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) {
debug!("commit_stmt {:?}", s);
let _s = s; // unused, but future checks might want to inspect `s`.
if self.last_token.as_ref().map_default(false, |t| is_ident_or_path(*t)) {
if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) {
let expected = vec::append(edible.to_owned(), inedible);
self.check_for_erroneous_unit_struct_expecting(expected);
}