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