1fad3a1d3Sopenharmony_ci#![allow(
2fad3a1d3Sopenharmony_ci    clippy::assertions_on_result_states,
3fad3a1d3Sopenharmony_ci    clippy::manual_let_else,
4fad3a1d3Sopenharmony_ci    clippy::too_many_lines,
5fad3a1d3Sopenharmony_ci    clippy::uninlined_format_args
6fad3a1d3Sopenharmony_ci)]
7fad3a1d3Sopenharmony_ci
8fad3a1d3Sopenharmony_ci#[macro_use]
9fad3a1d3Sopenharmony_cimod macros;
10fad3a1d3Sopenharmony_ci
11fad3a1d3Sopenharmony_ciuse quote::quote;
12fad3a1d3Sopenharmony_ciuse syn::{Data, DeriveInput};
13fad3a1d3Sopenharmony_ci
14fad3a1d3Sopenharmony_ci#[test]
15fad3a1d3Sopenharmony_cifn test_unit() {
16fad3a1d3Sopenharmony_ci    let input = quote! {
17fad3a1d3Sopenharmony_ci        struct Unit;
18fad3a1d3Sopenharmony_ci    };
19fad3a1d3Sopenharmony_ci
20fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
21fad3a1d3Sopenharmony_ci    DeriveInput {
22fad3a1d3Sopenharmony_ci        vis: Visibility::Inherited,
23fad3a1d3Sopenharmony_ci        ident: "Unit",
24fad3a1d3Sopenharmony_ci        generics: Generics,
25fad3a1d3Sopenharmony_ci        data: Data::Struct {
26fad3a1d3Sopenharmony_ci            fields: Fields::Unit,
27fad3a1d3Sopenharmony_ci            semi_token: Some,
28fad3a1d3Sopenharmony_ci        },
29fad3a1d3Sopenharmony_ci    }
30fad3a1d3Sopenharmony_ci    "###);
31fad3a1d3Sopenharmony_ci}
32fad3a1d3Sopenharmony_ci
33fad3a1d3Sopenharmony_ci#[test]
34fad3a1d3Sopenharmony_cifn test_struct() {
35fad3a1d3Sopenharmony_ci    let input = quote! {
36fad3a1d3Sopenharmony_ci        #[derive(Debug, Clone)]
37fad3a1d3Sopenharmony_ci        pub struct Item {
38fad3a1d3Sopenharmony_ci            pub ident: Ident,
39fad3a1d3Sopenharmony_ci            pub attrs: Vec<Attribute>
40fad3a1d3Sopenharmony_ci        }
41fad3a1d3Sopenharmony_ci    };
42fad3a1d3Sopenharmony_ci
43fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
44fad3a1d3Sopenharmony_ci    DeriveInput {
45fad3a1d3Sopenharmony_ci        attrs: [
46fad3a1d3Sopenharmony_ci            Attribute {
47fad3a1d3Sopenharmony_ci                style: AttrStyle::Outer,
48fad3a1d3Sopenharmony_ci                meta: Meta::List {
49fad3a1d3Sopenharmony_ci                    path: Path {
50fad3a1d3Sopenharmony_ci                        segments: [
51fad3a1d3Sopenharmony_ci                            PathSegment {
52fad3a1d3Sopenharmony_ci                                ident: "derive",
53fad3a1d3Sopenharmony_ci                            },
54fad3a1d3Sopenharmony_ci                        ],
55fad3a1d3Sopenharmony_ci                    },
56fad3a1d3Sopenharmony_ci                    delimiter: MacroDelimiter::Paren,
57fad3a1d3Sopenharmony_ci                    tokens: TokenStream(`Debug , Clone`),
58fad3a1d3Sopenharmony_ci                },
59fad3a1d3Sopenharmony_ci            },
60fad3a1d3Sopenharmony_ci        ],
61fad3a1d3Sopenharmony_ci        vis: Visibility::Public,
62fad3a1d3Sopenharmony_ci        ident: "Item",
63fad3a1d3Sopenharmony_ci        generics: Generics,
64fad3a1d3Sopenharmony_ci        data: Data::Struct {
65fad3a1d3Sopenharmony_ci            fields: Fields::Named {
66fad3a1d3Sopenharmony_ci                named: [
67fad3a1d3Sopenharmony_ci                    Field {
68fad3a1d3Sopenharmony_ci                        vis: Visibility::Public,
69fad3a1d3Sopenharmony_ci                        ident: Some("ident"),
70fad3a1d3Sopenharmony_ci                        colon_token: Some,
71fad3a1d3Sopenharmony_ci                        ty: Type::Path {
72fad3a1d3Sopenharmony_ci                            path: Path {
73fad3a1d3Sopenharmony_ci                                segments: [
74fad3a1d3Sopenharmony_ci                                    PathSegment {
75fad3a1d3Sopenharmony_ci                                        ident: "Ident",
76fad3a1d3Sopenharmony_ci                                    },
77fad3a1d3Sopenharmony_ci                                ],
78fad3a1d3Sopenharmony_ci                            },
79fad3a1d3Sopenharmony_ci                        },
80fad3a1d3Sopenharmony_ci                    },
81fad3a1d3Sopenharmony_ci                    Token![,],
82fad3a1d3Sopenharmony_ci                    Field {
83fad3a1d3Sopenharmony_ci                        vis: Visibility::Public,
84fad3a1d3Sopenharmony_ci                        ident: Some("attrs"),
85fad3a1d3Sopenharmony_ci                        colon_token: Some,
86fad3a1d3Sopenharmony_ci                        ty: Type::Path {
87fad3a1d3Sopenharmony_ci                            path: Path {
88fad3a1d3Sopenharmony_ci                                segments: [
89fad3a1d3Sopenharmony_ci                                    PathSegment {
90fad3a1d3Sopenharmony_ci                                        ident: "Vec",
91fad3a1d3Sopenharmony_ci                                        arguments: PathArguments::AngleBracketed {
92fad3a1d3Sopenharmony_ci                                            args: [
93fad3a1d3Sopenharmony_ci                                                GenericArgument::Type(Type::Path {
94fad3a1d3Sopenharmony_ci                                                    path: Path {
95fad3a1d3Sopenharmony_ci                                                        segments: [
96fad3a1d3Sopenharmony_ci                                                            PathSegment {
97fad3a1d3Sopenharmony_ci                                                                ident: "Attribute",
98fad3a1d3Sopenharmony_ci                                                            },
99fad3a1d3Sopenharmony_ci                                                        ],
100fad3a1d3Sopenharmony_ci                                                    },
101fad3a1d3Sopenharmony_ci                                                }),
102fad3a1d3Sopenharmony_ci                                            ],
103fad3a1d3Sopenharmony_ci                                        },
104fad3a1d3Sopenharmony_ci                                    },
105fad3a1d3Sopenharmony_ci                                ],
106fad3a1d3Sopenharmony_ci                            },
107fad3a1d3Sopenharmony_ci                        },
108fad3a1d3Sopenharmony_ci                    },
109fad3a1d3Sopenharmony_ci                ],
110fad3a1d3Sopenharmony_ci            },
111fad3a1d3Sopenharmony_ci        },
112fad3a1d3Sopenharmony_ci    }
113fad3a1d3Sopenharmony_ci    "###);
114fad3a1d3Sopenharmony_ci
115fad3a1d3Sopenharmony_ci    snapshot!(&input.attrs[0].meta, @r###"
116fad3a1d3Sopenharmony_ci    Meta::List {
117fad3a1d3Sopenharmony_ci        path: Path {
118fad3a1d3Sopenharmony_ci            segments: [
119fad3a1d3Sopenharmony_ci                PathSegment {
120fad3a1d3Sopenharmony_ci                    ident: "derive",
121fad3a1d3Sopenharmony_ci                },
122fad3a1d3Sopenharmony_ci            ],
123fad3a1d3Sopenharmony_ci        },
124fad3a1d3Sopenharmony_ci        delimiter: MacroDelimiter::Paren,
125fad3a1d3Sopenharmony_ci        tokens: TokenStream(`Debug , Clone`),
126fad3a1d3Sopenharmony_ci    }
127fad3a1d3Sopenharmony_ci    "###);
128fad3a1d3Sopenharmony_ci}
129fad3a1d3Sopenharmony_ci
130fad3a1d3Sopenharmony_ci#[test]
131fad3a1d3Sopenharmony_cifn test_union() {
132fad3a1d3Sopenharmony_ci    let input = quote! {
133fad3a1d3Sopenharmony_ci        union MaybeUninit<T> {
134fad3a1d3Sopenharmony_ci            uninit: (),
135fad3a1d3Sopenharmony_ci            value: T
136fad3a1d3Sopenharmony_ci        }
137fad3a1d3Sopenharmony_ci    };
138fad3a1d3Sopenharmony_ci
139fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
140fad3a1d3Sopenharmony_ci    DeriveInput {
141fad3a1d3Sopenharmony_ci        vis: Visibility::Inherited,
142fad3a1d3Sopenharmony_ci        ident: "MaybeUninit",
143fad3a1d3Sopenharmony_ci        generics: Generics {
144fad3a1d3Sopenharmony_ci            lt_token: Some,
145fad3a1d3Sopenharmony_ci            params: [
146fad3a1d3Sopenharmony_ci                GenericParam::Type(TypeParam {
147fad3a1d3Sopenharmony_ci                    ident: "T",
148fad3a1d3Sopenharmony_ci                }),
149fad3a1d3Sopenharmony_ci            ],
150fad3a1d3Sopenharmony_ci            gt_token: Some,
151fad3a1d3Sopenharmony_ci        },
152fad3a1d3Sopenharmony_ci        data: Data::Union {
153fad3a1d3Sopenharmony_ci            fields: FieldsNamed {
154fad3a1d3Sopenharmony_ci                named: [
155fad3a1d3Sopenharmony_ci                    Field {
156fad3a1d3Sopenharmony_ci                        vis: Visibility::Inherited,
157fad3a1d3Sopenharmony_ci                        ident: Some("uninit"),
158fad3a1d3Sopenharmony_ci                        colon_token: Some,
159fad3a1d3Sopenharmony_ci                        ty: Type::Tuple,
160fad3a1d3Sopenharmony_ci                    },
161fad3a1d3Sopenharmony_ci                    Token![,],
162fad3a1d3Sopenharmony_ci                    Field {
163fad3a1d3Sopenharmony_ci                        vis: Visibility::Inherited,
164fad3a1d3Sopenharmony_ci                        ident: Some("value"),
165fad3a1d3Sopenharmony_ci                        colon_token: Some,
166fad3a1d3Sopenharmony_ci                        ty: Type::Path {
167fad3a1d3Sopenharmony_ci                            path: Path {
168fad3a1d3Sopenharmony_ci                                segments: [
169fad3a1d3Sopenharmony_ci                                    PathSegment {
170fad3a1d3Sopenharmony_ci                                        ident: "T",
171fad3a1d3Sopenharmony_ci                                    },
172fad3a1d3Sopenharmony_ci                                ],
173fad3a1d3Sopenharmony_ci                            },
174fad3a1d3Sopenharmony_ci                        },
175fad3a1d3Sopenharmony_ci                    },
176fad3a1d3Sopenharmony_ci                ],
177fad3a1d3Sopenharmony_ci            },
178fad3a1d3Sopenharmony_ci        },
179fad3a1d3Sopenharmony_ci    }
180fad3a1d3Sopenharmony_ci    "###);
181fad3a1d3Sopenharmony_ci}
182fad3a1d3Sopenharmony_ci
183fad3a1d3Sopenharmony_ci#[test]
184fad3a1d3Sopenharmony_ci#[cfg(feature = "full")]
185fad3a1d3Sopenharmony_cifn test_enum() {
186fad3a1d3Sopenharmony_ci    let input = quote! {
187fad3a1d3Sopenharmony_ci        /// See the std::result module documentation for details.
188fad3a1d3Sopenharmony_ci        #[must_use]
189fad3a1d3Sopenharmony_ci        pub enum Result<T, E> {
190fad3a1d3Sopenharmony_ci            Ok(T),
191fad3a1d3Sopenharmony_ci            Err(E),
192fad3a1d3Sopenharmony_ci            Surprise = 0isize,
193fad3a1d3Sopenharmony_ci
194fad3a1d3Sopenharmony_ci            // Smuggling data into a proc_macro_derive,
195fad3a1d3Sopenharmony_ci            // in the style of https://github.com/dtolnay/proc-macro-hack
196fad3a1d3Sopenharmony_ci            ProcMacroHack = (0, "data").0
197fad3a1d3Sopenharmony_ci        }
198fad3a1d3Sopenharmony_ci    };
199fad3a1d3Sopenharmony_ci
200fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
201fad3a1d3Sopenharmony_ci    DeriveInput {
202fad3a1d3Sopenharmony_ci        attrs: [
203fad3a1d3Sopenharmony_ci            Attribute {
204fad3a1d3Sopenharmony_ci                style: AttrStyle::Outer,
205fad3a1d3Sopenharmony_ci                meta: Meta::NameValue {
206fad3a1d3Sopenharmony_ci                    path: Path {
207fad3a1d3Sopenharmony_ci                        segments: [
208fad3a1d3Sopenharmony_ci                            PathSegment {
209fad3a1d3Sopenharmony_ci                                ident: "doc",
210fad3a1d3Sopenharmony_ci                            },
211fad3a1d3Sopenharmony_ci                        ],
212fad3a1d3Sopenharmony_ci                    },
213fad3a1d3Sopenharmony_ci                    value: Expr::Lit {
214fad3a1d3Sopenharmony_ci                        lit: " See the std::result module documentation for details.",
215fad3a1d3Sopenharmony_ci                    },
216fad3a1d3Sopenharmony_ci                },
217fad3a1d3Sopenharmony_ci            },
218fad3a1d3Sopenharmony_ci            Attribute {
219fad3a1d3Sopenharmony_ci                style: AttrStyle::Outer,
220fad3a1d3Sopenharmony_ci                meta: Meta::Path {
221fad3a1d3Sopenharmony_ci                    segments: [
222fad3a1d3Sopenharmony_ci                        PathSegment {
223fad3a1d3Sopenharmony_ci                            ident: "must_use",
224fad3a1d3Sopenharmony_ci                        },
225fad3a1d3Sopenharmony_ci                    ],
226fad3a1d3Sopenharmony_ci                },
227fad3a1d3Sopenharmony_ci            },
228fad3a1d3Sopenharmony_ci        ],
229fad3a1d3Sopenharmony_ci        vis: Visibility::Public,
230fad3a1d3Sopenharmony_ci        ident: "Result",
231fad3a1d3Sopenharmony_ci        generics: Generics {
232fad3a1d3Sopenharmony_ci            lt_token: Some,
233fad3a1d3Sopenharmony_ci            params: [
234fad3a1d3Sopenharmony_ci                GenericParam::Type(TypeParam {
235fad3a1d3Sopenharmony_ci                    ident: "T",
236fad3a1d3Sopenharmony_ci                }),
237fad3a1d3Sopenharmony_ci                Token![,],
238fad3a1d3Sopenharmony_ci                GenericParam::Type(TypeParam {
239fad3a1d3Sopenharmony_ci                    ident: "E",
240fad3a1d3Sopenharmony_ci                }),
241fad3a1d3Sopenharmony_ci            ],
242fad3a1d3Sopenharmony_ci            gt_token: Some,
243fad3a1d3Sopenharmony_ci        },
244fad3a1d3Sopenharmony_ci        data: Data::Enum {
245fad3a1d3Sopenharmony_ci            variants: [
246fad3a1d3Sopenharmony_ci                Variant {
247fad3a1d3Sopenharmony_ci                    ident: "Ok",
248fad3a1d3Sopenharmony_ci                    fields: Fields::Unnamed {
249fad3a1d3Sopenharmony_ci                        unnamed: [
250fad3a1d3Sopenharmony_ci                            Field {
251fad3a1d3Sopenharmony_ci                                vis: Visibility::Inherited,
252fad3a1d3Sopenharmony_ci                                ty: Type::Path {
253fad3a1d3Sopenharmony_ci                                    path: Path {
254fad3a1d3Sopenharmony_ci                                        segments: [
255fad3a1d3Sopenharmony_ci                                            PathSegment {
256fad3a1d3Sopenharmony_ci                                                ident: "T",
257fad3a1d3Sopenharmony_ci                                            },
258fad3a1d3Sopenharmony_ci                                        ],
259fad3a1d3Sopenharmony_ci                                    },
260fad3a1d3Sopenharmony_ci                                },
261fad3a1d3Sopenharmony_ci                            },
262fad3a1d3Sopenharmony_ci                        ],
263fad3a1d3Sopenharmony_ci                    },
264fad3a1d3Sopenharmony_ci                },
265fad3a1d3Sopenharmony_ci                Token![,],
266fad3a1d3Sopenharmony_ci                Variant {
267fad3a1d3Sopenharmony_ci                    ident: "Err",
268fad3a1d3Sopenharmony_ci                    fields: Fields::Unnamed {
269fad3a1d3Sopenharmony_ci                        unnamed: [
270fad3a1d3Sopenharmony_ci                            Field {
271fad3a1d3Sopenharmony_ci                                vis: Visibility::Inherited,
272fad3a1d3Sopenharmony_ci                                ty: Type::Path {
273fad3a1d3Sopenharmony_ci                                    path: Path {
274fad3a1d3Sopenharmony_ci                                        segments: [
275fad3a1d3Sopenharmony_ci                                            PathSegment {
276fad3a1d3Sopenharmony_ci                                                ident: "E",
277fad3a1d3Sopenharmony_ci                                            },
278fad3a1d3Sopenharmony_ci                                        ],
279fad3a1d3Sopenharmony_ci                                    },
280fad3a1d3Sopenharmony_ci                                },
281fad3a1d3Sopenharmony_ci                            },
282fad3a1d3Sopenharmony_ci                        ],
283fad3a1d3Sopenharmony_ci                    },
284fad3a1d3Sopenharmony_ci                },
285fad3a1d3Sopenharmony_ci                Token![,],
286fad3a1d3Sopenharmony_ci                Variant {
287fad3a1d3Sopenharmony_ci                    ident: "Surprise",
288fad3a1d3Sopenharmony_ci                    fields: Fields::Unit,
289fad3a1d3Sopenharmony_ci                    discriminant: Some(Expr::Lit {
290fad3a1d3Sopenharmony_ci                        lit: 0isize,
291fad3a1d3Sopenharmony_ci                    }),
292fad3a1d3Sopenharmony_ci                },
293fad3a1d3Sopenharmony_ci                Token![,],
294fad3a1d3Sopenharmony_ci                Variant {
295fad3a1d3Sopenharmony_ci                    ident: "ProcMacroHack",
296fad3a1d3Sopenharmony_ci                    fields: Fields::Unit,
297fad3a1d3Sopenharmony_ci                    discriminant: Some(Expr::Field {
298fad3a1d3Sopenharmony_ci                        base: Expr::Tuple {
299fad3a1d3Sopenharmony_ci                            elems: [
300fad3a1d3Sopenharmony_ci                                Expr::Lit {
301fad3a1d3Sopenharmony_ci                                    lit: 0,
302fad3a1d3Sopenharmony_ci                                },
303fad3a1d3Sopenharmony_ci                                Token![,],
304fad3a1d3Sopenharmony_ci                                Expr::Lit {
305fad3a1d3Sopenharmony_ci                                    lit: "data",
306fad3a1d3Sopenharmony_ci                                },
307fad3a1d3Sopenharmony_ci                            ],
308fad3a1d3Sopenharmony_ci                        },
309fad3a1d3Sopenharmony_ci                        member: Member::Unnamed(Index {
310fad3a1d3Sopenharmony_ci                            index: 0,
311fad3a1d3Sopenharmony_ci                        }),
312fad3a1d3Sopenharmony_ci                    }),
313fad3a1d3Sopenharmony_ci                },
314fad3a1d3Sopenharmony_ci            ],
315fad3a1d3Sopenharmony_ci        },
316fad3a1d3Sopenharmony_ci    }
317fad3a1d3Sopenharmony_ci    "###);
318fad3a1d3Sopenharmony_ci
319fad3a1d3Sopenharmony_ci    let meta_items: Vec<_> = input.attrs.into_iter().map(|attr| attr.meta).collect();
320fad3a1d3Sopenharmony_ci
321fad3a1d3Sopenharmony_ci    snapshot!(meta_items, @r###"
322fad3a1d3Sopenharmony_ci    [
323fad3a1d3Sopenharmony_ci        Meta::NameValue {
324fad3a1d3Sopenharmony_ci            path: Path {
325fad3a1d3Sopenharmony_ci                segments: [
326fad3a1d3Sopenharmony_ci                    PathSegment {
327fad3a1d3Sopenharmony_ci                        ident: "doc",
328fad3a1d3Sopenharmony_ci                    },
329fad3a1d3Sopenharmony_ci                ],
330fad3a1d3Sopenharmony_ci            },
331fad3a1d3Sopenharmony_ci            value: Expr::Lit {
332fad3a1d3Sopenharmony_ci                lit: " See the std::result module documentation for details.",
333fad3a1d3Sopenharmony_ci            },
334fad3a1d3Sopenharmony_ci        },
335fad3a1d3Sopenharmony_ci        Meta::Path {
336fad3a1d3Sopenharmony_ci            segments: [
337fad3a1d3Sopenharmony_ci                PathSegment {
338fad3a1d3Sopenharmony_ci                    ident: "must_use",
339fad3a1d3Sopenharmony_ci                },
340fad3a1d3Sopenharmony_ci            ],
341fad3a1d3Sopenharmony_ci        },
342fad3a1d3Sopenharmony_ci    ]
343fad3a1d3Sopenharmony_ci    "###);
344fad3a1d3Sopenharmony_ci}
345fad3a1d3Sopenharmony_ci
346fad3a1d3Sopenharmony_ci#[test]
347fad3a1d3Sopenharmony_cifn test_attr_with_non_mod_style_path() {
348fad3a1d3Sopenharmony_ci    let input = quote! {
349fad3a1d3Sopenharmony_ci        #[inert <T>]
350fad3a1d3Sopenharmony_ci        struct S;
351fad3a1d3Sopenharmony_ci    };
352fad3a1d3Sopenharmony_ci
353fad3a1d3Sopenharmony_ci    syn::parse2::<DeriveInput>(input).unwrap_err();
354fad3a1d3Sopenharmony_ci}
355fad3a1d3Sopenharmony_ci
356fad3a1d3Sopenharmony_ci#[test]
357fad3a1d3Sopenharmony_cifn test_attr_with_mod_style_path_with_self() {
358fad3a1d3Sopenharmony_ci    let input = quote! {
359fad3a1d3Sopenharmony_ci        #[foo::self]
360fad3a1d3Sopenharmony_ci        struct S;
361fad3a1d3Sopenharmony_ci    };
362fad3a1d3Sopenharmony_ci
363fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
364fad3a1d3Sopenharmony_ci    DeriveInput {
365fad3a1d3Sopenharmony_ci        attrs: [
366fad3a1d3Sopenharmony_ci            Attribute {
367fad3a1d3Sopenharmony_ci                style: AttrStyle::Outer,
368fad3a1d3Sopenharmony_ci                meta: Meta::Path {
369fad3a1d3Sopenharmony_ci                    segments: [
370fad3a1d3Sopenharmony_ci                        PathSegment {
371fad3a1d3Sopenharmony_ci                            ident: "foo",
372fad3a1d3Sopenharmony_ci                        },
373fad3a1d3Sopenharmony_ci                        Token![::],
374fad3a1d3Sopenharmony_ci                        PathSegment {
375fad3a1d3Sopenharmony_ci                            ident: "self",
376fad3a1d3Sopenharmony_ci                        },
377fad3a1d3Sopenharmony_ci                    ],
378fad3a1d3Sopenharmony_ci                },
379fad3a1d3Sopenharmony_ci            },
380fad3a1d3Sopenharmony_ci        ],
381fad3a1d3Sopenharmony_ci        vis: Visibility::Inherited,
382fad3a1d3Sopenharmony_ci        ident: "S",
383fad3a1d3Sopenharmony_ci        generics: Generics,
384fad3a1d3Sopenharmony_ci        data: Data::Struct {
385fad3a1d3Sopenharmony_ci            fields: Fields::Unit,
386fad3a1d3Sopenharmony_ci            semi_token: Some,
387fad3a1d3Sopenharmony_ci        },
388fad3a1d3Sopenharmony_ci    }
389fad3a1d3Sopenharmony_ci    "###);
390fad3a1d3Sopenharmony_ci
391fad3a1d3Sopenharmony_ci    snapshot!(&input.attrs[0].meta, @r###"
392fad3a1d3Sopenharmony_ci    Meta::Path {
393fad3a1d3Sopenharmony_ci        segments: [
394fad3a1d3Sopenharmony_ci            PathSegment {
395fad3a1d3Sopenharmony_ci                ident: "foo",
396fad3a1d3Sopenharmony_ci            },
397fad3a1d3Sopenharmony_ci            Token![::],
398fad3a1d3Sopenharmony_ci            PathSegment {
399fad3a1d3Sopenharmony_ci                ident: "self",
400fad3a1d3Sopenharmony_ci            },
401fad3a1d3Sopenharmony_ci        ],
402fad3a1d3Sopenharmony_ci    }
403fad3a1d3Sopenharmony_ci    "###);
404fad3a1d3Sopenharmony_ci}
405fad3a1d3Sopenharmony_ci
406fad3a1d3Sopenharmony_ci#[test]
407fad3a1d3Sopenharmony_cifn test_pub_restricted() {
408fad3a1d3Sopenharmony_ci    // Taken from tests/rust/src/test/ui/resolve/auxiliary/privacy-struct-ctor.rs
409fad3a1d3Sopenharmony_ci    let input = quote! {
410fad3a1d3Sopenharmony_ci        pub(in m) struct Z(pub(in m::n) u8);
411fad3a1d3Sopenharmony_ci    };
412fad3a1d3Sopenharmony_ci
413fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
414fad3a1d3Sopenharmony_ci    DeriveInput {
415fad3a1d3Sopenharmony_ci        vis: Visibility::Restricted {
416fad3a1d3Sopenharmony_ci            in_token: Some,
417fad3a1d3Sopenharmony_ci            path: Path {
418fad3a1d3Sopenharmony_ci                segments: [
419fad3a1d3Sopenharmony_ci                    PathSegment {
420fad3a1d3Sopenharmony_ci                        ident: "m",
421fad3a1d3Sopenharmony_ci                    },
422fad3a1d3Sopenharmony_ci                ],
423fad3a1d3Sopenharmony_ci            },
424fad3a1d3Sopenharmony_ci        },
425fad3a1d3Sopenharmony_ci        ident: "Z",
426fad3a1d3Sopenharmony_ci        generics: Generics,
427fad3a1d3Sopenharmony_ci        data: Data::Struct {
428fad3a1d3Sopenharmony_ci            fields: Fields::Unnamed {
429fad3a1d3Sopenharmony_ci                unnamed: [
430fad3a1d3Sopenharmony_ci                    Field {
431fad3a1d3Sopenharmony_ci                        vis: Visibility::Restricted {
432fad3a1d3Sopenharmony_ci                            in_token: Some,
433fad3a1d3Sopenharmony_ci                            path: Path {
434fad3a1d3Sopenharmony_ci                                segments: [
435fad3a1d3Sopenharmony_ci                                    PathSegment {
436fad3a1d3Sopenharmony_ci                                        ident: "m",
437fad3a1d3Sopenharmony_ci                                    },
438fad3a1d3Sopenharmony_ci                                    Token![::],
439fad3a1d3Sopenharmony_ci                                    PathSegment {
440fad3a1d3Sopenharmony_ci                                        ident: "n",
441fad3a1d3Sopenharmony_ci                                    },
442fad3a1d3Sopenharmony_ci                                ],
443fad3a1d3Sopenharmony_ci                            },
444fad3a1d3Sopenharmony_ci                        },
445fad3a1d3Sopenharmony_ci                        ty: Type::Path {
446fad3a1d3Sopenharmony_ci                            path: Path {
447fad3a1d3Sopenharmony_ci                                segments: [
448fad3a1d3Sopenharmony_ci                                    PathSegment {
449fad3a1d3Sopenharmony_ci                                        ident: "u8",
450fad3a1d3Sopenharmony_ci                                    },
451fad3a1d3Sopenharmony_ci                                ],
452fad3a1d3Sopenharmony_ci                            },
453fad3a1d3Sopenharmony_ci                        },
454fad3a1d3Sopenharmony_ci                    },
455fad3a1d3Sopenharmony_ci                ],
456fad3a1d3Sopenharmony_ci            },
457fad3a1d3Sopenharmony_ci            semi_token: Some,
458fad3a1d3Sopenharmony_ci        },
459fad3a1d3Sopenharmony_ci    }
460fad3a1d3Sopenharmony_ci    "###);
461fad3a1d3Sopenharmony_ci}
462fad3a1d3Sopenharmony_ci
463fad3a1d3Sopenharmony_ci#[test]
464fad3a1d3Sopenharmony_cifn test_pub_restricted_crate() {
465fad3a1d3Sopenharmony_ci    let input = quote! {
466fad3a1d3Sopenharmony_ci        pub(crate) struct S;
467fad3a1d3Sopenharmony_ci    };
468fad3a1d3Sopenharmony_ci
469fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
470fad3a1d3Sopenharmony_ci    DeriveInput {
471fad3a1d3Sopenharmony_ci        vis: Visibility::Restricted {
472fad3a1d3Sopenharmony_ci            path: Path {
473fad3a1d3Sopenharmony_ci                segments: [
474fad3a1d3Sopenharmony_ci                    PathSegment {
475fad3a1d3Sopenharmony_ci                        ident: "crate",
476fad3a1d3Sopenharmony_ci                    },
477fad3a1d3Sopenharmony_ci                ],
478fad3a1d3Sopenharmony_ci            },
479fad3a1d3Sopenharmony_ci        },
480fad3a1d3Sopenharmony_ci        ident: "S",
481fad3a1d3Sopenharmony_ci        generics: Generics,
482fad3a1d3Sopenharmony_ci        data: Data::Struct {
483fad3a1d3Sopenharmony_ci            fields: Fields::Unit,
484fad3a1d3Sopenharmony_ci            semi_token: Some,
485fad3a1d3Sopenharmony_ci        },
486fad3a1d3Sopenharmony_ci    }
487fad3a1d3Sopenharmony_ci    "###);
488fad3a1d3Sopenharmony_ci}
489fad3a1d3Sopenharmony_ci
490fad3a1d3Sopenharmony_ci#[test]
491fad3a1d3Sopenharmony_cifn test_pub_restricted_super() {
492fad3a1d3Sopenharmony_ci    let input = quote! {
493fad3a1d3Sopenharmony_ci        pub(super) struct S;
494fad3a1d3Sopenharmony_ci    };
495fad3a1d3Sopenharmony_ci
496fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
497fad3a1d3Sopenharmony_ci    DeriveInput {
498fad3a1d3Sopenharmony_ci        vis: Visibility::Restricted {
499fad3a1d3Sopenharmony_ci            path: Path {
500fad3a1d3Sopenharmony_ci                segments: [
501fad3a1d3Sopenharmony_ci                    PathSegment {
502fad3a1d3Sopenharmony_ci                        ident: "super",
503fad3a1d3Sopenharmony_ci                    },
504fad3a1d3Sopenharmony_ci                ],
505fad3a1d3Sopenharmony_ci            },
506fad3a1d3Sopenharmony_ci        },
507fad3a1d3Sopenharmony_ci        ident: "S",
508fad3a1d3Sopenharmony_ci        generics: Generics,
509fad3a1d3Sopenharmony_ci        data: Data::Struct {
510fad3a1d3Sopenharmony_ci            fields: Fields::Unit,
511fad3a1d3Sopenharmony_ci            semi_token: Some,
512fad3a1d3Sopenharmony_ci        },
513fad3a1d3Sopenharmony_ci    }
514fad3a1d3Sopenharmony_ci    "###);
515fad3a1d3Sopenharmony_ci}
516fad3a1d3Sopenharmony_ci
517fad3a1d3Sopenharmony_ci#[test]
518fad3a1d3Sopenharmony_cifn test_pub_restricted_in_super() {
519fad3a1d3Sopenharmony_ci    let input = quote! {
520fad3a1d3Sopenharmony_ci        pub(in super) struct S;
521fad3a1d3Sopenharmony_ci    };
522fad3a1d3Sopenharmony_ci
523fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
524fad3a1d3Sopenharmony_ci    DeriveInput {
525fad3a1d3Sopenharmony_ci        vis: Visibility::Restricted {
526fad3a1d3Sopenharmony_ci            in_token: Some,
527fad3a1d3Sopenharmony_ci            path: Path {
528fad3a1d3Sopenharmony_ci                segments: [
529fad3a1d3Sopenharmony_ci                    PathSegment {
530fad3a1d3Sopenharmony_ci                        ident: "super",
531fad3a1d3Sopenharmony_ci                    },
532fad3a1d3Sopenharmony_ci                ],
533fad3a1d3Sopenharmony_ci            },
534fad3a1d3Sopenharmony_ci        },
535fad3a1d3Sopenharmony_ci        ident: "S",
536fad3a1d3Sopenharmony_ci        generics: Generics,
537fad3a1d3Sopenharmony_ci        data: Data::Struct {
538fad3a1d3Sopenharmony_ci            fields: Fields::Unit,
539fad3a1d3Sopenharmony_ci            semi_token: Some,
540fad3a1d3Sopenharmony_ci        },
541fad3a1d3Sopenharmony_ci    }
542fad3a1d3Sopenharmony_ci    "###);
543fad3a1d3Sopenharmony_ci}
544fad3a1d3Sopenharmony_ci
545fad3a1d3Sopenharmony_ci#[test]
546fad3a1d3Sopenharmony_cifn test_fields_on_unit_struct() {
547fad3a1d3Sopenharmony_ci    let input = quote! {
548fad3a1d3Sopenharmony_ci        struct S;
549fad3a1d3Sopenharmony_ci    };
550fad3a1d3Sopenharmony_ci
551fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
552fad3a1d3Sopenharmony_ci    DeriveInput {
553fad3a1d3Sopenharmony_ci        vis: Visibility::Inherited,
554fad3a1d3Sopenharmony_ci        ident: "S",
555fad3a1d3Sopenharmony_ci        generics: Generics,
556fad3a1d3Sopenharmony_ci        data: Data::Struct {
557fad3a1d3Sopenharmony_ci            fields: Fields::Unit,
558fad3a1d3Sopenharmony_ci            semi_token: Some,
559fad3a1d3Sopenharmony_ci        },
560fad3a1d3Sopenharmony_ci    }
561fad3a1d3Sopenharmony_ci    "###);
562fad3a1d3Sopenharmony_ci
563fad3a1d3Sopenharmony_ci    let data = match input.data {
564fad3a1d3Sopenharmony_ci        Data::Struct(data) => data,
565fad3a1d3Sopenharmony_ci        _ => panic!("expected a struct"),
566fad3a1d3Sopenharmony_ci    };
567fad3a1d3Sopenharmony_ci
568fad3a1d3Sopenharmony_ci    assert_eq!(0, data.fields.iter().count());
569fad3a1d3Sopenharmony_ci}
570fad3a1d3Sopenharmony_ci
571fad3a1d3Sopenharmony_ci#[test]
572fad3a1d3Sopenharmony_cifn test_fields_on_named_struct() {
573fad3a1d3Sopenharmony_ci    let input = quote! {
574fad3a1d3Sopenharmony_ci        struct S {
575fad3a1d3Sopenharmony_ci            foo: i32,
576fad3a1d3Sopenharmony_ci            pub bar: String,
577fad3a1d3Sopenharmony_ci        }
578fad3a1d3Sopenharmony_ci    };
579fad3a1d3Sopenharmony_ci
580fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
581fad3a1d3Sopenharmony_ci    DeriveInput {
582fad3a1d3Sopenharmony_ci        vis: Visibility::Inherited,
583fad3a1d3Sopenharmony_ci        ident: "S",
584fad3a1d3Sopenharmony_ci        generics: Generics,
585fad3a1d3Sopenharmony_ci        data: Data::Struct {
586fad3a1d3Sopenharmony_ci            fields: Fields::Named {
587fad3a1d3Sopenharmony_ci                named: [
588fad3a1d3Sopenharmony_ci                    Field {
589fad3a1d3Sopenharmony_ci                        vis: Visibility::Inherited,
590fad3a1d3Sopenharmony_ci                        ident: Some("foo"),
591fad3a1d3Sopenharmony_ci                        colon_token: Some,
592fad3a1d3Sopenharmony_ci                        ty: Type::Path {
593fad3a1d3Sopenharmony_ci                            path: Path {
594fad3a1d3Sopenharmony_ci                                segments: [
595fad3a1d3Sopenharmony_ci                                    PathSegment {
596fad3a1d3Sopenharmony_ci                                        ident: "i32",
597fad3a1d3Sopenharmony_ci                                    },
598fad3a1d3Sopenharmony_ci                                ],
599fad3a1d3Sopenharmony_ci                            },
600fad3a1d3Sopenharmony_ci                        },
601fad3a1d3Sopenharmony_ci                    },
602fad3a1d3Sopenharmony_ci                    Token![,],
603fad3a1d3Sopenharmony_ci                    Field {
604fad3a1d3Sopenharmony_ci                        vis: Visibility::Public,
605fad3a1d3Sopenharmony_ci                        ident: Some("bar"),
606fad3a1d3Sopenharmony_ci                        colon_token: Some,
607fad3a1d3Sopenharmony_ci                        ty: Type::Path {
608fad3a1d3Sopenharmony_ci                            path: Path {
609fad3a1d3Sopenharmony_ci                                segments: [
610fad3a1d3Sopenharmony_ci                                    PathSegment {
611fad3a1d3Sopenharmony_ci                                        ident: "String",
612fad3a1d3Sopenharmony_ci                                    },
613fad3a1d3Sopenharmony_ci                                ],
614fad3a1d3Sopenharmony_ci                            },
615fad3a1d3Sopenharmony_ci                        },
616fad3a1d3Sopenharmony_ci                    },
617fad3a1d3Sopenharmony_ci                    Token![,],
618fad3a1d3Sopenharmony_ci                ],
619fad3a1d3Sopenharmony_ci            },
620fad3a1d3Sopenharmony_ci        },
621fad3a1d3Sopenharmony_ci    }
622fad3a1d3Sopenharmony_ci    "###);
623fad3a1d3Sopenharmony_ci
624fad3a1d3Sopenharmony_ci    let data = match input.data {
625fad3a1d3Sopenharmony_ci        Data::Struct(data) => data,
626fad3a1d3Sopenharmony_ci        _ => panic!("expected a struct"),
627fad3a1d3Sopenharmony_ci    };
628fad3a1d3Sopenharmony_ci
629fad3a1d3Sopenharmony_ci    snapshot!(data.fields.into_iter().collect::<Vec<_>>(), @r###"
630fad3a1d3Sopenharmony_ci    [
631fad3a1d3Sopenharmony_ci        Field {
632fad3a1d3Sopenharmony_ci            vis: Visibility::Inherited,
633fad3a1d3Sopenharmony_ci            ident: Some("foo"),
634fad3a1d3Sopenharmony_ci            colon_token: Some,
635fad3a1d3Sopenharmony_ci            ty: Type::Path {
636fad3a1d3Sopenharmony_ci                path: Path {
637fad3a1d3Sopenharmony_ci                    segments: [
638fad3a1d3Sopenharmony_ci                        PathSegment {
639fad3a1d3Sopenharmony_ci                            ident: "i32",
640fad3a1d3Sopenharmony_ci                        },
641fad3a1d3Sopenharmony_ci                    ],
642fad3a1d3Sopenharmony_ci                },
643fad3a1d3Sopenharmony_ci            },
644fad3a1d3Sopenharmony_ci        },
645fad3a1d3Sopenharmony_ci        Field {
646fad3a1d3Sopenharmony_ci            vis: Visibility::Public,
647fad3a1d3Sopenharmony_ci            ident: Some("bar"),
648fad3a1d3Sopenharmony_ci            colon_token: Some,
649fad3a1d3Sopenharmony_ci            ty: Type::Path {
650fad3a1d3Sopenharmony_ci                path: Path {
651fad3a1d3Sopenharmony_ci                    segments: [
652fad3a1d3Sopenharmony_ci                        PathSegment {
653fad3a1d3Sopenharmony_ci                            ident: "String",
654fad3a1d3Sopenharmony_ci                        },
655fad3a1d3Sopenharmony_ci                    ],
656fad3a1d3Sopenharmony_ci                },
657fad3a1d3Sopenharmony_ci            },
658fad3a1d3Sopenharmony_ci        },
659fad3a1d3Sopenharmony_ci    ]
660fad3a1d3Sopenharmony_ci    "###);
661fad3a1d3Sopenharmony_ci}
662fad3a1d3Sopenharmony_ci
663fad3a1d3Sopenharmony_ci#[test]
664fad3a1d3Sopenharmony_cifn test_fields_on_tuple_struct() {
665fad3a1d3Sopenharmony_ci    let input = quote! {
666fad3a1d3Sopenharmony_ci        struct S(i32, pub String);
667fad3a1d3Sopenharmony_ci    };
668fad3a1d3Sopenharmony_ci
669fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
670fad3a1d3Sopenharmony_ci    DeriveInput {
671fad3a1d3Sopenharmony_ci        vis: Visibility::Inherited,
672fad3a1d3Sopenharmony_ci        ident: "S",
673fad3a1d3Sopenharmony_ci        generics: Generics,
674fad3a1d3Sopenharmony_ci        data: Data::Struct {
675fad3a1d3Sopenharmony_ci            fields: Fields::Unnamed {
676fad3a1d3Sopenharmony_ci                unnamed: [
677fad3a1d3Sopenharmony_ci                    Field {
678fad3a1d3Sopenharmony_ci                        vis: Visibility::Inherited,
679fad3a1d3Sopenharmony_ci                        ty: Type::Path {
680fad3a1d3Sopenharmony_ci                            path: Path {
681fad3a1d3Sopenharmony_ci                                segments: [
682fad3a1d3Sopenharmony_ci                                    PathSegment {
683fad3a1d3Sopenharmony_ci                                        ident: "i32",
684fad3a1d3Sopenharmony_ci                                    },
685fad3a1d3Sopenharmony_ci                                ],
686fad3a1d3Sopenharmony_ci                            },
687fad3a1d3Sopenharmony_ci                        },
688fad3a1d3Sopenharmony_ci                    },
689fad3a1d3Sopenharmony_ci                    Token![,],
690fad3a1d3Sopenharmony_ci                    Field {
691fad3a1d3Sopenharmony_ci                        vis: Visibility::Public,
692fad3a1d3Sopenharmony_ci                        ty: Type::Path {
693fad3a1d3Sopenharmony_ci                            path: Path {
694fad3a1d3Sopenharmony_ci                                segments: [
695fad3a1d3Sopenharmony_ci                                    PathSegment {
696fad3a1d3Sopenharmony_ci                                        ident: "String",
697fad3a1d3Sopenharmony_ci                                    },
698fad3a1d3Sopenharmony_ci                                ],
699fad3a1d3Sopenharmony_ci                            },
700fad3a1d3Sopenharmony_ci                        },
701fad3a1d3Sopenharmony_ci                    },
702fad3a1d3Sopenharmony_ci                ],
703fad3a1d3Sopenharmony_ci            },
704fad3a1d3Sopenharmony_ci            semi_token: Some,
705fad3a1d3Sopenharmony_ci        },
706fad3a1d3Sopenharmony_ci    }
707fad3a1d3Sopenharmony_ci    "###);
708fad3a1d3Sopenharmony_ci
709fad3a1d3Sopenharmony_ci    let data = match input.data {
710fad3a1d3Sopenharmony_ci        Data::Struct(data) => data,
711fad3a1d3Sopenharmony_ci        _ => panic!("expected a struct"),
712fad3a1d3Sopenharmony_ci    };
713fad3a1d3Sopenharmony_ci
714fad3a1d3Sopenharmony_ci    snapshot!(data.fields.iter().collect::<Vec<_>>(), @r###"
715fad3a1d3Sopenharmony_ci    [
716fad3a1d3Sopenharmony_ci        Field {
717fad3a1d3Sopenharmony_ci            vis: Visibility::Inherited,
718fad3a1d3Sopenharmony_ci            ty: Type::Path {
719fad3a1d3Sopenharmony_ci                path: Path {
720fad3a1d3Sopenharmony_ci                    segments: [
721fad3a1d3Sopenharmony_ci                        PathSegment {
722fad3a1d3Sopenharmony_ci                            ident: "i32",
723fad3a1d3Sopenharmony_ci                        },
724fad3a1d3Sopenharmony_ci                    ],
725fad3a1d3Sopenharmony_ci                },
726fad3a1d3Sopenharmony_ci            },
727fad3a1d3Sopenharmony_ci        },
728fad3a1d3Sopenharmony_ci        Field {
729fad3a1d3Sopenharmony_ci            vis: Visibility::Public,
730fad3a1d3Sopenharmony_ci            ty: Type::Path {
731fad3a1d3Sopenharmony_ci                path: Path {
732fad3a1d3Sopenharmony_ci                    segments: [
733fad3a1d3Sopenharmony_ci                        PathSegment {
734fad3a1d3Sopenharmony_ci                            ident: "String",
735fad3a1d3Sopenharmony_ci                        },
736fad3a1d3Sopenharmony_ci                    ],
737fad3a1d3Sopenharmony_ci                },
738fad3a1d3Sopenharmony_ci            },
739fad3a1d3Sopenharmony_ci        },
740fad3a1d3Sopenharmony_ci    ]
741fad3a1d3Sopenharmony_ci    "###);
742fad3a1d3Sopenharmony_ci}
743fad3a1d3Sopenharmony_ci
744fad3a1d3Sopenharmony_ci#[test]
745fad3a1d3Sopenharmony_cifn test_ambiguous_crate() {
746fad3a1d3Sopenharmony_ci    let input = quote! {
747fad3a1d3Sopenharmony_ci        // The field type is `(crate::X)` not `crate (::X)`.
748fad3a1d3Sopenharmony_ci        struct S(crate::X);
749fad3a1d3Sopenharmony_ci    };
750fad3a1d3Sopenharmony_ci
751fad3a1d3Sopenharmony_ci    snapshot!(input as DeriveInput, @r###"
752fad3a1d3Sopenharmony_ci    DeriveInput {
753fad3a1d3Sopenharmony_ci        vis: Visibility::Inherited,
754fad3a1d3Sopenharmony_ci        ident: "S",
755fad3a1d3Sopenharmony_ci        generics: Generics,
756fad3a1d3Sopenharmony_ci        data: Data::Struct {
757fad3a1d3Sopenharmony_ci            fields: Fields::Unnamed {
758fad3a1d3Sopenharmony_ci                unnamed: [
759fad3a1d3Sopenharmony_ci                    Field {
760fad3a1d3Sopenharmony_ci                        vis: Visibility::Inherited,
761fad3a1d3Sopenharmony_ci                        ty: Type::Path {
762fad3a1d3Sopenharmony_ci                            path: Path {
763fad3a1d3Sopenharmony_ci                                segments: [
764fad3a1d3Sopenharmony_ci                                    PathSegment {
765fad3a1d3Sopenharmony_ci                                        ident: "crate",
766fad3a1d3Sopenharmony_ci                                    },
767fad3a1d3Sopenharmony_ci                                    Token![::],
768fad3a1d3Sopenharmony_ci                                    PathSegment {
769fad3a1d3Sopenharmony_ci                                        ident: "X",
770fad3a1d3Sopenharmony_ci                                    },
771fad3a1d3Sopenharmony_ci                                ],
772fad3a1d3Sopenharmony_ci                            },
773fad3a1d3Sopenharmony_ci                        },
774fad3a1d3Sopenharmony_ci                    },
775fad3a1d3Sopenharmony_ci                ],
776fad3a1d3Sopenharmony_ci            },
777fad3a1d3Sopenharmony_ci            semi_token: Some,
778fad3a1d3Sopenharmony_ci        },
779fad3a1d3Sopenharmony_ci    }
780fad3a1d3Sopenharmony_ci    "###);
781fad3a1d3Sopenharmony_ci}
782