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