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