diff options
10 files changed, 488 insertions, 150 deletions
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs index bbf57004d..5b6400042 100644 --- a/crates/ra_hir/src/marks.rs +++ b/crates/ra_hir/src/marks.rs | |||
@@ -8,4 +8,5 @@ test_utils::marks!( | |||
8 | glob_enum | 8 | glob_enum |
9 | glob_across_crates | 9 | glob_across_crates |
10 | std_prelude | 10 | std_prelude |
11 | match_ergonomics_ref | ||
11 | ); | 12 | ); |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c9a5bc7a1..735cdecb9 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -63,6 +63,30 @@ enum ExprOrPatId { | |||
63 | 63 | ||
64 | impl_froms!(ExprOrPatId: ExprId, PatId); | 64 | impl_froms!(ExprOrPatId: ExprId, PatId); |
65 | 65 | ||
66 | /// Binding modes inferred for patterns. | ||
67 | /// https://doc.rust-lang.org/reference/patterns.html#binding-modes | ||
68 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
69 | enum BindingMode { | ||
70 | Move, | ||
71 | Ref(Mutability), | ||
72 | } | ||
73 | |||
74 | impl BindingMode { | ||
75 | pub fn convert(annotation: &BindingAnnotation) -> BindingMode { | ||
76 | match annotation { | ||
77 | BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, | ||
78 | BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), | ||
79 | BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | |||
84 | impl Default for BindingMode { | ||
85 | fn default() -> Self { | ||
86 | BindingMode::Move | ||
87 | } | ||
88 | } | ||
89 | |||
66 | /// The result of type inference: A mapping from expressions and patterns to types. | 90 | /// The result of type inference: A mapping from expressions and patterns to types. |
67 | #[derive(Clone, PartialEq, Eq, Debug)] | 91 | #[derive(Clone, PartialEq, Eq, Debug)] |
68 | pub struct InferenceResult { | 92 | pub struct InferenceResult { |
@@ -530,6 +554,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
530 | path: Option<&Path>, | 554 | path: Option<&Path>, |
531 | subpats: &[PatId], | 555 | subpats: &[PatId], |
532 | expected: &Ty, | 556 | expected: &Ty, |
557 | default_bm: BindingMode, | ||
533 | ) -> Ty { | 558 | ) -> Ty { |
534 | let (ty, def) = self.resolve_variant(path); | 559 | let (ty, def) = self.resolve_variant(path); |
535 | 560 | ||
@@ -542,13 +567,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
542 | .and_then(|d| d.field(self.db, &Name::tuple_field_name(i))) | 567 | .and_then(|d| d.field(self.db, &Name::tuple_field_name(i))) |
543 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 568 | .map_or(Ty::Unknown, |field| field.ty(self.db)) |
544 | .subst(&substs); | 569 | .subst(&substs); |
545 | self.infer_pat(subpat, &expected_ty); | 570 | self.infer_pat(subpat, &expected_ty, default_bm); |
546 | } | 571 | } |
547 | 572 | ||
548 | ty | 573 | ty |
549 | } | 574 | } |
550 | 575 | ||
551 | fn infer_struct_pat(&mut self, path: Option<&Path>, subpats: &[FieldPat], expected: &Ty) -> Ty { | 576 | fn infer_struct_pat( |
577 | &mut self, | ||
578 | path: Option<&Path>, | ||
579 | subpats: &[FieldPat], | ||
580 | expected: &Ty, | ||
581 | default_bm: BindingMode, | ||
582 | ) -> Ty { | ||
552 | let (ty, def) = self.resolve_variant(path); | 583 | let (ty, def) = self.resolve_variant(path); |
553 | 584 | ||
554 | self.unify(&ty, expected); | 585 | self.unify(&ty, expected); |
@@ -559,15 +590,45 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
559 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); | 590 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); |
560 | let expected_ty = | 591 | let expected_ty = |
561 | matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); | 592 | matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); |
562 | self.infer_pat(subpat.pat, &expected_ty); | 593 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
563 | } | 594 | } |
564 | 595 | ||
565 | ty | 596 | ty |
566 | } | 597 | } |
567 | 598 | ||
568 | fn infer_pat(&mut self, pat: PatId, expected: &Ty) -> Ty { | 599 | fn infer_pat(&mut self, pat: PatId, mut expected: &Ty, mut default_bm: BindingMode) -> Ty { |
569 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 600 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
570 | 601 | ||
602 | let is_non_ref_pat = match &body[pat] { | ||
603 | Pat::Tuple(..) | ||
604 | | Pat::TupleStruct { .. } | ||
605 | | Pat::Struct { .. } | ||
606 | | Pat::Range { .. } | ||
607 | | Pat::Slice { .. } => true, | ||
608 | // TODO: Path/Lit might actually evaluate to ref, but inference is unimplemented. | ||
609 | Pat::Path(..) | Pat::Lit(..) => true, | ||
610 | Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, | ||
611 | }; | ||
612 | if is_non_ref_pat { | ||
613 | while let Ty::Ref(inner, mutability) = expected { | ||
614 | expected = inner; | ||
615 | default_bm = match default_bm { | ||
616 | BindingMode::Move => BindingMode::Ref(*mutability), | ||
617 | BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), | ||
618 | BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(*mutability), | ||
619 | } | ||
620 | } | ||
621 | } else if let Pat::Ref { .. } = &body[pat] { | ||
622 | tested_by!(match_ergonomics_ref); | ||
623 | // When you encounter a `&pat` pattern, reset to Move. | ||
624 | // This is so that `w` is by value: `let (_, &w) = &(1, &2);` | ||
625 | default_bm = BindingMode::Move; | ||
626 | } | ||
627 | |||
628 | // Lose mutability. | ||
629 | let default_bm = default_bm; | ||
630 | let expected = expected; | ||
631 | |||
571 | let ty = match &body[pat] { | 632 | let ty = match &body[pat] { |
572 | Pat::Tuple(ref args) => { | 633 | Pat::Tuple(ref args) => { |
573 | let expectations = match *expected { | 634 | let expectations = match *expected { |
@@ -579,7 +640,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
579 | let inner_tys = args | 640 | let inner_tys = args |
580 | .iter() | 641 | .iter() |
581 | .zip(expectations_iter) | 642 | .zip(expectations_iter) |
582 | .map(|(&pat, ty)| self.infer_pat(pat, ty)) | 643 | .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm)) |
583 | .collect::<Vec<_>>() | 644 | .collect::<Vec<_>>() |
584 | .into(); | 645 | .into(); |
585 | 646 | ||
@@ -595,14 +656,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
595 | } | 656 | } |
596 | _ => &Ty::Unknown, | 657 | _ => &Ty::Unknown, |
597 | }; | 658 | }; |
598 | let subty = self.infer_pat(*pat, expectation); | 659 | let subty = self.infer_pat(*pat, expectation, default_bm); |
599 | Ty::Ref(subty.into(), *mutability) | 660 | Ty::Ref(subty.into(), *mutability) |
600 | } | 661 | } |
601 | Pat::TupleStruct { path: ref p, args: ref subpats } => { | 662 | Pat::TupleStruct { path: ref p, args: ref subpats } => { |
602 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected) | 663 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) |
603 | } | 664 | } |
604 | Pat::Struct { path: ref p, args: ref fields } => { | 665 | Pat::Struct { path: ref p, args: ref fields } => { |
605 | self.infer_struct_pat(p.as_ref(), fields, expected) | 666 | self.infer_struct_pat(p.as_ref(), fields, expected, default_bm) |
606 | } | 667 | } |
607 | Pat::Path(path) => { | 668 | Pat::Path(path) => { |
608 | // TODO use correct resolver for the surrounding expression | 669 | // TODO use correct resolver for the surrounding expression |
@@ -610,17 +671,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
610 | self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) | 671 | self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) |
611 | } | 672 | } |
612 | Pat::Bind { mode, name: _name, subpat } => { | 673 | Pat::Bind { mode, name: _name, subpat } => { |
674 | let mode = if mode == &BindingAnnotation::Unannotated { | ||
675 | default_bm | ||
676 | } else { | ||
677 | BindingMode::convert(mode) | ||
678 | }; | ||
613 | let inner_ty = if let Some(subpat) = subpat { | 679 | let inner_ty = if let Some(subpat) = subpat { |
614 | self.infer_pat(*subpat, expected) | 680 | self.infer_pat(*subpat, expected, default_bm) |
615 | } else { | 681 | } else { |
616 | expected.clone() | 682 | expected.clone() |
617 | }; | 683 | }; |
618 | let inner_ty = self.insert_type_vars_shallow(inner_ty); | 684 | let inner_ty = self.insert_type_vars_shallow(inner_ty); |
619 | 685 | ||
620 | let bound_ty = match mode { | 686 | let bound_ty = match mode { |
621 | BindingAnnotation::Ref => Ty::Ref(inner_ty.clone().into(), Mutability::Shared), | 687 | BindingMode::Ref(mutability) => Ty::Ref(inner_ty.clone().into(), mutability), |
622 | BindingAnnotation::RefMut => Ty::Ref(inner_ty.clone().into(), Mutability::Mut), | 688 | BindingMode::Move => inner_ty.clone(), |
623 | BindingAnnotation::Mutable | BindingAnnotation::Unannotated => inner_ty.clone(), | ||
624 | }; | 689 | }; |
625 | let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty); | 690 | let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty); |
626 | self.write_pat_ty(pat, bound_ty); | 691 | self.write_pat_ty(pat, bound_ty); |
@@ -700,7 +765,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
700 | } | 765 | } |
701 | Expr::For { iterable, body, pat } => { | 766 | Expr::For { iterable, body, pat } => { |
702 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 767 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
703 | self.infer_pat(*pat, &Ty::Unknown); | 768 | self.infer_pat(*pat, &Ty::Unknown, BindingMode::default()); |
704 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 769 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
705 | Ty::unit() | 770 | Ty::unit() |
706 | } | 771 | } |
@@ -714,7 +779,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
714 | } else { | 779 | } else { |
715 | Ty::Unknown | 780 | Ty::Unknown |
716 | }; | 781 | }; |
717 | self.infer_pat(*arg_pat, &expected); | 782 | self.infer_pat(*arg_pat, &expected, BindingMode::default()); |
718 | } | 783 | } |
719 | 784 | ||
720 | // TODO: infer lambda type etc. | 785 | // TODO: infer lambda type etc. |
@@ -807,7 +872,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
807 | 872 | ||
808 | for arm in arms { | 873 | for arm in arms { |
809 | for &pat in &arm.pats { | 874 | for &pat in &arm.pats { |
810 | let _pat_ty = self.infer_pat(pat, &input_ty); | 875 | let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default()); |
811 | } | 876 | } |
812 | if let Some(guard_expr) = arm.guard { | 877 | if let Some(guard_expr) = arm.guard { |
813 | self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool)); | 878 | self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool)); |
@@ -1007,7 +1072,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1007 | decl_ty | 1072 | decl_ty |
1008 | }; | 1073 | }; |
1009 | 1074 | ||
1010 | self.infer_pat(*pat, &ty); | 1075 | self.infer_pat(*pat, &ty, BindingMode::default()); |
1011 | } | 1076 | } |
1012 | Statement::Expr(expr) => { | 1077 | Statement::Expr(expr) => { |
1013 | self.infer_expr(*expr, &Expectation::none()); | 1078 | self.infer_expr(*expr, &Expectation::none()); |
@@ -1023,7 +1088,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1023 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { | 1088 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { |
1024 | let ty = self.make_ty(type_ref); | 1089 | let ty = self.make_ty(type_ref); |
1025 | 1090 | ||
1026 | self.infer_pat(*pat, &ty); | 1091 | self.infer_pat(*pat, &ty, BindingMode::default()); |
1027 | } | 1092 | } |
1028 | self.return_ty = self.make_ty(signature.ret_type()); | 1093 | self.return_ty = self.make_ty(signature.ret_type()); |
1029 | } | 1094 | } |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index acae71c26..0f2172ddf 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -831,6 +831,60 @@ fn test(x: &i32) { | |||
831 | } | 831 | } |
832 | 832 | ||
833 | #[test] | 833 | #[test] |
834 | fn infer_pattern_match_ergonomics() { | ||
835 | assert_snapshot_matches!( | ||
836 | infer(r#" | ||
837 | struct A<T>(T); | ||
838 | |||
839 | fn test() { | ||
840 | let A(n) = &A(1); | ||
841 | let A(n) = &mut A(1); | ||
842 | } | ||
843 | "#), | ||
844 | @r###" | ||
845 | [28; 79) '{ ...(1); }': () | ||
846 | [38; 42) 'A(n)': A<i32> | ||
847 | [40; 41) 'n': &i32 | ||
848 | [45; 50) '&A(1)': &A<i32> | ||
849 | [46; 47) 'A': A<i32>(T) -> A<T> | ||
850 | [46; 50) 'A(1)': A<i32> | ||
851 | [48; 49) '1': i32 | ||
852 | [60; 64) 'A(n)': A<i32> | ||
853 | [62; 63) 'n': &mut i32 | ||
854 | [67; 76) '&mut A(1)': &mut A<i32> | ||
855 | [72; 73) 'A': A<i32>(T) -> A<T> | ||
856 | [72; 76) 'A(1)': A<i32> | ||
857 | [74; 75) '1': i32"### | ||
858 | ); | ||
859 | } | ||
860 | |||
861 | #[test] | ||
862 | fn infer_pattern_match_ergonomics_ref() { | ||
863 | covers!(match_ergonomics_ref); | ||
864 | assert_snapshot_matches!( | ||
865 | infer(r#" | ||
866 | fn test() { | ||
867 | let v = &(1, &2); | ||
868 | let (_, &w) = v; | ||
869 | } | ||
870 | "#), | ||
871 | @r###" | ||
872 | [11; 57) '{ ...= v; }': () | ||
873 | [21; 22) 'v': &(i32, &i32) | ||
874 | [25; 33) '&(1, &2)': &(i32, &i32) | ||
875 | [26; 33) '(1, &2)': (i32, &i32) | ||
876 | [27; 28) '1': i32 | ||
877 | [30; 32) '&2': &i32 | ||
878 | [31; 32) '2': i32 | ||
879 | [43; 50) '(_, &w)': (i32, &i32) | ||
880 | [44; 45) '_': i32 | ||
881 | [47; 49) '&w': &i32 | ||
882 | [48; 49) 'w': i32 | ||
883 | [53; 54) 'v': &(i32, &i32)"### | ||
884 | ); | ||
885 | } | ||
886 | |||
887 | #[test] | ||
834 | fn infer_adt_pattern() { | 888 | fn infer_adt_pattern() { |
835 | assert_snapshot_matches!( | 889 | assert_snapshot_matches!( |
836 | infer(r#" | 890 | infer(r#" |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 6d3e379a3..ccbc905ab 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -148,6 +148,7 @@ fn current_op(p: &Parser) -> (u8, Op) { | |||
148 | (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)), | 148 | (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)), |
149 | (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)), | 149 | (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)), |
150 | (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)), | 150 | (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)), |
151 | (PERCENT, EQ) => return (1, Op::Composite(PERCENTEQ, 2)), | ||
151 | (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)), | 152 | (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)), |
152 | (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)), | 153 | (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)), |
153 | (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)), | 154 | (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)), |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 53bb26c5f..d933288cd 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -342,21 +342,6 @@ pub(crate) fn match_arm_list(p: &mut Parser) { | |||
342 | continue; | 342 | continue; |
343 | } | 343 | } |
344 | 344 | ||
345 | // test match_arms_outer_attributes | ||
346 | // fn foo() { | ||
347 | // match () { | ||
348 | // #[cfg(feature = "some")] | ||
349 | // _ => (), | ||
350 | // #[cfg(feature = "other")] | ||
351 | // _ => (), | ||
352 | // #[cfg(feature = "many")] | ||
353 | // #[cfg(feature = "attributes")] | ||
354 | // #[cfg(feature = "before")] | ||
355 | // _ => (), | ||
356 | // } | ||
357 | // } | ||
358 | attributes::outer_attributes(p); | ||
359 | |||
360 | // test match_arms_commas | 345 | // test match_arms_commas |
361 | // fn foo() { | 346 | // fn foo() { |
362 | // match () { | 347 | // match () { |
@@ -387,6 +372,21 @@ pub(crate) fn match_arm_list(p: &mut Parser) { | |||
387 | // } | 372 | // } |
388 | fn match_arm(p: &mut Parser) -> BlockLike { | 373 | fn match_arm(p: &mut Parser) -> BlockLike { |
389 | let m = p.start(); | 374 | let m = p.start(); |
375 | // test match_arms_outer_attributes | ||
376 | // fn foo() { | ||
377 | // match () { | ||
378 | // #[cfg(feature = "some")] | ||
379 | // _ => (), | ||
380 | // #[cfg(feature = "other")] | ||
381 | // _ => (), | ||
382 | // #[cfg(feature = "many")] | ||
383 | // #[cfg(feature = "attributes")] | ||
384 | // #[cfg(feature = "before")] | ||
385 | // _ => (), | ||
386 | // } | ||
387 | // } | ||
388 | attributes::outer_attributes(p); | ||
389 | |||
390 | patterns::pattern_list_r(p, TokenSet::empty()); | 390 | patterns::pattern_list_r(p, TokenSet::empty()); |
391 | if p.at(IF_KW) { | 391 | if p.at(IF_KW) { |
392 | match_guard(p); | 392 | match_guard(p); |
diff --git a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt index b7543abc9..ed5735a63 100644 --- a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt +++ b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt | |||
@@ -33,11 +33,11 @@ SOURCE_FILE@[0; 293) | |||
33 | R_PAREN@[40; 41) | 33 | R_PAREN@[40; 41) |
34 | COMMA@[41; 42) | 34 | COMMA@[41; 42) |
35 | WHITESPACE@[42; 51) | 35 | WHITESPACE@[42; 51) |
36 | ATTR@[51; 52) | 36 | MATCH_ARM@[51; 78) |
37 | POUND@[51; 52) | 37 | ATTR@[51; 52) |
38 | err: `expected `[`` | 38 | POUND@[51; 52) |
39 | err: `expected pattern` | 39 | err: `expected `[`` |
40 | MATCH_ARM@[52; 78) | 40 | err: `expected pattern` |
41 | ERROR@[52; 53) | 41 | ERROR@[52; 53) |
42 | EXCL@[52; 53) | 42 | EXCL@[52; 53) |
43 | err: `expected FAT_ARROW` | 43 | err: `expected FAT_ARROW` |
@@ -103,11 +103,11 @@ SOURCE_FILE@[0; 293) | |||
103 | R_PAREN@[149; 150) | 103 | R_PAREN@[149; 150) |
104 | COMMA@[150; 151) | 104 | COMMA@[150; 151) |
105 | WHITESPACE@[151; 160) | 105 | WHITESPACE@[151; 160) |
106 | ATTR@[160; 161) | 106 | MATCH_ARM@[160; 179) |
107 | POUND@[160; 161) | 107 | ATTR@[160; 161) |
108 | err: `expected `[`` | 108 | POUND@[160; 161) |
109 | err: `expected pattern` | 109 | err: `expected `[`` |
110 | MATCH_ARM@[161; 179) | 110 | err: `expected pattern` |
111 | ERROR@[161; 162) | 111 | ERROR@[161; 162) |
112 | EXCL@[161; 162) | 112 | EXCL@[161; 162) |
113 | err: `expected FAT_ARROW` | 113 | err: `expected FAT_ARROW` |
@@ -138,22 +138,22 @@ SOURCE_FILE@[0; 293) | |||
138 | MATCH_ARM_LIST@[200; 290) | 138 | MATCH_ARM_LIST@[200; 290) |
139 | L_CURLY@[200; 201) | 139 | L_CURLY@[200; 201) |
140 | WHITESPACE@[201; 210) | 140 | WHITESPACE@[201; 210) |
141 | ATTR@[210; 222) | 141 | MATCH_ARM@[210; 250) |
142 | POUND@[210; 211) | 142 | ATTR@[210; 222) |
143 | TOKEN_TREE@[211; 222) | 143 | POUND@[210; 211) |
144 | L_BRACK@[211; 212) | 144 | TOKEN_TREE@[211; 222) |
145 | IDENT@[212; 215) "cfg" | 145 | L_BRACK@[211; 212) |
146 | TOKEN_TREE@[215; 221) | 146 | IDENT@[212; 215) "cfg" |
147 | L_PAREN@[215; 216) | 147 | TOKEN_TREE@[215; 221) |
148 | IDENT@[216; 220) "test" | 148 | L_PAREN@[215; 216) |
149 | R_PAREN@[220; 221) | 149 | IDENT@[216; 220) "test" |
150 | R_BRACK@[221; 222) | 150 | R_PAREN@[220; 221) |
151 | WHITESPACE@[222; 231) | 151 | R_BRACK@[221; 222) |
152 | ATTR@[231; 232) | 152 | WHITESPACE@[222; 231) |
153 | POUND@[231; 232) | 153 | ATTR@[231; 232) |
154 | err: `expected `[`` | 154 | POUND@[231; 232) |
155 | err: `expected pattern` | 155 | err: `expected `[`` |
156 | MATCH_ARM@[232; 250) | 156 | err: `expected pattern` |
157 | ERROR@[232; 233) | 157 | ERROR@[232; 233) |
158 | EXCL@[232; 233) | 158 | EXCL@[232; 233) |
159 | err: `expected FAT_ARROW` | 159 | err: `expected FAT_ARROW` |
diff --git a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt index 7f8767001..f540409bc 100644 --- a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt +++ b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt | |||
@@ -43,21 +43,21 @@ SOURCE_FILE@[0; 89) | |||
43 | R_PAREN@[57; 58) | 43 | R_PAREN@[57; 58) |
44 | COMMA@[58; 59) | 44 | COMMA@[58; 59) |
45 | WHITESPACE@[59; 68) | 45 | WHITESPACE@[59; 68) |
46 | ATTR@[68; 80) | 46 | MATCH_ARM@[68; 80) |
47 | POUND@[68; 69) | 47 | ATTR@[68; 80) |
48 | TOKEN_TREE@[69; 80) | 48 | POUND@[68; 69) |
49 | L_BRACK@[69; 70) | 49 | TOKEN_TREE@[69; 80) |
50 | IDENT@[70; 73) "cfg" | 50 | L_BRACK@[69; 70) |
51 | TOKEN_TREE@[73; 79) | 51 | IDENT@[70; 73) "cfg" |
52 | L_PAREN@[73; 74) | 52 | TOKEN_TREE@[73; 79) |
53 | IDENT@[74; 78) "test" | 53 | L_PAREN@[73; 74) |
54 | R_PAREN@[78; 79) | 54 | IDENT@[74; 78) "test" |
55 | R_BRACK@[79; 80) | 55 | R_PAREN@[78; 79) |
56 | R_BRACK@[79; 80) | ||
57 | err: `expected pattern` | ||
58 | err: `expected FAT_ARROW` | ||
59 | err: `expected expression` | ||
56 | WHITESPACE@[80; 85) | 60 | WHITESPACE@[80; 85) |
57 | err: `expected pattern` | ||
58 | err: `expected FAT_ARROW` | ||
59 | err: `expected expression` | ||
60 | MATCH_ARM@[85; 85) | ||
61 | R_CURLY@[85; 86) | 61 | R_CURLY@[85; 86) |
62 | WHITESPACE@[86; 87) | 62 | WHITESPACE@[86; 87) |
63 | R_CURLY@[87; 88) | 63 | R_CURLY@[87; 88) |
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt index c888fb8f0..e52a290bf 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt | |||
@@ -21,22 +21,22 @@ SOURCE_FILE@[0; 259) | |||
21 | MATCH_ARM_LIST@[24; 256) | 21 | MATCH_ARM_LIST@[24; 256) |
22 | L_CURLY@[24; 25) | 22 | L_CURLY@[24; 25) |
23 | WHITESPACE@[25; 34) | 23 | WHITESPACE@[25; 34) |
24 | ATTR@[34; 58) | 24 | MATCH_ARM@[34; 74) |
25 | POUND@[34; 35) | 25 | ATTR@[34; 58) |
26 | TOKEN_TREE@[35; 58) | 26 | POUND@[34; 35) |
27 | L_BRACK@[35; 36) | 27 | TOKEN_TREE@[35; 58) |
28 | IDENT@[36; 39) "cfg" | 28 | L_BRACK@[35; 36) |
29 | TOKEN_TREE@[39; 57) | 29 | IDENT@[36; 39) "cfg" |
30 | L_PAREN@[39; 40) | 30 | TOKEN_TREE@[39; 57) |
31 | IDENT@[40; 47) "feature" | 31 | L_PAREN@[39; 40) |
32 | WHITESPACE@[47; 48) | 32 | IDENT@[40; 47) "feature" |
33 | EQ@[48; 49) | 33 | WHITESPACE@[47; 48) |
34 | WHITESPACE@[49; 50) | 34 | EQ@[48; 49) |
35 | STRING@[50; 56) | 35 | WHITESPACE@[49; 50) |
36 | R_PAREN@[56; 57) | 36 | STRING@[50; 56) |
37 | R_BRACK@[57; 58) | 37 | R_PAREN@[56; 57) |
38 | WHITESPACE@[58; 67) | 38 | R_BRACK@[57; 58) |
39 | MATCH_ARM@[67; 74) | 39 | WHITESPACE@[58; 67) |
40 | PLACEHOLDER_PAT@[67; 68) | 40 | PLACEHOLDER_PAT@[67; 68) |
41 | UNDERSCORE@[67; 68) | 41 | UNDERSCORE@[67; 68) |
42 | WHITESPACE@[68; 69) | 42 | WHITESPACE@[68; 69) |
@@ -47,22 +47,22 @@ SOURCE_FILE@[0; 259) | |||
47 | R_PAREN@[73; 74) | 47 | R_PAREN@[73; 74) |
48 | COMMA@[74; 75) | 48 | COMMA@[74; 75) |
49 | WHITESPACE@[75; 84) | 49 | WHITESPACE@[75; 84) |
50 | ATTR@[84; 109) | 50 | MATCH_ARM@[84; 125) |
51 | POUND@[84; 85) | 51 | ATTR@[84; 109) |
52 | TOKEN_TREE@[85; 109) | 52 | POUND@[84; 85) |
53 | L_BRACK@[85; 86) | 53 | TOKEN_TREE@[85; 109) |
54 | IDENT@[86; 89) "cfg" | 54 | L_BRACK@[85; 86) |
55 | TOKEN_TREE@[89; 108) | 55 | IDENT@[86; 89) "cfg" |
56 | L_PAREN@[89; 90) | 56 | TOKEN_TREE@[89; 108) |
57 | IDENT@[90; 97) "feature" | 57 | L_PAREN@[89; 90) |
58 | WHITESPACE@[97; 98) | 58 | IDENT@[90; 97) "feature" |
59 | EQ@[98; 99) | 59 | WHITESPACE@[97; 98) |
60 | WHITESPACE@[99; 100) | 60 | EQ@[98; 99) |
61 | STRING@[100; 107) | 61 | WHITESPACE@[99; 100) |
62 | R_PAREN@[107; 108) | 62 | STRING@[100; 107) |
63 | R_BRACK@[108; 109) | 63 | R_PAREN@[107; 108) |
64 | WHITESPACE@[109; 118) | 64 | R_BRACK@[108; 109) |
65 | MATCH_ARM@[118; 125) | 65 | WHITESPACE@[109; 118) |
66 | PLACEHOLDER_PAT@[118; 119) | 66 | PLACEHOLDER_PAT@[118; 119) |
67 | UNDERSCORE@[118; 119) | 67 | UNDERSCORE@[118; 119) |
68 | WHITESPACE@[119; 120) | 68 | WHITESPACE@[119; 120) |
@@ -73,52 +73,52 @@ SOURCE_FILE@[0; 259) | |||
73 | R_PAREN@[124; 125) | 73 | R_PAREN@[124; 125) |
74 | COMMA@[125; 126) | 74 | COMMA@[125; 126) |
75 | WHITESPACE@[126; 135) | 75 | WHITESPACE@[126; 135) |
76 | ATTR@[135; 159) | 76 | MATCH_ARM@[135; 249) |
77 | POUND@[135; 136) | 77 | ATTR@[135; 159) |
78 | TOKEN_TREE@[136; 159) | 78 | POUND@[135; 136) |
79 | L_BRACK@[136; 137) | 79 | TOKEN_TREE@[136; 159) |
80 | IDENT@[137; 140) "cfg" | 80 | L_BRACK@[136; 137) |
81 | TOKEN_TREE@[140; 158) | 81 | IDENT@[137; 140) "cfg" |
82 | L_PAREN@[140; 141) | 82 | TOKEN_TREE@[140; 158) |
83 | IDENT@[141; 148) "feature" | 83 | L_PAREN@[140; 141) |
84 | WHITESPACE@[148; 149) | 84 | IDENT@[141; 148) "feature" |
85 | EQ@[149; 150) | 85 | WHITESPACE@[148; 149) |
86 | WHITESPACE@[150; 151) | 86 | EQ@[149; 150) |
87 | STRING@[151; 157) | 87 | WHITESPACE@[150; 151) |
88 | R_PAREN@[157; 158) | 88 | STRING@[151; 157) |
89 | R_BRACK@[158; 159) | 89 | R_PAREN@[157; 158) |
90 | WHITESPACE@[159; 168) | 90 | R_BRACK@[158; 159) |
91 | ATTR@[168; 198) | 91 | WHITESPACE@[159; 168) |
92 | POUND@[168; 169) | 92 | ATTR@[168; 198) |
93 | TOKEN_TREE@[169; 198) | 93 | POUND@[168; 169) |
94 | L_BRACK@[169; 170) | 94 | TOKEN_TREE@[169; 198) |
95 | IDENT@[170; 173) "cfg" | 95 | L_BRACK@[169; 170) |
96 | TOKEN_TREE@[173; 197) | 96 | IDENT@[170; 173) "cfg" |
97 | L_PAREN@[173; 174) | 97 | TOKEN_TREE@[173; 197) |
98 | IDENT@[174; 181) "feature" | 98 | L_PAREN@[173; 174) |
99 | WHITESPACE@[181; 182) | 99 | IDENT@[174; 181) "feature" |
100 | EQ@[182; 183) | 100 | WHITESPACE@[181; 182) |
101 | WHITESPACE@[183; 184) | 101 | EQ@[182; 183) |
102 | STRING@[184; 196) | 102 | WHITESPACE@[183; 184) |
103 | R_PAREN@[196; 197) | 103 | STRING@[184; 196) |
104 | R_BRACK@[197; 198) | 104 | R_PAREN@[196; 197) |
105 | WHITESPACE@[198; 207) | 105 | R_BRACK@[197; 198) |
106 | ATTR@[207; 233) | 106 | WHITESPACE@[198; 207) |
107 | POUND@[207; 208) | 107 | ATTR@[207; 233) |
108 | TOKEN_TREE@[208; 233) | 108 | POUND@[207; 208) |
109 | L_BRACK@[208; 209) | 109 | TOKEN_TREE@[208; 233) |
110 | IDENT@[209; 212) "cfg" | 110 | L_BRACK@[208; 209) |
111 | TOKEN_TREE@[212; 232) | 111 | IDENT@[209; 212) "cfg" |
112 | L_PAREN@[212; 213) | 112 | TOKEN_TREE@[212; 232) |
113 | IDENT@[213; 220) "feature" | 113 | L_PAREN@[212; 213) |
114 | WHITESPACE@[220; 221) | 114 | IDENT@[213; 220) "feature" |
115 | EQ@[221; 222) | 115 | WHITESPACE@[220; 221) |
116 | WHITESPACE@[222; 223) | 116 | EQ@[221; 222) |
117 | STRING@[223; 231) | 117 | WHITESPACE@[222; 223) |
118 | R_PAREN@[231; 232) | 118 | STRING@[223; 231) |
119 | R_BRACK@[232; 233) | 119 | R_PAREN@[231; 232) |
120 | WHITESPACE@[233; 242) | 120 | R_BRACK@[232; 233) |
121 | MATCH_ARM@[242; 249) | 121 | WHITESPACE@[233; 242) |
122 | PLACEHOLDER_PAT@[242; 243) | 122 | PLACEHOLDER_PAT@[242; 243) |
123 | UNDERSCORE@[242; 243) | 123 | UNDERSCORE@[242; 243) |
124 | WHITESPACE@[243; 244) | 124 | WHITESPACE@[243; 244) |
diff --git a/crates/ra_syntax/tests/data/parser/ok/0048_compound_assignment.rs b/crates/ra_syntax/tests/data/parser/ok/0048_compound_assignment.rs new file mode 100644 index 000000000..871720a49 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0048_compound_assignment.rs | |||
@@ -0,0 +1,17 @@ | |||
1 | // https://github.com/rust-analyzer/rust-analyzer/pull/983 | ||
2 | |||
3 | fn compound_assignment() { | ||
4 | let mut a = 0; | ||
5 | a += 1; | ||
6 | a -= 2; | ||
7 | a *= 3; | ||
8 | a %= 4; | ||
9 | a /= 5; | ||
10 | a |= 6; | ||
11 | a &= 7; | ||
12 | a ^= 8; | ||
13 | a <= 9; | ||
14 | a >= 10; | ||
15 | a >>= 11; | ||
16 | a <<= 12; | ||
17 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0048_compound_assignment.txt b/crates/ra_syntax/tests/data/parser/ok/0048_compound_assignment.txt new file mode 100644 index 000000000..c5ff06823 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0048_compound_assignment.txt | |||
@@ -0,0 +1,200 @@ | |||
1 | SOURCE_FILE@[0; 257) | ||
2 | COMMENT@[0; 58) | ||
3 | WHITESPACE@[58; 60) | ||
4 | FN_DEF@[60; 256) | ||
5 | FN_KW@[60; 62) | ||
6 | WHITESPACE@[62; 63) | ||
7 | NAME@[63; 82) | ||
8 | IDENT@[63; 82) "compound_assignment" | ||
9 | PARAM_LIST@[82; 84) | ||
10 | L_PAREN@[82; 83) | ||
11 | R_PAREN@[83; 84) | ||
12 | WHITESPACE@[84; 85) | ||
13 | BLOCK@[85; 256) | ||
14 | L_CURLY@[85; 86) | ||
15 | WHITESPACE@[86; 91) | ||
16 | LET_STMT@[91; 105) | ||
17 | LET_KW@[91; 94) | ||
18 | WHITESPACE@[94; 95) | ||
19 | BIND_PAT@[95; 100) | ||
20 | MUT_KW@[95; 98) | ||
21 | WHITESPACE@[98; 99) | ||
22 | NAME@[99; 100) | ||
23 | IDENT@[99; 100) "a" | ||
24 | WHITESPACE@[100; 101) | ||
25 | EQ@[101; 102) | ||
26 | WHITESPACE@[102; 103) | ||
27 | LITERAL@[103; 104) | ||
28 | INT_NUMBER@[103; 104) "0" | ||
29 | SEMI@[104; 105) | ||
30 | WHITESPACE@[105; 110) | ||
31 | EXPR_STMT@[110; 117) | ||
32 | BIN_EXPR@[110; 116) | ||
33 | PATH_EXPR@[110; 111) | ||
34 | PATH@[110; 111) | ||
35 | PATH_SEGMENT@[110; 111) | ||
36 | NAME_REF@[110; 111) | ||
37 | IDENT@[110; 111) "a" | ||
38 | WHITESPACE@[111; 112) | ||
39 | PLUSEQ@[112; 114) | ||
40 | WHITESPACE@[114; 115) | ||
41 | LITERAL@[115; 116) | ||
42 | INT_NUMBER@[115; 116) "1" | ||
43 | SEMI@[116; 117) | ||
44 | WHITESPACE@[117; 122) | ||
45 | EXPR_STMT@[122; 129) | ||
46 | BIN_EXPR@[122; 128) | ||
47 | PATH_EXPR@[122; 123) | ||
48 | PATH@[122; 123) | ||
49 | PATH_SEGMENT@[122; 123) | ||
50 | NAME_REF@[122; 123) | ||
51 | IDENT@[122; 123) "a" | ||
52 | WHITESPACE@[123; 124) | ||
53 | MINUSEQ@[124; 126) | ||
54 | WHITESPACE@[126; 127) | ||
55 | LITERAL@[127; 128) | ||
56 | INT_NUMBER@[127; 128) "2" | ||
57 | SEMI@[128; 129) | ||
58 | WHITESPACE@[129; 134) | ||
59 | EXPR_STMT@[134; 141) | ||
60 | BIN_EXPR@[134; 140) | ||
61 | PATH_EXPR@[134; 135) | ||
62 | PATH@[134; 135) | ||
63 | PATH_SEGMENT@[134; 135) | ||
64 | NAME_REF@[134; 135) | ||
65 | IDENT@[134; 135) "a" | ||
66 | WHITESPACE@[135; 136) | ||
67 | STAREQ@[136; 138) | ||
68 | WHITESPACE@[138; 139) | ||
69 | LITERAL@[139; 140) | ||
70 | INT_NUMBER@[139; 140) "3" | ||
71 | SEMI@[140; 141) | ||
72 | WHITESPACE@[141; 146) | ||
73 | EXPR_STMT@[146; 153) | ||
74 | BIN_EXPR@[146; 152) | ||
75 | PATH_EXPR@[146; 147) | ||
76 | PATH@[146; 147) | ||
77 | PATH_SEGMENT@[146; 147) | ||
78 | NAME_REF@[146; 147) | ||
79 | IDENT@[146; 147) "a" | ||
80 | WHITESPACE@[147; 148) | ||
81 | PERCENTEQ@[148; 150) | ||
82 | WHITESPACE@[150; 151) | ||
83 | LITERAL@[151; 152) | ||
84 | INT_NUMBER@[151; 152) "4" | ||
85 | SEMI@[152; 153) | ||
86 | WHITESPACE@[153; 158) | ||
87 | EXPR_STMT@[158; 165) | ||
88 | BIN_EXPR@[158; 164) | ||
89 | PATH_EXPR@[158; 159) | ||
90 | PATH@[158; 159) | ||
91 | PATH_SEGMENT@[158; 159) | ||
92 | NAME_REF@[158; 159) | ||
93 | IDENT@[158; 159) "a" | ||
94 | WHITESPACE@[159; 160) | ||
95 | SLASHEQ@[160; 162) | ||
96 | WHITESPACE@[162; 163) | ||
97 | LITERAL@[163; 164) | ||
98 | INT_NUMBER@[163; 164) "5" | ||
99 | SEMI@[164; 165) | ||
100 | WHITESPACE@[165; 170) | ||
101 | EXPR_STMT@[170; 177) | ||
102 | BIN_EXPR@[170; 176) | ||
103 | PATH_EXPR@[170; 171) | ||
104 | PATH@[170; 171) | ||
105 | PATH_SEGMENT@[170; 171) | ||
106 | NAME_REF@[170; 171) | ||
107 | IDENT@[170; 171) "a" | ||
108 | WHITESPACE@[171; 172) | ||
109 | PIPEEQ@[172; 174) | ||
110 | WHITESPACE@[174; 175) | ||
111 | LITERAL@[175; 176) | ||
112 | INT_NUMBER@[175; 176) "6" | ||
113 | SEMI@[176; 177) | ||
114 | WHITESPACE@[177; 182) | ||
115 | EXPR_STMT@[182; 189) | ||
116 | BIN_EXPR@[182; 188) | ||
117 | PATH_EXPR@[182; 183) | ||
118 | PATH@[182; 183) | ||
119 | PATH_SEGMENT@[182; 183) | ||
120 | NAME_REF@[182; 183) | ||
121 | IDENT@[182; 183) "a" | ||
122 | WHITESPACE@[183; 184) | ||
123 | AMPEQ@[184; 186) | ||
124 | WHITESPACE@[186; 187) | ||
125 | LITERAL@[187; 188) | ||
126 | INT_NUMBER@[187; 188) "7" | ||
127 | SEMI@[188; 189) | ||
128 | WHITESPACE@[189; 194) | ||
129 | EXPR_STMT@[194; 201) | ||
130 | BIN_EXPR@[194; 200) | ||
131 | PATH_EXPR@[194; 195) | ||
132 | PATH@[194; 195) | ||
133 | PATH_SEGMENT@[194; 195) | ||
134 | NAME_REF@[194; 195) | ||
135 | IDENT@[194; 195) "a" | ||
136 | WHITESPACE@[195; 196) | ||
137 | CARETEQ@[196; 198) | ||
138 | WHITESPACE@[198; 199) | ||
139 | LITERAL@[199; 200) | ||
140 | INT_NUMBER@[199; 200) "8" | ||
141 | SEMI@[200; 201) | ||
142 | WHITESPACE@[201; 206) | ||
143 | EXPR_STMT@[206; 213) | ||
144 | BIN_EXPR@[206; 212) | ||
145 | PATH_EXPR@[206; 207) | ||
146 | PATH@[206; 207) | ||
147 | PATH_SEGMENT@[206; 207) | ||
148 | NAME_REF@[206; 207) | ||
149 | IDENT@[206; 207) "a" | ||
150 | WHITESPACE@[207; 208) | ||
151 | LTEQ@[208; 210) | ||
152 | WHITESPACE@[210; 211) | ||
153 | LITERAL@[211; 212) | ||
154 | INT_NUMBER@[211; 212) "9" | ||
155 | SEMI@[212; 213) | ||
156 | WHITESPACE@[213; 218) | ||
157 | EXPR_STMT@[218; 226) | ||
158 | BIN_EXPR@[218; 225) | ||
159 | PATH_EXPR@[218; 219) | ||
160 | PATH@[218; 219) | ||
161 | PATH_SEGMENT@[218; 219) | ||
162 | NAME_REF@[218; 219) | ||
163 | IDENT@[218; 219) "a" | ||
164 | WHITESPACE@[219; 220) | ||
165 | GTEQ@[220; 222) | ||
166 | WHITESPACE@[222; 223) | ||
167 | LITERAL@[223; 225) | ||
168 | INT_NUMBER@[223; 225) "10" | ||
169 | SEMI@[225; 226) | ||
170 | WHITESPACE@[226; 231) | ||
171 | EXPR_STMT@[231; 240) | ||
172 | BIN_EXPR@[231; 239) | ||
173 | PATH_EXPR@[231; 232) | ||
174 | PATH@[231; 232) | ||
175 | PATH_SEGMENT@[231; 232) | ||
176 | NAME_REF@[231; 232) | ||
177 | IDENT@[231; 232) "a" | ||
178 | WHITESPACE@[232; 233) | ||
179 | SHREQ@[233; 236) | ||
180 | WHITESPACE@[236; 237) | ||
181 | LITERAL@[237; 239) | ||
182 | INT_NUMBER@[237; 239) "11" | ||
183 | SEMI@[239; 240) | ||
184 | WHITESPACE@[240; 245) | ||
185 | EXPR_STMT@[245; 254) | ||
186 | BIN_EXPR@[245; 253) | ||
187 | PATH_EXPR@[245; 246) | ||
188 | PATH@[245; 246) | ||
189 | PATH_SEGMENT@[245; 246) | ||
190 | NAME_REF@[245; 246) | ||
191 | IDENT@[245; 246) "a" | ||
192 | WHITESPACE@[246; 247) | ||
193 | SHLEQ@[247; 250) | ||
194 | WHITESPACE@[250; 251) | ||
195 | LITERAL@[251; 253) | ||
196 | INT_NUMBER@[251; 253) "12" | ||
197 | SEMI@[253; 254) | ||
198 | WHITESPACE@[254; 255) | ||
199 | R_CURLY@[255; 256) | ||
200 | WHITESPACE@[256; 257) | ||