Skip to content

Commit

Permalink
auto merge of #9115 : erickt/rust/master, r=erickt
Browse files Browse the repository at this point in the history
This is a series of patches to modernize option and result. The highlights are:

* rename `.unwrap_or_default(value)` and etc to `.unwrap_or(value)`
* add `.unwrap_or_default()` that uses the `Default` trait
* add `Default` implementations for vecs, HashMap, Option
* add  `Option.and(T) -> Option<T>`, `Option.and_then(&fn() -> Option<T>) -> Option<T>`, `Option.or(T) -> Option<T>`, and `Option.or_else(&fn() -> Option<T>) -> Option<T>`
* add `option::ToOption`, `option::IntoOption`, `option::AsOption`, `result::ToResult`, `result::IntoResult`, `result::AsResult`, `either::ToEither`, and `either::IntoEither`, `either::AsEither`
* renamed `Option::chain*` and `Result::chain*` to `and_then` and `or_else` to avoid the eventual collision with `Iterator.chain`.
* Added a bunch of impls of `Default`
* Added a `#[deriving(Default)]` syntax extension
* Removed impls of `Zero` for `Option<T>` and vecs.
  • Loading branch information
bors committed Sep 14, 2013
2 parents 4ac10f8 + 93683ae commit 2aa578e
Show file tree
Hide file tree
Showing 55 changed files with 1,099 additions and 227 deletions.
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

0 comments on commit 2aa578e

Please sign in to comment.