• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(clippy::uninlined_format_args)]
2 
3 #[macro_use]
4 mod macros;
5 
6 use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
7 use quote::{quote, ToTokens};
8 use syn::{parse_quote, Expr, Type, TypePath};
9 
10 #[test]
parse_interpolated_leading_component()11 fn parse_interpolated_leading_component() {
12     // mimics the token stream corresponding to `$mod::rest`
13     let tokens = TokenStream::from_iter(vec![
14         TokenTree::Group(Group::new(Delimiter::None, quote! { first })),
15         TokenTree::Punct(Punct::new(':', Spacing::Joint)),
16         TokenTree::Punct(Punct::new(':', Spacing::Alone)),
17         TokenTree::Ident(Ident::new("rest", Span::call_site())),
18     ]);
19 
20     snapshot!(tokens.clone() as Expr, @r###"
21     Expr::Path {
22         path: Path {
23             segments: [
24                 PathSegment {
25                     ident: "first",
26                 },
27                 PathSegment {
28                     ident: "rest",
29                 },
30             ],
31         },
32     }
33     "###);
34 
35     snapshot!(tokens as Type, @r###"
36     Type::Path {
37         path: Path {
38             segments: [
39                 PathSegment {
40                     ident: "first",
41                 },
42                 PathSegment {
43                     ident: "rest",
44                 },
45             ],
46         },
47     }
48     "###);
49 }
50 
51 #[test]
print_incomplete_qpath()52 fn print_incomplete_qpath() {
53     // qpath with `as` token
54     let mut ty: TypePath = parse_quote!(<Self as A>::Q);
55     snapshot!(ty.to_token_stream(), @r###"
56     TokenStream(`< Self as A > :: Q`)
57     "###);
58     assert!(ty.path.segments.pop().is_some());
59     snapshot!(ty.to_token_stream(), @r###"
60     TokenStream(`< Self as A > ::`)
61     "###);
62     assert!(ty.path.segments.pop().is_some());
63     snapshot!(ty.to_token_stream(), @r###"
64     TokenStream(`< Self >`)
65     "###);
66     assert!(ty.path.segments.pop().is_none());
67 
68     // qpath without `as` token
69     let mut ty: TypePath = parse_quote!(<Self>::A::B);
70     snapshot!(ty.to_token_stream(), @r###"
71     TokenStream(`< Self > :: A :: B`)
72     "###);
73     assert!(ty.path.segments.pop().is_some());
74     snapshot!(ty.to_token_stream(), @r###"
75     TokenStream(`< Self > :: A ::`)
76     "###);
77     assert!(ty.path.segments.pop().is_some());
78     snapshot!(ty.to_token_stream(), @r###"
79     TokenStream(`< Self > ::`)
80     "###);
81     assert!(ty.path.segments.pop().is_none());
82 
83     // normal path
84     let mut ty: TypePath = parse_quote!(Self::A::B);
85     snapshot!(ty.to_token_stream(), @r###"
86     TokenStream(`Self :: A :: B`)
87     "###);
88     assert!(ty.path.segments.pop().is_some());
89     snapshot!(ty.to_token_stream(), @r###"
90     TokenStream(`Self :: A ::`)
91     "###);
92     assert!(ty.path.segments.pop().is_some());
93     snapshot!(ty.to_token_stream(), @r###"
94     TokenStream(`Self ::`)
95     "###);
96     assert!(ty.path.segments.pop().is_some());
97     snapshot!(ty.to_token_stream(), @r###"
98     TokenStream(``)
99     "###);
100     assert!(ty.path.segments.pop().is_none());
101 }
102 
103 #[test]
parse_parenthesized_path_arguments_with_disambiguator()104 fn parse_parenthesized_path_arguments_with_disambiguator() {
105     #[rustfmt::skip]
106     let tokens = quote!(dyn FnOnce::() -> !);
107     snapshot!(tokens as Type, @r###"
108     Type::TraitObject {
109         dyn_token: Some,
110         bounds: [
111             TypeParamBound::Trait(TraitBound {
112                 path: Path {
113                     segments: [
114                         PathSegment {
115                             ident: "FnOnce",
116                             arguments: PathArguments::Parenthesized {
117                                 output: ReturnType::Type(
118                                     Type::Never,
119                                 ),
120                             },
121                         },
122                     ],
123                 },
124             }),
125         ],
126     }
127     "###);
128 }
129