Skip to content

Commit cee2f21

Browse files
alecmocattaRustyYato
authored andcommitted
working on stable
1 parent 498d8db commit cee2f21

File tree

4 files changed

+77
-10
lines changed

4 files changed

+77
-10
lines changed

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(try_trait, alloc_layout_extra)]
21
#![forbid(missing_docs)]
32

43
/*!
@@ -172,7 +171,9 @@ impl<F: FnOnce()> Drop for OnDrop<F> {
172171
}
173172

174173
mod boxed;
174+
mod r#try;
175175
mod vec;
176176

177177
pub use self::boxed::*;
178+
pub use self::r#try::*;
178179
pub use self::vec::*;

src/try.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/// A stable version of [`core::ops::Try`].
2+
pub trait Try {
3+
/// The type of this value when viewed as successful.
4+
type Ok;
5+
/// The type of this value when viewed as failed.
6+
type Error;
7+
8+
/// A return of `Ok(t)` means that the
9+
/// execution should continue normally, and the result of `?` is the
10+
/// value `t`. A return of `Err(e)` means that execution should branch
11+
/// to the innermost enclosing `catch`, or return from the function.
12+
fn into_result(self) -> Result<Self::Ok, Self::Error>;
13+
14+
/// Wrap an error value to construct the composite result. For example,
15+
/// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
16+
fn from_error(v: Self::Error) -> Self;
17+
18+
/// Wrap an OK value to construct the composite result. For example,
19+
/// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
20+
fn from_ok(v: Self::Ok) -> Self;
21+
}
22+
23+
impl<T, E> Try for Result<T, E> {
24+
type Ok = T;
25+
type Error = E;
26+
27+
fn into_result(self) -> Result<<Self as Try>::Ok, <Self as Try>::Error> {
28+
self
29+
}
30+
fn from_error(v: <Self as Try>::Error) -> Self {
31+
Err(v)
32+
}
33+
fn from_ok(v: <Self as Try>::Ok) -> Self {
34+
Ok(v)
35+
}
36+
}
37+
38+
/// The error type that results from applying the try operator (`?`) to a `None` value.
39+
pub struct NoneError;
40+
41+
impl<T> Try for Option<T> {
42+
type Ok = T;
43+
type Error = NoneError;
44+
45+
fn into_result(self) -> Result<<Self as Try>::Ok, <Self as Try>::Error> {
46+
self.ok_or(NoneError)
47+
}
48+
fn from_error(_v: <Self as Try>::Error) -> Self {
49+
None
50+
}
51+
fn from_ok(v: <Self as Try>::Ok) -> Self {
52+
Some(v)
53+
}
54+
}
55+
56+
/// Unwraps a result or propagates its error.
57+
#[macro_export]
58+
macro_rules! r#try {
59+
($expr:expr) => {
60+
match $crate::Try::into_result($expr) {
61+
Ok(val) => val,
62+
Err(err) => return $crate::Try::from_error(::core::convert::From::from(err)),
63+
}
64+
};
65+
($expr:expr,) => {
66+
$crate::r#try!($expr)
67+
};
68+
}

src/vec.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use std::alloc::Layout;
12
use std::marker::PhantomData;
23
use std::mem::ManuallyDrop;
3-
use std::ops::Try;
44

5-
use std::alloc::Layout;
5+
use super::{r#try, Try};
66

77
mod general_zip;
88

@@ -214,7 +214,7 @@ impl<T, U> MapIter<T, U> {
214214
// does a pointer walk, easy for LLVM to optimize
215215
while self.init_len < self.data.len {
216216
unsafe {
217-
let value = f(self.data.ptr.read())?;
217+
let value = r#try!(f(self.data.ptr.read()));
218218

219219
(self.data.ptr as *mut U).write(value);
220220

@@ -303,7 +303,7 @@ impl<T, U, V> ZipWithIter<T, U, V> {
303303
self.left.ptr = self.left.ptr.add(1);
304304
self.right.ptr = self.right.ptr.add(1);
305305

306-
let value = f(left.read(), right.read())?;
306+
let value = r#try!(f(left.read(), right.read()));
307307

308308
out.write(value);
309309
}

src/vec/general_zip.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use super::{Input, Output};
2-
3-
#[doc(hidden)]
4-
pub use std::ops::Try;
51
use std::alloc::Layout;
62

3+
use super::{r#try, Input, Output, Try};
4+
75
use seal::Seal;
86
mod seal {
97
use super::*;
@@ -402,7 +400,7 @@ impl<V, In: Tuple> ZipWithIter<V, In> {
402400

403401
let input = In::next_unchecked(&mut self.input);
404402

405-
self.output.ptr.write(f(input)?);
403+
self.output.ptr.write(r#try!(f(input)));
406404
self.output.ptr = self.output.ptr.add(1);
407405
}
408406

0 commit comments

Comments
 (0)