xref: /third_party/rust/crates/syn/tests/test_path.rs (revision fad3a1d3)
1#![allow(clippy::uninlined_format_args)]
2
3#[macro_use]
4mod macros;
5
6use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
7use quote::{quote, ToTokens};
8use syn::{parse_quote, Expr, Type, TypePath};
9
10#[test]
11fn 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                Token![::],
28                PathSegment {
29                    ident: "rest",
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                },
43                Token![::],
44                PathSegment {
45                    ident: "rest",
46                },
47            ],
48        },
49    }
50    "###);
51}
52
53#[test]
54fn print_incomplete_qpath() {
55    // qpath with `as` token
56    let mut ty: TypePath = parse_quote!(<Self as A>::Q);
57    snapshot!(ty.to_token_stream(), @r###"
58    TokenStream(`< Self as A > :: Q`)
59    "###);
60    assert!(ty.path.segments.pop().is_some());
61    snapshot!(ty.to_token_stream(), @r###"
62    TokenStream(`< Self as A > ::`)
63    "###);
64    assert!(ty.path.segments.pop().is_some());
65    snapshot!(ty.to_token_stream(), @r###"
66    TokenStream(`< Self >`)
67    "###);
68    assert!(ty.path.segments.pop().is_none());
69
70    // qpath without `as` token
71    let mut ty: TypePath = parse_quote!(<Self>::A::B);
72    snapshot!(ty.to_token_stream(), @r###"
73    TokenStream(`< Self > :: A :: B`)
74    "###);
75    assert!(ty.path.segments.pop().is_some());
76    snapshot!(ty.to_token_stream(), @r###"
77    TokenStream(`< Self > :: A ::`)
78    "###);
79    assert!(ty.path.segments.pop().is_some());
80    snapshot!(ty.to_token_stream(), @r###"
81    TokenStream(`< Self > ::`)
82    "###);
83    assert!(ty.path.segments.pop().is_none());
84
85    // normal path
86    let mut ty: TypePath = parse_quote!(Self::A::B);
87    snapshot!(ty.to_token_stream(), @r###"
88    TokenStream(`Self :: A :: B`)
89    "###);
90    assert!(ty.path.segments.pop().is_some());
91    snapshot!(ty.to_token_stream(), @r###"
92    TokenStream(`Self :: A ::`)
93    "###);
94    assert!(ty.path.segments.pop().is_some());
95    snapshot!(ty.to_token_stream(), @r###"
96    TokenStream(`Self ::`)
97    "###);
98    assert!(ty.path.segments.pop().is_some());
99    snapshot!(ty.to_token_stream(), @r###"
100    TokenStream(``)
101    "###);
102    assert!(ty.path.segments.pop().is_none());
103}
104
105#[test]
106fn parse_parenthesized_path_arguments_with_disambiguator() {
107    #[rustfmt::skip]
108    let tokens = quote!(dyn FnOnce::() -> !);
109    snapshot!(tokens as Type, @r###"
110    Type::TraitObject {
111        dyn_token: Some,
112        bounds: [
113            TypeParamBound::Trait(TraitBound {
114                path: Path {
115                    segments: [
116                        PathSegment {
117                            ident: "FnOnce",
118                            arguments: PathArguments::Parenthesized {
119                                output: ReturnType::Type(
120                                    Type::Never,
121                                ),
122                            },
123                        },
124                    ],
125                },
126            }),
127        ],
128    }
129    "###);
130}
131