Skip to content

Use moving out of self to clean up unwrap functions #4222

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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: 3 additions & 0 deletions src/libcore/dvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ priv impl<A> DVec<A> {
self.data = move data;
}
}

#[inline(always)]
fn unwrap(self) -> ~[A] { unwrap(self) }
}

// In theory, most everything should work with any A, but in practice
Expand Down
8 changes: 8 additions & 0 deletions src/libcore/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ pub pure fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
}
}

impl<T, U> Either<T, U> {
#[inline(always)]
fn unwrap_left(self) -> T { unwrap_left(self) }

#[inline(always)]
fn unwrap_right(self) -> U { unwrap_right(self) }
}

#[test]
fn test_either_left() {
let val = Left(10);
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ impl<T> Data<T> {
op(unsafe{transmute_immut(&mut self.value)})
}
}

#[inline(always)]
fn unwrap(self) -> T { unwrap(self) }
}

#[test]
Expand Down
98 changes: 58 additions & 40 deletions src/libcore/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,6 @@ pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
}
}

pub pure fn expect<T>(opt: Option<T>, reason: ~str) -> T {
/*!
* Gets the value out of an option without copying, printing a
* specified message on failure.
*
* # Failure
*
* Fails if the value equals `none`
*/
if opt.is_some() { move option::unwrap(move opt) }
else { fail reason }
}

pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
//! Maps a `some` value by reference from one type to another

Expand Down Expand Up @@ -235,35 +222,46 @@ pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
unwrap(util::replace(opt, None))
}

pub pure fn unwrap_expect<T>(opt: Option<T>, reason: &str) -> T {
pub pure fn expect<T>(opt: Option<T>, reason: &str) -> T {
//! As unwrap, but with a specified failure message.
if opt.is_none() { fail reason.to_owned(); }
unwrap(move opt)
match move opt {
Some(move val) => val,
None => fail reason.to_owned(),
}
}

// Some of these should change to be &Option<T>, some should not. See below.
impl<T> Option<T> {
/// Returns true if the option equals `none`
pure fn is_none() -> bool { is_none(&self) }
#[inline(always)]
pure fn is_none(&self) -> bool { is_none(self) }

/// Returns true if the option contains some value
pure fn is_some() -> bool { is_some(&self) }
}
#[inline(always)]
pure fn is_some(&self) -> bool { is_some(self) }

impl<T> &Option<T> {
/**
* Update an optional value by optionally running its content by reference
* through a function that returns an option.
*/
pure fn chain_ref<U>(f: fn(x: &T) -> Option<U>) -> Option<U> {
#[inline(always)]
pure fn chain_ref<U>(&self, f: fn(x: &T) -> Option<U>) -> Option<U> {
chain_ref(self, f)
}

/// Maps a `some` value from one type to another by reference
#[inline(always)]
pure fn map<U>(&self, f: fn(x: &T) -> U) -> Option<U> { map(self, f) }

/// Applies a function to the contained value or returns a default
pure fn map_default<U>(def: U, f: fn(x: &T) -> U) -> U
{ map_default(self, move def, f) }
#[inline(always)]
pure fn map_default<U>(&self, def: U, f: fn(x: &T) -> U) -> U {
map_default(self, move def, f)
}

/// Performs an operation on the contained value by reference
pure fn iter(f: fn(x: &T)) { iter(self, f) }
/// Maps a `some` value from one type to another by reference
pure fn map<U>(f: fn(x: &T) -> U) -> Option<U> { map(self, f) }
#[inline(always)]
pure fn iter(&self, f: fn(x: &T)) { iter(self, f) }

/**
Gets an immutable reference to the value inside an option.

Expand All @@ -278,7 +276,29 @@ impl<T> &Option<T> {
Instead, prefer to use pattern matching and handle the `None`
case explicitly.
*/
pure fn get_ref() -> &self/T { get_ref(self) }
#[inline(always)]
pure fn get_ref(&self) -> &self/T { get_ref(self) }

/**
* Gets the value out of an option without copying.
*
* # Failure
*
* Fails if the value equals `none`
*/
#[inline(always)]
pure fn unwrap(self) -> T { unwrap(self) }

/**
* Gets the value out of an option, printing a specified message on
* failure
*
* # Failure
*
* Fails if the value equals `none`
*/
#[inline(always)]
pure fn expect(self, reason: &str) -> T { expect(self, reason) }
}

impl<T: Copy> Option<T> {
Expand All @@ -296,19 +316,17 @@ impl<T: Copy> Option<T> {
Instead, prefer to use pattern matching and handle the `None`
case explicitly.
*/
pure fn get() -> T { get(self) }
pure fn get_default(def: T) -> T { get_default(self, def) }
/**
* Gets the value out of an option, printing a specified message on
* failure
*
* # Failure
*
* Fails if the value equals `none`
*/
pure fn expect(reason: ~str) -> T { expect(self, move reason) }
#[inline(always)]
pure fn get(self) -> T { get(self) }

#[inline(always)]
pure fn get_default(self, def: T) -> T { get_default(self, def) }

/// Applies a function zero or more times until the result is none.
pure fn while_some(blk: fn(v: T) -> Option<T>) { while_some(self, blk) }
#[inline(always)]
pure fn while_some(self, blk: fn(v: T) -> Option<T>) {
while_some(self, blk)
}
}

#[test]
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ Fails if the sender closes the connection.
*/
pub fn recv<T: Owned, Tbuffer: Owned>(
p: RecvPacketBuffered<T, Tbuffer>) -> T {
option::unwrap_expect(try_recv(move p), "connection closed")
try_recv(move p).expect("connection closed")
}

/** Attempts to receive a message from a pipe.
Expand Down Expand Up @@ -1102,7 +1102,7 @@ impl<T: Owned> PortSet<T> : GenericPort<T> {
}

fn recv() -> T {
option::unwrap_expect(self.try_recv(), "port_set: endpoints closed")
self.try_recv().expect("port_set: endpoints closed")
}

}
Expand Down
87 changes: 43 additions & 44 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub pure fn to_either<T: Copy, U: Copy>(res: &Result<U, T>)
* ok(parse_bytes(buf))
* }
*/
pub fn chain<T, U, V>(res: Result<T, V>, op: fn(t: T)
pub pure fn chain<T, U, V>(res: Result<T, V>, op: fn(T)
-> Result<U, V>) -> Result<U, V> {
match move res {
Ok(move t) => op(move t),
Expand All @@ -130,7 +130,7 @@ pub fn chain<T, U, V>(res: Result<T, V>, op: fn(t: T)
* immediately returned. This function can be used to pass through a
* successful result while handling an error.
*/
pub fn chain_err<T, U, V>(
pub pure fn chain_err<T, U, V>(
res: Result<T, V>,
op: fn(t: V) -> Result<T, U>)
-> Result<T, U> {
Expand All @@ -154,7 +154,7 @@ pub fn chain_err<T, U, V>(
* print_buf(buf)
* }
*/
pub fn iter<T, E>(res: &Result<T, E>, f: fn(&T)) {
pub pure fn iter<T, E>(res: &Result<T, E>, f: fn(&T)) {
match *res {
Ok(ref t) => f(t),
Err(_) => ()
Expand All @@ -169,7 +169,7 @@ pub fn iter<T, E>(res: &Result<T, E>, f: fn(&T)) {
* This function can be used to pass through a successful result while
* handling an error.
*/
pub fn iter_err<T, E>(res: &Result<T, E>, f: fn(&E)) {
pub pure fn iter_err<T, E>(res: &Result<T, E>, f: fn(&E)) {
match *res {
Ok(_) => (),
Err(ref e) => f(e)
Expand All @@ -190,7 +190,7 @@ pub fn iter_err<T, E>(res: &Result<T, E>, f: fn(&E)) {
* parse_bytes(buf)
* }
*/
pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: fn(&T) -> U)
pub pure fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: fn(&T) -> U)
-> Result<U, E> {
match *res {
Ok(ref t) => Ok(op(t)),
Expand All @@ -206,7 +206,7 @@ pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: fn(&T) -> U)
* is immediately returned. This function can be used to pass through a
* successful result while handling an error.
*/
pub fn map_err<T: Copy, E, F: Copy>(res: &Result<T, E>, op: fn(&E) -> F)
pub pure fn map_err<T: Copy, E, F: Copy>(res: &Result<T, E>, op: fn(&E) -> F)
-> Result<T, F> {
match *res {
Ok(copy t) => Ok(t),
Expand All @@ -215,58 +215,55 @@ pub fn map_err<T: Copy, E, F: Copy>(res: &Result<T, E>, op: fn(&E) -> F)
}

impl<T, E> Result<T, E> {
#[inline(always)]
pure fn get_ref(&self) -> &self/T { get_ref(self) }

pure fn is_ok() -> bool { is_ok(&self) }
#[inline(always)]
pure fn is_ok(&self) -> bool { is_ok(self) }

pure fn is_err() -> bool { is_err(&self) }
#[inline(always)]
pure fn is_err(&self) -> bool { is_err(self) }

pure fn iter(f: fn(&T)) {
match self {
Ok(ref t) => f(t),
Err(_) => ()
}
#[inline(always)]
pure fn iter(&self, f: fn(&T)) { iter(self, f) }

#[inline(always)]
pure fn iter_err(&self, f: fn(&E)) { iter_err(self, f) }

#[inline(always)]
pure fn unwrap(self) -> T { unwrap(self) }

#[inline(always)]
pure fn unwrap_err(self) -> T { unwrap(self) }

#[inline(always)]
pure fn chain<U>(self, op: fn(T) -> Result<U,E>) -> Result<U,E> {
chain(self, op)
}

fn iter_err(f: fn(&E)) {
match self {
Ok(_) => (),
Err(ref e) => f(e)
}
#[inline(always)]
pure fn chain_err<F>(self, op: fn(E) -> Result<T,F>) -> Result<T,F> {
chain_err(self, op)
}
}

impl<T: Copy, E> Result<T, E> {
pure fn get() -> T { get(&self) }
#[inline(always)]
pure fn get(&self) -> T { get(self) }

fn map_err<F:Copy>(op: fn(&E) -> F) -> Result<T,F> {
match self {
Ok(copy t) => Ok(t),
Err(ref e) => Err(op(e))
}
#[inline(always)]
pure fn map_err<F:Copy>(&self, op: fn(&E) -> F) -> Result<T,F> {
map_err(self, op)
}
}

impl<T, E: Copy> Result<T, E> {
pure fn get_err() -> E { get_err(&self) }

fn map<U:Copy>(op: fn(&T) -> U) -> Result<U,E> {
match self {
Ok(ref t) => Ok(op(t)),
Err(copy e) => Err(e)
}
}
}

impl<T: Copy, E: Copy> Result<T, E> {
fn chain<U:Copy>(op: fn(t: T) -> Result<U,E>) -> Result<U,E> {
// XXX: Bad copy
chain(copy self, op)
}
#[inline(always)]
pure fn get_err(&self) -> E { get_err(self) }

fn chain_err<F:Copy>(op: fn(t: E) -> Result<T,F>) -> Result<T,F> {
// XXX: Bad copy
chain_err(copy self, op)
#[inline(always)]
pure fn map<U:Copy>(&self, op: fn(&T) -> U) -> Result<U,E> {
map(self, op)
}
}

Expand Down Expand Up @@ -360,15 +357,17 @@ pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
}

/// Unwraps a result, assuming it is an `ok(T)`
pub fn unwrap<T, U>(res: Result<T, U>) -> T {
#[inline(always)]
pub pure fn unwrap<T, U>(res: Result<T, U>) -> T {
match move res {
Ok(move t) => move t,
Err(_) => fail ~"unwrap called on an err result"
}
}

/// Unwraps a result, assuming it is an `err(U)`
pub fn unwrap_err<T, U>(res: Result<T, U>) -> U {
#[inline(always)]
pub pure fn unwrap_err<T, U>(res: Result<T, U>) -> U {
match move res {
Err(move u) => move u,
Ok(_) => fail ~"unwrap called on an ok result"
Expand Down
8 changes: 4 additions & 4 deletions src/libstd/par.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn map_slices<A: Copy Owned, B: Copy Owned>(

/// A parallel version of map.
pub fn map<A: Copy Owned, B: Copy Owned>(
xs: &[A], f: fn~((&A)) -> B) -> ~[B] {
xs: &[A], f: fn~(&A) -> B) -> ~[B] {
vec::concat(map_slices(xs, || {
fn~(_base: uint, slice : &[A], copy f) -> ~[B] {
vec::map(slice, |x| f(x))
Expand All @@ -95,7 +95,7 @@ pub fn map<A: Copy Owned, B: Copy Owned>(

/// A parallel version of mapi.
pub fn mapi<A: Copy Owned, B: Copy Owned>(xs: &[A],
f: fn~(uint, (&A)) -> B) -> ~[B] {
f: fn~(uint, &A) -> B) -> ~[B] {
let slices = map_slices(xs, || {
fn~(base: uint, slice : &[A], copy f) -> ~[B] {
vec::mapi(slice, |i, x| {
Expand Down Expand Up @@ -132,7 +132,7 @@ pub fn mapi_factory<A: Copy Owned, B: Copy Owned>(
}

/// Returns true if the function holds for all elements in the vector.
pub fn alli<A: Copy Owned>(xs: &[A], f: fn~(uint, (&A)) -> bool) -> bool {
pub fn alli<A: Copy Owned>(xs: &[A], f: fn~(uint, &A) -> bool) -> bool {
do vec::all(map_slices(xs, || {
fn~(base: uint, slice : &[A], copy f) -> bool {
vec::alli(slice, |i, x| {
Expand All @@ -143,7 +143,7 @@ pub fn alli<A: Copy Owned>(xs: &[A], f: fn~(uint, (&A)) -> bool) -> bool {
}

/// Returns true if the function holds for any elements in the vector.
pub fn any<A: Copy Owned>(xs: &[A], f: fn~(&(A)) -> bool) -> bool {
pub fn any<A: Copy Owned>(xs: &[A], f: fn~(&A) -> bool) -> bool {
do vec::any(map_slices(xs, || {
fn~(_base : uint, slice: &[A], copy f) -> bool {
vec::any(slice, |x| f(x))
Expand Down