1#![allow(clippy::uninlined_format_args)] 2 3#[macro_use] 4mod macros; 5 6use proc_macro2::{Delimiter, Group, TokenStream, TokenTree}; 7use quote::{quote, ToTokens as _}; 8use syn::parse::Parser; 9use syn::punctuated::Punctuated; 10use syn::{parse_quote, token, Item, Pat, PatTuple, Stmt, Token}; 11 12#[test] 13fn 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] 21fn 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] 29fn 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] 49fn 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] 71fn 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] 101fn 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