about summary refs log tree commit diff
path: root/tests/ui/try-trait/try-operator-various-contexts.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/try-trait/try-operator-various-contexts.rs')
-rw-r--r--tests/ui/try-trait/try-operator-various-contexts.rs195
1 files changed, 195 insertions, 0 deletions
diff --git a/tests/ui/try-trait/try-operator-various-contexts.rs b/tests/ui/try-trait/try-operator-various-contexts.rs
new file mode 100644
index 00000000000..41c3679c96f
--- /dev/null
+++ b/tests/ui/try-trait/try-operator-various-contexts.rs
@@ -0,0 +1,195 @@
+//! Checks the functionality of the `?` operator in various syntactic contexts.
+
+//@ run-pass
+
+#![allow(dead_code)]
+
+use std::fs::File;
+use std::io::{self, Read};
+use std::num::ParseIntError;
+use std::str::FromStr;
+
+fn on_method() -> Result<i32, ParseIntError> {
+    Ok("1".parse::<i32>()? + "2".parse::<i32>()?)
+}
+
+fn in_chain() -> Result<String, ParseIntError> {
+    Ok("3".parse::<i32>()?.to_string())
+}
+
+fn on_call() -> Result<i32, ParseIntError> {
+    fn parse<T: FromStr>(s: &str) -> Result<T, T::Err> {
+        s.parse()
+    }
+
+    Ok(parse("4")?)
+}
+
+fn nested() -> Result<i32, ParseIntError> {
+    Ok("5".parse::<i32>()?.to_string().parse()?)
+}
+
+fn on_path() -> Result<i32, ParseIntError> {
+    let x = "6".parse::<i32>();
+
+    Ok(x?)
+}
+
+fn on_macro() -> Result<i32, ParseIntError> {
+    macro_rules! id {
+        ($e:expr) => {
+            $e
+        };
+    }
+
+    Ok(id!("7".parse::<i32>())?)
+}
+
+fn on_parens() -> Result<i32, ParseIntError> {
+    let x = "8".parse::<i32>();
+
+    Ok((x)?)
+}
+
+fn on_block() -> Result<i32, ParseIntError> {
+    let x = "9".parse::<i32>();
+
+    Ok({ x }?)
+}
+
+fn on_field() -> Result<i32, ParseIntError> {
+    struct Pair<A, B> {
+        a: A,
+        b: B,
+    }
+
+    let x = Pair { a: "10".parse::<i32>(), b: 0 };
+
+    Ok(x.a?)
+}
+
+fn on_tuple_field() -> Result<i32, ParseIntError> {
+    let x = ("11".parse::<i32>(), 0);
+
+    Ok(x.0?)
+}
+
+fn on_try() -> Result<i32, ParseIntError> {
+    let x = "12".parse::<i32>().map(|i| i.to_string().parse::<i32>());
+
+    Ok(x??)
+}
+
+fn on_binary_op() -> Result<i32, ParseIntError> {
+    let x = 13 - "14".parse::<i32>()?;
+    let y = "15".parse::<i32>()? - 16;
+    let z = "17".parse::<i32>()? - "18".parse::<i32>()?;
+
+    Ok(x + y + z)
+}
+
+fn on_index() -> Result<i32, ParseIntError> {
+    let x = [19];
+    let y = "0".parse::<usize>();
+
+    Ok(x[y?])
+}
+
+fn on_args() -> Result<i32, ParseIntError> {
+    fn sub(x: i32, y: i32) -> i32 {
+        x - y
+    }
+
+    let x = "20".parse();
+    let y = "21".parse();
+
+    Ok(sub(x?, y?))
+}
+
+fn on_if() -> Result<i32, ParseIntError> {
+    Ok(if true { "22".parse::<i32>() } else { "23".parse::<i32>() }?)
+}
+
+fn on_if_let() -> Result<i32, ParseIntError> {
+    Ok(if let Ok(..) = "24".parse::<i32>() { "25".parse::<i32>() } else { "26".parse::<i32>() }?)
+}
+
+fn on_match() -> Result<i32, ParseIntError> {
+    Ok(match "27".parse::<i32>() {
+        Err(..) => "28".parse::<i32>(),
+        Ok(..) => "29".parse::<i32>(),
+    }?)
+}
+
+fn tight_binding() -> Result<bool, ()> {
+    fn ok<T>(x: T) -> Result<T, ()> {
+        Ok(x)
+    }
+
+    let x = ok(true);
+    Ok(!x?)
+}
+
+// just type check
+fn merge_error() -> Result<i32, Error> {
+    let mut s = String::new();
+
+    File::open("foo.txt")?.read_to_string(&mut s)?;
+
+    Ok(s.parse::<i32>()? + 1)
+}
+
+fn main() {
+    assert_eq!(Ok(3), on_method());
+
+    assert_eq!(Ok("3".to_string()), in_chain());
+
+    assert_eq!(Ok(4), on_call());
+
+    assert_eq!(Ok(5), nested());
+
+    assert_eq!(Ok(6), on_path());
+
+    assert_eq!(Ok(7), on_macro());
+
+    assert_eq!(Ok(8), on_parens());
+
+    assert_eq!(Ok(9), on_block());
+
+    assert_eq!(Ok(10), on_field());
+
+    assert_eq!(Ok(11), on_tuple_field());
+
+    assert_eq!(Ok(12), on_try());
+
+    assert_eq!(Ok(-3), on_binary_op());
+
+    assert_eq!(Ok(19), on_index());
+
+    assert_eq!(Ok(-1), on_args());
+
+    assert_eq!(Ok(22), on_if());
+
+    assert_eq!(Ok(25), on_if_let());
+
+    assert_eq!(Ok(29), on_match());
+
+    assert_eq!(Ok(false), tight_binding());
+}
+
+enum Error {
+    Io(io::Error),
+    Parse(ParseIntError),
+}
+
+impl From<io::Error> for Error {
+    fn from(e: io::Error) -> Error {
+        Error::Io(e)
+    }
+}
+
+impl From<ParseIntError> for Error {
+    fn from(e: ParseIntError) -> Error {
+        Error::Parse(e)
+    }
+}