blob: 2028af584f24eca767cf9453f0b998f3bea3febe [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
Alex Crichtonccbb45d2017-05-23 10:58:24 -07009#![cfg(feature = "extra-traits")]
10
Arnavion02ef13f2017-04-25 00:54:31 -070011extern crate syn;
12use syn::*;
13
14macro_rules! assert_let {
15 ($p:pat = $e:expr) => {
16 assert_let!($p = $e; {})
17 };
18
19 ($p:pat = $e:expr; $body:block) => {
20 if let $p = $e
21 $body
22 else {
23 panic!("Expected to match {} but got {:?}", stringify!($p), $e)
24 }
25 };
26}
27
28#[test]
29#[cfg(feature = "full")]
30fn test_catch_expr() {
31 // Taken from tests/rust/src/test/run-pass/catch-expr.rs
32 let raw = r#"
33 struct catch {}
34
35 pub fn main() {
36 let catch_result = do catch {
37 let x = 5;
38 x
39 };
40 assert_eq!(catch_result, 5);
41
42 let mut catch = true;
43 while catch { catch = false; }
44 assert_eq!(catch, false);
45
46 catch = if catch { false } else { true };
47 assert_eq!(catch, true);
48
49 match catch {
50 _ => {}
51 };
52
53 let catch_err = do catch {
54 Err(22)?;
55 Ok(1)
56 };
57 assert_eq!(catch_err, Err(22));
58
59 let catch_okay: Result<i32, i32> = do catch {
60 if false { Err(25)?; }
61 Ok::<(), i32>(())?;
62 Ok(28)
63 };
64 assert_eq!(catch_okay, Ok(28));
65
66 let catch_from_loop: Result<i32, i32> = do catch {
67 for i in 0..10 {
68 if i < 5 { Ok::<i32, i32>(i)?; } else { Err(i)?; }
69 }
70 Ok(22)
71 };
72 assert_eq!(catch_from_loop, Err(5));
73
74 let cfg_init;
75 let _res: Result<(), ()> = do catch {
76 cfg_init = 5;
77 Ok(())
78 };
79 assert_eq!(cfg_init, 5);
80
81 let cfg_init_2;
82 let _res: Result<(), ()> = do catch {
83 cfg_init_2 = 6;
84 Err(())?;
85 Ok(())
86 };
87 assert_eq!(cfg_init_2, 6);
88
89 let my_string = "test".to_string();
90 let res: Result<&str, ()> = do catch {
91 Ok(&my_string)
92 };
93 assert_eq!(res, Ok("test"));
94 }
95 "#;
96
David Tolnayc7a5d3d2017-06-04 12:11:05 -070097 let actual: File = syn::parse_str(raw).unwrap();
Arnavion02ef13f2017-04-25 00:54:31 -070098
David Tolnayc6b55bc2017-11-09 22:48:38 -080099 assert_let!(Item::Struct(ItemStruct { ref ident, .. }) = actual.items[0]; {
David Tolnay63e3dee2017-06-03 20:13:17 -0700100 assert_eq!(ident, "catch");
101 });
Arnavion02ef13f2017-04-25 00:54:31 -0700102
David Tolnayc6b55bc2017-11-09 22:48:38 -0800103 assert_let!(Item::Fn(ItemFn { ref block, .. }) = actual.items[1]; {
Alex Crichton62a0a592017-05-22 13:58:53 -0700104 assert_let!(Stmt::Local(ref local) = block.stmts[0]; {
David Tolnay8b4d3022017-12-29 12:11:10 -0500105 assert_let!(Local { init: Some((_, ref init_expr)), .. } = **local; {
David Tolnay8c91b882017-12-28 23:04:32 -0500106 assert_let!(Expr::Catch(..) = **init_expr);
Arnavion02ef13f2017-04-25 00:54:31 -0700107 });
108 });
109
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 assert_let!(Stmt::Local(ref local) = block.stmts[2]; {
David Tolnay24237fb2017-12-29 02:15:26 -0500111 assert_let!(Pat::Ident(PatIdent { by_ref: None, mutability: Some(_), ref ident, .. }) = *local.pat; {
Arnavion02ef13f2017-04-25 00:54:31 -0700112 assert_eq!(ident, "catch");
113 });
114 });
115
Alex Crichton62a0a592017-05-22 13:58:53 -0700116 assert_let!(Stmt::Expr(ref expr) = block.stmts[3]; {
David Tolnay8c91b882017-12-28 23:04:32 -0500117 assert_let!(Expr::While(ExprWhile { ref cond, .. }) = **expr; {
118 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
Alex Crichton62a0a592017-05-22 13:58:53 -0700119 assert_eq!(*path, "catch".into());
Arnavion02ef13f2017-04-25 00:54:31 -0700120 });
121 });
122 });
123
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700124 assert_let!(Stmt::Semi(ref expr, _) = block.stmts[5]; {
David Tolnay8c91b882017-12-28 23:04:32 -0500125 assert_let!(Expr::Assign(ExprAssign { ref left, ref right, .. }) = **expr; {
126 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **left; {
Alex Crichton62a0a592017-05-22 13:58:53 -0700127 assert_eq!(*path, "catch".into());
Arnavion02ef13f2017-04-25 00:54:31 -0700128 });
129
David Tolnay8c91b882017-12-28 23:04:32 -0500130 assert_let!(Expr::If(ExprIf { ref cond, .. }) = **right; {
131 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
Alex Crichton62a0a592017-05-22 13:58:53 -0700132 assert_eq!(*path, "catch".into());
Arnavion02ef13f2017-04-25 00:54:31 -0700133 });
134 });
135 });
136 });
137
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700138 assert_let!(Stmt::Semi(ref expr, _) = block.stmts[7]; {
David Tolnay8c91b882017-12-28 23:04:32 -0500139 assert_let!(Expr::Match(ExprMatch { ref expr, .. }) = **expr; {
140 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **expr; {
Alex Crichton62a0a592017-05-22 13:58:53 -0700141 assert_eq!(*path, "catch".into());
Arnavion02ef13f2017-04-25 00:54:31 -0700142 });
143 });
144 });
145 });
146}