Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernizing parts of Option, Result, and Default #9115

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
45c62c0
std: rename Option::unwrap_or_default() to unwrap_or()
erickt Sep 10, 2013
653400a
std: add default implementations to HashMap
erickt Sep 10, 2013
4a73c8e
std: add default implementations to Option
erickt Sep 10, 2013
f1374a7
libsyntax: add Default implementation to OptVec
erickt Sep 10, 2013
e6c1131
std: Add Option.{result_or_default,or_default} that uses Default
erickt Sep 10, 2013
2bd87ad
std: Add Default implementation for vecs
erickt Sep 10, 2013
7380b1c
std: Add Option.unwrap_or_else and a couple tests
erickt Sep 11, 2013
d625d4a
std: Add Option.{and,and_then,or,or_else}
erickt Sep 11, 2013
b8a284e
std: fix a warning
erickt Sep 11, 2013
ff34740
std: Add ToOption/IntoOption/AsOption
erickt Sep 11, 2013
12e0d7e
std: Add ToResult/IntoResult/AsResult
erickt Sep 11, 2013
e03d60e
std: Add ToEither/IntoEither/AsEither
erickt Sep 11, 2013
38f97ea
std: Rename {Option,Result}::chain{,_err}* to {and_then,or_else}
erickt Sep 11, 2013
ca47eeb
std: Add a bunch of Default impls
erickt Sep 12, 2013
a0e123e
syntax: add #[deriving(Default)] syntax extension
erickt Sep 12, 2013
43aba85
std: Remove Zero impl from vec
erickt Sep 12, 2013
f107718
std: Remove Zero impl for Option
erickt Sep 12, 2013
7c08abb
Document the Zero trait
erickt Sep 12, 2013
7f9c5aa
std: Restore Option::chain{,_mut}_ref as and_then{,_mut}_ref
erickt Sep 13, 2013
28eb49b
std: rename Option.chain to Option.and_then on windows
erickt Sep 13, 2013
93683ae
std: Fix another windows problem with the unwrap_or_default rename
erickt Sep 13, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -1717,7 +1717,8 @@ Supported traits for `deriving` are:
* `Clone` and `DeepClone`, to perform (deep) copies.
* `IterBytes`, to iterate over the bytes in a data type.
* `Rand`, to create a random instance of a data type.
* `Zero`, to create an zero (or empty) instance of a data type.
* `Default`, to create an empty instance of a data type.
* `Zero`, to create an zero instance of a numeric data type.
* `ToStr`, to convert to a string. For a type with this instance,
`obj.to_str()` has similar output as `fmt!("%?", obj)`, but it differs in that
each constituent field of the type must also implement `ToStr` and will have
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -2249,7 +2249,7 @@ enum ABC { A, B, C }

The full list of derivable traits is `Eq`, `TotalEq`, `Ord`,
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
`IterBytes`, `Rand`, `Zero`, and `ToStr`.
`IterBytes`, `Rand`, `Default`, `Zero`, and `ToStr`.

# Crates and the module system

Expand Down
2 changes: 1 addition & 1 deletion src/compiletest/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName {
let filename = path.filename();
let p = path.pop();
let dir = p.filename();
fmt!("%s/%s", dir.unwrap_or_default(""), filename.unwrap_or_default(""))
fmt!("%s/%s", dir.unwrap_or(""), filename.unwrap_or(""))
}

test::DynTestName(fmt!("[%s] %s",
Expand Down
46 changes: 43 additions & 3 deletions src/libextra/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,17 @@ fn list_dir_sorted(path: &Path) -> ~[Path] {
/**
* A compiled Unix shell style pattern.
*/
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Zero)]
#[cfg(stage0)]
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
pub struct Pattern {
priv tokens: ~[PatternToken]
}

/**
* A compiled Unix shell style pattern.
*/
#[cfg(not(stage0))]
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
pub struct Pattern {
priv tokens: ~[PatternToken]
}
Expand Down Expand Up @@ -312,7 +322,7 @@ impl Pattern {
let require_literal = |c| {
(options.require_literal_separator && is_sep(c)) ||
(options.require_literal_leading_dot && c == '.'
&& is_sep(prev_char.unwrap_or_default('/')))
&& is_sep(prev_char.unwrap_or('/')))
};

for (ti, token) in self.tokens.slice_from(i).iter().enumerate() {
Expand Down Expand Up @@ -458,7 +468,37 @@ fn is_sep(c: char) -> bool {
/**
* Configuration options to modify the behaviour of `Pattern::matches_with(..)`
*/
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Zero)]
#[cfg(stage0)]
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
pub struct MatchOptions {

/**
* Whether or not patterns should be matched in a case-sensitive manner. This
* currently only considers upper/lower case relationships between ASCII characters,
* but in future this might be extended to work with Unicode.
*/
case_sensitive: bool,

/**
* If this is true then path-component separator characters (e.g. `/` on Posix)
* must be matched by a literal `/`, rather than by `*` or `?` or `[...]`
*/
require_literal_separator: bool,

/**
* If this is true then paths that contain components that start with a `.` will
* not match unless the `.` appears literally in the pattern: `*`, `?` or `[...]`
* will not match. This is useful because such files are conventionally considered
* hidden on Unix systems and it might be desirable to skip them when listing files.
*/
require_literal_leading_dot: bool
}

/**
* Configuration options to modify the behaviour of `Pattern::matches_with(..)`
*/
#[cfg(not(stage0))]
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
pub struct MatchOptions {

/**
Expand Down
4 changes: 2 additions & 2 deletions src/libextra/num/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ impl BigUint {

// Converts this BigUint into an int, unless it would overflow.
pub fn to_int_opt(&self) -> Option<int> {
self.to_uint_opt().chain(|n| {
self.to_uint_opt().and_then(|n| {
// If top bit of uint is set, it's too large to convert to
// int.
if (n >> (2*BigDigit::bits - 1) != 0) {
Expand Down Expand Up @@ -1221,7 +1221,7 @@ impl BigInt {
match self.sign {
Plus => self.data.to_int_opt(),
Zero => Some(0),
Minus => self.data.to_uint_opt().chain(|n| {
Minus => self.data.to_uint_opt().and_then(|n| {
let m: uint = 1 << (2*BigDigit::bits-1);
if (n > m) {
None
Expand Down
8 changes: 4 additions & 4 deletions src/libextra/num/rational.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ impl<T: FromStr + Clone + Integer + Ord>
return None
}
let a_option: Option<T> = FromStr::from_str(split[0]);
do a_option.chain |a| {
do a_option.and_then |a| {
let b_option: Option<T> = FromStr::from_str(split[1]);
do b_option.chain |b| {
do b_option.and_then |b| {
Some(Ratio::new(a.clone(), b.clone()))
}
}
Expand All @@ -291,10 +291,10 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
} else {
let a_option: Option<T> = FromStrRadix::from_str_radix(split[0],
radix);
do a_option.chain |a| {
do a_option.and_then |a| {
let b_option: Option<T> =
FromStrRadix::from_str_radix(split[1], radix);
do b_option.chain |b| {
do b_option.and_then |b| {
Some(Ratio::new(a.clone(), b.clone()))
}
}
Expand Down
64 changes: 32 additions & 32 deletions src/libextra/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,21 +442,21 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
},
'c' => {
parse_type(s, pos, 'a', &mut *tm)
.chain(|pos| parse_char(s, pos, ' '))
.chain(|pos| parse_type(s, pos, 'b', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
.chain(|pos| parse_type(s, pos, 'e', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
.chain(|pos| parse_type(s, pos, 'T', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
.chain(|pos| parse_type(s, pos, 'Y', &mut *tm))
.and_then(|pos| parse_char(s, pos, ' '))
.and_then(|pos| parse_type(s, pos, 'b', &mut *tm))
.and_then(|pos| parse_char(s, pos, ' '))
.and_then(|pos| parse_type(s, pos, 'e', &mut *tm))
.and_then(|pos| parse_char(s, pos, ' '))
.and_then(|pos| parse_type(s, pos, 'T', &mut *tm))
.and_then(|pos| parse_char(s, pos, ' '))
.and_then(|pos| parse_type(s, pos, 'Y', &mut *tm))
}
'D' | 'x' => {
parse_type(s, pos, 'm', &mut *tm)
.chain(|pos| parse_char(s, pos, '/'))
.chain(|pos| parse_type(s, pos, 'd', &mut *tm))
.chain(|pos| parse_char(s, pos, '/'))
.chain(|pos| parse_type(s, pos, 'y', &mut *tm))
.and_then(|pos| parse_char(s, pos, '/'))
.and_then(|pos| parse_type(s, pos, 'd', &mut *tm))
.and_then(|pos| parse_char(s, pos, '/'))
.and_then(|pos| parse_type(s, pos, 'y', &mut *tm))
}
'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32,
31_i32) {
Expand All @@ -475,10 +475,10 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
}
'F' => {
parse_type(s, pos, 'Y', &mut *tm)
.chain(|pos| parse_char(s, pos, '-'))
.chain(|pos| parse_type(s, pos, 'm', &mut *tm))
.chain(|pos| parse_char(s, pos, '-'))
.chain(|pos| parse_type(s, pos, 'd', &mut *tm))
.and_then(|pos| parse_char(s, pos, '-'))
.and_then(|pos| parse_type(s, pos, 'm', &mut *tm))
.and_then(|pos| parse_char(s, pos, '-'))
.and_then(|pos| parse_type(s, pos, 'd', &mut *tm))
}
'H' => {
match match_digits_in_range(s, pos, 2u, false, 0_i32, 23_i32) {
Expand Down Expand Up @@ -553,17 +553,17 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
},
'R' => {
parse_type(s, pos, 'H', &mut *tm)
.chain(|pos| parse_char(s, pos, ':'))
.chain(|pos| parse_type(s, pos, 'M', &mut *tm))
.and_then(|pos| parse_char(s, pos, ':'))
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
}
'r' => {
parse_type(s, pos, 'I', &mut *tm)
.chain(|pos| parse_char(s, pos, ':'))
.chain(|pos| parse_type(s, pos, 'M', &mut *tm))
.chain(|pos| parse_char(s, pos, ':'))
.chain(|pos| parse_type(s, pos, 'S', &mut *tm))
.chain(|pos| parse_char(s, pos, ' '))
.chain(|pos| parse_type(s, pos, 'p', &mut *tm))
.and_then(|pos| parse_char(s, pos, ':'))
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
.and_then(|pos| parse_char(s, pos, ':'))
.and_then(|pos| parse_type(s, pos, 'S', &mut *tm))
.and_then(|pos| parse_char(s, pos, ' '))
.and_then(|pos| parse_type(s, pos, 'p', &mut *tm))
}
'S' => {
match match_digits_in_range(s, pos, 2u, false, 0_i32, 60_i32) {
Expand All @@ -578,10 +578,10 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
//'s' {}
'T' | 'X' => {
parse_type(s, pos, 'H', &mut *tm)
.chain(|pos| parse_char(s, pos, ':'))
.chain(|pos| parse_type(s, pos, 'M', &mut *tm))
.chain(|pos| parse_char(s, pos, ':'))
.chain(|pos| parse_type(s, pos, 'S', &mut *tm))
.and_then(|pos| parse_char(s, pos, ':'))
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
.and_then(|pos| parse_char(s, pos, ':'))
.and_then(|pos| parse_type(s, pos, 'S', &mut *tm))
}
't' => parse_char(s, pos, '\t'),
'u' => {
Expand All @@ -596,10 +596,10 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
}
'v' => {
parse_type(s, pos, 'e', &mut *tm)
.chain(|pos| parse_char(s, pos, '-'))
.chain(|pos| parse_type(s, pos, 'b', &mut *tm))
.chain(|pos| parse_char(s, pos, '-'))
.chain(|pos| parse_type(s, pos, 'Y', &mut *tm))
.and_then(|pos| parse_char(s, pos, '-'))
.and_then(|pos| parse_type(s, pos, 'b', &mut *tm))
.and_then(|pos| parse_char(s, pos, '-'))
.and_then(|pos| parse_type(s, pos, 'Y', &mut *tm))
}
//'W' {}
'w' => {
Expand Down
7 changes: 7 additions & 0 deletions src/libextra/uuid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,13 @@ impl Uuid {
}
}

impl Default for Uuid {
/// Returns the nil UUID, which is all zeroes
fn default() -> Uuid {
Uuid::new_nil()
}
}

impl Zero for Uuid {
/// Returns the nil UUID, which is all zeroes
fn zero() -> Uuid {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,9 +681,9 @@ pub fn build_session_options(binary: @str,
link::output_type_bitcode
} else { link::output_type_exe };
let sysroot_opt = getopts::opt_maybe_str(matches, "sysroot").map_move(|m| @Path(m));
let target = getopts::opt_maybe_str(matches, "target").unwrap_or_default(host_triple());
let target_cpu = getopts::opt_maybe_str(matches, "target-cpu").unwrap_or_default(~"generic");
let target_feature = getopts::opt_maybe_str(matches, "target-feature").unwrap_or_default(~"");
let target = getopts::opt_maybe_str(matches, "target").unwrap_or(host_triple());
let target_cpu = getopts::opt_maybe_str(matches, "target-cpu").unwrap_or(~"generic");
let target_feature = getopts::opt_maybe_str(matches, "target-feature").unwrap_or(~"");
let save_temps = getopts::opt_present(matches, "save-temps");
let opt_level = {
if (debugging_opts & session::no_opt) != 0 {
Expand Down Expand Up @@ -961,7 +961,7 @@ pub fn build_output_filenames(input: &input,
if !linkage_metas.is_empty() {
// But if a linkage meta is present, that overrides
let maybe_name = linkage_metas.iter().find(|m| "name" == m.name());
match maybe_name.chain(|m| m.value_str()) {
match maybe_name.and_then(|m| m.value_str()) {
Some(s) => stem = s,
_ => ()
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/front/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn filter_view_item<'r>(cx: @Context, view_item: &'r ast::view_item)-> Option<&'

fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod {
let filtered_items = do m.items.iter().filter_map |a| {
filter_item(cx, *a).chain(|x| fld.fold_item(x))
filter_item(cx, *a).and_then(|x| fld.fold_item(x))
}.collect();
let filtered_view_items = do m.view_items.iter().filter_map |a| {
do filter_view_item(cx, a).map_move |x| {
Expand Down Expand Up @@ -139,7 +139,7 @@ fn fold_block(
fld: @fold::ast_fold
) -> ast::Block {
let resulting_stmts = do b.stmts.iter().filter_map |a| {
filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt))
filter_stmt(cx, *a).and_then(|stmt| fld.fold_stmt(stmt))
}.collect();
let filtered_view_items = do b.view_items.iter().filter_map |a| {
filter_view_item(cx, a).map(|x| fld.fold_view_item(*x))
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ fn visit_item(e: &Env, i: @ast::item) {
ast::named => {
let link_name = i.attrs.iter()
.find(|at| "link_name" == at.name())
.chain(|at| at.value_str());
.and_then(|at| at.value_str());

let foreign_name = match link_name {
Some(nn) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
}

fn variant_disr_val(d: ebml::Doc) -> Option<ty::Disr> {
do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
do reader::maybe_get_doc(d, tag_disr_val).and_then |val_doc| {
do reader::with_doc_data(val_doc) |data| { u64::parse_bytes(data, 10u) }
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,7 @@ impl PrivacyVisitor {
// If the method is a default method, we need to use the def_id of
// the default implementation.
// Having to do this this is really unfortunate.
let method_id = ty::method(self.tcx, method_id).provided_source
.unwrap_or_default(method_id);
let method_id = ty::method(self.tcx, method_id).provided_source.unwrap_or(method_id);

if method_id.crate == LOCAL_CRATE {
let is_private = self.method_is_private(span, method_id.node);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ impl get_node_info for ast::Block {

impl get_node_info for Option<@ast::Expr> {
fn info(&self) -> Option<NodeInfo> {
self.chain_ref(|s| s.info())
self.and_then_ref(|s| s.info())
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/trans/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ impl Value {
/// must be the only user of this value, and there must not be any conditional
/// branches between the store and the given block.
pub fn get_dominating_store(self, bcx: @mut Block) -> Option<Value> {
match self.get_single_user().chain(|user| user.as_store_inst()) {
match self.get_single_user().and_then(|user| user.as_store_inst()) {
Some(store) => {
do store.get_parent().chain |store_bb| {
do store.get_parent().and_then |store_bb| {
let mut bb = BasicBlock(bcx.llbb);
let mut ret = Some(store);
while *bb != *store_bb {
Expand Down Expand Up @@ -150,7 +150,7 @@ impl Iterator<Value> for UserIterator {
fn next(&mut self) -> Option<Value> {
let current = self.next;

self.next = do current.chain |u| { u.get_next_use() };
self.next = do current.and_then |u| { u.get_next_use() };

do current.map |u| { u.get_user() }
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ pub fn ty_of_closure<AC:AstConv,RS:RegionScope + Clone + 'static>(
RegionParamNames(bound_lifetime_names.clone()));

let input_tys = do decl.inputs.iter().enumerate().map |(i, a)| {
let expected_arg_ty = do expected_sig.chain_ref |e| {
let expected_arg_ty = do expected_sig.and_then_ref |e| {
// no guarantee that the correct number of expected args
// were supplied
if i < e.inputs.len() {Some(e.inputs[i])} else {None}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::Pat, path: &ast::Path,
fcx.write_error(pat.id);
kind_name = "[error]";
arg_types = (*subpats).clone()
.unwrap_or_default(~[])
.unwrap_or_default()
.map(|_| ty::mk_err());
}
}
Expand Down Expand Up @@ -222,7 +222,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::Pat, path: &ast::Path,
fcx.write_error(pat.id);
kind_name = "[error]";
arg_types = (*subpats).clone()
.unwrap_or_default(~[])
.unwrap_or_default()
.map(|_| ty::mk_err());
}
}
Expand Down
Loading