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