1 #![allow(clippy::uninlined_format_args)]
2
3 #[macro_use]
4 mod macros;
5
6 use proc_macro2::{Delimiter, Group, TokenStream, TokenTree};
7 use quote::{quote, ToTokens as _};
8 use syn::parse::Parser;
9 use syn::punctuated::Punctuated;
10 use syn::{parse_quote, token, Item, Pat, PatTuple, Stmt, Token};
11
12 #[test]
test_pat_ident()13 fn test_pat_ident() {
14 match Pat::parse_single.parse2(quote!(self)).unwrap() {
15 Pat::Ident(_) => (),
16 value => panic!("expected PatIdent, got {:?}", value),
17 }
18 }
19
20 #[test]
test_pat_path()21 fn test_pat_path() {
22 match Pat::parse_single.parse2(quote!(self::CONST)).unwrap() {
23 Pat::Path(_) => (),
24 value => panic!("expected PatPath, got {:?}", value),
25 }
26 }
27
28 #[test]
test_leading_vert()29 fn test_leading_vert() {
30 // https://github.com/rust-lang/rust/blob/1.43.0/src/test/ui/or-patterns/remove-leading-vert.rs
31
32 syn::parse_str::<Item>("fn f() {}").unwrap();
33 syn::parse_str::<Item>("fn fun1(| A: E) {}").unwrap_err();
34 syn::parse_str::<Item>("fn fun2(|| A: E) {}").unwrap_err();
35
36 syn::parse_str::<Stmt>("let | () = ();").unwrap_err();
37 syn::parse_str::<Stmt>("let (| A): E;").unwrap();
38 syn::parse_str::<Stmt>("let (|| A): (E);").unwrap_err();
39 syn::parse_str::<Stmt>("let (| A,): (E,);").unwrap();
40 syn::parse_str::<Stmt>("let [| A]: [E; 1];").unwrap();
41 syn::parse_str::<Stmt>("let [|| A]: [E; 1];").unwrap_err();
42 syn::parse_str::<Stmt>("let TS(| A): TS;").unwrap();
43 syn::parse_str::<Stmt>("let TS(|| A): TS;").unwrap_err();
44 syn::parse_str::<Stmt>("let NS { f: | A }: NS;").unwrap();
45 syn::parse_str::<Stmt>("let NS { f: || A }: NS;").unwrap_err();
46 }
47
48 #[test]
test_group()49 fn test_group() {
50 let group = Group::new(Delimiter::None, quote!(Some(_)));
51 let tokens = TokenStream::from_iter(vec![TokenTree::Group(group)]);
52 let pat = Pat::parse_single.parse2(tokens).unwrap();
53
54 snapshot!(pat, @r###"
55 Pat::TupleStruct {
56 path: Path {
57 segments: [
58 PathSegment {
59 ident: "Some",
60 },
61 ],
62 },
63 elems: [
64 Pat::Wild,
65 ],
66 }
67 "###);
68 }
69
70 #[test]
test_ranges()71 fn test_ranges() {
72 Pat::parse_single.parse_str("..").unwrap();
73 Pat::parse_single.parse_str("..hi").unwrap();
74 Pat::parse_single.parse_str("lo..").unwrap();
75 Pat::parse_single.parse_str("lo..hi").unwrap();
76
77 Pat::parse_single.parse_str("..=").unwrap_err();
78 Pat::parse_single.parse_str("..=hi").unwrap();
79 Pat::parse_single.parse_str("lo..=").unwrap_err();
80 Pat::parse_single.parse_str("lo..=hi").unwrap();
81
82 Pat::parse_single.parse_str("...").unwrap_err();
83 Pat::parse_single.parse_str("...hi").unwrap_err();
84 Pat::parse_single.parse_str("lo...").unwrap_err();
85 Pat::parse_single.parse_str("lo...hi").unwrap();
86
87 Pat::parse_single.parse_str("[lo..]").unwrap_err();
88 Pat::parse_single.parse_str("[..=hi]").unwrap_err();
89 Pat::parse_single.parse_str("[(lo..)]").unwrap();
90 Pat::parse_single.parse_str("[(..=hi)]").unwrap();
91 Pat::parse_single.parse_str("[lo..=hi]").unwrap();
92
93 Pat::parse_single.parse_str("[_, lo.., _]").unwrap_err();
94 Pat::parse_single.parse_str("[_, ..=hi, _]").unwrap_err();
95 Pat::parse_single.parse_str("[_, (lo..), _]").unwrap();
96 Pat::parse_single.parse_str("[_, (..=hi), _]").unwrap();
97 Pat::parse_single.parse_str("[_, lo..=hi, _]").unwrap();
98 }
99
100 #[test]
test_tuple_comma()101 fn test_tuple_comma() {
102 let mut expr = PatTuple {
103 attrs: Vec::new(),
104 paren_token: token::Paren::default(),
105 elems: Punctuated::new(),
106 };
107 snapshot!(expr.to_token_stream() as Pat, @"Pat::Tuple");
108
109 expr.elems.push_value(parse_quote!(_));
110 // Must not parse to Pat::Paren
111 snapshot!(expr.to_token_stream() as Pat, @r###"
112 Pat::Tuple {
113 elems: [
114 Pat::Wild,
115 Token![,],
116 ],
117 }
118 "###);
119
120 expr.elems.push_punct(<Token![,]>::default());
121 snapshot!(expr.to_token_stream() as Pat, @r###"
122 Pat::Tuple {
123 elems: [
124 Pat::Wild,
125 Token![,],
126 ],
127 }
128 "###);
129
130 expr.elems.push_value(parse_quote!(_));
131 snapshot!(expr.to_token_stream() as Pat, @r###"
132 Pat::Tuple {
133 elems: [
134 Pat::Wild,
135 Token![,],
136 Pat::Wild,
137 ],
138 }
139 "###);
140
141 expr.elems.push_punct(<Token![,]>::default());
142 snapshot!(expr.to_token_stream() as Pat, @r###"
143 Pat::Tuple {
144 elems: [
145 Pat::Wild,
146 Token![,],
147 Pat::Wild,
148 Token![,],
149 ],
150 }
151 "###);
152 }
153