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