blob: 4b5bf8c55f2edbe680b8ff4fd89ee4793b4f182e [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
Alex Crichtonbfec0d32018-05-17 10:48:17 -070011extern crate proc_macro2;
David Tolnay65fb5662018-05-20 20:02:28 -070012extern crate syn;
Alex Crichtonbfec0d32018-05-17 10:48:17 -070013use proc_macro2::*;
David Tolnay65fb5662018-05-20 20:02:28 -070014use syn::*;
Arnavion02ef13f2017-04-25 00:54:31 -070015
16macro_rules! assert_let {
17 ($p:pat = $e:expr) => {
18 assert_let!($p = $e; {})
19 };
20
21 ($p:pat = $e:expr; $body:block) => {
22 if let $p = $e
23 $body
24 else {
25 panic!("Expected to match {} but got {:?}", stringify!($p), $e)
26 }
27 };
28}
29
30#[test]
31#[cfg(feature = "full")]
32fn test_catch_expr() {
33 // Taken from tests/rust/src/test/run-pass/catch-expr.rs
34 let raw = r#"
35 struct catch {}
36
37 pub fn main() {
38 let catch_result = do catch {
39 let x = 5;
40 x
41 };
42 assert_eq!(catch_result, 5);
43
44 let mut catch = true;
45 while catch { catch = false; }
46 assert_eq!(catch, false);
47
48 catch = if catch { false } else { true };
49 assert_eq!(catch, true);
50
51 match catch {
52 _ => {}
53 };
54
55 let catch_err = do catch {
56 Err(22)?;
57 Ok(1)
58 };
59 assert_eq!(catch_err, Err(22));
60
61 let catch_okay: Result<i32, i32> = do catch {
62 if false { Err(25)?; }
63 Ok::<(), i32>(())?;
64 Ok(28)
65 };
66 assert_eq!(catch_okay, Ok(28));
67
68 let catch_from_loop: Result<i32, i32> = do catch {
69 for i in 0..10 {
70 if i < 5 { Ok::<i32, i32>(i)?; } else { Err(i)?; }
71 }
72 Ok(22)
73 };
74 assert_eq!(catch_from_loop, Err(5));
75
76 let cfg_init;
77 let _res: Result<(), ()> = do catch {
78 cfg_init = 5;
79 Ok(())
80 };
81 assert_eq!(cfg_init, 5);
82
83 let cfg_init_2;
84 let _res: Result<(), ()> = do catch {
85 cfg_init_2 = 6;
86 Err(())?;
87 Ok(())
88 };
89 assert_eq!(cfg_init_2, 6);
90
91 let my_string = "test".to_string();
92 let res: Result<&str, ()> = do catch {
93 Ok(&my_string)
94 };
95 assert_eq!(res, Ok("test"));
96 }
97 "#;
98
David Tolnayc7a5d3d2017-06-04 12:11:05 -070099 let actual: File = syn::parse_str(raw).unwrap();
Arnavion02ef13f2017-04-25 00:54:31 -0700100
David Tolnayc6b55bc2017-11-09 22:48:38 -0800101 assert_let!(Item::Struct(ItemStruct { ref ident, .. }) = actual.items[0]; {
David Tolnay446f7d62018-05-20 17:58:15 -0700102 assert_eq!(ident, "catch");
David Tolnay63e3dee2017-06-03 20:13:17 -0700103 });
Arnavion02ef13f2017-04-25 00:54:31 -0700104
David Tolnayc6b55bc2017-11-09 22:48:38 -0800105 assert_let!(Item::Fn(ItemFn { ref block, .. }) = actual.items[1]; {
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 assert_let!(Stmt::Local(ref local) = block.stmts[0]; {
David Tolnay1f0b7b82018-01-06 16:07:14 -0800107 assert_let!(Local { init: Some((_, ref init_expr)), .. } = *local; {
David Tolnay8c91b882017-12-28 23:04:32 -0500108 assert_let!(Expr::Catch(..) = **init_expr);
Arnavion02ef13f2017-04-25 00:54:31 -0700109 });
110 });
111
Alex Crichton62a0a592017-05-22 13:58:53 -0700112 assert_let!(Stmt::Local(ref local) = block.stmts[2]; {
David Tolnay6fc475f2018-03-31 21:09:24 +0200113 assert_let!(Pat::Ident(PatIdent { by_ref: None, mutability: Some(_), ref ident, .. }) = local.pats.iter().next().unwrap(); {
David Tolnay446f7d62018-05-20 17:58:15 -0700114 assert_eq!(ident, "catch");
Arnavion02ef13f2017-04-25 00:54:31 -0700115 });
116 });
117
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 assert_let!(Stmt::Expr(ref expr) = block.stmts[3]; {
David Tolnay1f0b7b82018-01-06 16:07:14 -0800119 assert_let!(Expr::While(ExprWhile { ref cond, .. }) = *expr; {
David Tolnay8c91b882017-12-28 23:04:32 -0500120 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
Alex Crichtonbfec0d32018-05-17 10:48:17 -0700121 let name = Ident::new("catch", Span::call_site());
122 assert_eq!(*path, name.into());
Arnavion02ef13f2017-04-25 00:54:31 -0700123 });
124 });
125 });
126
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700127 assert_let!(Stmt::Semi(ref expr, _) = block.stmts[5]; {
David Tolnay1f0b7b82018-01-06 16:07:14 -0800128 assert_let!(Expr::Assign(ExprAssign { ref left, ref right, .. }) = *expr; {
David Tolnay8c91b882017-12-28 23:04:32 -0500129 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **left; {
Alex Crichtonbfec0d32018-05-17 10:48:17 -0700130 let name = Ident::new("catch", Span::call_site());
131 assert_eq!(*path, name.into());
Arnavion02ef13f2017-04-25 00:54:31 -0700132 });
133
David Tolnay8c91b882017-12-28 23:04:32 -0500134 assert_let!(Expr::If(ExprIf { ref cond, .. }) = **right; {
135 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
Alex Crichtonbfec0d32018-05-17 10:48:17 -0700136 let name = Ident::new("catch", Span::call_site());
137 assert_eq!(*path, name.into());
Arnavion02ef13f2017-04-25 00:54:31 -0700138 });
139 });
140 });
141 });
142
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143 assert_let!(Stmt::Semi(ref expr, _) = block.stmts[7]; {
David Tolnay1f0b7b82018-01-06 16:07:14 -0800144 assert_let!(Expr::Match(ExprMatch { ref expr, .. }) = *expr; {
David Tolnay8c91b882017-12-28 23:04:32 -0500145 assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **expr; {
Alex Crichtonbfec0d32018-05-17 10:48:17 -0700146 let name = Ident::new("catch", Span::call_site());
147 assert_eq!(*path, name.into());
Arnavion02ef13f2017-04-25 00:54:31 -0700148 });
149 });
150 });
151 });
152}