aboutsummaryrefslogtreecommitdiff
path: root/xtask/src
diff options
context:
space:
mode:
Diffstat (limited to 'xtask/src')
-rw-r--r--xtask/src/ast_src.rs2001
-rw-r--r--xtask/src/codegen/gen_syntax.rs224
-rw-r--r--xtask/src/codegen/rust.ungram529
3 files changed, 754 insertions, 2000 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 425814d73..83449437b 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -223,12 +223,14 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
223 ], 223 ],
224}; 224};
225 225
226#[derive(Default, Debug)]
226pub(crate) struct AstSrc { 227pub(crate) struct AstSrc {
227 pub(crate) tokens: Vec<String>, 228 pub(crate) tokens: Vec<String>,
228 pub(crate) nodes: Vec<AstNodeSrc>, 229 pub(crate) nodes: Vec<AstNodeSrc>,
229 pub(crate) enums: Vec<AstEnumSrc>, 230 pub(crate) enums: Vec<AstEnumSrc>,
230} 231}
231 232
233#[derive(Debug)]
232pub(crate) struct AstNodeSrc { 234pub(crate) struct AstNodeSrc {
233 pub(crate) doc: Vec<String>, 235 pub(crate) doc: Vec<String>,
234 pub(crate) name: String, 236 pub(crate) name: String,
@@ -236,2016 +238,23 @@ pub(crate) struct AstNodeSrc {
236 pub(crate) fields: Vec<Field>, 238 pub(crate) fields: Vec<Field>,
237} 239}
238 240
241#[derive(Debug, Eq, PartialEq)]
239pub(crate) enum Field { 242pub(crate) enum Field {
240 Token(String), 243 Token(String),
241 Node { name: String, src: FieldSrc }, 244 Node { name: String, src: FieldSrc },
242} 245}
243 246
247#[derive(Debug, Eq, PartialEq)]
244pub(crate) enum FieldSrc { 248pub(crate) enum FieldSrc {
245 Shorthand, 249 Shorthand,
246 Optional(String), 250 Optional(String),
247 Many(String), 251 Many(String),
248} 252}
249 253
254#[derive(Debug)]
250pub(crate) struct AstEnumSrc { 255pub(crate) struct AstEnumSrc {
251 pub(crate) doc: Vec<String>, 256 pub(crate) doc: Vec<String>,
252 pub(crate) name: String, 257 pub(crate) name: String,
253 pub(crate) traits: Vec<String>, 258 pub(crate) traits: Vec<String>,
254 pub(crate) variants: Vec<String>, 259 pub(crate) variants: Vec<String>,
255} 260}
256
257macro_rules! ast_nodes {
258 ($(
259 $(#[doc = $doc:expr])+
260 struct $name:ident$(: $($trait:ident),*)? {
261 $($field_name:ident $(![$token:tt])? $(: $ty:tt)?),*$(,)?
262 }
263 )*) => {
264 vec![$(
265 AstNodeSrc {
266 doc: vec![$($doc.to_string()),*],
267 name: stringify!($name).to_string(),
268 traits: vec![$($(stringify!($trait).to_string()),*)?],
269 fields: vec![
270 $(field!($(T![$token])? $field_name $($ty)?)),*
271 ],
272
273 }
274 ),*]
275 };
276}
277
278macro_rules! field {
279 (T![$token:tt] T) => {
280 Field::Token(stringify!($token).to_string())
281 };
282 ($field_name:ident) => {
283 Field::Node { name: stringify!($field_name).to_string(), src: FieldSrc::Shorthand }
284 };
285 ($field_name:ident [$ty:ident]) => {
286 Field::Node {
287 name: stringify!($field_name).to_string(),
288 src: FieldSrc::Many(stringify!($ty).to_string()),
289 }
290 };
291 ($field_name:ident $ty:ident) => {
292 Field::Node {
293 name: stringify!($field_name).to_string(),
294 src: FieldSrc::Optional(stringify!($ty).to_string()),
295 }
296 };
297}
298
299macro_rules! ast_enums {
300 ($(
301 $(#[doc = $doc:expr])+
302 enum $name:ident $(: $($trait:ident),*)? {
303 $($variant:ident),*$(,)?
304 }
305 )*) => {
306 vec![$(
307 AstEnumSrc {
308 doc: vec![$($doc.to_string()),*],
309 name: stringify!($name).to_string(),
310 traits: vec![$($(stringify!($trait).to_string()),*)?],
311 variants: vec![$(stringify!($variant).to_string()),*],
312 }
313 ),*]
314 };
315}
316
317pub(crate) fn rust_ast() -> AstSrc {
318 AstSrc {
319 tokens: vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()],
320 nodes: ast_nodes! {
321 /// The entire Rust source file. Includes all top-level inner attributes and module items.
322 ///
323 /// [Reference](https://doc.rust-lang.org/reference/crates-and-source-files.html)
324 struct SourceFile: ModuleItemOwner, AttrsOwner, DocCommentsOwner {
325 modules: [Module],
326 }
327
328 /// Function definition either with body or not.
329 /// Includes all of its attributes and doc comments.
330 ///
331 /// ```
332 /// ❰
333 /// /// Docs
334 /// #[attr]
335 /// pub extern "C" fn foo<T>(#[attr] Patern {p}: Pattern) -> u32
336 /// where
337 /// T: Debug
338 /// {
339 /// 42
340 /// }
341 /// ❱
342 ///
343 /// extern "C" {
344 /// ❰ fn fn_decl(also_variadic_ffi: u32, ...) -> u32; ❱
345 /// }
346 /// ```
347 ///
348 /// - [Reference](https://doc.rust-lang.org/reference/items/functions.html)
349 /// - [Nomicon](https://doc.rust-lang.org/nomicon/ffi.html#variadic-functions)
350 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
351 Abi,
352 T![const],
353 T![default],
354 T![async],
355 T![unsafe],
356 T![fn],
357 ParamList,
358 RetType,
359 body: BlockExpr,
360 T![;]
361 }
362
363 /// Return type annotation.
364 ///
365 /// ```
366 /// fn foo(a: u32) ❰ -> Option<u32> ❱ { Some(a) }
367 /// ```
368 ///
369 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
370 struct RetType { T![->], TypeRef }
371
372 /// Struct definition.
373 /// Includes all of its attributes and doc comments.
374 ///
375 /// ```
376 /// ❰
377 /// /// Docs
378 /// #[attr]
379 /// struct Foo<T> where T: Debug {
380 /// /// Docs
381 /// #[attr]
382 /// pub a: u32,
383 /// b: T,
384 /// }
385 /// ❱
386 ///
387 /// ❰ struct Foo; ❱
388 /// ❰ struct Foo<T>(#[attr] T) where T: Debug; ❱
389 /// ```
390 ///
391 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
392 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
393 T![struct],
394 FieldDefList,
395 T![;]
396 }
397
398 /// Union definition.
399 /// Includes all of its attributes and doc comments.
400 ///
401 /// ```
402 /// ❰
403 /// /// Docs
404 /// #[attr]
405 /// pub union Foo<T> where T: Debug {
406 /// /// Docs
407 /// #[attr]
408 /// a: T,
409 /// b: u32,
410 /// }
411 /// ❱
412 /// ```
413 ///
414 /// [Reference](https://doc.rust-lang.org/reference/items/unions.html)
415 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
416 T![union],
417 RecordFieldDefList,
418 }
419
420 /// Record field definition list including enclosing curly braces.
421 ///
422 /// ```
423 /// struct Foo // same for union
424 /// ❰
425 /// {
426 /// a: u32,
427 /// b: bool,
428 /// }
429 /// ❱
430 /// ```
431 ///
432 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
433 struct RecordFieldDefList { T!['{'], fields: [RecordFieldDef], T!['}'] }
434
435 /// Record field definition including its attributes and doc comments.
436 ///
437 /// ` ``
438 /// same for union
439 /// struct Foo {
440 /// ❰
441 /// /// Docs
442 /// #[attr]
443 /// pub a: u32
444 /// ❱
445 ///
446 /// ❰ b: bool ❱
447 /// }
448 /// ```
449 ///
450 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
451 struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
452
453 /// Tuple field definition list including enclosing parens.
454 ///
455 /// ```
456 /// struct Foo ❰ (u32, String, Vec<u32>) ❱;
457 /// ```
458 ///
459 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
460 struct TupleFieldDefList { T!['('], fields: [TupleFieldDef], T![')'] }
461
462 /// Tuple field definition including its attributes.
463 ///
464 /// ```
465 /// struct Foo(❰ #[attr] u32 ❱);
466 /// ```
467 ///
468 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
469 struct TupleFieldDef: VisibilityOwner, AttrsOwner {
470 TypeRef,
471 }
472
473 /// Enum definition.
474 /// Includes all of its attributes and doc comments.
475 ///
476 /// ```
477 /// ❰
478 /// /// Docs
479 /// #[attr]
480 /// pub enum Foo<T> where T: Debug {
481 /// /// Docs
482 /// #[attr]
483 /// Bar,
484 /// Baz(#[attr] u32),
485 /// Bruh {
486 /// a: u32,
487 /// /// Docs
488 /// #[attr]
489 /// b: T,
490 /// }
491 /// }
492 /// ❱
493 /// ```
494 ///
495 /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
496 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
497 T![enum],
498 variant_list: EnumVariantList,
499 }
500
501 /// Enum variant definition list including enclosing curly braces.
502 ///
503 /// ```
504 /// enum Foo
505 /// ❰
506 /// {
507 /// Bar,
508 /// Baz(u32),
509 /// Bruh {
510 /// a: u32
511 /// }
512 /// }
513 /// ❱
514 /// ```
515 ///
516 /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
517 struct EnumVariantList {
518 T!['{'],
519 variants: [EnumVariant],
520 T!['}']
521 }
522
523 /// Enum variant definition including its attributes and discriminant value definition.
524 ///
525 /// ```
526 /// enum Foo {
527 /// ❰
528 /// /// Docs
529 /// #[attr]
530 /// Bar
531 /// ❱
532 ///
533 /// // same for tuple and record variants
534 /// }
535 /// ```
536 ///
537 /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
538 struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner {
539 FieldDefList,
540 T![=],
541 Expr
542 }
543
544 /// Trait definition.
545 /// Includes all of its attributes and doc comments.
546 ///
547 /// ```
548 /// ❰
549 /// /// Docs
550 /// #[attr]
551 /// pub unsafe trait Foo<T>: Debug where T: Debug {
552 /// // ...
553 /// }
554 /// ❱
555 /// ```
556 ///
557 /// [Reference](https://doc.rust-lang.org/reference/items/traits.html)
558 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
559 T![unsafe],
560 T![auto],
561 T![trait],
562 ItemList,
563 }
564
565 /// Module definition either with body or not.
566 /// Includes all of its inner and outer attributes, module items, doc comments.
567 ///
568 /// ```
569 /// ❰
570 /// /// Docs
571 /// #[attr]
572 /// pub mod foo;
573 /// ❱
574 ///
575 /// ❰
576 /// /// Docs
577 /// #[attr]
578 /// pub mod bar {
579 /// //! Inner docs
580 /// #![inner_attr]
581 /// }
582 /// ❱
583 /// ```
584 ///
585 /// [Reference](https://doc.rust-lang.org/reference/items/modules.html)
586 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
587 T![mod],
588 ItemList,
589 T![;]
590 }
591
592 /// Item defintion list.
593 /// This is used for both top-level items and impl block items.
594 ///
595 /// ```
596 /// ❰
597 /// fn foo {}
598 /// struct Bar;
599 /// enum Baz;
600 /// trait Bruh;
601 /// const BRUUH: u32 = 42;
602 /// ❱
603 ///
604 /// impl Foo
605 /// ❰
606 /// {
607 /// fn bar() {}
608 /// const BAZ: u32 = 42;
609 /// }
610 /// ❱
611 /// ```
612 ///
613 /// [Reference](https://doc.rust-lang.org/reference/items.html)
614 struct ItemList: ModuleItemOwner {
615 T!['{'],
616 assoc_items: [AssocItem],
617 T!['}']
618 }
619
620 /// Constant variable definition.
621 /// Includes all of its attributes and doc comments.
622 ///
623 /// ```
624 /// ❰
625 /// /// Docs
626 /// #[attr]
627 /// pub const FOO: u32 = 42;
628 /// ❱
629 /// ```
630 ///
631 /// [Reference](https://doc.rust-lang.org/reference/items/constant-items.html)
632 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
633 T![default],
634 T![const],
635 T![=],
636 body: Expr,
637 T![;]
638 }
639
640
641 /// Static variable definition.
642 /// Includes all of its attributes and doc comments.
643 ///
644 /// ```
645 /// ❰
646 /// /// Docs
647 /// #[attr]
648 /// pub static mut FOO: u32 = 42;
649 /// ❱
650 /// ```
651 ///
652 /// [Reference](https://doc.rust-lang.org/reference/items/static-items.html)
653 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
654 T![static],
655 T![mut],
656 T![=],
657 body: Expr,
658 T![;]
659 }
660
661 /// Type alias definition.
662 /// Includes associated type clauses with type bounds.
663 ///
664 /// ```
665 /// ❰
666 /// /// Docs
667 /// #[attr]
668 /// pub type Foo<T> where T: Debug = T;
669 /// ❱
670 ///
671 /// trait Bar {
672 /// ❰ type Baz: Debug; ❱
673 /// ❰ type Bruh = String; ❱
674 /// ❰ type Bruuh: Debug = u32; ❱
675 /// }
676 /// ```
677 ///
678 /// [Reference](https://doc.rust-lang.org/reference/items/type-aliases.html)
679 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
680 T![default],
681 T![type],
682 T![=],
683 TypeRef,
684 T![;]
685 }
686
687 /// Inherent and trait impl definition.
688 /// Includes all of its inner and outer attributes.
689 ///
690 /// ```
691 /// ❰
692 /// #[attr]
693 /// unsafe impl<T> const !Foo for Bar where T: Debug {
694 /// #![inner_attr]
695 /// // ...
696 /// }
697 /// ❱
698 /// ```
699 ///
700 /// [Reference](https://doc.rust-lang.org/reference/items/implementations.html)
701 struct ImplDef: TypeParamsOwner, AttrsOwner, DocCommentsOwner {
702 T![default],
703 T![const],
704 T![unsafe],
705 T![impl],
706 T![!],
707 T![for],
708 ItemList,
709 }
710
711
712 /// Parenthesized type reference.
713 /// Note: parens are only used for grouping, this is not a tuple type.
714 ///
715 /// ```
716 /// // This is effectively just `u32`.
717 /// // Single-item tuple must be defined with a trailing comma: `(u32,)`
718 /// type Foo = ❰ (u32) ❱;
719 ///
720 /// let bar: &'static ❰ (dyn Debug) ❱ = "bruh";
721 /// ```
722 struct ParenType { T!['('], TypeRef, T![')'] }
723
724 /// Unnamed tuple type.
725 ///
726 /// ```
727 /// let foo: ❰ (u32, bool) ❱ = (42, true);
728 /// ```
729 ///
730 /// [Reference](https://doc.rust-lang.org/reference/types/tuple.html)
731 struct TupleType { T!['('], fields: [TypeRef], T![')'] }
732
733 /// The never type (i.e. the exclamation point).
734 ///
735 /// ```
736 /// type T = ❰ ! ❱;
737 ///
738 /// fn no_return() -> ❰ ! ❱ {
739 /// loop {}
740 /// }
741 /// ```
742 ///
743 /// [Reference](https://doc.rust-lang.org/reference/types/never.html)
744 struct NeverType { T![!] }
745
746 /// Path to a type.
747 /// Includes single identifier type names and elaborate paths with
748 /// generic parameters.
749 ///
750 /// ```
751 /// type Foo = ❰ String ❱;
752 /// type Bar = ❰ std::vec::Vec<T> ❱;
753 /// type Baz = ❰ ::bruh::<Bruuh as Iterator>::Item ❱;
754 /// ```
755 ///
756 /// [Reference](https://doc.rust-lang.org/reference/paths.html)
757 struct PathType { Path }
758
759 /// Raw pointer type.
760 ///
761 /// ```
762 /// type Foo = ❰ *const u32 ❱;
763 /// type Bar = ❰ *mut u32 ❱;
764 /// ```
765 ///
766 /// [Reference](https://doc.rust-lang.org/reference/types/pointer.html#raw-pointers-const-and-mut)
767 struct PointerType { T![*], T![const], T![mut], TypeRef }
768
769 /// Array type.
770 ///
771 /// ```
772 /// type Foo = ❰ [u32; 24 - 3] ❱;
773 /// ```
774 ///
775 /// [Reference](https://doc.rust-lang.org/reference/types/array.html)
776 struct ArrayType { T!['['], TypeRef, T![;], Expr, T![']'] }
777
778 /// Slice type.
779 ///
780 /// ```
781 /// type Foo = ❰ [u8] ❱;
782 /// ```
783 ///
784 /// [Reference](https://doc.rust-lang.org/reference/types/slice.html)
785 struct SliceType { T!['['], TypeRef, T![']'] }
786
787 /// Reference type.
788 ///
789 /// ```
790 /// type Foo = ❰ &'static str ❱;
791 /// ```
792 ///
793 /// [Reference](https://doc.rust-lang.org/reference/types/pointer.html)
794 struct ReferenceType { T![&], T![lifetime], T![mut], TypeRef }
795
796 /// Placeholder type (i.e. the underscore).
797 ///
798 /// ```
799 /// let foo: ❰ _ ❱ = 42_u32;
800 /// ```
801 ///
802 /// [Reference](https://doc.rust-lang.org/reference/types/inferred.html)
803 struct PlaceholderType { T![_] }
804
805 /// Function pointer type (not to be confused with `Fn*` family of traits).
806 ///
807 /// ```
808 /// type Foo = ❰ async fn(#[attr] u32, named: bool) -> u32 ❱;
809 ///
810 /// type Bar = ❰ extern "C" fn(variadic: u32, #[attr] ...) ❱;
811 /// ```
812 ///
813 /// [Reference](https://doc.rust-lang.org/reference/types/function-pointer.html)
814 struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType }
815
816 /// Higher order type.
817 ///
818 /// ```
819 /// type Foo = ❰ for<'a> fn(&'a str) ❱;
820 /// ```
821 ///
822 /// [Reference](https://doc.rust-lang.org/nomicon/hrtb.html)
823 struct ForType { T![for], TypeParamList, TypeRef }
824
825 /// Opaque `impl Trait` type.
826 ///
827 /// ```
828 /// fn foo(bar: ❰ impl Debug + Eq ❱) {}
829 /// ```
830 ///
831 /// [Reference](https://doc.rust-lang.org/reference/types/impl-trait.html)
832 struct ImplTraitType: TypeBoundsOwner { T![impl] }
833
834 /// Trait object type.
835 ///
836 /// ```
837 /// type Foo = ❰ dyn Debug ❱;
838 /// ```
839 ///
840 /// [Reference](https://doc.rust-lang.org/reference/types/trait-object.html)
841 struct DynTraitType: TypeBoundsOwner { T![dyn] }
842
843 /// Tuple literal.
844 ///
845 /// ```
846 /// ❰ (42, true) ❱;
847 /// ```
848 ///
849 /// [Reference](https://doc.rust-lang.org/reference/expressions/tuple-expr.html)
850 struct TupleExpr: AttrsOwner { T!['('], exprs: [Expr], T![')'] }
851
852 /// Array literal.
853 ///
854 /// ```
855 /// ❰ [#![inner_attr] true, false, true] ❱;
856 ///
857 /// ❰ ["baz"; 24] ❱;
858 /// ```
859 ///
860 /// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
861 struct ArrayExpr: AttrsOwner { T!['['], exprs: [Expr], T![;], T![']'] }
862
863 /// Parenthesized expression.
864 /// Note: parens are only used for grouping, this is not a tuple literal.
865 ///
866 /// ```
867 /// ❰ (#![inner_attr] 2 + 2) ❱ * 2;
868 /// ```
869 ///
870 /// [Reference](https://doc.rust-lang.org/reference/expressions/grouped-expr.html)
871 struct ParenExpr: AttrsOwner { T!['('], Expr, T![')'] }
872
873 /// Path to a symbol in expression context.
874 /// Includes single identifier variable names and elaborate paths with
875 /// generic parameters.
876 ///
877 /// ```
878 /// ❰ Some::<i32> ❱;
879 /// ❰ foo ❱ + 42;
880 /// ❰ Vec::<i32>::push ❱;
881 /// ❰ <[i32]>::reverse ❱;
882 /// ❰ <String as std::borrow::Borrow<str>>::borrow ❱;
883 /// ```
884 ///
885 /// [Reference](https://doc.rust-lang.org/reference/expressions/path-expr.html)
886 struct PathExpr { Path }
887
888 /// Anonymous callable object literal a.k.a. closure, lambda or functor.
889 ///
890 /// ```
891 /// ❰ || 42 ❱;
892 /// ❰ |a: u32| val + 1 ❱;
893 /// ❰ async |#[attr] Pattern(_): Pattern| { bar } ❱;
894 /// ❰ move || baz ❱;
895 /// ❰ || -> u32 { closure_with_ret_type_annotation_requires_block_expr } ❱
896 /// ```
897 ///
898 /// [Reference](https://doc.rust-lang.org/reference/expressions/closure-expr.html)
899 struct LambdaExpr: AttrsOwner {
900 T![static], // Note(@matklad): I belive this is (used to be?) syntax for generators
901 T![async],
902 T![move],
903 ParamList,
904 RetType,
905 body: Expr,
906 }
907
908 /// If expression. Includes both regular `if` and `if let` forms.
909 /// Beware that `else if` is a special case syntax sugar, because in general
910 /// there has to be block expression after `else`.
911 ///
912 /// ```
913 /// ❰ if bool_cond { 42 } ❱
914 /// ❰ if bool_cond { 42 } else { 24 } ❱
915 /// ❰ if bool_cond { 42 } else if bool_cond2 { 42 } ❱
916 ///
917 /// ❰
918 /// if let Pattern(foo) = bar {
919 /// foo
920 /// } else {
921 /// panic!();
922 /// }
923 /// ❱
924 /// ```
925 ///
926 /// [Reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
927 struct IfExpr: AttrsOwner { T![if], Condition }
928
929 /// Unconditional loop expression.
930 ///
931 /// ```
932 /// ❰
933 /// loop {
934 /// // yeah, it's that simple...
935 /// }
936 /// ❱
937 /// ```
938 ///
939 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html)
940 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
941
942 /// Block expression with an optional prefix (label, try ketword,
943 /// unsafe keyword, async keyword...).
944 ///
945 /// ```
946 /// ❰
947 /// 'label: try {
948 /// None?
949 /// }
950 /// ❱
951 /// ```
952 ///
953 /// - [try block](https://doc.rust-lang.org/unstable-book/language-features/try-blocks.html)
954 /// - [unsafe block](https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks)
955 /// - [async block](https://doc.rust-lang.org/reference/expressions/block-expr.html#async-blocks)
956 struct EffectExpr: AttrsOwner { Label, T![try], T![unsafe], T![async], BlockExpr }
957
958
959 /// For loop expression.
960 /// Note: record struct literals are not valid as iterable expression
961 /// due to ambiguity.
962 ///
963 /// ```
964 /// ❰
965 /// for i in (0..4) {
966 /// dbg!(i);
967 /// }
968 /// ❱
969 /// ```
970 ///
971 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops)
972 struct ForExpr: AttrsOwner, LoopBodyOwner {
973 T![for],
974 Pat,
975 T![in],
976 iterable: Expr,
977 }
978
979 /// While loop expression. Includes both regular `while` and `while let` forms.
980 ///
981 /// ```
982 /// ❰
983 /// while bool_cond {
984 /// 42;
985 /// }
986 /// ❱
987 /// ❰
988 /// while let Pattern(foo) = bar {
989 /// bar += 1;
990 /// }
991 /// ❱
992 /// ```
993 ///
994 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
995 struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition }
996
997 /// Continue expression.
998 ///
999 /// ```
1000 /// while bool_cond {
1001 /// ❰ continue ❱;
1002 /// }
1003 ///
1004 /// 'outer: loop {
1005 /// loop {
1006 /// ❰ continue 'outer ❱;
1007 /// }
1008 /// }
1009 ///
1010 /// ```
1011 ///
1012 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)
1013 struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
1014
1015 /// Break expression.
1016 ///
1017 /// ```
1018 /// while bool_cond {
1019 /// ❰ break ❱;
1020 /// }
1021 /// 'outer: loop {
1022 /// for foo in bar {
1023 /// ❰ break 'outer ❱;
1024 /// }
1025 /// }
1026 /// 'outer: loop {
1027 /// loop {
1028 /// ❰ break 'outer 42 ❱;
1029 /// }
1030 /// }
1031 /// ```
1032 ///
1033 /// [Refernce](https://doc.rust-lang.org/reference/expressions/loop-expr.html#break-expressions)
1034 struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
1035
1036 /// Label.
1037 ///
1038 /// ```
1039 /// ❰ 'outer: ❱ loop {}
1040 ///
1041 /// let foo = ❰ 'bar: ❱ loop {}
1042 ///
1043 /// ❰ 'baz: ❱ {
1044 /// break 'baz;
1045 /// }
1046 /// ```
1047 ///
1048 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html?highlight=label#loop-labels)
1049 /// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
1050 struct Label { T![lifetime] }
1051
1052 /// Block expression. Includes unsafe blocks and block labels.
1053 ///
1054 /// ```
1055 /// let foo = ❰
1056 /// {
1057 /// #![inner_attr]
1058 /// ❰ { } ❱
1059 ///
1060 /// ❰ 'label: { break 'label } ❱
1061 /// }
1062 /// ❱;
1063 /// ```
1064 ///
1065 /// [Reference](https://doc.rust-lang.org/reference/expressions/block-expr.html)
1066 /// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
1067 struct BlockExpr: AttrsOwner, ModuleItemOwner {
1068 Label, T!['{'], statements: [Stmt], Expr, T!['}'],
1069 }
1070
1071 /// Return expression.
1072 ///
1073 /// ```
1074 /// || ❰ return 42 ❱;
1075 ///
1076 /// fn bar() {
1077 /// ❰ return ❱;
1078 /// }
1079 /// ```
1080 ///
1081 /// [Reference](https://doc.rust-lang.org/reference/expressions/return-expr.html)
1082 struct ReturnExpr: AttrsOwner { Expr }
1083
1084 /// Call expression (not to be confused with method call expression, it is
1085 /// a separate ast node).
1086 ///
1087 /// ```
1088 /// ❰ foo() ❱;
1089 /// ❰ &str::len("bar") ❱;
1090 /// ❰ <&str as PartialEq<&str>>::eq(&"", &"") ❱;
1091 /// ```
1092 ///
1093 /// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
1094 struct CallExpr: ArgListOwner { Expr }
1095
1096 /// Method call expression.
1097 ///
1098 /// ```
1099 /// ❰ receiver_expr.method() ❱;
1100 /// ❰ receiver_expr.method::<T>(42, true) ❱;
1101 ///
1102 /// ❰ ❰ ❰ foo.bar() ❱ .baz() ❱ .bruh() ❱;
1103 /// ```
1104 ///
1105 /// [Reference](https://doc.rust-lang.org/reference/expressions/method-call-expr.html)
1106 struct MethodCallExpr: AttrsOwner, ArgListOwner {
1107 Expr, T![.], NameRef, TypeArgList,
1108 }
1109
1110 /// Index expression a.k.a. subscript operator call.
1111 ///
1112 /// ```
1113 /// ❰ foo[42] ❱;
1114 /// ```
1115 ///
1116 /// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
1117 struct IndexExpr: AttrsOwner { T!['['], T![']'] }
1118
1119 /// Field access expression.
1120 ///
1121 /// ```
1122 /// ❰ expr.bar ❱;
1123 ///
1124 /// ❰ ❰ ❰ foo.bar ❱ .baz ❱ .bruh ❱;
1125 /// ```
1126 ///
1127 /// [Reference](https://doc.rust-lang.org/reference/expressions/field-expr.html)
1128 struct FieldExpr: AttrsOwner { Expr, T![.], NameRef }
1129
1130 /// Await operator call expression.
1131 ///
1132 /// ```
1133 /// ❰ expr.await ❱;
1134 /// ```
1135 ///
1136 /// [Reference](https://doc.rust-lang.org/reference/expressions/await-expr.html)
1137 struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] }
1138
1139 /// The question mark operator call.
1140 ///
1141 /// ```
1142 /// ❰ expr? ❱;
1143 /// ```
1144 ///
1145 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)
1146 struct TryExpr: AttrsOwner { Expr, T![?] }
1147
1148 /// Type cast expression.
1149 ///
1150 /// ```
1151 /// ❰ expr as T ❱;
1152 /// ```
1153 ///
1154 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions)
1155 struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
1156
1157
1158 /// Borrow operator call.
1159 ///
1160 /// ```
1161 /// ❰ &foo ❱;
1162 /// ❰ &mut bar ❱;
1163 /// ❰ &raw const bar ❱;
1164 /// ❰ &raw mut bar ❱;
1165 /// ```
1166 ///
1167 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators)
1168 struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], T![const], Expr }
1169
1170 /// Prefix operator call. This is either `!` or `*` or `-`.
1171 ///
1172 /// ```
1173 /// ❰ !foo ❱;
1174 /// ❰ *bar ❱;
1175 /// ❰ -42 ❱;
1176 /// ```
1177 ///
1178 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html)
1179 struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr }
1180
1181 /// Box operator call.
1182 ///
1183 /// ```
1184 /// ❰ box 42 ❱;
1185 /// ```
1186 ///
1187 /// [RFC](https://github.com/rust-lang/rfcs/blob/0806be4f282144cfcd55b1d20284b43f87cbe1c6/text/0809-box-and-in-for-stdlib.md)
1188 struct BoxExpr: AttrsOwner { T![box], Expr }
1189
1190 /// Range operator call.
1191 ///
1192 /// ```
1193 /// ❰ 0..42 ❱;
1194 /// ❰ ..42 ❱;
1195 /// ❰ 0.. ❱;
1196 /// ❰ .. ❱;
1197 /// ❰ 0..=42 ❱;
1198 /// ❰ ..=42 ❱;
1199 /// ```
1200 ///
1201 /// [Reference](https://doc.rust-lang.org/reference/expressions/range-expr.html)
1202 struct RangeExpr: AttrsOwner { /*RangeOp*/ }
1203
1204
1205 /// Binary operator call.
1206 /// Includes all arithmetic, logic, bitwise and assignment operators.
1207 ///
1208 /// ```
1209 /// ❰ 2 + ❰ 2 * 2 ❱ ❱;
1210 /// ❰ ❰ true && false ❱ || true ❱;
1211 /// ```
1212 ///
1213 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators)
1214 struct BinExpr: AttrsOwner { /*BinOp*/ }
1215
1216
1217 /// [Raw] string, [raw] byte string, char, byte, integer, float or bool literal.
1218 ///
1219 /// ```
1220 /// ❰ "str" ❱;
1221 /// ❰ br##"raw byte str"## ❱;
1222 /// ❰ 'c' ❱;
1223 /// ❰ b'c' ❱;
1224 /// ❰ 42 ❱;
1225 /// ❰ 1e9 ❱;
1226 /// ❰ true ❱;
1227 /// ```
1228 ///
1229 /// [Reference](https://doc.rust-lang.org/reference/expressions/literal-expr.html)
1230 struct Literal { /*LiteralToken*/ }
1231
1232 /// Match expression.
1233 ///
1234 /// ```
1235 /// ❰
1236 /// match expr {
1237 /// Pat1 => {}
1238 /// Pat2(_) => 42,
1239 /// }
1240 /// ❱
1241 /// ```
1242 ///
1243 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
1244 struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList }
1245
1246 /// Match arm list part of match expression. Includes its inner attributes.
1247 ///
1248 /// ```
1249 /// match expr
1250 /// ❰
1251 /// {
1252 /// #![inner_attr]
1253 /// Pat1 => {}
1254 /// Pat2(_) => 42,
1255 /// }
1256 /// ❱
1257 /// ```
1258 ///
1259 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
1260 struct MatchArmList: AttrsOwner { T!['{'], arms: [MatchArm], T!['}'] }
1261
1262
1263 /// Match arm.
1264 /// Note: record struct literals are not valid as target match expression
1265 /// due to ambiguity.
1266 /// ```
1267 /// match expr {
1268 /// ❰ #[attr] Pattern(it) if bool_cond => it ❱,
1269 /// }
1270 /// ```
1271 ///
1272 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
1273 struct MatchArm: AttrsOwner {
1274 pat: Pat,
1275 guard: MatchGuard,
1276 T![=>],
1277 Expr,
1278 }
1279
1280 /// Match guard.
1281 ///
1282 /// ```
1283 /// match expr {
1284 /// Pattern(it) ❰ if bool_cond ❱ => it,
1285 /// }
1286 /// ```
1287 ///
1288 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards)
1289 struct MatchGuard { T![if], Expr }
1290
1291 /// Record literal expression. The same syntax is used for structs,
1292 /// unions and record enum variants.
1293 ///
1294 /// ```
1295 /// ❰
1296 /// foo::Bar {
1297 /// #![inner_attr]
1298 /// baz: 42,
1299 /// bruh: true,
1300 /// ..spread
1301 /// }
1302 /// ❱
1303 /// ```
1304 ///
1305 /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
1306 struct RecordLit { Path, RecordFieldList}
1307
1308 /// Record field list including enclosing curly braces.
1309 ///
1310 /// foo::Bar ❰
1311 /// {
1312 /// baz: 42,
1313 /// ..spread
1314 /// }
1315 /// ❱
1316 ///
1317 /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
1318 struct RecordFieldList {
1319 T!['{'],
1320 fields: [RecordField],
1321 T![..],
1322 spread: Expr,
1323 T!['}']
1324 }
1325
1326 /// Record field.
1327 ///
1328 /// ```
1329 /// foo::Bar {
1330 /// ❰ #[attr] baz: 42 ❱
1331 /// }
1332 /// ```
1333 ///
1334 /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
1335 struct RecordField: AttrsOwner { NameRef, T![:], Expr }
1336
1337 /// Disjunction of patterns.
1338 ///
1339 /// ```
1340 /// let ❰ Foo(it) | Bar(it) | Baz(it) ❱ = bruh;
1341 /// ```
1342 ///
1343 /// [Reference](https://doc.rust-lang.org/reference/patterns.html)
1344 struct OrPat { pats: [Pat] }
1345
1346 /// Parenthesized pattern.
1347 /// Note: parens are only used for grouping, this is not a tuple pattern.
1348 ///
1349 /// ```
1350 /// if let ❰ &(0..=42) ❱ = foo {}
1351 /// ```
1352 ///
1353 /// https://doc.rust-lang.org/reference/patterns.html#grouped-patterns
1354 struct ParenPat { T!['('], Pat, T![')'] }
1355
1356 /// Reference pattern.
1357 /// Note: this has nothing to do with `ref` keyword, the latter is used in bind patterns.
1358 ///
1359 /// ```
1360 /// let ❰ &mut foo ❱ = bar;
1361 ///
1362 /// let ❰ & ❰ &mut ❰ &_ ❱ ❱ ❱ = baz;
1363 /// ```
1364 ///
1365 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#reference-patterns)
1366 struct RefPat { T![&], T![mut], Pat }
1367
1368 /// Box pattern.
1369 ///
1370 /// ```
1371 /// let ❰ box foo ❱ = box 42;
1372 /// ```
1373 ///
1374 /// [Unstable book](https://doc.rust-lang.org/unstable-book/language-features/box-patterns.html)
1375 struct BoxPat { T![box], Pat }
1376
1377 /// Bind pattern.
1378 ///
1379 /// ```
1380 /// match foo {
1381 /// Some(❰ ref mut bar ❱) => {}
1382 /// ❰ baz @ None ❱ => {}
1383 /// }
1384 /// ```
1385 ///
1386 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#identifier-patterns)
1387 struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], T![@], Pat }
1388
1389 /// Placeholder pattern a.k.a. the wildcard pattern or the underscore.
1390 ///
1391 /// ```
1392 /// let ❰ _ ❱ = foo;
1393 /// ```
1394 ///
1395 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#wildcard-pattern)
1396 struct PlaceholderPat { T![_] }
1397
1398 /// Rest-of-the record/tuple pattern.
1399 /// Note: this is not the unbonded range pattern (even more: it doesn't exist).
1400 ///
1401 /// ```
1402 /// let Foo { bar, ❰ .. ❱ } = baz;
1403 /// let (❰ .. ❱, bruh) = (42, 24, 42);
1404 /// let Bruuh(❰ .. ❱) = bruuuh;
1405 /// ```
1406 ///
1407 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1408 struct DotDotPat { T![..] }
1409
1410 /// Path pattern.
1411 /// Doesn't include the underscore pattern (it is a special case, namely `PlaceholderPat`).
1412 ///
1413 /// ```
1414 /// let ❰ foo::bar::Baz ❱ { .. } = bruh;
1415 /// if let ❰ CONST ❱ = 42 {}
1416 /// ```
1417 ///
1418 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#path-patterns)
1419 struct PathPat { Path }
1420
1421 /// Slice pattern.
1422 ///
1423 /// ```
1424 /// let ❰ [foo, bar, baz] ❱ = [1, 2, 3];
1425 /// ```
1426 ///
1427 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#slice-patterns)
1428 struct SlicePat { T!['['], args: [Pat], T![']'] }
1429
1430 /// Range pattern.
1431 ///
1432 /// ```
1433 /// match foo {
1434 /// ❰ 0..42 ❱ => {}
1435 /// ❰ 0..=42 ❱ => {}
1436 /// }
1437 /// ```
1438 ///
1439 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#range-patterns)
1440 struct RangePat { } // FIXME(@matklad): here should be T![..], T![..=] I think, if we don't already have an accessor in expresions_ext
1441
1442 /// Literal pattern.
1443 /// Includes only bool, number, char, and string literals.
1444 ///
1445 /// ```
1446 /// match foo {
1447 /// Number(❰ 42 ❱) => {}
1448 /// String(❰ "42" ❱) => {}
1449 /// Bool(❰ true ❱) => {}
1450 /// }
1451 /// ```
1452 ///
1453 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#literal-patterns)
1454 struct LiteralPat { Literal }
1455
1456 /// Macro invocation in pattern position.
1457 ///
1458 /// ```
1459 /// let ❰ foo!(my custom syntax) ❱ = baz;
1460 ///
1461 /// ```
1462 /// [Reference](https://doc.rust-lang.org/reference/macros.html#macro-invocation)
1463 struct MacroPat { MacroCall }
1464
1465 /// Record literal pattern.
1466 ///
1467 /// ```
1468 /// let ❰ foo::Bar { baz, .. } ❱ = bruh;
1469 /// ```
1470 ///
1471 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1472 struct RecordPat { RecordFieldPatList, Path }
1473
1474 /// Record literal's field patterns list including enclosing curly braces.
1475 ///
1476 /// ```
1477 /// let foo::Bar ❰ { baz, bind @ bruh, .. } ❱ = bruuh;
1478 /// ``
1479 ///
1480 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1481 struct RecordFieldPatList {
1482 T!['{'],
1483 pats: [RecordInnerPat],
1484 record_field_pats: [RecordFieldPat],
1485 bind_pats: [BindPat],
1486 T![..],
1487 T!['}']
1488 }
1489
1490 /// Record literal's field pattern.
1491 /// Note: record literal can also match tuple structs.
1492 ///
1493 /// ```
1494 /// let Foo { ❰ bar: _ ❱ } = baz;
1495 /// let TupleStruct { ❰ 0: _ ❱ } = bruh;
1496 /// ```
1497 ///
1498 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1499 struct RecordFieldPat: AttrsOwner { NameRef, T![:], Pat }
1500
1501 /// Tuple struct literal pattern.
1502 ///
1503 /// ```
1504 /// let ❰ foo::Bar(baz, bruh) ❱ = bruuh;
1505 /// ```
1506 ///
1507 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-struct-patterns)
1508 struct TupleStructPat { Path, T!['('], args: [Pat], T![')'] }
1509
1510 /// Tuple pattern.
1511 /// Note: this doesn't include tuple structs (see `TupleStructPat`)
1512 ///
1513 /// ```
1514 /// let ❰ (foo, bar, .., baz) ❱ = bruh;
1515 /// ```
1516 ///
1517 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-patterns)
1518 struct TuplePat { T!['('], args: [Pat], T![')'] }
1519
1520 /// Visibility.
1521 ///
1522 /// ```
1523 /// ❰ pub mod ❱ foo;
1524 /// ❰ pub(crate) ❱ struct Bar;
1525 /// ❰ pub(self) ❱ enum Baz {}
1526 /// ❰ pub(super) ❱ fn bruh() {}
1527 /// ❰ pub(in bruuh::bruuuh) ❱ type T = u64;
1528 /// ```
1529 ///
1530 /// [Reference](https://doc.rust-lang.org/reference/visibility-and-privacy.html)
1531 struct Visibility { T![pub], T![super], T![self], T![crate] }
1532
1533 /// Single identifier.
1534 /// Note(@matklad): `Name` is for things that install a new name into the scope,
1535 /// `NameRef` is a usage of a name. Most of the time, this definition/reference
1536 /// distinction can be determined purely syntactically, ie in
1537 /// ```
1538 /// fn foo() { foo() }
1539 /// ```
1540 /// the first foo is `Name`, the second one is `NameRef`.
1541 /// The notable exception are patterns, where in
1542 /// ``
1543 /// let x = 92
1544 /// ```
1545 /// `x` can be semantically either a name or a name ref, depeding on
1546 /// wether there's an `x` constant in scope.
1547 /// We use `Name` for patterns, and disambiguate semantically (see `NameClass` in ide_db).
1548 ///
1549 /// ```
1550 /// let ❰ foo ❱ = bar;
1551 /// struct ❰ Baz ❱;
1552 /// fn ❰ bruh ❱() {}
1553 /// ```
1554 ///
1555 /// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
1556 struct Name { T![ident] }
1557
1558 /// Reference to a name.
1559 /// See the explanation on the difference between `Name` and `NameRef`
1560 /// in `Name` ast node docs.
1561 ///
1562 /// ```
1563 /// let foo = ❰ bar ❱(❰ Baz(❰ bruh ❱) ❱;
1564 /// ```
1565 ///
1566 /// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
1567 struct NameRef { }
1568
1569 /// Macro call.
1570 /// Includes all of its attributes and doc comments.
1571 ///
1572 /// ```
1573 /// ❰
1574 /// /// Docs
1575 /// #[attr]
1576 /// macro_rules! foo { // macro rules is also a macro call
1577 /// ($bar: tt) => {}
1578 /// }
1579 /// ❱
1580 ///
1581 /// // semicolon is a part of `MacroCall` when it is used in item positions
1582 /// ❰ foo!(); ❱
1583 ///
1584 /// fn main() {
1585 /// ❰ foo!() ❱; // macro call in expression positions doesn't include the semi
1586 /// }
1587 /// ```
1588 ///
1589 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
1590 struct MacroCall: NameOwner, AttrsOwner, DocCommentsOwner {
1591 Path, T![!], TokenTree, T![;]
1592 }
1593
1594 /// Attribute.
1595 ///
1596 /// ```
1597 /// ❰ #![inner_attr] ❱
1598 ///
1599 /// ❰ #[attr] ❱
1600 /// ❰ #[foo = "bar"] ❱
1601 /// ❰ #[baz(bruh::bruuh = "42")] ❱
1602 /// struct Foo;
1603 /// ```
1604 ///
1605 /// [Reference](https://doc.rust-lang.org/reference/attributes.html)
1606 struct Attr { T![#], T![!], T!['['], Path, T![=], input: AttrInput, T![']'] }
1607
1608 /// Stores a list of lexer tokens and other `TokenTree`s.
1609 /// It appears in attributes, macro_rules and macro call (foo!)
1610 ///
1611 /// ```
1612 /// macro_call! ❰ { my syntax here } ❱;
1613 /// ```
1614 ///
1615 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
1616 struct TokenTree {}
1617
1618 /// Generic lifetime, type and constants parameters list **declaration**.
1619 ///
1620 /// ```
1621 /// fn foo❰ <'a, 'b, T, U, const BAR: u64> ❱() {}
1622 ///
1623 /// struct Baz❰ <T> ❱(T);
1624 ///
1625 /// impl❰ <T> ❱ Bruh<T> {}
1626 ///
1627 /// type Bruuh = for❰ <'a> ❱ fn(&'a str) -> &'a str;
1628 /// ```
1629 ///
1630 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
1631 struct TypeParamList {
1632 T![<],
1633 generic_params: [GenericParam],
1634 type_params: [TypeParam],
1635 lifetime_params: [LifetimeParam],
1636 const_params: [ConstParam],
1637 T![>]
1638 }
1639
1640 /// Single type parameter **declaration**.
1641 ///
1642 /// ```
1643 /// fn foo<❰ K ❱, ❰ I ❱, ❰ E: Debug ❱, ❰ V = DefaultType ❱>() {}
1644 /// ```
1645 ///
1646 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
1647 struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
1648 T![=],
1649 default_type: TypeRef,
1650 }
1651
1652 /// Const generic parameter **declaration**.
1653 /// ```
1654 /// fn foo<T, U, ❰ const BAR: usize ❱, ❰ const BAZ: bool ❱>() {}
1655 /// ```
1656 ///
1657 /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
1658 struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
1659 T![=],
1660 default_val: Expr,
1661 }
1662
1663 /// Lifetime parameter **declaration**.
1664 ///
1665 /// ```
1666 /// fn foo<❰ 'a ❱, ❰ 'b ❱, V, G, D>(bar: &'a str, baz: &'b mut str) {}
1667 /// ```
1668 ///
1669 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
1670 struct LifetimeParam: AttrsOwner { T![lifetime] }
1671
1672 /// Type bound declaration clause.
1673 ///
1674 /// ```
1675 /// fn foo<T: ❰ ?Sized ❱ + ❰ Debug ❱>() {}
1676 ///
1677 /// trait Bar<T>
1678 /// where
1679 /// T: ❰ Send ❱ + ❰ Sync ❱
1680 /// {
1681 /// type Baz: ❰ !Sync ❱ + ❰ Debug ❱ + ❰ ?const Add ❱;
1682 /// }
1683 /// ```
1684 ///
1685 /// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
1686 struct TypeBound { T![lifetime], /* Question, */ T![const], /* Question, */ TypeRef }
1687
1688 /// Type bounds list.
1689 ///
1690 /// ```
1691 ///
1692 /// fn foo<T: ❰ ?Sized + Debug ❱>() {}
1693 ///
1694 /// trait Bar<T>
1695 /// where
1696 /// T: ❰ Send + Sync ❱
1697 /// {
1698 /// type Baz: ❰ !Sync + Debug ❱;
1699 /// }
1700 /// ```
1701 ///
1702 /// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
1703 struct TypeBoundList { bounds: [TypeBound] }
1704
1705 /// Single where predicate.
1706 ///
1707 /// ```
1708 /// trait Foo<'a, 'b, T>
1709 /// where
1710 /// ❰ 'a: 'b ❱,
1711 /// ❰ T: IntoIterator ❱,
1712 /// ❰ for<'c> <T as IntoIterator>::Item: Bar<'c> ❱
1713 /// {}
1714 /// ```
1715 ///
1716 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
1717 struct WherePred: TypeBoundsOwner { T![for], TypeParamList, T![lifetime], TypeRef }
1718
1719 /// Where clause.
1720 ///
1721 /// ```
1722 /// trait Foo<'a, T> ❰ where 'a: 'static, T: Debug ❱ {}
1723 ///
1724 /// ```
1725 ///
1726 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
1727 struct WhereClause { T![where], predicates: [WherePred] }
1728
1729 /// Abi declaration.
1730 /// Note: the abi string is optional.
1731 ///
1732 /// ```
1733 /// ❰ extern "C" ❱ {
1734 /// fn foo() {}
1735 /// }
1736 ///
1737 /// type Bar = ❰ extern ❱ fn() -> u32;
1738 ///
1739 /// type Baz = ❰ extern r#"stdcall"# ❱ fn() -> bool;
1740 /// ```
1741 ///
1742 /// - [Extern blocks reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
1743 /// - [FFI function pointers reference](https://doc.rust-lang.org/reference/items/functions.html#functions)
1744 struct Abi { /*String*/ }
1745
1746 /// Expression statement.
1747 ///
1748 /// ```
1749 /// ❰ 42; ❱
1750 /// ❰ foo(); ❱
1751 /// ❰ (); ❱
1752 /// ❰ {}; ❱
1753 ///
1754 /// // constructions with trailing curly brace can omit the semicolon
1755 /// // but only when there are satements immediately after them (this is important!)
1756 /// ❰ if bool_cond { } ❱
1757 /// ❰ loop {} ❱
1758 /// ❰ somestatment; ❱
1759 /// ```
1760 ///
1761 /// [Reference](https://doc.rust-lang.org/reference/statements.html)
1762 struct ExprStmt: AttrsOwner { Expr, T![;] }
1763
1764 /// Let statement.
1765 ///
1766 /// ```
1767 /// ❰ #[attr] let foo; ❱
1768 /// ❰ let bar: u64; ❱
1769 /// ❰ let baz = 42; ❱
1770 /// ❰ let bruh: bool = true; ❱
1771 /// ```
1772 ///
1773 /// [Reference](https://doc.rust-lang.org/reference/statements.html#let-statements)
1774 struct LetStmt: AttrsOwner, TypeAscriptionOwner {
1775 T![let],
1776 Pat,
1777 T![=],
1778 initializer: Expr,
1779 T![;],
1780 }
1781
1782 /// Condition of `if` or `while` expression.
1783 ///
1784 /// ```
1785 /// if ❰ true ❱ {}
1786 /// if ❰ let Pat(foo) = bar ❱ {}
1787 ///
1788 /// while ❰ true ❱ {}
1789 /// while ❰ let Pat(baz) = bruh ❱ {}
1790 /// ```
1791 ///
1792 /// [If expression reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
1793 /// [While expression reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
1794 struct Condition { T![let], Pat, T![=], Expr }
1795
1796 /// Parameter list **declaration**.
1797 ///
1798 /// ```
1799 /// fn foo❰ (a: u32, b: bool) ❱ -> u32 {}
1800 /// let bar = ❰ |a, b| ❱ {};
1801 ///
1802 /// impl Baz {
1803 /// fn bruh❰ (&self, a: u32) ❱ {}
1804 /// }
1805 /// ```
1806 ///
1807 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)ocs to codegen script
1808 struct ParamList { // FIXME: this node is used by closure expressions too, but hey use pipes instead of parens...
1809 T!['('],
1810 SelfParam,
1811 params: [Param],
1812 T![')']
1813 }
1814
1815 /// Self parameter **declaration**.
1816 ///
1817 /// ```
1818 /// impl Bruh {
1819 /// fn foo(❰ self ❱) {}
1820 /// fn bar(❰ &self ❱) {}
1821 /// fn baz(❰ &mut self ❱) {}
1822 /// fn blah<'a>(❰ &'a self ❱) {}
1823 /// fn blin(❰ self: Box<Self> ❱) {}
1824 /// }
1825 /// ```
1826 ///
1827 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
1828 struct SelfParam: TypeAscriptionOwner, AttrsOwner { T![&], T![mut], T![lifetime], T![self] }
1829
1830 /// Parameter **declaration**.
1831 ///
1832 /// ```
1833 /// fn foo(❰ #[attr] Pat(bar): Pat(u32) ❱, ❰ #[attr] _: bool ❱) {}
1834 ///
1835 /// extern "C" {
1836 /// fn bar(❰ baz: u32 ❱, ❰ ... ❱) -> u32;
1837 /// }
1838 /// ```
1839 ///
1840 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
1841 struct Param: TypeAscriptionOwner, AttrsOwner {
1842 Pat,
1843 T![...]
1844 }
1845
1846 /// Use declaration.
1847 ///
1848 /// ```
1849 /// ❰ #[attr] pub use foo; ❱
1850 /// ❰ use bar as baz; ❱
1851 /// ❰ use bruh::{self, bruuh}; ❱
1852 /// ❰ use { blin::blen, blah::* };
1853 /// ```
1854 ///
1855 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1856 struct UseItem: AttrsOwner, VisibilityOwner {
1857 T![use],
1858 UseTree,
1859 }
1860
1861 /// Use tree.
1862 ///
1863 /// ```
1864 /// pub use ❰ foo::❰ * ❱ ❱;
1865 /// use ❰ bar as baz ❱;
1866 /// use ❰ bruh::bruuh::{ ❰ self ❱, ❰ blin ❱ } ❱;
1867 /// use ❰ { ❰ blin::blen ❱ } ❱
1868 /// ```
1869 ///
1870 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1871 struct UseTree {
1872 Path, T![*], UseTreeList, Alias
1873 }
1874
1875 /// Item alias.
1876 /// Note: this is not the type alias.
1877 ///
1878 /// ```
1879 /// use foo ❰ as bar ❱;
1880 /// use baz::{bruh ❰ as _ ❱};
1881 /// extern crate bruuh ❰ as blin ❱;
1882 /// ```
1883 ///
1884 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1885 struct Alias: NameOwner { T![as] }
1886
1887 /// Sublist of use trees.
1888 ///
1889 /// ```
1890 /// use bruh::bruuh::❰ { ❰ self ❱, ❰ blin ❱ } ❱;
1891 /// use ❰ { blin::blen::❰ {} ❱ } ❱
1892 /// ```
1893 ///
1894 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1895 struct UseTreeList { T!['{'], use_trees: [UseTree], T!['}'] }
1896
1897 /// Extern crate item.
1898 ///
1899 /// ```
1900 /// ❰ #[attr] pub extern crate foo; ❱
1901 /// ❰ extern crate self as bar; ❱
1902 /// ```
1903 ///
1904 /// [Reference](https://doc.rust-lang.org/reference/items/extern-crates.html)
1905 struct ExternCrateItem: AttrsOwner, VisibilityOwner {
1906 T![extern], T![crate], NameRef, Alias,
1907 }
1908
1909 /// Call site arguments list.
1910 ///
1911 /// ```
1912 /// foo::<T, U>❰ (42, true) ❱;
1913 /// ```
1914 ///
1915 /// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
1916 struct ArgList {
1917 T!['('],
1918 args: [Expr],
1919 T![')']
1920 }
1921
1922 /// Path to a symbol. Includes single identifier names and elaborate paths with
1923 /// generic parameters.
1924 ///
1925 /// ```
1926 /// (0..10).❰ ❰ collect ❱ ::<Vec<_>> ❱();
1927 /// ❰ ❰ ❰ Vec ❱ ::<u8> ❱ ::with_capacity ❱(1024);
1928 /// ❰ ❰ <❰ Foo ❱ as ❰ ❰ bar ❱ ::Bar ❱> ❱ ::baz ❱();
1929 /// ❰ ❰ <❰ bruh ❱> ❱ ::bruuh ❱();
1930 /// ```
1931 ///
1932 /// [Reference](https://doc.rust-lang.org/reference/paths.html)
1933 struct Path {
1934 segment: PathSegment,
1935 T![::],
1936 qualifier: Path,
1937 }
1938
1939 /// Segment of the path to a symbol.
1940 /// Only path segment of an absolute path holds the `::` token,
1941 /// all other `::` tokens that connect path segments reside under `Path` itself.`
1942 ///
1943 /// ```
1944 /// (0..10).❰ collect ❱ :: ❰ <Vec<_>> ❱();
1945 /// ❰ Vec ❱ :: ❰ <u8> ❱ :: ❰ with_capacity ❱(1024);
1946 /// ❰ <❰ Foo ❱ as ❰ bar ❱ :: ❰ Bar ❱> ❱ :: ❰ baz ❱();
1947 /// ❰ <❰ bruh ❱> ❱ :: ❰ bruuh ❱();
1948 ///
1949 /// // Note that only in this case `::` token is inlcuded:
1950 /// ❰ ::foo ❱;
1951 /// ```
1952 ///
1953 /// [Reference](https://doc.rust-lang.org/reference/paths.html)
1954 struct PathSegment {
1955 T![::], T![crate], T![self], T![super], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>]
1956 }
1957
1958 /// List of type arguments that are passed at generic instantiation site.
1959 ///
1960 /// ```
1961 /// type _ = Foo ❰ ::<'a, u64, Item = Bar, 42, {true}> ❱::Bar;
1962 ///
1963 /// Vec❰ ::<bool> ❱::();
1964 /// ```
1965 ///
1966 /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
1967 struct TypeArgList {
1968 T![::],
1969 T![<],
1970 generic_args: [GenericArg],
1971 type_args: [TypeArg],
1972 lifetime_args: [LifetimeArg],
1973 assoc_type_args: [AssocTypeArg],
1974 const_args: [ConstArg],
1975 T![>]
1976 }
1977
1978 /// Type argument that is passed at generic instantiation site.
1979 ///
1980 /// ```
1981 /// type _ = Foo::<'a, ❰ u64 ❱, ❰ bool ❱, Item = Bar, 42>::Baz;
1982 /// ```
1983 ///
1984 /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
1985 struct TypeArg { TypeRef }
1986
1987 /// Associated type argument that is passed at generic instantiation site.
1988 /// ```
1989 /// type Foo = Bar::<'a, u64, bool, ❰ Item = Baz ❱, 42>::Bruh;
1990 ///
1991 /// trait Bruh<T>: Iterator<❰ Item: Debug ❱> {}
1992 /// ```
1993 ///
1994 struct AssocTypeArg : TypeBoundsOwner { NameRef, T![=], TypeRef }
1995
1996 /// Lifetime argument that is passed at generic instantiation site.
1997 ///
1998 /// ```
1999 /// fn foo<'a>(s: &'a str) {
2000 /// bar::<❰ 'a ❱>(s);
2001 /// }
2002 /// ```
2003 ///
2004 /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
2005 struct LifetimeArg { T![lifetime] }
2006
2007 /// Constant value argument that is passed at generic instantiation site.
2008 ///
2009 /// ```
2010 /// foo::<u32, ❰ { true } ❱>();
2011 ///
2012 /// bar::<❰ { 2 + 2} ❱>();
2013 /// ```
2014 ///
2015 /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
2016 struct ConstArg { Literal, BlockExpr }
2017
2018
2019 /// FIXME: (@edwin0cheng) Remove it to use ItemList instead
2020 /// https://github.com/rust-analyzer/rust-analyzer/pull/4083#discussion_r422666243
2021 ///
2022 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
2023 struct MacroItems: ModuleItemOwner { }
2024
2025 /// FIXME: (@edwin0cheng) add some documentation here. As per the writing
2026 /// of this comment this ast node is not used.
2027 ///
2028 /// ```
2029 /// // FIXME: example here
2030 /// ```
2031 ///
2032 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
2033 struct MacroStmts {
2034 statements: [Stmt],
2035 Expr,
2036 }
2037
2038 /// List of items in an extern block.
2039 ///
2040 /// ```
2041 /// extern "C" ❰
2042 /// {
2043 /// fn foo();
2044 /// static var: u32;
2045 /// }
2046 /// ❱
2047 /// ```
2048 ///
2049 /// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
2050 struct ExternItemList: ModuleItemOwner {
2051 T!['{'],
2052 extern_items: [ExternItem],
2053 T!['}']
2054 }
2055
2056 /// Extern block.
2057 ///
2058 /// ```
2059 /// ❰
2060 /// extern "C" {
2061 /// fn foo();
2062 /// }
2063 /// ❱
2064 ///
2065 /// ```
2066 ///
2067 /// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
2068 struct ExternBlock {
2069 Abi,
2070 ExternItemList
2071 }
2072
2073 /// Meta item in an attribute.
2074 ///
2075 /// ```
2076 /// #[❰ bar::baz = "42" ❱]
2077 /// #[❰ bruh(bruuh("true")) ❱]
2078 /// struct Foo;
2079 /// ```
2080 ///
2081 /// [Reference](https://doc.rust-lang.org/reference/attributes.html?highlight=meta,item#meta-item-attribute-syntax)
2082 struct MetaItem {
2083 Path, T![=], AttrInput, nested_meta_items: [MetaItem]
2084 }
2085
2086 /// Macro 2.0 definition.
2087 /// Their syntax is still WIP by rustc team...
2088 /// ```
2089 /// ❰
2090 /// macro foo { }
2091 /// ❱
2092 /// ```
2093 ///
2094 /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/1584-macros.md)
2095 struct MacroDef {
2096 Name, TokenTree
2097 }
2098 },
2099 enums: ast_enums! {
2100 /// Any kind of nominal type definition.
2101 enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
2102 StructDef, EnumDef, UnionDef,
2103 }
2104
2105 /// Any kind of **declared** generic parameter
2106 enum GenericParam {
2107 LifetimeParam,
2108 TypeParam,
2109 ConstParam
2110 }
2111
2112 /// Any kind of generic argument passed at instantiation site
2113 enum GenericArg {
2114 LifetimeArg,
2115 TypeArg,
2116 ConstArg,
2117 AssocTypeArg
2118 }
2119
2120 /// Any kind of construct valid in type context
2121 enum TypeRef {
2122 ParenType,
2123 TupleType,
2124 NeverType,
2125 PathType,
2126 PointerType,
2127 ArrayType,
2128 SliceType,
2129 ReferenceType,
2130 PlaceholderType,
2131 FnPointerType,
2132 ForType,
2133 ImplTraitType,
2134 DynTraitType,
2135 }
2136
2137 /// Any kind of top-level item that may appear in a module
2138 enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner {
2139 StructDef,
2140 UnionDef,
2141 EnumDef,
2142 FnDef,
2143 TraitDef,
2144 TypeAliasDef,
2145 ImplDef,
2146 UseItem,
2147 ExternCrateItem,
2148 ConstDef,
2149 StaticDef,
2150 Module,
2151 MacroCall,
2152 ExternBlock
2153 }
2154
2155
2156
2157 /// Any kind of item that may appear in an impl block
2158 ///
2159 /// // FIXME: impl blocks can also contain MacroCall
2160 enum AssocItem: NameOwner, AttrsOwner {
2161 FnDef, TypeAliasDef, ConstDef
2162 }
2163
2164 /// Any kind of item that may appear in an extern block
2165 ///
2166 /// // FIXME: extern blocks can also contain MacroCall
2167 enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner {
2168 FnDef, StaticDef
2169 }
2170
2171 /// Any kind of expression
2172 enum Expr: AttrsOwner {
2173 TupleExpr,
2174 ArrayExpr,
2175 ParenExpr,
2176 PathExpr,
2177 LambdaExpr,
2178 IfExpr,
2179 LoopExpr,
2180 ForExpr,
2181 WhileExpr,
2182 ContinueExpr,
2183 BreakExpr,
2184 Label,
2185 BlockExpr,
2186 ReturnExpr,
2187 MatchExpr,
2188 RecordLit,
2189 CallExpr,
2190 IndexExpr,
2191 MethodCallExpr,
2192 FieldExpr,
2193 AwaitExpr,
2194 TryExpr,
2195 EffectExpr,
2196 CastExpr,
2197 RefExpr,
2198 PrefixExpr,
2199 RangeExpr,
2200 BinExpr,
2201 Literal,
2202 MacroCall,
2203 BoxExpr,
2204 }
2205
2206 /// Any kind of pattern
2207 enum Pat {
2208 OrPat,
2209 ParenPat,
2210 RefPat,
2211 BoxPat,
2212 BindPat,
2213 PlaceholderPat,
2214 DotDotPat,
2215 PathPat,
2216 RecordPat,
2217 TupleStructPat,
2218 TuplePat,
2219 SlicePat,
2220 RangePat,
2221 LiteralPat,
2222 MacroPat,
2223 }
2224
2225 /// Any kind of pattern that appears directly inside of the curly
2226 /// braces of a record pattern
2227 enum RecordInnerPat {
2228 RecordFieldPat,
2229 BindPat
2230 }
2231
2232 /// Any kind of input to an attribute
2233 enum AttrInput { Literal, TokenTree }
2234
2235 /// Any kind of statement
2236 /// Note: there are no empty statements, these are just represented as
2237 /// bare semicolons without a dedicated statement ast node.
2238 enum Stmt {
2239 LetStmt,
2240 ExprStmt,
2241 // macro calls are parsed as expression statements
2242 }
2243
2244 /// Any kind of fields list (record or tuple field lists)
2245 enum FieldDefList {
2246 RecordFieldDefList,
2247 TupleFieldDefList,
2248 }
2249 },
2250 }
2251}
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 5a18b3e2b..24e8be1fb 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -3,19 +3,27 @@
3//! Specifically, it generates the `SyntaxKind` enum and a number of newtype 3//! Specifically, it generates the `SyntaxKind` enum and a number of newtype
4//! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`. 4//! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`.
5 5
6use std::{collections::HashSet, fmt::Write}; 6use std::{
7 collections::{BTreeSet, HashSet},
8 fmt::Write,
9};
7 10
8use proc_macro2::{Punct, Spacing}; 11use proc_macro2::{Punct, Spacing};
9use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
13use ungrammar::{Grammar, Rule};
10 14
11use crate::{ 15use crate::{
12 ast_src::{rust_ast, AstSrc, Field, FieldSrc, KindsSrc, KINDS_SRC}, 16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Field, FieldSrc, KindsSrc, KINDS_SRC},
13 codegen::{self, update, Mode}, 17 codegen::{self, update, Mode},
14 project_root, Result, 18 project_root, Result,
15}; 19};
16 20
17pub fn generate_syntax(mode: Mode) -> Result<()> { 21pub fn generate_syntax(mode: Mode) -> Result<()> {
18 let ast = rust_ast(); 22 let grammar = include_str!("rust.ungram")
23 .parse::<Grammar>()
24 .unwrap_or_else(|err| panic!("\n \x1b[91merror\x1b[0m: {}\n", err));
25 let ast = lower(&grammar);
26
19 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS); 27 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS);
20 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; 28 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
21 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; 29 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
@@ -215,7 +223,9 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> {
215 .map(|kind| to_pascal_case(kind)) 223 .map(|kind| to_pascal_case(kind))
216 .filter(|name| !defined_nodes.iter().any(|&it| it == name)) 224 .filter(|name| !defined_nodes.iter().any(|&it| it == name))
217 { 225 {
218 eprintln!("Warning: node {} not defined in ast source", node); 226 drop(node)
227 // TODO: restore this
228 // eprintln!("Warning: node {} not defined in ast source", node);
219 } 229 }
220 230
221 let ast = quote! { 231 let ast = quote! {
@@ -414,6 +424,10 @@ fn to_pascal_case(s: &str) -> String {
414 buf 424 buf
415} 425}
416 426
427fn pluralize(s: &str) -> String {
428 format!("{}s", s)
429}
430
417impl Field { 431impl Field {
418 fn is_many(&self) -> bool { 432 fn is_many(&self) -> bool {
419 matches!(self, Field::Node { src: FieldSrc::Many(_), .. }) 433 matches!(self, Field::Node { src: FieldSrc::Many(_), .. })
@@ -449,6 +463,7 @@ impl Field {
449 "." => "dot", 463 "." => "dot",
450 ".." => "dotdot", 464 ".." => "dotdot",
451 "..." => "dotdotdot", 465 "..." => "dotdotdot",
466 "..=" => "dotdoteq",
452 "=>" => "fat_arrow", 467 "=>" => "fat_arrow",
453 "@" => "at", 468 "@" => "at",
454 ":" => "colon", 469 ":" => "colon",
@@ -475,3 +490,204 @@ impl Field {
475 } 490 }
476 } 491 }
477} 492}
493
494fn lower(grammar: &Grammar) -> AstSrc {
495 let mut res = AstSrc::default();
496 res.tokens = vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()];
497
498 let nodes = grammar
499 .iter()
500 .filter(|&node| match grammar[node].rule {
501 Rule::Node(it) if it == node => false,
502 _ => true,
503 })
504 .collect::<Vec<_>>();
505
506 for &node in &nodes {
507 let name = grammar[node].name.clone();
508 let rule = &grammar[node].rule;
509 match lower_enum(grammar, rule) {
510 Some(variants) => {
511 let enum_src = AstEnumSrc { doc: Vec::new(), name, traits: Vec::new(), variants };
512 res.enums.push(enum_src);
513 }
514 None => {
515 let mut fields = Vec::new();
516 lower_rule(&mut fields, grammar, rule);
517 res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields });
518 }
519 }
520 }
521
522 deduplicate_fields(&mut res);
523 extract_enums(&mut res);
524 extract_struct_traits(&mut res);
525 extract_enum_traits(&mut res);
526 res
527}
528
529fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
530 let alternatives = match rule {
531 Rule::Alt(it) => it,
532 _ => return None,
533 };
534 let mut variants = Vec::new();
535 for alternative in alternatives {
536 match alternative {
537 Rule::Node(it) => variants.push(grammar[*it].name.clone()),
538 _ => return None,
539 }
540 }
541 Some(variants)
542}
543
544fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
545 match rule {
546 Rule::Node(node) => {
547 let field = Field::Node { name: grammar[*node].name.clone(), src: FieldSrc::Shorthand };
548 acc.push(field);
549 }
550 Rule::Token(token) => {
551 let mut name = grammar[*token].name.clone();
552 if name != "int_number" && name != "string" {
553 if "[]{}()".contains(&name) {
554 name = format!("'{}'", name);
555 }
556 let field = Field::Token(name);
557 acc.push(field);
558 }
559 }
560 Rule::Rep(inner) => {
561 if let Rule::Node(node) = &**inner {
562 let name = grammar[*node].name.clone();
563 let label = pluralize(&to_lower_snake_case(&name));
564 let field = Field::Node { name: label.clone(), src: FieldSrc::Many(name) };
565 acc.push(field);
566 return;
567 }
568 todo!("{:?}", rule)
569 }
570 Rule::Labeled { label, rule } => {
571 let node = match &**rule {
572 Rule::Rep(inner) | Rule::Opt(inner) => match &**inner {
573 Rule::Node(node) => node,
574 _ => todo!("{:?}", rule),
575 },
576 Rule::Node(node) => node,
577 _ => todo!("{:?}", rule),
578 };
579 let field = Field::Node {
580 name: label.clone(),
581 src: match &**rule {
582 Rule::Rep(_) => FieldSrc::Many(grammar[*node].name.clone()),
583 _ => FieldSrc::Optional(grammar[*node].name.clone()),
584 },
585 };
586 acc.push(field);
587 }
588 Rule::Seq(rules) | Rule::Alt(rules) => {
589 for rule in rules {
590 lower_rule(acc, grammar, rule)
591 }
592 }
593 Rule::Opt(rule) => lower_rule(acc, grammar, rule),
594 }
595}
596
597fn deduplicate_fields(ast: &mut AstSrc) {
598 eprintln!();
599 for node in &mut ast.nodes {
600 let mut i = 0;
601 'outer: while i < node.fields.len() {
602 for j in 0..i {
603 let f1 = &node.fields[i];
604 let f2 = &node.fields[j];
605 if f1 == f2 {
606 node.fields.remove(i);
607 continue 'outer;
608 }
609 }
610 i += 1;
611 }
612 }
613}
614
615fn extract_enums(ast: &mut AstSrc) {
616 for node in &mut ast.nodes {
617 for enm in &ast.enums {
618 let mut to_remove = Vec::new();
619 for (i, field) in node.fields.iter().enumerate() {
620 let ty = field.ty().to_string();
621 if enm.variants.iter().any(|it| it == &ty) {
622 to_remove.push(i);
623 }
624 }
625 if to_remove.len() == enm.variants.len() {
626 node.remove_field(to_remove);
627 node.fields.push(Field::Node { name: enm.name.clone(), src: FieldSrc::Shorthand });
628 }
629 }
630 }
631}
632
633fn extract_struct_traits(ast: &mut AstSrc) {
634 let traits: &[(&str, &[&str])] = &[
635 ("AttrsOwner", &["attrs"]),
636 ("NameOwner", &["name"]),
637 ("VisibilityOwner", &["visibility"]),
638 ("TypeParamsOwner", &["type_param_list", "where_clause"]),
639 ("TypeBoundsOwner", &["type_bound_list", "colon_token"]),
640 ("ModuleItemOwner", &["items"]),
641 ("TypeAscriptionOwner", &["ascribed_type"]),
642 ("LoopBodyOwner", &["label", "loop_body"]),
643 ("ArgListOwner", &["arg_list"]),
644 ];
645
646 for node in &mut ast.nodes {
647 for (name, methods) in traits {
648 extract_struct_trait(node, name, methods);
649 }
650 }
651}
652
653fn extract_struct_trait(node: &mut AstNodeSrc, trait_name: &str, methods: &[&str]) {
654 let mut to_remove = Vec::new();
655 for (i, field) in node.fields.iter().enumerate() {
656 let method_name = field.method_name().to_string();
657 if methods.iter().any(|&it| it == &method_name) {
658 to_remove.push(i);
659 }
660 }
661 if to_remove.len() == methods.len() {
662 node.traits.push(trait_name.to_string());
663 node.remove_field(to_remove);
664 }
665}
666
667fn extract_enum_traits(ast: &mut AstSrc) {
668 for enm in &mut ast.enums {
669 let nodes = &ast.nodes;
670 let mut variant_traits = enm
671 .variants
672 .iter()
673 .map(|var| nodes.iter().find(|it| &it.name == var).unwrap())
674 .map(|node| node.traits.iter().cloned().collect::<BTreeSet<_>>());
675
676 let mut enum_traits = match variant_traits.next() {
677 Some(it) => it,
678 None => continue,
679 };
680 for traits in variant_traits {
681 enum_traits = enum_traits.intersection(&traits).cloned().collect();
682 }
683 enm.traits = enum_traits.into_iter().collect();
684 }
685}
686
687impl AstNodeSrc {
688 fn remove_field(&mut self, to_remove: Vec<usize>) {
689 to_remove.into_iter().rev().for_each(|idx| {
690 self.fields.remove(idx);
691 });
692 }
693}
diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram
new file mode 100644
index 000000000..b6ec5d5e7
--- /dev/null
+++ b/xtask/src/codegen/rust.ungram
@@ -0,0 +1,529 @@
1SourceFile =
2 Attr*
3 items:ModuleItem*
4
5FnDef =
6 Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList?
7 ParamList RetType?
8 WhereClause?
9 (body:BlockExpr | ';')
10
11RetType =
12 '->' TypeRef
13
14StructDef =
15 Attr* Visibility? 'struct' Name TypeParamList? (
16 WhereClause? (RecordFieldDefList | ';')
17 | TupleFieldDefList WhereClause? ';'
18 )
19
20UnionDef =
21 Attr* Visibility? 'union' Name TypeParamList? WhereClause?
22 RecordFieldDefList
23
24RecordFieldDefList =
25 '{' fields:RecordFieldDef* '}'
26
27RecordFieldDef =
28 Attr* Visibility? Name ':' ascribed_type:TypeRef
29
30TupleFieldDefList =
31 '(' fields:TupleFieldDef* ')'
32
33TupleFieldDef =
34 Attr* Visibility? Name TypeRef
35
36FieldDefList =
37 RecordFieldDefList
38| TupleFieldDefList
39
40EnumDef =
41 Attr* Visibility? 'enum' Name TypeParamList? WhereClause?
42 variant_list:EnumVariantList
43
44EnumVariantList =
45 '{' variants:EnumVariant* '}'
46
47EnumVariant =
48 Attr* Visibility? Name FieldDefList ('=' Expr)?
49
50TraitDef =
51 Attr* Visibility? 'unsafe'? 'auto'? 'trait' Name TypeParamList
52 (':' TypeBoundList?)? WhereClause
53 ItemList
54
55Module =
56 Attr* Visibility? 'mod' Name
57 (ItemList | ';')
58
59ItemList =
60 '{'
61 AssocItem*
62 items:ModuleItem*
63 '}'
64
65ConstDef =
66 Attr* Visibility? 'default'? 'const' Name ':' ascribed_type:TypeRef
67 '=' body:Expr ';'
68
69StaticDef =
70 Attr* Visibility? 'static'? 'mut'? 'static' Name ':' ascribed_type:TypeRef
71 '=' body:Expr ';'
72
73TypeAliasDef =
74 Attr* Visibility? 'default'? 'type' Name TypeParamList? WhereClause? (':' TypeBoundList?)?
75 '=' TypeRef ';'
76
77ImplDef =
78 Attr* Visibility? 'const'? 'default'? 'unsafe'? 'impl' TypeParamList? '!'? 'for'
79 WhereClause?
80 ItemList
81
82ParenType =
83 '(' TypeRef ')'
84
85TupleType =
86 '(' fields:TypeRef* ')'
87
88NeverType =
89 '!'
90
91PathType =
92 Path
93
94PointerType =
95 '*' ('const' | 'mut') TypeRef
96
97ArrayType =
98 '[' TypeRef ';' Expr ']'
99
100SliceType =
101 '[' TypeRef ']'
102
103ReferenceType =
104 '&' 'lifetime'? 'mut'? TypeRef
105
106PlaceholderType =
107 '_'
108
109FnPointerType =
110 Abi 'unsafe'? 'fn' ParamList RetType?
111
112ForType =
113 'for' TypeParamList TypeRef
114
115ImplTraitType =
116 'impl' TypeBoundList
117
118DynTraitType =
119 'dyn' TypeBoundList
120
121TupleExpr =
122 Attr* '(' Expr* ')'
123
124ArrayExpr =
125 Attr* '[' (Expr* | Expr ';' Expr) ']'
126
127ParenExpr =
128 Attr* '(' Expr ')'
129
130PathExpr =
131 Path
132
133LambdaExpr =
134 Attr* 'static'? 'async'? 'move'? ParamList RetType?
135 body:Expr
136
137IfExpr =
138 Attr* 'if' Condition
139
140Condition =
141 'let' Pat '=' Expr
142| Expr
143
144EffectExpr =
145 Attr* Label? ('try' | 'unsafe' | 'async') BlockExpr
146
147LoopExpr =
148 Attr* Label? 'loop'
149 loop_body:BlockExpr?
150
151ForExpr =
152 Attr* Label? 'for' Pat 'in' iterable:Expr
153 loop_body:BlockExpr?
154
155WhileExpr =
156 Attr* Label? 'while' Condition
157 loop_body:BlockExpr?
158
159ContinueExpr =
160 Attr* 'continue' 'lifetime'?
161
162BreakExpr =
163 Attr* 'break' 'lifetime'? Expr?
164
165Label =
166 'lifetime'
167
168BlockExpr =
169 Attr* Label
170 '{'
171 items:ModuleItem*
172 statements:Stmt*
173 Expr?
174 '}'
175
176ReturnExpr =
177 Attr* 'return' Expr
178
179CallExpr =
180 Attr* Expr ArgList
181
182MethodCallExpr =
183 Attr* Expr '.' NameRef TypeArgList? ArgList
184
185ArgList =
186 '(' args:Expr* ')'
187
188FieldExpr =
189 Attr* Expr '.' NameRef
190
191IndexExpr =
192 Attr* '[' ']'
193
194AwaitExpr =
195 Attr* Expr '.' 'await'
196
197TryExpr =
198 Attr* Expr '?'
199
200CastExpr =
201 Attr* Expr 'as' TypeRef
202
203RefExpr =
204 Attr* '&' ('raw' | 'mut' | 'const') Expr
205
206PrefixExpr =
207 Attr* Expr
208
209BoxExpr =
210 Attr* 'box' Expr
211
212RangeExpr =
213 Attr*
214
215BinExpr =
216 Attr*
217
218Literal =
219 'int_number'
220
221MatchExpr =
222 Attr* 'match' Expr MatchArmList
223
224MatchArmList =
225 '{' arms:MatchArm* '}'
226
227MatchArm =
228 Attr* Pat guard:MatchGuard? '=>' Expr
229
230MatchGuard =
231 'if' Expr
232
233RecordLit =
234 Path RecordFieldList
235
236RecordFieldList =
237 '{'
238 fields:RecordField*
239 ('..' spread:Expr)?
240 '}'
241
242RecordField =
243 Attr* NameRef (':' Expr)?
244
245OrPat =
246 Pat*
247
248ParenPat =
249 '(' Pat ')'
250
251RefPat =
252 '&' 'mut'? Pat
253
254BoxPat =
255 'box' Path
256
257BindPat =
258 Attr* 'ref'? 'mut'? Name ('@' Pat)?
259
260PlaceholderPat =
261 '_'
262
263DotDotPat =
264 '..'
265
266PathPat =
267 Path
268
269SlicePat =
270 '[' args:Pat* ']'
271
272RangePat =
273 '..' | '..='
274
275LiteralPat =
276 Literal
277
278MacroPat =
279 MacroCall
280
281RecordPat =
282 Path RecordFieldPatList
283
284RecordFieldPatList =
285 '{'
286 record_field_pats:RecordFieldPat*
287 BindPat*
288 '..'?
289 '}'
290
291RecordFieldPat =
292 Attr* NameRef ':' Pat
293
294TupleStructPat =
295 Path '(' args:Pat* ')'
296
297TuplePat =
298 '(' args:Pat* ')'
299
300Visibility =
301 'pub' ('(' 'super' | 'self' | 'crate' | 'in' Path ')')?
302
303Name =
304 'ident'
305
306NameRef =
307 'ident' | 'int_number'
308
309MacroCall =
310 Attr* Path '!' Name? TokenTree ';'?
311
312MacroDef =
313 Name TokenTree
314
315TokenTree =
316 '(' ')' | '{' '}' | '[' ']'
317
318MacroItems =
319 items:ModuleItem*
320
321MacroStmts =
322 statements:Stmt*
323 Expr?
324
325Attr =
326 '#' '!'? '[' Path ('=' input:AttrInput)? ']'
327
328TypeParamList =
329 '<'
330 TypeParam*
331 LifetimeParam*
332 ConstParam*
333 '>'
334
335TypeParam =
336 Attr* Name (':' TypeBoundList?)?
337 ('=' default_type:TypeRef)?
338
339ConstParam =
340 Attr* 'const' Name ':' ascribed_type:TypeRef
341 ('=' default_val:Expr)?
342
343LifetimeParam =
344 Attr* 'lifetime'
345
346TypeBound =
347 'lifetime' | 'const'? TypeRef
348
349TypeBoundList =
350 bounds:TypeBound*
351
352WherePred =
353 ('for' TypeParamList)? ('lifetime' | TypeRef) ':' TypeBoundList
354
355WhereClause =
356 'where' predicates:WherePred*
357
358Abi =
359 'string'
360
361ExprStmt =
362 Attr* Expr ';'
363
364LetStmt =
365 Attr* 'let' Pat (':' ascribed_type:TypeRef)
366 '=' initializer:Expr ';'
367
368ParamList =
369 '(' SelfParam Param* ')'
370
371SelfParam =
372 Attr* ('&' 'lifetime'?)? 'mut'? 'self' (':' ascribed_type:TypeRef)
373
374Param =
375 Attr* Pat (':' ascribed_type:TypeRef)
376| '...'
377
378UseItem =
379 Attr* Visibility? 'use' UseTree ';'
380
381UseTree =
382 Path ('::' ('*' | UseTreeList)) Alias?
383
384UseTreeList =
385 '{' UseTree* '}'
386
387Alias =
388 'as' Name
389
390ExternCrateItem =
391 Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Alias? ';'
392
393Path =
394 (qualifier:Path '::')? segment:PathSegment
395
396PathSegment =
397 '::' | 'crate' | 'self' | 'super'
398| '<' NameRef TypeArgList ParamList RetType PathType '>'
399
400TypeArgList =
401 '::'? '<'
402 TypeArg*
403 LifetimeArg*
404 AssocTypeArg*
405 ConstArg*
406 '>'
407
408TypeArg =
409 TypeRef
410
411AssocTypeArg =
412 NameRef (':' TypeBoundList | '=' TypeRef)
413
414LifetimeArg =
415 'lifetime'
416
417ConstArg =
418 Literal | BlockExpr BlockExpr
419
420ExternBlock =
421 Attr* Abi ExternItemList
422
423ExternItemList =
424 '{' extern_items:ExternItem* '}'
425
426MetaItem =
427 Path '=' AttrInput nested_meta_items:MetaItem*
428
429AdtDef =
430 StructDef
431| EnumDef
432| UnionDef
433
434TypeRef =
435 ParenType
436| TupleType
437| NeverType
438| PathType
439| PointerType
440| ArrayType
441| SliceType
442| ReferenceType
443| PlaceholderType
444| FnPointerType
445| ForType
446| ImplTraitType
447| DynTraitType
448
449AssocItem =
450 FnDef
451| TypeAliasDef
452| ConstDef
453
454ExternItem =
455 FnDef | StaticDef
456
457ModuleItem =
458 StructDef
459| UnionDef
460| EnumDef
461| FnDef
462| TraitDef
463| TypeAliasDef
464| ImplDef
465| UseItem
466| ExternCrateItem
467| ConstDef
468| StaticDef
469| Module
470| MacroCall
471| ExternBlock
472
473AttrInput =
474 Literal
475| TokenTree
476
477Stmt =
478 LetStmt
479| ExprStmt
480
481Pat =
482 OrPat
483| ParenPat
484| RefPat
485| BoxPat
486| BindPat
487| PlaceholderPat
488| DotDotPat
489| PathPat
490| RecordPat
491| TupleStructPat
492| TuplePat
493| SlicePat
494| RangePat
495| LiteralPat
496| MacroPat
497
498Expr =
499 TupleExpr
500| ArrayExpr
501| ParenExpr
502| PathExpr
503| LambdaExpr
504| IfExpr
505| LoopExpr
506| ForExpr
507| WhileExpr
508| ContinueExpr
509| BreakExpr
510| Label
511| BlockExpr
512| ReturnExpr
513| MatchExpr
514| RecordLit
515| CallExpr
516| IndexExpr
517| MethodCallExpr
518| FieldExpr
519| AwaitExpr
520| TryExpr
521| EffectExpr
522| CastExpr
523| RefExpr
524| PrefixExpr
525| RangeExpr
526| BinExpr
527| Literal
528| MacroCall
529| BoxExpr