aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/Cargo.toml2
-rw-r--r--crates/ra_syntax/fuzz/fuzz_targets/parser.rs2
-rw-r--r--crates/ra_syntax/fuzz/fuzz_targets/reparse.rs2
-rw-r--r--crates/ra_syntax/src/algo.rs19
-rw-r--r--crates/ra_syntax/src/algo/visit.rs110
-rw-r--r--crates/ra_syntax/src/ast.rs1
-rw-r--r--crates/ra_syntax/src/ast/edit.rs271
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs93
-rw-r--r--crates/ra_syntax/src/ast/generated.rs46
-rw-r--r--crates/ra_syntax/src/ast/make.rs48
-rw-r--r--crates/ra_syntax/src/ast/traits.rs2
-rw-r--r--crates/ra_syntax/src/fuzz.rs2
-rw-r--r--crates/ra_syntax/src/grammar.ron8
-rw-r--r--crates/ra_syntax/src/lib.rs31
-rw-r--r--crates/ra_syntax/src/parsing/lexer.rs2
-rw-r--r--crates/ra_syntax/src/parsing/text_token_source.rs2
-rw-r--r--crates/ra_syntax/src/parsing/text_tree_sink.rs2
-rw-r--r--crates/ra_syntax/src/ptr.rs2
-rw-r--r--crates/ra_syntax/src/syntax_error.rs2
-rw-r--r--crates/ra_syntax/src/validation.rs20
-rw-r--r--crates/ra_syntax/src/validation/block.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt68
-rw-r--r--crates/ra_syntax/test_data/parser/err/0028_macro_2.0.txt10
-rw-r--r--crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt72
-rw-r--r--crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt18
-rw-r--r--crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt18
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt20
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt34
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt26
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt43
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt65
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rs6
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt107
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt26
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt18
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt54
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt130
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt36
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt18
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt50
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt20
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt18
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt18
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rs3
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.txt43
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt268
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt10
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rs3
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt53
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt20
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt89
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt26
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt90
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt18
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt150
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt10
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rs7
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.txt97
63 files changed, 1627 insertions, 828 deletions
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index 724c38e17..9bc85404a 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -12,6 +12,8 @@ itertools = "0.8.0"
12rowan = "0.6.1" 12rowan = "0.6.1"
13rustc_lexer = "0.1.0" 13rustc_lexer = "0.1.0"
14rustc-hash = "1.0.1" 14rustc-hash = "1.0.1"
15arrayvec = "0.4.10"
16once_cell = "1.2.0"
15 17
16# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here 18# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here
17# to reduce number of compilations 19# to reduce number of compilations
diff --git a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs
index 76a8b08d0..7bc4ef30d 100644
--- a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs
+++ b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1#![no_main] 3#![no_main]
2use libfuzzer_sys::fuzz_target; 4use libfuzzer_sys::fuzz_target;
3use ra_syntax::fuzz::check_parser; 5use ra_syntax::fuzz::check_parser;
diff --git a/crates/ra_syntax/fuzz/fuzz_targets/reparse.rs b/crates/ra_syntax/fuzz/fuzz_targets/reparse.rs
index 45524d4c1..16598f5f1 100644
--- a/crates/ra_syntax/fuzz/fuzz_targets/reparse.rs
+++ b/crates/ra_syntax/fuzz/fuzz_targets/reparse.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1#![no_main] 3#![no_main]
2use libfuzzer_sys::fuzz_target; 4use libfuzzer_sys::fuzz_target;
3use ra_syntax::fuzz::CheckReparse; 5use ra_syntax::fuzz::CheckReparse;
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs
index 46680a08f..7cfea70f9 100644
--- a/crates/ra_syntax/src/algo.rs
+++ b/crates/ra_syntax/src/algo.rs
@@ -1,8 +1,9 @@
1pub mod visit; 1//! FIXME: write short doc here
2 2
3use std::ops::RangeInclusive; 3use std::ops::RangeInclusive;
4 4
5use itertools::Itertools; 5use itertools::Itertools;
6use ra_text_edit::TextEditBuilder;
6use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
7 8
8use crate::{ 9use crate::{
@@ -63,6 +64,18 @@ pub enum InsertPosition<T> {
63 After(T), 64 After(T),
64} 65}
65 66
67pub struct TreeDiff {
68 replacements: FxHashMap<SyntaxElement, SyntaxElement>,
69}
70
71impl TreeDiff {
72 pub fn into_text_edit(&self, builder: &mut TextEditBuilder) {
73 for (from, to) in self.replacements.iter() {
74 builder.replace(from.text_range(), to.to_string())
75 }
76 }
77}
78
66/// Finds minimal the diff, which, applied to `from`, will result in `to`. 79/// Finds minimal the diff, which, applied to `from`, will result in `to`.
67/// 80///
68/// Specifically, returns a map whose keys are descendants of `from` and values 81/// Specifically, returns a map whose keys are descendants of `from` and values
@@ -70,12 +83,12 @@ pub enum InsertPosition<T> {
70/// 83///
71/// A trivial solution is a singletom map `{ from: to }`, but this function 84/// A trivial solution is a singletom map `{ from: to }`, but this function
72/// tries to find a more fine-grained diff. 85/// tries to find a more fine-grained diff.
73pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> FxHashMap<SyntaxElement, SyntaxElement> { 86pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
74 let mut buf = FxHashMap::default(); 87 let mut buf = FxHashMap::default();
75 // FIXME: this is both horrible inefficient and gives larger than 88 // FIXME: this is both horrible inefficient and gives larger than
76 // necessary diff. I bet there's a cool algorithm to diff trees properly. 89 // necessary diff. I bet there's a cool algorithm to diff trees properly.
77 go(&mut buf, from.clone().into(), to.clone().into()); 90 go(&mut buf, from.clone().into(), to.clone().into());
78 return buf; 91 return TreeDiff { replacements: buf };
79 92
80 fn go( 93 fn go(
81 buf: &mut FxHashMap<SyntaxElement, SyntaxElement>, 94 buf: &mut FxHashMap<SyntaxElement, SyntaxElement>,
diff --git a/crates/ra_syntax/src/algo/visit.rs b/crates/ra_syntax/src/algo/visit.rs
deleted file mode 100644
index 87bd15cc0..000000000
--- a/crates/ra_syntax/src/algo/visit.rs
+++ /dev/null
@@ -1,110 +0,0 @@
1use crate::{AstNode, SyntaxNode};
2
3use std::marker::PhantomData;
4
5pub fn visitor<'a, T>() -> impl Visitor<'a, Output = T> {
6 EmptyVisitor { ph: PhantomData }
7}
8
9pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output = T, Ctx = C> {
10 EmptyVisitorCtx { ph: PhantomData, ctx }
11}
12
13pub trait Visitor<'a>: Sized {
14 type Output;
15 fn accept(self, node: &'a SyntaxNode) -> Option<Self::Output>;
16 fn visit<N, F>(self, f: F) -> Vis<Self, N, F>
17 where
18 N: AstNode + 'a,
19 F: FnOnce(N) -> Self::Output,
20 {
21 Vis { inner: self, f, ph: PhantomData }
22 }
23}
24
25pub trait VisitorCtx<'a>: Sized {
26 type Output;
27 type Ctx;
28 fn accept(self, node: &'a SyntaxNode) -> Result<Self::Output, Self::Ctx>;
29 fn visit<N, F>(self, f: F) -> VisCtx<Self, N, F>
30 where
31 N: AstNode + 'a,
32 F: FnOnce(N, Self::Ctx) -> Self::Output,
33 {
34 VisCtx { inner: self, f, ph: PhantomData }
35 }
36}
37
38#[derive(Debug)]
39struct EmptyVisitor<T> {
40 ph: PhantomData<fn() -> T>,
41}
42
43impl<'a, T> Visitor<'a> for EmptyVisitor<T> {
44 type Output = T;
45
46 fn accept(self, _node: &'a SyntaxNode) -> Option<T> {
47 None
48 }
49}
50
51#[derive(Debug)]
52struct EmptyVisitorCtx<T, C> {
53 ctx: C,
54 ph: PhantomData<fn() -> T>,
55}
56
57impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx<T, C> {
58 type Output = T;
59 type Ctx = C;
60
61 fn accept(self, _node: &'a SyntaxNode) -> Result<T, C> {
62 Err(self.ctx)
63 }
64}
65
66#[derive(Debug)]
67pub struct Vis<V, N, F> {
68 inner: V,
69 f: F,
70 ph: PhantomData<fn(N)>,
71}
72
73impl<'a, V, N, F> Visitor<'a> for Vis<V, N, F>
74where
75 V: Visitor<'a>,
76 N: AstNode + 'a,
77 F: FnOnce(N) -> <V as Visitor<'a>>::Output,
78{
79 type Output = <V as Visitor<'a>>::Output;
80
81 fn accept(self, node: &'a SyntaxNode) -> Option<Self::Output> {
82 let Vis { inner, f, .. } = self;
83 inner.accept(node).or_else(|| N::cast(node.clone()).map(f))
84 }
85}
86
87#[derive(Debug)]
88pub struct VisCtx<V, N, F> {
89 inner: V,
90 f: F,
91 ph: PhantomData<fn(N)>,
92}
93
94impl<'a, V, N, F> VisitorCtx<'a> for VisCtx<V, N, F>
95where
96 V: VisitorCtx<'a>,
97 N: AstNode + 'a,
98 F: FnOnce(N, <V as VisitorCtx<'a>>::Ctx) -> <V as VisitorCtx<'a>>::Output,
99{
100 type Output = <V as VisitorCtx<'a>>::Output;
101 type Ctx = <V as VisitorCtx<'a>>::Ctx;
102
103 fn accept(self, node: &'a SyntaxNode) -> Result<Self::Output, Self::Ctx> {
104 let VisCtx { inner, f, .. } = self;
105 inner.accept(node).or_else(|ctx| match N::cast(node.clone()) {
106 None => Err(ctx),
107 Some(node) => Ok(f(node, ctx)),
108 })
109 }
110}
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index f464d6534..1b2ce921a 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -5,6 +5,7 @@ mod traits;
5mod tokens; 5mod tokens;
6mod extensions; 6mod extensions;
7mod expr_extensions; 7mod expr_extensions;
8pub mod edit;
8pub mod make; 9pub mod make;
9 10
10use std::marker::PhantomData; 11use std::marker::PhantomData;
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
new file mode 100644
index 000000000..03f3b5fbb
--- /dev/null
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -0,0 +1,271 @@
1//! This module contains functions for editing syntax trees. As the trees are
2//! immutable, all function here return a fresh copy of the tree, instead of
3//! doing an in-place modification.
4use std::{iter, ops::RangeInclusive};
5
6use arrayvec::ArrayVec;
7use rustc_hash::FxHashMap;
8
9use crate::{
10 algo,
11 ast::{
12 self,
13 make::{self, tokens},
14 AstNode, TypeBoundsOwner,
15 },
16 AstToken, Direction, InsertPosition, SmolStr, SyntaxElement,
17 SyntaxKind::{ATTR, COMMENT, WHITESPACE},
18 SyntaxNode, T,
19};
20
21impl ast::FnDef {
22 #[must_use]
23 pub fn with_body(&self, body: ast::Block) -> ast::FnDef {
24 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
25 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() {
26 old_body.syntax().clone().into()
27 } else if let Some(semi) = self.semicolon_token() {
28 to_insert.push(make::tokens::single_space().into());
29 semi.into()
30 } else {
31 to_insert.push(make::tokens::single_space().into());
32 to_insert.push(body.syntax().clone().into());
33 return insert_children(self, InsertPosition::Last, to_insert.into_iter());
34 };
35 to_insert.push(body.syntax().clone().into());
36 let replace_range = RangeInclusive::new(old_body_or_semi.clone(), old_body_or_semi);
37 replace_children(self, replace_range, to_insert.into_iter())
38 }
39}
40
41impl ast::ItemList {
42 #[must_use]
43 pub fn append_items(&self, items: impl Iterator<Item = ast::ImplItem>) -> ast::ItemList {
44 let mut res = self.clone();
45 if !self.syntax().text().contains_char('\n') {
46 res = res.make_multiline();
47 }
48 items.for_each(|it| res = res.append_item(it));
49 res
50 }
51
52 #[must_use]
53 pub fn append_item(&self, item: ast::ImplItem) -> ast::ItemList {
54 let (indent, position) = match self.impl_items().last() {
55 Some(it) => (
56 leading_indent(it.syntax()).unwrap_or_default().to_string(),
57 InsertPosition::After(it.syntax().clone().into()),
58 ),
59 None => match self.l_curly() {
60 Some(it) => (
61 " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(),
62 InsertPosition::After(it),
63 ),
64 None => return self.clone(),
65 },
66 };
67 let ws = tokens::WsBuilder::new(&format!("\n{}", indent));
68 let to_insert: ArrayVec<[SyntaxElement; 2]> =
69 [ws.ws().into(), item.syntax().clone().into()].into();
70 insert_children(self, position, to_insert.into_iter())
71 }
72
73 fn l_curly(&self) -> Option<SyntaxElement> {
74 self.syntax().children_with_tokens().find(|it| it.kind() == T!['{'])
75 }
76
77 fn make_multiline(&self) -> ast::ItemList {
78 let l_curly = match self.syntax().children_with_tokens().find(|it| it.kind() == T!['{']) {
79 Some(it) => it,
80 None => return self.clone(),
81 };
82 let sibling = match l_curly.next_sibling_or_token() {
83 Some(it) => it,
84 None => return self.clone(),
85 };
86 let existing_ws = match sibling.as_token() {
87 None => None,
88 Some(tok) if tok.kind() != WHITESPACE => None,
89 Some(ws) => {
90 if ws.text().contains('\n') {
91 return self.clone();
92 }
93 Some(ws.clone())
94 }
95 };
96
97 let indent = leading_indent(self.syntax()).unwrap_or("".into());
98 let ws = tokens::WsBuilder::new(&format!("\n{}", indent));
99 let to_insert = iter::once(ws.ws().into());
100 match existing_ws {
101 None => insert_children(self, InsertPosition::After(l_curly), to_insert),
102 Some(ws) => {
103 replace_children(self, RangeInclusive::new(ws.clone().into(), ws.into()), to_insert)
104 }
105 }
106 }
107}
108
109impl ast::RecordFieldList {
110 #[must_use]
111 pub fn append_field(&self, field: &ast::RecordField) -> ast::RecordFieldList {
112 self.insert_field(InsertPosition::Last, field)
113 }
114
115 #[must_use]
116 pub fn insert_field(
117 &self,
118 position: InsertPosition<&'_ ast::RecordField>,
119 field: &ast::RecordField,
120 ) -> ast::RecordFieldList {
121 let is_multiline = self.syntax().text().contains_char('\n');
122 let ws;
123 let space = if is_multiline {
124 ws = tokens::WsBuilder::new(&format!(
125 "\n{} ",
126 leading_indent(self.syntax()).unwrap_or("".into())
127 ));
128 ws.ws()
129 } else {
130 tokens::single_space()
131 };
132
133 let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new();
134 to_insert.push(space.into());
135 to_insert.push(field.syntax().clone().into());
136 to_insert.push(tokens::comma().into());
137
138 macro_rules! after_l_curly {
139 () => {{
140 let anchor = match self.l_curly() {
141 Some(it) => it,
142 None => return self.clone(),
143 };
144 InsertPosition::After(anchor)
145 }};
146 }
147
148 macro_rules! after_field {
149 ($anchor:expr) => {
150 if let Some(comma) = $anchor
151 .syntax()
152 .siblings_with_tokens(Direction::Next)
153 .find(|it| it.kind() == T![,])
154 {
155 InsertPosition::After(comma)
156 } else {
157 to_insert.insert(0, tokens::comma().into());
158 InsertPosition::After($anchor.syntax().clone().into())
159 }
160 };
161 };
162
163 let position = match position {
164 InsertPosition::First => after_l_curly!(),
165 InsertPosition::Last => {
166 if !is_multiline {
167 // don't insert comma before curly
168 to_insert.pop();
169 }
170 match self.fields().last() {
171 Some(it) => after_field!(it),
172 None => after_l_curly!(),
173 }
174 }
175 InsertPosition::Before(anchor) => {
176 InsertPosition::Before(anchor.syntax().clone().into())
177 }
178 InsertPosition::After(anchor) => after_field!(anchor),
179 };
180
181 insert_children(self, position, to_insert.iter().cloned())
182 }
183
184 fn l_curly(&self) -> Option<SyntaxElement> {
185 self.syntax().children_with_tokens().find(|it| it.kind() == T!['{'])
186 }
187}
188
189impl ast::TypeParam {
190 #[must_use]
191 pub fn remove_bounds(&self) -> ast::TypeParam {
192 let colon = match self.colon_token() {
193 Some(it) => it,
194 None => return self.clone(),
195 };
196 let end = match self.type_bound_list() {
197 Some(it) => it.syntax().clone().into(),
198 None => colon.clone().into(),
199 };
200 replace_children(self, RangeInclusive::new(colon.into(), end), iter::empty())
201 }
202}
203
204#[must_use]
205pub fn strip_attrs_and_docs<N: ast::AttrsOwner>(node: &N) -> N {
206 N::cast(strip_attrs_and_docs_inner(node.syntax().clone())).unwrap()
207}
208
209fn strip_attrs_and_docs_inner(mut node: SyntaxNode) -> SyntaxNode {
210 while let Some(start) =
211 node.children_with_tokens().find(|it| it.kind() == ATTR || it.kind() == COMMENT)
212 {
213 let end = match &start.next_sibling_or_token() {
214 Some(el) if el.kind() == WHITESPACE => el.clone(),
215 Some(_) | None => start.clone(),
216 };
217 node = algo::replace_children(&node, RangeInclusive::new(start, end), &mut iter::empty());
218 }
219 node
220}
221
222#[must_use]
223pub fn replace_descendants<N: AstNode, D: AstNode>(
224 parent: &N,
225 replacement_map: impl Iterator<Item = (D, D)>,
226) -> N {
227 let map = replacement_map
228 .map(|(from, to)| (from.syntax().clone().into(), to.syntax().clone().into()))
229 .collect::<FxHashMap<_, _>>();
230 let new_syntax = algo::replace_descendants(parent.syntax(), &map);
231 N::cast(new_syntax).unwrap()
232}
233
234// Note this is copy-pasted from fmt. It seems like fmt should be a separate
235// crate, but basic tree building should be this crate. However, tree building
236// might want to call into fmt...
237fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> {
238 let prev_tokens = std::iter::successors(node.first_token(), |token| token.prev_token());
239 for token in prev_tokens {
240 if let Some(ws) = ast::Whitespace::cast(token.clone()) {
241 let ws_text = ws.text();
242 if let Some(pos) = ws_text.rfind('\n') {
243 return Some(ws_text[pos + 1..].into());
244 }
245 }
246 if token.text().contains('\n') {
247 break;
248 }
249 }
250 None
251}
252
253#[must_use]
254fn insert_children<N: AstNode>(
255 parent: &N,
256 position: InsertPosition<SyntaxElement>,
257 mut to_insert: impl Iterator<Item = SyntaxElement>,
258) -> N {
259 let new_syntax = algo::insert_children(parent.syntax(), position, &mut to_insert);
260 N::cast(new_syntax).unwrap()
261}
262
263#[must_use]
264fn replace_children<N: AstNode>(
265 parent: &N,
266 to_replace: RangeInclusive<SyntaxElement>,
267 mut to_insert: impl Iterator<Item = SyntaxElement>,
268) -> N {
269 let new_syntax = algo::replace_children(parent.syntax(), to_replace, &mut to_insert);
270 N::cast(new_syntax).unwrap()
271}
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index 5f7e9f5b1..cefc00402 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -1,10 +1,8 @@
1//! Various extension methods to ast Nodes, which are hard to code-generate. 1//! Various extension methods to ast Nodes, which are hard to code-generate.
2//! Extensions for various expressions live in a sibling `expr_extensions` module. 2//! Extensions for various expressions live in a sibling `expr_extensions` module.
3 3
4use itertools::Itertools;
5
6use crate::{ 4use crate::{
7 ast::{self, child_opt, children, AstNode, SyntaxNode}, 5 ast::{self, child_opt, children, AstChildren, AstNode, AttrInput, SyntaxNode},
8 SmolStr, SyntaxElement, 6 SmolStr, SyntaxElement,
9 SyntaxKind::*, 7 SyntaxKind::*,
10 SyntaxToken, T, 8 SyntaxToken, T,
@@ -21,6 +19,16 @@ impl ast::NameRef {
21 pub fn text(&self) -> &SmolStr { 19 pub fn text(&self) -> &SmolStr {
22 text_of_first_token(self.syntax()) 20 text_of_first_token(self.syntax())
23 } 21 }
22
23 pub fn as_tuple_field(&self) -> Option<usize> {
24 self.syntax().children_with_tokens().find_map(|c| {
25 if c.kind() == SyntaxKind::INT_NUMBER {
26 c.as_token().and_then(|tok| tok.text().as_str().parse().ok())
27 } else {
28 None
29 }
30 })
31 }
24} 32}
25 33
26fn text_of_first_token(node: &SyntaxNode) -> &SmolStr { 34fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
@@ -28,62 +36,37 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
28} 36}
29 37
30impl ast::Attr { 38impl ast::Attr {
31 pub fn is_inner(&self) -> bool { 39 pub fn as_simple_atom(&self) -> Option<SmolStr> {
32 let tt = match self.value() { 40 match self.input() {
33 None => return false, 41 None => self.simple_name(),
34 Some(tt) => tt, 42 Some(_) => None,
35 };
36
37 let prev = match tt.syntax().prev_sibling() {
38 None => return false,
39 Some(prev) => prev,
40 };
41
42 prev.kind() == T![!]
43 }
44
45 pub fn as_atom(&self) -> Option<SmolStr> {
46 let tt = self.value()?;
47 let (_bra, attr, _ket) = tt.syntax().children_with_tokens().collect_tuple()?;
48 if attr.kind() == IDENT {
49 Some(attr.as_token()?.text().clone())
50 } else {
51 None
52 } 43 }
53 } 44 }
54 45
55 pub fn as_call(&self) -> Option<(SmolStr, ast::TokenTree)> { 46 pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
56 let tt = self.value()?; 47 match self.input() {
57 let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; 48 Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)),
58 let args = ast::TokenTree::cast(args.as_node()?.clone())?; 49 _ => None,
59 if attr.kind() == IDENT {
60 Some((attr.as_token()?.text().clone(), args))
61 } else {
62 None
63 } 50 }
64 } 51 }
65 52
66 pub fn as_named(&self) -> Option<SmolStr> { 53 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
67 let tt = self.value()?; 54 match self.input() {
68 let attr = tt.syntax().children_with_tokens().nth(1)?; 55 Some(AttrInput::Literal(lit)) => {
69 if attr.kind() == IDENT { 56 let key = self.simple_name()?;
70 Some(attr.as_token()?.text().clone()) 57 // FIXME: escape? raw string?
71 } else { 58 let value = lit.syntax().first_token()?.text().trim_matches('"').into();
72 None 59 Some((key, value))
60 }
61 _ => None,
73 } 62 }
74 } 63 }
75 64
76 pub fn as_key_value(&self) -> Option<(SmolStr, SmolStr)> { 65 pub fn simple_name(&self) -> Option<SmolStr> {
77 let tt = self.value()?; 66 let path = self.path()?;
78 let tt_node = tt.syntax(); 67 match (path.segment(), path.qualifier()) {
79 let attr = tt_node.children_with_tokens().nth(1)?; 68 (Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()),
80 if attr.kind() == IDENT { 69 _ => None,
81 let key = attr.as_token()?.text().clone();
82 let val_node = tt_node.children_with_tokens().find(|t| t.kind() == STRING)?;
83 let val = val_node.as_token()?.text().trim_start_matches('"').trim_end_matches('"');
84 Some((key, SmolStr::new(val)))
85 } else {
86 None
87 } 70 }
88 } 71 }
89} 72}
@@ -193,6 +176,16 @@ impl ast::ImplBlock {
193 } 176 }
194} 177}
195 178
179impl ast::AttrsOwner for ast::ImplItem {
180 fn attrs(&self) -> AstChildren<ast::Attr> {
181 match self {
182 ast::ImplItem::FnDef(it) => it.attrs(),
183 ast::ImplItem::TypeAliasDef(it) => it.attrs(),
184 ast::ImplItem::ConstDef(it) => it.attrs(),
185 }
186 }
187}
188
196#[derive(Debug, Clone, PartialEq, Eq)] 189#[derive(Debug, Clone, PartialEq, Eq)]
197pub enum StructKind { 190pub enum StructKind {
198 Tuple(ast::TupleFieldDefList), 191 Tuple(ast::TupleFieldDefList),
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index dc1f8c82c..34b22c3e2 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -1,4 +1,4 @@
1// Generated file, do not edit by hand, see `crate/ra_tools/src/codegen` 1//! Generated file, do not edit by hand, see `crate/ra_tools/src/codegen`
2 2
3use crate::{ 3use crate::{
4 ast::{self, AstChildren, AstNode}, 4 ast::{self, AstChildren, AstNode},
@@ -166,11 +166,52 @@ impl AstNode for Attr {
166 } 166 }
167} 167}
168impl Attr { 168impl Attr {
169 pub fn value(&self) -> Option<TokenTree> { 169 pub fn path(&self) -> Option<Path> {
170 AstChildren::new(&self.syntax).next()
171 }
172 pub fn input(&self) -> Option<AttrInput> {
170 AstChildren::new(&self.syntax).next() 173 AstChildren::new(&self.syntax).next()
171 } 174 }
172} 175}
173#[derive(Debug, Clone, PartialEq, Eq, Hash)] 176#[derive(Debug, Clone, PartialEq, Eq, Hash)]
177pub enum AttrInput {
178 Literal(Literal),
179 TokenTree(TokenTree),
180}
181impl From<Literal> for AttrInput {
182 fn from(node: Literal) -> AttrInput {
183 AttrInput::Literal(node)
184 }
185}
186impl From<TokenTree> for AttrInput {
187 fn from(node: TokenTree) -> AttrInput {
188 AttrInput::TokenTree(node)
189 }
190}
191impl AstNode for AttrInput {
192 fn can_cast(kind: SyntaxKind) -> bool {
193 match kind {
194 LITERAL | TOKEN_TREE => true,
195 _ => false,
196 }
197 }
198 fn cast(syntax: SyntaxNode) -> Option<Self> {
199 let res = match syntax.kind() {
200 LITERAL => AttrInput::Literal(Literal { syntax }),
201 TOKEN_TREE => AttrInput::TokenTree(TokenTree { syntax }),
202 _ => return None,
203 };
204 Some(res)
205 }
206 fn syntax(&self) -> &SyntaxNode {
207 match self {
208 AttrInput::Literal(it) => &it.syntax,
209 AttrInput::TokenTree(it) => &it.syntax,
210 }
211 }
212}
213impl AttrInput {}
214#[derive(Debug, Clone, PartialEq, Eq, Hash)]
174pub struct AwaitExpr { 215pub struct AwaitExpr {
175 pub(crate) syntax: SyntaxNode, 216 pub(crate) syntax: SyntaxNode,
176} 217}
@@ -1921,6 +1962,7 @@ impl AstNode for ModuleItem {
1921 } 1962 }
1922 } 1963 }
1923} 1964}
1965impl ast::AttrsOwner for ModuleItem {}
1924impl ModuleItem {} 1966impl ModuleItem {}
1925#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1967#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1926pub struct Name { 1968pub struct Name {
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index c06c62b3b..287a40bee 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -133,3 +133,51 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
133 let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); 133 let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap();
134 res 134 res
135} 135}
136
137pub mod tokens {
138 use crate::{AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken, T};
139 use once_cell::sync::Lazy;
140
141 static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| SourceFile::parse(",\n; ;"));
142
143 pub fn comma() -> SyntaxToken {
144 SOURCE_FILE
145 .tree()
146 .syntax()
147 .descendants_with_tokens()
148 .filter_map(|it| it.into_token())
149 .find(|it| it.kind() == T![,])
150 .unwrap()
151 }
152
153 pub fn single_space() -> SyntaxToken {
154 SOURCE_FILE
155 .tree()
156 .syntax()
157 .descendants_with_tokens()
158 .filter_map(|it| it.into_token())
159 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == " ")
160 .unwrap()
161 }
162
163 pub fn single_newline() -> SyntaxToken {
164 SOURCE_FILE
165 .tree()
166 .syntax()
167 .descendants_with_tokens()
168 .filter_map(|it| it.into_token())
169 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == "\n")
170 .unwrap()
171 }
172
173 pub struct WsBuilder(SourceFile);
174
175 impl WsBuilder {
176 pub fn new(text: &str) -> WsBuilder {
177 WsBuilder(SourceFile::parse(text).ok().unwrap())
178 }
179 pub fn ws(&self) -> SyntaxToken {
180 self.0.syntax().first_child_or_token().unwrap().into_token().unwrap()
181 }
182 }
183}
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index c3e676d4c..f275a4955 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -99,7 +99,7 @@ pub trait AttrsOwner: AstNode {
99 children(self) 99 children(self)
100 } 100 }
101 fn has_atom_attr(&self, atom: &str) -> bool { 101 fn has_atom_attr(&self, atom: &str) -> bool {
102 self.attrs().filter_map(|x| x.as_atom()).any(|x| x == atom) 102 self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom)
103 } 103 }
104} 104}
105 105
diff --git a/crates/ra_syntax/src/fuzz.rs b/crates/ra_syntax/src/fuzz.rs
index 698a624ec..7012df7f0 100644
--- a/crates/ra_syntax/src/fuzz.rs
+++ b/crates/ra_syntax/src/fuzz.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1use crate::{validation, AstNode, SourceFile, TextRange, TextUnit}; 3use crate::{validation, AstNode, SourceFile, TextRange, TextUnit};
2use ra_text_edit::AtomTextEdit; 4use ra_text_edit::AtomTextEdit;
3use std::str::{self, FromStr}; 5use std::str::{self, FromStr};
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 5f395501a..25e6f64ce 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -1,5 +1,5 @@
1// Stores definitions which must be used in multiple places 1// Stores definitions which must be used in multiple places
2// See `cargo gen-syntax` (defined in crates/tools/src/main.rs) 2// See `cargo gen-syntax` (defined in crates/ra_tools/src/main.rs)
3Grammar( 3Grammar(
4 punct: [ 4 punct: [
5 (";", "SEMI"), 5 (";", "SEMI"),
@@ -397,7 +397,8 @@ Grammar(
397 ), 397 ),
398 "ModuleItem": ( 398 "ModuleItem": (
399 enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", 399 enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
400 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] 400 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
401 traits: ["AttrsOwner"]
401 ), 402 ),
402 "ImplItem": ( 403 "ImplItem": (
403 enum: ["FnDef", "TypeAliasDef", "ConstDef"] 404 enum: ["FnDef", "TypeAliasDef", "ConstDef"]
@@ -576,7 +577,8 @@ Grammar(
576 traits: [ "NameOwner", "AttrsOwner","DocCommentsOwner" ], 577 traits: [ "NameOwner", "AttrsOwner","DocCommentsOwner" ],
577 options: [ "TokenTree", "Path" ], 578 options: [ "TokenTree", "Path" ],
578 ), 579 ),
579 "Attr": ( options: [ ["value", "TokenTree"] ] ), 580 "AttrInput": ( enum: [ "Literal", "TokenTree" ] ),
581 "Attr": ( options: [ "Path", [ "input", "AttrInput" ] ] ),
580 "TokenTree": (), 582 "TokenTree": (),
581 "TypeParamList": ( 583 "TypeParamList": (
582 collections: [ 584 collections: [
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index edb6076bb..c315ba552 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -160,6 +160,17 @@ impl SourceFile {
160 } 160 }
161} 161}
162 162
163#[macro_export]
164macro_rules! match_ast {
165 (match $node:ident {
166 $( ast::$ast:ident($it:ident) => $res:block, )*
167 _ => $catch_all:expr,
168 }) => {{
169 $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
170 { $catch_all }
171 }};
172}
173
163/// This test does not assert anything and instead just shows off the crate's 174/// This test does not assert anything and instead just shows off the crate's
164/// API. 175/// API.
165#[test] 176#[test]
@@ -294,7 +305,7 @@ fn api_walkthrough() {
294 // To recursively process the tree, there are three approaches: 305 // To recursively process the tree, there are three approaches:
295 // 1. explicitly call getter methods on AST nodes. 306 // 1. explicitly call getter methods on AST nodes.
296 // 2. use descendants and `AstNode::cast`. 307 // 2. use descendants and `AstNode::cast`.
297 // 3. use descendants and the visitor. 308 // 3. use descendants and `match_ast!`.
298 // 309 //
299 // Here's how the first one looks like: 310 // Here's how the first one looks like:
300 let exprs_cast: Vec<String> = file 311 let exprs_cast: Vec<String> = file
@@ -304,17 +315,17 @@ fn api_walkthrough() {
304 .map(|expr| expr.syntax().text().to_string()) 315 .map(|expr| expr.syntax().text().to_string())
305 .collect(); 316 .collect();
306 317
307 // An alternative is to use a visitor. The visitor does not do traversal 318 // An alternative is to use a macro.
308 // automatically (so it's more akin to a generic lambda) and is constructed
309 // from closures. This seems more flexible than a single generated visitor
310 // trait.
311 use algo::visit::{visitor, Visitor};
312 let mut exprs_visit = Vec::new(); 319 let mut exprs_visit = Vec::new();
313 for node in file.syntax().descendants() { 320 for node in file.syntax().descendants() {
314 if let Some(result) = 321 match_ast! {
315 visitor().visit::<ast::Expr, _>(|expr| expr.syntax().text().to_string()).accept(&node) 322 match node {
316 { 323 ast::Expr(it) => {
317 exprs_visit.push(result); 324 let res = it.syntax().text().to_string();
325 exprs_visit.push(res);
326 },
327 _ => (),
328 }
318 } 329 }
319 } 330 }
320 assert_eq!(exprs_cast, exprs_visit); 331 assert_eq!(exprs_cast, exprs_visit);
diff --git a/crates/ra_syntax/src/parsing/lexer.rs b/crates/ra_syntax/src/parsing/lexer.rs
index bdb01d40b..6d839208d 100644
--- a/crates/ra_syntax/src/parsing/lexer.rs
+++ b/crates/ra_syntax/src/parsing/lexer.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1use crate::{ 3use crate::{
2 SyntaxKind::{self, *}, 4 SyntaxKind::{self, *},
3 TextUnit, 5 TextUnit,
diff --git a/crates/ra_syntax/src/parsing/text_token_source.rs b/crates/ra_syntax/src/parsing/text_token_source.rs
index 64cb20ae8..e793f93a4 100644
--- a/crates/ra_syntax/src/parsing/text_token_source.rs
+++ b/crates/ra_syntax/src/parsing/text_token_source.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1use ra_parser::Token as PToken; 3use ra_parser::Token as PToken;
2use ra_parser::TokenSource; 4use ra_parser::TokenSource;
3 5
diff --git a/crates/ra_syntax/src/parsing/text_tree_sink.rs b/crates/ra_syntax/src/parsing/text_tree_sink.rs
index be6e51780..142164316 100644
--- a/crates/ra_syntax/src/parsing/text_tree_sink.rs
+++ b/crates/ra_syntax/src/parsing/text_tree_sink.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1use std::mem; 3use std::mem;
2 4
3use ra_parser::{ParseError, TreeSink}; 5use ra_parser::{ParseError, TreeSink};
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs
index 992034ef0..31167cada 100644
--- a/crates/ra_syntax/src/ptr.rs
+++ b/crates/ra_syntax/src/ptr.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1use std::{iter::successors, marker::PhantomData}; 3use std::{iter::successors, marker::PhantomData};
2 4
3use crate::{AstNode, SyntaxKind, SyntaxNode, TextRange}; 5use crate::{AstNode, SyntaxKind, SyntaxNode, TextRange};
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs
index 5aefec768..d6eca2ad7 100644
--- a/crates/ra_syntax/src/syntax_error.rs
+++ b/crates/ra_syntax/src/syntax_error.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1use std::fmt; 3use std::fmt;
2 4
3use ra_parser::ParseError; 5use ra_parser::ParseError;
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
index 16824f3c4..ab4f15908 100644
--- a/crates/ra_syntax/src/validation.rs
+++ b/crates/ra_syntax/src/validation.rs
@@ -1,10 +1,11 @@
1//! FIXME: write short doc here
2
1mod block; 3mod block;
2 4
3use rustc_lexer::unescape; 5use rustc_lexer::unescape;
4 6
5use crate::{ 7use crate::{
6 algo::visit::{visitor_ctx, VisitorCtx}, 8 ast, match_ast, AstNode, SyntaxError, SyntaxErrorKind,
7 ast, AstNode, SyntaxError, SyntaxErrorKind,
8 SyntaxKind::{BYTE, BYTE_STRING, CHAR, INT_NUMBER, STRING}, 9 SyntaxKind::{BYTE, BYTE_STRING, CHAR, INT_NUMBER, STRING},
9 SyntaxNode, SyntaxToken, TextUnit, T, 10 SyntaxNode, SyntaxToken, TextUnit, T,
10}; 11};
@@ -95,12 +96,15 @@ impl From<rustc_lexer::unescape::EscapeError> for SyntaxErrorKind {
95pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { 96pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
96 let mut errors = Vec::new(); 97 let mut errors = Vec::new();
97 for node in root.descendants() { 98 for node in root.descendants() {
98 let _ = visitor_ctx(&mut errors) 99 match_ast! {
99 .visit::<ast::Literal, _>(validate_literal) 100 match node {
100 .visit::<ast::BlockExpr, _>(block::validate_block_expr) 101 ast::Literal(it) => { validate_literal(it, &mut errors) },
101 .visit::<ast::FieldExpr, _>(|it, errors| validate_numeric_name(it.name_ref(), errors)) 102 ast::BlockExpr(it) => { block::validate_block_expr(it, &mut errors) },
102 .visit::<ast::RecordField, _>(|it, errors| validate_numeric_name(it.name_ref(), errors)) 103 ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) },
103 .accept(&node); 104 ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) },
105 _ => (),
106 }
107 }
104 } 108 }
105 errors 109 errors
106} 110}
diff --git a/crates/ra_syntax/src/validation/block.rs b/crates/ra_syntax/src/validation/block.rs
index 3c9e96eb3..c85bbc1f4 100644
--- a/crates/ra_syntax/src/validation/block.rs
+++ b/crates/ra_syntax/src/validation/block.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1use crate::{ 3use crate::{
2 ast::{self, AstNode, AttrsOwner}, 4 ast::{self, AstNode, AttrsOwner},
3 SyntaxError, 5 SyntaxError,
diff --git a/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt b/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt
index 378b92834..7c1a23170 100644
--- a/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt
+++ b/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt
@@ -2,20 +2,22 @@ SOURCE_FILE@[0; 54)
2 FN_DEF@[0; 31) 2 FN_DEF@[0; 31)
3 ATTR@[0; 18) 3 ATTR@[0; 18)
4 POUND@[0; 1) "#" 4 POUND@[0; 1) "#"
5 TOKEN_TREE@[1; 18) 5 L_BRACK@[1; 2) "["
6 L_BRACK@[1; 2) "[" 6 PATH@[2; 5)
7 IDENT@[2; 5) "foo" 7 PATH_SEGMENT@[2; 5)
8 TOKEN_TREE@[5; 17) 8 NAME_REF@[2; 5)
9 L_PAREN@[5; 6) "(" 9 IDENT@[2; 5) "foo"
10 IDENT@[6; 9) "foo" 10 TOKEN_TREE@[5; 17)
11 COMMA@[9; 10) "," 11 L_PAREN@[5; 6) "("
12 WHITESPACE@[10; 11) " " 12 IDENT@[6; 9) "foo"
13 PLUS@[11; 12) "+" 13 COMMA@[9; 10) ","
14 COMMA@[12; 13) "," 14 WHITESPACE@[10; 11) " "
15 WHITESPACE@[13; 14) " " 15 PLUS@[11; 12) "+"
16 INT_NUMBER@[14; 16) "92" 16 COMMA@[12; 13) ","
17 R_PAREN@[16; 17) ")" 17 WHITESPACE@[13; 14) " "
18 R_BRACK@[17; 18) "]" 18 INT_NUMBER@[14; 16) "92"
19 R_PAREN@[16; 17) ")"
20 R_BRACK@[17; 18) "]"
19 WHITESPACE@[18; 19) "\n" 21 WHITESPACE@[18; 19) "\n"
20 FN_KW@[19; 21) "fn" 22 FN_KW@[19; 21) "fn"
21 WHITESPACE@[21; 22) " " 23 WHITESPACE@[21; 22) " "
@@ -33,24 +35,26 @@ SOURCE_FILE@[0; 54)
33 WHITESPACE@[31; 34) "\n\n\n" 35 WHITESPACE@[31; 34) "\n\n\n"
34 ATTR@[34; 53) 36 ATTR@[34; 53)
35 POUND@[34; 35) "#" 37 POUND@[34; 35) "#"
36 TOKEN_TREE@[35; 53) 38 L_BRACK@[35; 36) "["
37 L_BRACK@[35; 36) "[" 39 PATH@[36; 39)
38 IDENT@[36; 39) "foo" 40 PATH_SEGMENT@[36; 39)
39 TOKEN_TREE@[39; 53) 41 NAME_REF@[36; 39)
40 L_PAREN@[39; 40) "(" 42 IDENT@[36; 39) "foo"
41 WHITESPACE@[40; 41) "\n" 43 TOKEN_TREE@[39; 53)
42 FN_KW@[41; 43) "fn" 44 L_PAREN@[39; 40) "("
43 WHITESPACE@[43; 44) " " 45 WHITESPACE@[40; 41) "\n"
44 IDENT@[44; 47) "foo" 46 FN_KW@[41; 43) "fn"
45 TOKEN_TREE@[47; 49) 47 WHITESPACE@[43; 44) " "
46 L_PAREN@[47; 48) "(" 48 IDENT@[44; 47) "foo"
47 R_PAREN@[48; 49) ")" 49 TOKEN_TREE@[47; 49)
48 WHITESPACE@[49; 50) " " 50 L_PAREN@[47; 48) "("
49 TOKEN_TREE@[50; 53) 51 R_PAREN@[48; 49) ")"
50 L_CURLY@[50; 51) "{" 52 WHITESPACE@[49; 50) " "
51 WHITESPACE@[51; 52) "\n" 53 TOKEN_TREE@[50; 53)
52 R_CURLY@[52; 53) "}" 54 L_CURLY@[50; 51) "{"
55 WHITESPACE@[51; 52) "\n"
56 R_CURLY@[52; 53) "}"
53 WHITESPACE@[53; 54) "\n" 57 WHITESPACE@[53; 54) "\n"
54error 53: expected R_PAREN 58error 53: expected R_PAREN
55error 53: expected R_BRACK 59error 53: expected `]`
56error 53: expected an item 60error 53: expected an item
diff --git a/crates/ra_syntax/test_data/parser/err/0028_macro_2.0.txt b/crates/ra_syntax/test_data/parser/err/0028_macro_2.0.txt
index 73d322c48..c5be73a5a 100644
--- a/crates/ra_syntax/test_data/parser/err/0028_macro_2.0.txt
+++ b/crates/ra_syntax/test_data/parser/err/0028_macro_2.0.txt
@@ -60,10 +60,12 @@ SOURCE_FILE@[0; 349)
60 FN_DEF@[95; 348) 60 FN_DEF@[95; 348)
61 ATTR@[95; 102) 61 ATTR@[95; 102)
62 POUND@[95; 96) "#" 62 POUND@[95; 96) "#"
63 TOKEN_TREE@[96; 102) 63 L_BRACK@[96; 97) "["
64 L_BRACK@[96; 97) "[" 64 PATH@[97; 101)
65 IDENT@[97; 101) "test" 65 PATH_SEGMENT@[97; 101)
66 R_BRACK@[101; 102) "]" 66 NAME_REF@[97; 101)
67 IDENT@[97; 101) "test"
68 R_BRACK@[101; 102) "]"
67 WHITESPACE@[102; 103) "\n" 69 WHITESPACE@[102; 103) "\n"
68 FN_KW@[103; 105) "fn" 70 FN_KW@[103; 105) "fn"
69 WHITESPACE@[105; 106) " " 71 WHITESPACE@[105; 106) " "
diff --git a/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt b/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt
index f67325b76..522a0d0e0 100644
--- a/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt
@@ -28,14 +28,16 @@ SOURCE_FILE@[0; 350)
28 ATTR@[39; 83) 28 ATTR@[39; 83)
29 POUND@[39; 40) "#" 29 POUND@[39; 40) "#"
30 EXCL@[40; 41) "!" 30 EXCL@[40; 41) "!"
31 TOKEN_TREE@[41; 83) 31 L_BRACK@[41; 42) "["
32 L_BRACK@[41; 42) "[" 32 PATH@[42; 45)
33 IDENT@[42; 45) "doc" 33 PATH_SEGMENT@[42; 45)
34 TOKEN_TREE@[45; 82) 34 NAME_REF@[42; 45)
35 L_PAREN@[45; 46) "(" 35 IDENT@[42; 45) "doc"
36 STRING@[46; 81) "\"Inner attributes not ..." 36 TOKEN_TREE@[45; 82)
37 R_PAREN@[81; 82) ")" 37 L_PAREN@[45; 46) "("
38 R_BRACK@[82; 83) "]" 38 STRING@[46; 81) "\"Inner attributes not ..."
39 R_PAREN@[81; 82) ")"
40 R_BRACK@[82; 83) "]"
39 WHITESPACE@[83; 92) "\n " 41 WHITESPACE@[83; 92) "\n "
40 COMMENT@[92; 122) "//! Nor are ModuleDoc ..." 42 COMMENT@[92; 122) "//! Nor are ModuleDoc ..."
41 WHITESPACE@[122; 127) "\n " 43 WHITESPACE@[122; 127) "\n "
@@ -57,26 +59,30 @@ SOURCE_FILE@[0; 350)
57 ATTR@[152; 171) 59 ATTR@[152; 171)
58 POUND@[152; 153) "#" 60 POUND@[152; 153) "#"
59 EXCL@[153; 154) "!" 61 EXCL@[153; 154) "!"
60 TOKEN_TREE@[154; 171) 62 L_BRACK@[154; 155) "["
61 L_BRACK@[154; 155) "[" 63 PATH@[155; 158)
62 IDENT@[155; 158) "doc" 64 PATH_SEGMENT@[155; 158)
63 TOKEN_TREE@[158; 170) 65 NAME_REF@[155; 158)
64 L_PAREN@[158; 159) "(" 66 IDENT@[155; 158) "doc"
65 STRING@[159; 169) "\"Nor here\"" 67 TOKEN_TREE@[158; 170)
66 R_PAREN@[169; 170) ")" 68 L_PAREN@[158; 159) "("
67 R_BRACK@[170; 171) "]" 69 STRING@[159; 169) "\"Nor here\""
70 R_PAREN@[169; 170) ")"
71 R_BRACK@[170; 171) "]"
68 WHITESPACE@[171; 180) "\n " 72 WHITESPACE@[171; 180) "\n "
69 ATTR@[180; 212) 73 ATTR@[180; 212)
70 POUND@[180; 181) "#" 74 POUND@[180; 181) "#"
71 EXCL@[181; 182) "!" 75 EXCL@[181; 182) "!"
72 TOKEN_TREE@[182; 212) 76 L_BRACK@[182; 183) "["
73 L_BRACK@[182; 183) "[" 77 PATH@[183; 186)
74 IDENT@[183; 186) "doc" 78 PATH_SEGMENT@[183; 186)
75 TOKEN_TREE@[186; 211) 79 NAME_REF@[183; 186)
76 L_PAREN@[186; 187) "(" 80 IDENT@[183; 186) "doc"
77 STRING@[187; 210) "\"We error on each attr\"" 81 TOKEN_TREE@[186; 211)
78 R_PAREN@[210; 211) ")" 82 L_PAREN@[186; 187) "("
79 R_BRACK@[211; 212) "]" 83 STRING@[187; 210) "\"We error on each attr\""
84 R_PAREN@[210; 211) ")"
85 R_BRACK@[211; 212) "]"
80 WHITESPACE@[212; 221) "\n " 86 WHITESPACE@[212; 221) "\n "
81 COMMENT@[221; 251) "//! Nor are ModuleDoc ..." 87 COMMENT@[221; 251) "//! Nor are ModuleDoc ..."
82 WHITESPACE@[251; 256) "\n " 88 WHITESPACE@[251; 256) "\n "
@@ -96,14 +102,16 @@ SOURCE_FILE@[0; 350)
96 ATTR@[283; 302) 102 ATTR@[283; 302)
97 POUND@[283; 284) "#" 103 POUND@[283; 284) "#"
98 EXCL@[284; 285) "!" 104 EXCL@[284; 285) "!"
99 TOKEN_TREE@[285; 302) 105 L_BRACK@[285; 286) "["
100 L_BRACK@[285; 286) "[" 106 PATH@[286; 289)
101 IDENT@[286; 289) "doc" 107 PATH_SEGMENT@[286; 289)
102 TOKEN_TREE@[289; 301) 108 NAME_REF@[286; 289)
103 L_PAREN@[289; 290) "(" 109 IDENT@[286; 289) "doc"
104 STRING@[290; 300) "\"Nor here\"" 110 TOKEN_TREE@[289; 301)
105 R_PAREN@[300; 301) ")" 111 L_PAREN@[289; 290) "("
106 R_BRACK@[301; 302) "]" 112 STRING@[290; 300) "\"Nor here\""
113 R_PAREN@[300; 301) ")"
114 R_BRACK@[301; 302) "]"
107 WHITESPACE@[302; 311) "\n " 115 WHITESPACE@[302; 311) "\n "
108 COMMENT@[311; 341) "//! Nor are ModuleDoc ..." 116 COMMENT@[311; 341) "//! Nor are ModuleDoc ..."
109 WHITESPACE@[341; 346) "\n " 117 WHITESPACE@[341; 346) "\n "
diff --git a/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt b/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt
index 1344fcbc2..dbc0081ac 100644
--- a/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt
@@ -135,14 +135,16 @@ SOURCE_FILE@[0; 293)
135 MATCH_ARM@[210; 250) 135 MATCH_ARM@[210; 250)
136 ATTR@[210; 222) 136 ATTR@[210; 222)
137 POUND@[210; 211) "#" 137 POUND@[210; 211) "#"
138 TOKEN_TREE@[211; 222) 138 L_BRACK@[211; 212) "["
139 L_BRACK@[211; 212) "[" 139 PATH@[212; 215)
140 IDENT@[212; 215) "cfg" 140 PATH_SEGMENT@[212; 215)
141 TOKEN_TREE@[215; 221) 141 NAME_REF@[212; 215)
142 L_PAREN@[215; 216) "(" 142 IDENT@[212; 215) "cfg"
143 IDENT@[216; 220) "test" 143 TOKEN_TREE@[215; 221)
144 R_PAREN@[220; 221) ")" 144 L_PAREN@[215; 216) "("
145 R_BRACK@[221; 222) "]" 145 IDENT@[216; 220) "test"
146 R_PAREN@[220; 221) ")"
147 R_BRACK@[221; 222) "]"
146 WHITESPACE@[222; 231) "\n " 148 WHITESPACE@[222; 231) "\n "
147 ATTR@[231; 232) 149 ATTR@[231; 232)
148 POUND@[231; 232) "#" 150 POUND@[231; 232) "#"
diff --git a/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt b/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt
index b65cc3de3..fd5ccc3f2 100644
--- a/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt
@@ -47,14 +47,16 @@ SOURCE_FILE@[0; 89)
47 MATCH_ARM@[68; 80) 47 MATCH_ARM@[68; 80)
48 ATTR@[68; 80) 48 ATTR@[68; 80)
49 POUND@[68; 69) "#" 49 POUND@[68; 69) "#"
50 TOKEN_TREE@[69; 80) 50 L_BRACK@[69; 70) "["
51 L_BRACK@[69; 70) "[" 51 PATH@[70; 73)
52 IDENT@[70; 73) "cfg" 52 PATH_SEGMENT@[70; 73)
53 TOKEN_TREE@[73; 79) 53 NAME_REF@[70; 73)
54 L_PAREN@[73; 74) "(" 54 IDENT@[70; 73) "cfg"
55 IDENT@[74; 78) "test" 55 TOKEN_TREE@[73; 79)
56 R_PAREN@[78; 79) ")" 56 L_PAREN@[73; 74) "("
57 R_BRACK@[79; 80) "]" 57 IDENT@[74; 78) "test"
58 R_PAREN@[78; 79) ")"
59 R_BRACK@[79; 80) "]"
58 WHITESPACE@[80; 85) "\n " 60 WHITESPACE@[80; 85) "\n "
59 R_CURLY@[85; 86) "}" 61 R_CURLY@[85; 86) "}"
60 WHITESPACE@[86; 87) "\n" 62 WHITESPACE@[86; 87) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt b/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
index eab9f5b91..2ca5b8f32 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
@@ -15,10 +15,12 @@ SOURCE_FILE@[0; 48)
15 EXPR_STMT@[14; 25) 15 EXPR_STMT@[14; 25)
16 ATTR@[14; 18) 16 ATTR@[14; 18)
17 POUND@[14; 15) "#" 17 POUND@[14; 15) "#"
18 TOKEN_TREE@[15; 18) 18 L_BRACK@[15; 16) "["
19 L_BRACK@[15; 16) "[" 19 PATH@[16; 17)
20 IDENT@[16; 17) "A" 20 PATH_SEGMENT@[16; 17)
21 R_BRACK@[17; 18) "]" 21 NAME_REF@[16; 17)
22 IDENT@[16; 17) "A"
23 R_BRACK@[17; 18) "]"
22 WHITESPACE@[18; 19) " " 24 WHITESPACE@[18; 19) " "
23 BIN_EXPR@[19; 24) 25 BIN_EXPR@[19; 24)
24 LITERAL@[19; 20) 26 LITERAL@[19; 20)
@@ -33,10 +35,12 @@ SOURCE_FILE@[0; 48)
33 EXPR_STMT@[29; 45) 35 EXPR_STMT@[29; 45)
34 ATTR@[29; 33) 36 ATTR@[29; 33)
35 POUND@[29; 30) "#" 37 POUND@[29; 30) "#"
36 TOKEN_TREE@[30; 33) 38 L_BRACK@[30; 31) "["
37 L_BRACK@[30; 31) "[" 39 PATH@[31; 32)
38 IDENT@[31; 32) "B" 40 PATH_SEGMENT@[31; 32)
39 R_BRACK@[32; 33) "]" 41 NAME_REF@[31; 32)
42 IDENT@[31; 32) "B"
43 R_BRACK@[32; 33) "]"
40 WHITESPACE@[33; 34) " " 44 WHITESPACE@[33; 34) " "
41 IF_EXPR@[34; 44) 45 IF_EXPR@[34; 44)
42 IF_KW@[34; 36) "if" 46 IF_KW@[34; 36) "if"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rs b/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rs
index 293046a04..2f8188160 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rs
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rs
@@ -1,4 +1,5 @@
1fn foo() { 1fn foo() {
2 while true {}; 2 while true {};
3 while let Some(x) = it.next() {}; 3 while let Some(x) = it.next() {};
4 while { true } {};
4} 5}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt
index 9b43d624c..a6e14a114 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 70) 1SOURCE_FILE@[0; 93)
2 FN_DEF@[0; 69) 2 FN_DEF@[0; 92)
3 FN_KW@[0; 2) "fn" 3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " " 4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6) 5 NAME@[3; 6)
@@ -8,8 +8,8 @@ SOURCE_FILE@[0; 70)
8 L_PAREN@[6; 7) "(" 8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")" 9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " " 10 WHITESPACE@[8; 9) " "
11 BLOCK_EXPR@[9; 69) 11 BLOCK_EXPR@[9; 92)
12 BLOCK@[9; 69) 12 BLOCK@[9; 92)
13 L_CURLY@[9; 10) "{" 13 L_CURLY@[9; 10) "{"
14 WHITESPACE@[10; 15) "\n " 14 WHITESPACE@[10; 15) "\n "
15 EXPR_STMT@[15; 29) 15 EXPR_STMT@[15; 29)
@@ -64,6 +64,26 @@ SOURCE_FILE@[0; 70)
64 L_CURLY@[64; 65) "{" 64 L_CURLY@[64; 65) "{"
65 R_CURLY@[65; 66) "}" 65 R_CURLY@[65; 66) "}"
66 SEMI@[66; 67) ";" 66 SEMI@[66; 67) ";"
67 WHITESPACE@[67; 68) "\n" 67 WHITESPACE@[67; 72) "\n "
68 R_CURLY@[68; 69) "}" 68 EXPR_STMT@[72; 90)
69 WHITESPACE@[69; 70) "\n" 69 WHILE_EXPR@[72; 89)
70 WHILE_KW@[72; 77) "while"
71 WHITESPACE@[77; 78) " "
72 CONDITION@[78; 86)
73 BLOCK_EXPR@[78; 86)
74 BLOCK@[78; 86)
75 L_CURLY@[78; 79) "{"
76 WHITESPACE@[79; 80) " "
77 LITERAL@[80; 84)
78 TRUE_KW@[80; 84) "true"
79 WHITESPACE@[84; 85) " "
80 R_CURLY@[85; 86) "}"
81 WHITESPACE@[86; 87) " "
82 BLOCK_EXPR@[87; 89)
83 BLOCK@[87; 89)
84 L_CURLY@[87; 88) "{"
85 R_CURLY@[88; 89) "}"
86 SEMI@[89; 90) ";"
87 WHITESPACE@[90; 91) "\n"
88 R_CURLY@[91; 92) "}"
89 WHITESPACE@[92; 93) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt b/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt
index 56aeba768..731c31f76 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt
@@ -11,18 +11,20 @@ SOURCE_FILE@[0; 64)
11 RECORD_FIELD_DEF@[15; 60) 11 RECORD_FIELD_DEF@[15; 60)
12 ATTR@[15; 43) 12 ATTR@[15; 43)
13 POUND@[15; 16) "#" 13 POUND@[15; 16) "#"
14 TOKEN_TREE@[16; 43) 14 L_BRACK@[16; 17) "["
15 L_BRACK@[16; 17) "[" 15 PATH@[17; 22)
16 IDENT@[17; 22) "serde" 16 PATH_SEGMENT@[17; 22)
17 TOKEN_TREE@[22; 42) 17 NAME_REF@[17; 22)
18 L_PAREN@[22; 23) "(" 18 IDENT@[17; 22) "serde"
19 IDENT@[23; 27) "with" 19 TOKEN_TREE@[22; 42)
20 WHITESPACE@[27; 28) " " 20 L_PAREN@[22; 23) "("
21 EQ@[28; 29) "=" 21 IDENT@[23; 27) "with"
22 WHITESPACE@[29; 30) " " 22 WHITESPACE@[27; 28) " "
23 STRING@[30; 41) "\"url_serde\"" 23 EQ@[28; 29) "="
24 R_PAREN@[41; 42) ")" 24 WHITESPACE@[29; 30) " "
25 R_BRACK@[42; 43) "]" 25 STRING@[30; 41) "\"url_serde\""
26 R_PAREN@[41; 42) ")"
27 R_BRACK@[42; 43) "]"
26 WHITESPACE@[43; 48) "\n " 28 WHITESPACE@[43; 48) "\n "
27 VISIBILITY@[48; 51) 29 VISIBILITY@[48; 51)
28 PUB_KW@[48; 51) "pub" 30 PUB_KW@[48; 51) "pub"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rs b/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rs
index 4b0d9af89..40f227ba3 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rs
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rs
@@ -3,4 +3,5 @@ fn foo() {
3 if true {} else {}; 3 if true {} else {};
4 if true {} else if false {} else {}; 4 if true {} else if false {} else {};
5 if S {}; 5 if S {};
6 if { true } { } else { };
6} 7}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt
index 14ea91fd2..2ace3c8ee 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 107) 1SOURCE_FILE@[0; 137)
2 FN_DEF@[0; 106) 2 FN_DEF@[0; 136)
3 FN_KW@[0; 2) "fn" 3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " " 4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6) 5 NAME@[3; 6)
@@ -8,8 +8,8 @@ SOURCE_FILE@[0; 107)
8 L_PAREN@[6; 7) "(" 8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")" 9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " " 10 WHITESPACE@[8; 9) " "
11 BLOCK_EXPR@[9; 106) 11 BLOCK_EXPR@[9; 136)
12 BLOCK@[9; 106) 12 BLOCK@[9; 136)
13 L_CURLY@[9; 10) "{" 13 L_CURLY@[9; 10) "{"
14 WHITESPACE@[10; 15) "\n " 14 WHITESPACE@[10; 15) "\n "
15 EXPR_STMT@[15; 26) 15 EXPR_STMT@[15; 26)
@@ -98,6 +98,35 @@ SOURCE_FILE@[0; 107)
98 L_CURLY@[101; 102) "{" 98 L_CURLY@[101; 102) "{"
99 R_CURLY@[102; 103) "}" 99 R_CURLY@[102; 103) "}"
100 SEMI@[103; 104) ";" 100 SEMI@[103; 104) ";"
101 WHITESPACE@[104; 105) "\n" 101 WHITESPACE@[104; 109) "\n "
102 R_CURLY@[105; 106) "}" 102 EXPR_STMT@[109; 134)
103 WHITESPACE@[106; 107) "\n" 103 IF_EXPR@[109; 133)
104 IF_KW@[109; 111) "if"
105 WHITESPACE@[111; 112) " "
106 CONDITION@[112; 120)
107 BLOCK_EXPR@[112; 120)
108 BLOCK@[112; 120)
109 L_CURLY@[112; 113) "{"
110 WHITESPACE@[113; 114) " "
111 LITERAL@[114; 118)
112 TRUE_KW@[114; 118) "true"
113 WHITESPACE@[118; 119) " "
114 R_CURLY@[119; 120) "}"
115 WHITESPACE@[120; 121) " "
116 BLOCK_EXPR@[121; 124)
117 BLOCK@[121; 124)
118 L_CURLY@[121; 122) "{"
119 WHITESPACE@[122; 123) " "
120 R_CURLY@[123; 124) "}"
121 WHITESPACE@[124; 125) " "
122 ELSE_KW@[125; 129) "else"
123 WHITESPACE@[129; 130) " "
124 BLOCK_EXPR@[130; 133)
125 BLOCK@[130; 133)
126 L_CURLY@[130; 131) "{"
127 WHITESPACE@[131; 132) " "
128 R_CURLY@[132; 133) "}"
129 SEMI@[133; 134) ";"
130 WHITESPACE@[134; 135) "\n"
131 R_CURLY@[135; 136) "}"
132 WHITESPACE@[136; 137) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rs b/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rs
index c9205dfa3..c4021dc10 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rs
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rs
@@ -1,4 +1,6 @@
1fn foo() { 1fn foo() {
2 match () { }; 2 match () { };
3 match S {}; 3 match S {};
4 match { } { _ => () };
5 match { S {} } {};
4} 6}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt
index f62b6c6d5..0af668056 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 47) 1SOURCE_FILE@[0; 97)
2 FN_DEF@[0; 46) 2 FN_DEF@[0; 96)
3 FN_KW@[0; 2) "fn" 3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " " 4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6) 5 NAME@[3; 6)
@@ -8,8 +8,8 @@ SOURCE_FILE@[0; 47)
8 L_PAREN@[6; 7) "(" 8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")" 9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " " 10 WHITESPACE@[8; 9) " "
11 BLOCK_EXPR@[9; 46) 11 BLOCK_EXPR@[9; 96)
12 BLOCK@[9; 46) 12 BLOCK@[9; 96)
13 L_CURLY@[9; 10) "{" 13 L_CURLY@[9; 10) "{"
14 WHITESPACE@[10; 15) "\n " 14 WHITESPACE@[10; 15) "\n "
15 EXPR_STMT@[15; 28) 15 EXPR_STMT@[15; 28)
@@ -40,6 +40,57 @@ SOURCE_FILE@[0; 47)
40 L_CURLY@[41; 42) "{" 40 L_CURLY@[41; 42) "{"
41 R_CURLY@[42; 43) "}" 41 R_CURLY@[42; 43) "}"
42 SEMI@[43; 44) ";" 42 SEMI@[43; 44) ";"
43 WHITESPACE@[44; 45) "\n" 43 WHITESPACE@[44; 49) "\n "
44 R_CURLY@[45; 46) "}" 44 EXPR_STMT@[49; 71)
45 WHITESPACE@[46; 47) "\n" 45 MATCH_EXPR@[49; 70)
46 MATCH_KW@[49; 54) "match"
47 WHITESPACE@[54; 55) " "
48 BLOCK_EXPR@[55; 58)
49 BLOCK@[55; 58)
50 L_CURLY@[55; 56) "{"
51 WHITESPACE@[56; 57) " "
52 R_CURLY@[57; 58) "}"
53 WHITESPACE@[58; 59) " "
54 MATCH_ARM_LIST@[59; 70)
55 L_CURLY@[59; 60) "{"
56 WHITESPACE@[60; 61) " "
57 MATCH_ARM@[61; 68)
58 PLACEHOLDER_PAT@[61; 62)
59 UNDERSCORE@[61; 62) "_"
60 WHITESPACE@[62; 63) " "
61 FAT_ARROW@[63; 65) "=>"
62 WHITESPACE@[65; 66) " "
63 TUPLE_EXPR@[66; 68)
64 L_PAREN@[66; 67) "("
65 R_PAREN@[67; 68) ")"
66 WHITESPACE@[68; 69) " "
67 R_CURLY@[69; 70) "}"
68 SEMI@[70; 71) ";"
69 WHITESPACE@[71; 76) "\n "
70 EXPR_STMT@[76; 94)
71 MATCH_EXPR@[76; 93)
72 MATCH_KW@[76; 81) "match"
73 WHITESPACE@[81; 82) " "
74 BLOCK_EXPR@[82; 90)
75 BLOCK@[82; 90)
76 L_CURLY@[82; 83) "{"
77 WHITESPACE@[83; 84) " "
78 RECORD_LIT@[84; 88)
79 PATH@[84; 85)
80 PATH_SEGMENT@[84; 85)
81 NAME_REF@[84; 85)
82 IDENT@[84; 85) "S"
83 WHITESPACE@[85; 86) " "
84 RECORD_FIELD_LIST@[86; 88)
85 L_CURLY@[86; 87) "{"
86 R_CURLY@[87; 88) "}"
87 WHITESPACE@[88; 89) " "
88 R_CURLY@[89; 90) "}"
89 WHITESPACE@[90; 91) " "
90 MATCH_ARM_LIST@[91; 93)
91 L_CURLY@[91; 92) "{"
92 R_CURLY@[92; 93) "}"
93 SEMI@[93; 94) ";"
94 WHITESPACE@[94; 95) "\n"
95 R_CURLY@[95; 96) "}"
96 WHITESPACE@[96; 97) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rs b/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rs
index c39fe8e68..e7b7cfc6b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rs
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rs
@@ -1 +1,5 @@
1fn foo() { let x = 1..; } 1fn foo() {
2 let x = 1..;
3 match 1.. { _ => () };
4 match a.b()..S { _ => () };
5}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt b/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt
index f3c292f5e..9f8a6b0f6 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 26) 1SOURCE_FILE@[0; 89)
2 FN_DEF@[0; 25) 2 FN_DEF@[0; 88)
3 FN_KW@[0; 2) "fn" 3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " " 4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6) 5 NAME@[3; 6)
@@ -8,24 +8,89 @@ SOURCE_FILE@[0; 26)
8 L_PAREN@[6; 7) "(" 8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")" 9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " " 10 WHITESPACE@[8; 9) " "
11 BLOCK_EXPR@[9; 25) 11 BLOCK_EXPR@[9; 88)
12 BLOCK@[9; 25) 12 BLOCK@[9; 88)
13 L_CURLY@[9; 10) "{" 13 L_CURLY@[9; 10) "{"
14 WHITESPACE@[10; 11) " " 14 WHITESPACE@[10; 15) "\n "
15 LET_STMT@[11; 23) 15 LET_STMT@[15; 27)
16 LET_KW@[11; 14) "let" 16 LET_KW@[15; 18) "let"
17 WHITESPACE@[14; 15) " "
18 BIND_PAT@[15; 16)
19 NAME@[15; 16)
20 IDENT@[15; 16) "x"
21 WHITESPACE@[16; 17) " "
22 EQ@[17; 18) "="
23 WHITESPACE@[18; 19) " " 17 WHITESPACE@[18; 19) " "
24 RANGE_EXPR@[19; 22) 18 BIND_PAT@[19; 20)
25 LITERAL@[19; 20) 19 NAME@[19; 20)
26 INT_NUMBER@[19; 20) "1" 20 IDENT@[19; 20) "x"
27 DOTDOT@[20; 22) ".." 21 WHITESPACE@[20; 21) " "
28 SEMI@[22; 23) ";" 22 EQ@[21; 22) "="
29 WHITESPACE@[23; 24) " " 23 WHITESPACE@[22; 23) " "
30 R_CURLY@[24; 25) "}" 24 RANGE_EXPR@[23; 26)
31 WHITESPACE@[25; 26) "\n" 25 LITERAL@[23; 24)
26 INT_NUMBER@[23; 24) "1"
27 DOTDOT@[24; 26) ".."
28 SEMI@[26; 27) ";"
29 WHITESPACE@[27; 32) "\n "
30 EXPR_STMT@[32; 54)
31 MATCH_EXPR@[32; 53)
32 MATCH_KW@[32; 37) "match"
33 WHITESPACE@[37; 38) " "
34 RANGE_EXPR@[38; 41)
35 LITERAL@[38; 39)
36 INT_NUMBER@[38; 39) "1"
37 DOTDOT@[39; 41) ".."
38 WHITESPACE@[41; 42) " "
39 MATCH_ARM_LIST@[42; 53)
40 L_CURLY@[42; 43) "{"
41 WHITESPACE@[43; 44) " "
42 MATCH_ARM@[44; 51)
43 PLACEHOLDER_PAT@[44; 45)
44 UNDERSCORE@[44; 45) "_"
45 WHITESPACE@[45; 46) " "
46 FAT_ARROW@[46; 48) "=>"
47 WHITESPACE@[48; 49) " "
48 TUPLE_EXPR@[49; 51)
49 L_PAREN@[49; 50) "("
50 R_PAREN@[50; 51) ")"
51 WHITESPACE@[51; 52) " "
52 R_CURLY@[52; 53) "}"
53 SEMI@[53; 54) ";"
54 WHITESPACE@[54; 59) "\n "
55 EXPR_STMT@[59; 86)
56 MATCH_EXPR@[59; 85)
57 MATCH_KW@[59; 64) "match"
58 WHITESPACE@[64; 65) " "
59 RANGE_EXPR@[65; 73)
60 METHOD_CALL_EXPR@[65; 70)
61 PATH_EXPR@[65; 66)
62 PATH@[65; 66)
63 PATH_SEGMENT@[65; 66)
64 NAME_REF@[65; 66)
65 IDENT@[65; 66) "a"
66 DOT@[66; 67) "."
67 NAME_REF@[67; 68)
68 IDENT@[67; 68) "b"
69 ARG_LIST@[68; 70)
70 L_PAREN@[68; 69) "("
71 R_PAREN@[69; 70) ")"
72 DOTDOT@[70; 72) ".."
73 PATH_EXPR@[72; 73)
74 PATH@[72; 73)
75 PATH_SEGMENT@[72; 73)
76 NAME_REF@[72; 73)
77 IDENT@[72; 73) "S"
78 WHITESPACE@[73; 74) " "
79 MATCH_ARM_LIST@[74; 85)
80 L_CURLY@[74; 75) "{"
81 WHITESPACE@[75; 76) " "
82 MATCH_ARM@[76; 83)
83 PLACEHOLDER_PAT@[76; 77)
84 UNDERSCORE@[76; 77) "_"
85 WHITESPACE@[77; 78) " "
86 FAT_ARROW@[78; 80) "=>"
87 WHITESPACE@[80; 81) " "
88 TUPLE_EXPR@[81; 83)
89 L_PAREN@[81; 82) "("
90 R_PAREN@[82; 83) ")"
91 WHITESPACE@[83; 84) " "
92 R_CURLY@[84; 85) "}"
93 SEMI@[85; 86) ";"
94 WHITESPACE@[86; 87) "\n"
95 R_CURLY@[87; 88) "}"
96 WHITESPACE@[88; 89) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt b/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt
index cb6d9f76d..8fe15d8e2 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt
@@ -11,18 +11,20 @@ SOURCE_FILE@[0; 60)
11 TUPLE_FIELD_DEF@[15; 55) 11 TUPLE_FIELD_DEF@[15; 55)
12 ATTR@[15; 43) 12 ATTR@[15; 43)
13 POUND@[15; 16) "#" 13 POUND@[15; 16) "#"
14 TOKEN_TREE@[16; 43) 14 L_BRACK@[16; 17) "["
15 L_BRACK@[16; 17) "[" 15 PATH@[17; 22)
16 IDENT@[17; 22) "serde" 16 PATH_SEGMENT@[17; 22)
17 TOKEN_TREE@[22; 42) 17 NAME_REF@[17; 22)
18 L_PAREN@[22; 23) "(" 18 IDENT@[17; 22) "serde"
19 IDENT@[23; 27) "with" 19 TOKEN_TREE@[22; 42)
20 WHITESPACE@[27; 28) " " 20 L_PAREN@[22; 23) "("
21 EQ@[28; 29) "=" 21 IDENT@[23; 27) "with"
22 WHITESPACE@[29; 30) " " 22 WHITESPACE@[27; 28) " "
23 STRING@[30; 41) "\"url_serde\"" 23 EQ@[28; 29) "="
24 R_PAREN@[41; 42) ")" 24 WHITESPACE@[29; 30) " "
25 R_BRACK@[42; 43) "]" 25 STRING@[30; 41) "\"url_serde\""
26 R_PAREN@[41; 42) ")"
27 R_BRACK@[42; 43) "]"
26 WHITESPACE@[43; 48) "\n " 28 WHITESPACE@[43; 48) "\n "
27 VISIBILITY@[48; 51) 29 VISIBILITY@[48; 51)
28 PUB_KW@[48; 51) "pub" 30 PUB_KW@[48; 51) "pub"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt
index 0ef3eeb75..0e9e9b95b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt
@@ -25,14 +25,16 @@ SOURCE_FILE@[0; 94)
25 ATTR@[54; 91) 25 ATTR@[54; 91)
26 POUND@[54; 55) "#" 26 POUND@[54; 55) "#"
27 EXCL@[55; 56) "!" 27 EXCL@[55; 56) "!"
28 TOKEN_TREE@[56; 91) 28 L_BRACK@[56; 57) "["
29 L_BRACK@[56; 57) "[" 29 PATH@[57; 60)
30 IDENT@[57; 60) "doc" 30 PATH_SEGMENT@[57; 60)
31 TOKEN_TREE@[60; 90) 31 NAME_REF@[57; 60)
32 L_PAREN@[60; 61) "(" 32 IDENT@[57; 60) "doc"
33 STRING@[61; 89) "\"This is also a doc c ..." 33 TOKEN_TREE@[60; 90)
34 R_PAREN@[89; 90) ")" 34 L_PAREN@[60; 61) "("
35 R_BRACK@[90; 91) "]" 35 STRING@[61; 89) "\"This is also a doc c ..."
36 R_PAREN@[89; 90) ")"
37 R_BRACK@[90; 91) "]"
36 WHITESPACE@[91; 92) "\n" 38 WHITESPACE@[91; 92) "\n"
37 R_CURLY@[92; 93) "}" 39 R_CURLY@[92; 93) "}"
38 WHITESPACE@[93; 94) "\n" 40 WHITESPACE@[93; 94) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt b/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt
index 3bbeb62bc..640e0640f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt
@@ -25,38 +25,44 @@ SOURCE_FILE@[0; 139)
25 ATTR@[34; 60) 25 ATTR@[34; 60)
26 POUND@[34; 35) "#" 26 POUND@[34; 35) "#"
27 EXCL@[35; 36) "!" 27 EXCL@[35; 36) "!"
28 TOKEN_TREE@[36; 60) 28 L_BRACK@[36; 37) "["
29 L_BRACK@[36; 37) "[" 29 PATH@[37; 40)
30 IDENT@[37; 40) "doc" 30 PATH_SEGMENT@[37; 40)
31 TOKEN_TREE@[40; 59) 31 NAME_REF@[37; 40)
32 L_PAREN@[40; 41) "(" 32 IDENT@[37; 40) "doc"
33 STRING@[41; 58) "\"Inner attribute\"" 33 TOKEN_TREE@[40; 59)
34 R_PAREN@[58; 59) ")" 34 L_PAREN@[40; 41) "("
35 R_BRACK@[59; 60) "]" 35 STRING@[41; 58) "\"Inner attribute\""
36 R_PAREN@[58; 59) ")"
37 R_BRACK@[59; 60) "]"
36 WHITESPACE@[60; 69) "\n " 38 WHITESPACE@[60; 69) "\n "
37 ATTR@[69; 86) 39 ATTR@[69; 86)
38 POUND@[69; 70) "#" 40 POUND@[69; 70) "#"
39 EXCL@[70; 71) "!" 41 EXCL@[70; 71) "!"
40 TOKEN_TREE@[71; 86) 42 L_BRACK@[71; 72) "["
41 L_BRACK@[71; 72) "[" 43 PATH@[72; 75)
42 IDENT@[72; 75) "doc" 44 PATH_SEGMENT@[72; 75)
43 TOKEN_TREE@[75; 85) 45 NAME_REF@[72; 75)
44 L_PAREN@[75; 76) "(" 46 IDENT@[72; 75) "doc"
45 STRING@[76; 84) "\"Can be\"" 47 TOKEN_TREE@[75; 85)
46 R_PAREN@[84; 85) ")" 48 L_PAREN@[75; 76) "("
47 R_BRACK@[85; 86) "]" 49 STRING@[76; 84) "\"Can be\""
50 R_PAREN@[84; 85) ")"
51 R_BRACK@[85; 86) "]"
48 WHITESPACE@[86; 95) "\n " 52 WHITESPACE@[86; 95) "\n "
49 ATTR@[95; 113) 53 ATTR@[95; 113)
50 POUND@[95; 96) "#" 54 POUND@[95; 96) "#"
51 EXCL@[96; 97) "!" 55 EXCL@[96; 97) "!"
52 TOKEN_TREE@[97; 113) 56 L_BRACK@[97; 98) "["
53 L_BRACK@[97; 98) "[" 57 PATH@[98; 101)
54 IDENT@[98; 101) "doc" 58 PATH_SEGMENT@[98; 101)
55 TOKEN_TREE@[101; 112) 59 NAME_REF@[98; 101)
56 L_PAREN@[101; 102) "(" 60 IDENT@[98; 101) "doc"
57 STRING@[102; 111) "\"Stacked\"" 61 TOKEN_TREE@[101; 112)
58 R_PAREN@[111; 112) ")" 62 L_PAREN@[101; 102) "("
59 R_BRACK@[112; 113) "]" 63 STRING@[102; 111) "\"Stacked\""
64 R_PAREN@[111; 112) ")"
65 R_BRACK@[112; 113) "]"
60 WHITESPACE@[113; 122) "\n " 66 WHITESPACE@[113; 122) "\n "
61 MATCH_ARM@[122; 129) 67 MATCH_ARM@[122; 129)
62 PLACEHOLDER_PAT@[122; 123) 68 PLACEHOLDER_PAT@[122; 123)
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt
index 5fd0adfc2..ff380b448 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt
@@ -25,18 +25,20 @@ SOURCE_FILE@[0; 259)
25 MATCH_ARM@[34; 74) 25 MATCH_ARM@[34; 74)
26 ATTR@[34; 58) 26 ATTR@[34; 58)
27 POUND@[34; 35) "#" 27 POUND@[34; 35) "#"
28 TOKEN_TREE@[35; 58) 28 L_BRACK@[35; 36) "["
29 L_BRACK@[35; 36) "[" 29 PATH@[36; 39)
30 IDENT@[36; 39) "cfg" 30 PATH_SEGMENT@[36; 39)
31 TOKEN_TREE@[39; 57) 31 NAME_REF@[36; 39)
32 L_PAREN@[39; 40) "(" 32 IDENT@[36; 39) "cfg"
33 IDENT@[40; 47) "feature" 33 TOKEN_TREE@[39; 57)
34 WHITESPACE@[47; 48) " " 34 L_PAREN@[39; 40) "("
35 EQ@[48; 49) "=" 35 IDENT@[40; 47) "feature"
36 WHITESPACE@[49; 50) " " 36 WHITESPACE@[47; 48) " "
37 STRING@[50; 56) "\"some\"" 37 EQ@[48; 49) "="
38 R_PAREN@[56; 57) ")" 38 WHITESPACE@[49; 50) " "
39 R_BRACK@[57; 58) "]" 39 STRING@[50; 56) "\"some\""
40 R_PAREN@[56; 57) ")"
41 R_BRACK@[57; 58) "]"
40 WHITESPACE@[58; 67) "\n " 42 WHITESPACE@[58; 67) "\n "
41 PLACEHOLDER_PAT@[67; 68) 43 PLACEHOLDER_PAT@[67; 68)
42 UNDERSCORE@[67; 68) "_" 44 UNDERSCORE@[67; 68) "_"
@@ -51,18 +53,20 @@ SOURCE_FILE@[0; 259)
51 MATCH_ARM@[84; 125) 53 MATCH_ARM@[84; 125)
52 ATTR@[84; 109) 54 ATTR@[84; 109)
53 POUND@[84; 85) "#" 55 POUND@[84; 85) "#"
54 TOKEN_TREE@[85; 109) 56 L_BRACK@[85; 86) "["
55 L_BRACK@[85; 86) "[" 57 PATH@[86; 89)
56 IDENT@[86; 89) "cfg" 58 PATH_SEGMENT@[86; 89)
57 TOKEN_TREE@[89; 108) 59 NAME_REF@[86; 89)
58 L_PAREN@[89; 90) "(" 60 IDENT@[86; 89) "cfg"
59 IDENT@[90; 97) "feature" 61 TOKEN_TREE@[89; 108)
60 WHITESPACE@[97; 98) " " 62 L_PAREN@[89; 90) "("
61 EQ@[98; 99) "=" 63 IDENT@[90; 97) "feature"
62 WHITESPACE@[99; 100) " " 64 WHITESPACE@[97; 98) " "
63 STRING@[100; 107) "\"other\"" 65 EQ@[98; 99) "="
64 R_PAREN@[107; 108) ")" 66 WHITESPACE@[99; 100) " "
65 R_BRACK@[108; 109) "]" 67 STRING@[100; 107) "\"other\""
68 R_PAREN@[107; 108) ")"
69 R_BRACK@[108; 109) "]"
66 WHITESPACE@[109; 118) "\n " 70 WHITESPACE@[109; 118) "\n "
67 PLACEHOLDER_PAT@[118; 119) 71 PLACEHOLDER_PAT@[118; 119)
68 UNDERSCORE@[118; 119) "_" 72 UNDERSCORE@[118; 119) "_"
@@ -77,48 +81,54 @@ SOURCE_FILE@[0; 259)
77 MATCH_ARM@[135; 249) 81 MATCH_ARM@[135; 249)
78 ATTR@[135; 159) 82 ATTR@[135; 159)
79 POUND@[135; 136) "#" 83 POUND@[135; 136) "#"
80 TOKEN_TREE@[136; 159) 84 L_BRACK@[136; 137) "["
81 L_BRACK@[136; 137) "[" 85 PATH@[137; 140)
82 IDENT@[137; 140) "cfg" 86 PATH_SEGMENT@[137; 140)
83 TOKEN_TREE@[140; 158) 87 NAME_REF@[137; 140)
84 L_PAREN@[140; 141) "(" 88 IDENT@[137; 140) "cfg"
85 IDENT@[141; 148) "feature" 89 TOKEN_TREE@[140; 158)
86 WHITESPACE@[148; 149) " " 90 L_PAREN@[140; 141) "("
87 EQ@[149; 150) "=" 91 IDENT@[141; 148) "feature"
88 WHITESPACE@[150; 151) " " 92 WHITESPACE@[148; 149) " "
89 STRING@[151; 157) "\"many\"" 93 EQ@[149; 150) "="
90 R_PAREN@[157; 158) ")" 94 WHITESPACE@[150; 151) " "
91 R_BRACK@[158; 159) "]" 95 STRING@[151; 157) "\"many\""
96 R_PAREN@[157; 158) ")"
97 R_BRACK@[158; 159) "]"
92 WHITESPACE@[159; 168) "\n " 98 WHITESPACE@[159; 168) "\n "
93 ATTR@[168; 198) 99 ATTR@[168; 198)
94 POUND@[168; 169) "#" 100 POUND@[168; 169) "#"
95 TOKEN_TREE@[169; 198) 101 L_BRACK@[169; 170) "["
96 L_BRACK@[169; 170) "[" 102 PATH@[170; 173)
97 IDENT@[170; 173) "cfg" 103 PATH_SEGMENT@[170; 173)
98 TOKEN_TREE@[173; 197) 104 NAME_REF@[170; 173)
99 L_PAREN@[173; 174) "(" 105 IDENT@[170; 173) "cfg"
100 IDENT@[174; 181) "feature" 106 TOKEN_TREE@[173; 197)
101 WHITESPACE@[181; 182) " " 107 L_PAREN@[173; 174) "("
102 EQ@[182; 183) "=" 108 IDENT@[174; 181) "feature"
103 WHITESPACE@[183; 184) " " 109 WHITESPACE@[181; 182) " "
104 STRING@[184; 196) "\"attributes\"" 110 EQ@[182; 183) "="
105 R_PAREN@[196; 197) ")" 111 WHITESPACE@[183; 184) " "
106 R_BRACK@[197; 198) "]" 112 STRING@[184; 196) "\"attributes\""
113 R_PAREN@[196; 197) ")"
114 R_BRACK@[197; 198) "]"
107 WHITESPACE@[198; 207) "\n " 115 WHITESPACE@[198; 207) "\n "
108 ATTR@[207; 233) 116 ATTR@[207; 233)
109 POUND@[207; 208) "#" 117 POUND@[207; 208) "#"
110 TOKEN_TREE@[208; 233) 118 L_BRACK@[208; 209) "["
111 L_BRACK@[208; 209) "[" 119 PATH@[209; 212)
112 IDENT@[209; 212) "cfg" 120 PATH_SEGMENT@[209; 212)
113 TOKEN_TREE@[212; 232) 121 NAME_REF@[209; 212)
114 L_PAREN@[212; 213) "(" 122 IDENT@[209; 212) "cfg"
115 IDENT@[213; 220) "feature" 123 TOKEN_TREE@[212; 232)
116 WHITESPACE@[220; 221) " " 124 L_PAREN@[212; 213) "("
117 EQ@[221; 222) "=" 125 IDENT@[213; 220) "feature"
118 WHITESPACE@[222; 223) " " 126 WHITESPACE@[220; 221) " "
119 STRING@[223; 231) "\"before\"" 127 EQ@[221; 222) "="
120 R_PAREN@[231; 232) ")" 128 WHITESPACE@[222; 223) " "
121 R_BRACK@[232; 233) "]" 129 STRING@[223; 231) "\"before\""
130 R_PAREN@[231; 232) ")"
131 R_BRACK@[232; 233) "]"
122 WHITESPACE@[233; 242) "\n " 132 WHITESPACE@[233; 242) "\n "
123 PLACEHOLDER_PAT@[242; 243) 133 PLACEHOLDER_PAT@[242; 243)
124 UNDERSCORE@[242; 243) "_" 134 UNDERSCORE@[242; 243) "_"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt b/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt
index bc7b68b90..a73ff9c90 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt
@@ -9,14 +9,16 @@ SOURCE_FILE@[0; 64)
9 LIFETIME_PARAM@[7; 29) 9 LIFETIME_PARAM@[7; 29)
10 ATTR@[7; 26) 10 ATTR@[7; 26)
11 POUND@[7; 8) "#" 11 POUND@[7; 8) "#"
12 TOKEN_TREE@[8; 26) 12 L_BRACK@[8; 9) "["
13 L_BRACK@[8; 9) "[" 13 PATH@[9; 15)
14 IDENT@[9; 15) "derive" 14 PATH_SEGMENT@[9; 15)
15 TOKEN_TREE@[15; 25) 15 NAME_REF@[9; 15)
16 L_PAREN@[15; 16) "(" 16 IDENT@[9; 15) "derive"
17 IDENT@[16; 24) "Lifetime" 17 TOKEN_TREE@[15; 25)
18 R_PAREN@[24; 25) ")" 18 L_PAREN@[15; 16) "("
19 R_BRACK@[25; 26) "]" 19 IDENT@[16; 24) "Lifetime"
20 R_PAREN@[24; 25) ")"
21 R_BRACK@[25; 26) "]"
20 WHITESPACE@[26; 27) " " 22 WHITESPACE@[26; 27) " "
21 LIFETIME@[27; 29) "\'a" 23 LIFETIME@[27; 29) "\'a"
22 COMMA@[29; 30) "," 24 COMMA@[29; 30) ","
@@ -24,14 +26,16 @@ SOURCE_FILE@[0; 64)
24 TYPE_PARAM@[31; 48) 26 TYPE_PARAM@[31; 48)
25 ATTR@[31; 46) 27 ATTR@[31; 46)
26 POUND@[31; 32) "#" 28 POUND@[31; 32) "#"
27 TOKEN_TREE@[32; 46) 29 L_BRACK@[32; 33) "["
28 L_BRACK@[32; 33) "[" 30 PATH@[33; 39)
29 IDENT@[33; 39) "derive" 31 PATH_SEGMENT@[33; 39)
30 TOKEN_TREE@[39; 45) 32 NAME_REF@[33; 39)
31 L_PAREN@[39; 40) "(" 33 IDENT@[33; 39) "derive"
32 IDENT@[40; 44) "Type" 34 TOKEN_TREE@[39; 45)
33 R_PAREN@[44; 45) ")" 35 L_PAREN@[39; 40) "("
34 R_BRACK@[45; 46) "]" 36 IDENT@[40; 44) "Type"
37 R_PAREN@[44; 45) ")"
38 R_BRACK@[45; 46) "]"
35 WHITESPACE@[46; 47) " " 39 WHITESPACE@[46; 47) " "
36 NAME@[47; 48) 40 NAME@[47; 48)
37 IDENT@[47; 48) "T" 41 IDENT@[47; 48) "T"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt
index 37cc438d9..a36c3df0e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt
@@ -24,14 +24,16 @@ SOURCE_FILE@[0; 46)
24 RECORD_FIELD@[20; 41) 24 RECORD_FIELD@[20; 41)
25 ATTR@[20; 32) 25 ATTR@[20; 32)
26 POUND@[20; 21) "#" 26 POUND@[20; 21) "#"
27 TOKEN_TREE@[21; 32) 27 L_BRACK@[21; 22) "["
28 L_BRACK@[21; 22) "[" 28 PATH@[22; 25)
29 IDENT@[22; 25) "cfg" 29 PATH_SEGMENT@[22; 25)
30 TOKEN_TREE@[25; 31) 30 NAME_REF@[22; 25)
31 L_PAREN@[25; 26) "(" 31 IDENT@[22; 25) "cfg"
32 IDENT@[26; 30) "test" 32 TOKEN_TREE@[25; 31)
33 R_PAREN@[30; 31) ")" 33 L_PAREN@[25; 26) "("
34 R_BRACK@[31; 32) "]" 34 IDENT@[26; 30) "test"
35 R_PAREN@[30; 31) ")"
36 R_BRACK@[31; 32) "]"
35 WHITESPACE@[32; 33) " " 37 WHITESPACE@[32; 33) " "
36 NAME_REF@[33; 38) 38 NAME_REF@[33; 38)
37 IDENT@[33; 38) "field" 39 IDENT@[33; 38) "field"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt b/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt
index 6bc0db077..5c311d18a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt
@@ -15,10 +15,12 @@ SOURCE_FILE@[0; 82)
15 EXPR_STMT@[15; 26) 15 EXPR_STMT@[15; 26)
16 ATTR@[15; 19) 16 ATTR@[15; 19)
17 POUND@[15; 16) "#" 17 POUND@[15; 16) "#"
18 TOKEN_TREE@[16; 19) 18 L_BRACK@[16; 17) "["
19 L_BRACK@[16; 17) "[" 19 PATH@[17; 18)
20 IDENT@[17; 18) "A" 20 PATH_SEGMENT@[17; 18)
21 R_BRACK@[18; 19) "]" 21 NAME_REF@[17; 18)
22 IDENT@[17; 18) "A"
23 R_BRACK@[18; 19) "]"
22 WHITESPACE@[19; 20) " " 24 WHITESPACE@[19; 20) " "
23 CALL_EXPR@[20; 25) 25 CALL_EXPR@[20; 25)
24 PATH_EXPR@[20; 23) 26 PATH_EXPR@[20; 23)
@@ -34,10 +36,12 @@ SOURCE_FILE@[0; 82)
34 EXPR_STMT@[31; 42) 36 EXPR_STMT@[31; 42)
35 ATTR@[31; 35) 37 ATTR@[31; 35)
36 POUND@[31; 32) "#" 38 POUND@[31; 32) "#"
37 TOKEN_TREE@[32; 35) 39 L_BRACK@[32; 33) "["
38 L_BRACK@[32; 33) "[" 40 PATH@[33; 34)
39 IDENT@[33; 34) "B" 41 PATH_SEGMENT@[33; 34)
40 R_BRACK@[34; 35) "]" 42 NAME_REF@[33; 34)
43 IDENT@[33; 34) "B"
44 R_BRACK@[34; 35) "]"
41 WHITESPACE@[35; 36) " " 45 WHITESPACE@[35; 36) " "
42 MACRO_CALL@[36; 42) 46 MACRO_CALL@[36; 42)
43 PATH@[36; 39) 47 PATH@[36; 39)
@@ -52,17 +56,21 @@ SOURCE_FILE@[0; 82)
52 EXPR_STMT@[47; 59) 56 EXPR_STMT@[47; 59)
53 ATTR@[47; 51) 57 ATTR@[47; 51)
54 POUND@[47; 48) "#" 58 POUND@[47; 48) "#"
55 TOKEN_TREE@[48; 51) 59 L_BRACK@[48; 49) "["
56 L_BRACK@[48; 49) "[" 60 PATH@[49; 50)
57 IDENT@[49; 50) "C" 61 PATH_SEGMENT@[49; 50)
58 R_BRACK@[50; 51) "]" 62 NAME_REF@[49; 50)
63 IDENT@[49; 50) "C"
64 R_BRACK@[50; 51) "]"
59 WHITESPACE@[51; 52) " " 65 WHITESPACE@[51; 52) " "
60 ATTR@[52; 56) 66 ATTR@[52; 56)
61 POUND@[52; 53) "#" 67 POUND@[52; 53) "#"
62 TOKEN_TREE@[53; 56) 68 L_BRACK@[53; 54) "["
63 L_BRACK@[53; 54) "[" 69 PATH@[54; 55)
64 IDENT@[54; 55) "D" 70 PATH_SEGMENT@[54; 55)
65 R_BRACK@[55; 56) "]" 71 NAME_REF@[54; 55)
72 IDENT@[54; 55) "D"
73 R_BRACK@[55; 56) "]"
66 WHITESPACE@[56; 57) " " 74 WHITESPACE@[56; 57) " "
67 BLOCK_EXPR@[57; 59) 75 BLOCK_EXPR@[57; 59)
68 BLOCK@[57; 59) 76 BLOCK@[57; 59)
@@ -72,10 +80,12 @@ SOURCE_FILE@[0; 82)
72 EXPR_STMT@[64; 79) 80 EXPR_STMT@[64; 79)
73 ATTR@[64; 68) 81 ATTR@[64; 68)
74 POUND@[64; 65) "#" 82 POUND@[64; 65) "#"
75 TOKEN_TREE@[65; 68) 83 L_BRACK@[65; 66) "["
76 L_BRACK@[65; 66) "[" 84 PATH@[66; 67)
77 IDENT@[66; 67) "D" 85 PATH_SEGMENT@[66; 67)
78 R_BRACK@[67; 68) "]" 86 NAME_REF@[66; 67)
87 IDENT@[66; 67) "D"
88 R_BRACK@[67; 68) "]"
79 WHITESPACE@[68; 69) " " 89 WHITESPACE@[68; 69) " "
80 RETURN_EXPR@[69; 78) 90 RETURN_EXPR@[69; 78)
81 RETURN_KW@[69; 75) "return" 91 RETURN_KW@[69; 75) "return"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt
index c201196ec..21f49690a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt
@@ -20,10 +20,12 @@ SOURCE_FILE@[0; 47)
20 TRY_EXPR@[17; 29) 20 TRY_EXPR@[17; 29)
21 ATTR@[17; 21) 21 ATTR@[17; 21)
22 POUND@[17; 18) "#" 22 POUND@[17; 18) "#"
23 TOKEN_TREE@[18; 21) 23 L_BRACK@[18; 19) "["
24 L_BRACK@[18; 19) "[" 24 PATH@[19; 20)
25 IDENT@[19; 20) "A" 25 PATH_SEGMENT@[19; 20)
26 R_BRACK@[20; 21) "]" 26 NAME_REF@[19; 20)
27 IDENT@[19; 20) "A"
28 R_BRACK@[20; 21) "]"
27 WHITESPACE@[21; 22) " " 29 WHITESPACE@[21; 22) " "
28 MACRO_CALL@[22; 28) 30 MACRO_CALL@[22; 28)
29 PATH@[22; 25) 31 PATH@[22; 25)
@@ -41,10 +43,12 @@ SOURCE_FILE@[0; 47)
41 REF_EXPR@[36; 44) 43 REF_EXPR@[36; 44)
42 ATTR@[36; 40) 44 ATTR@[36; 40)
43 POUND@[36; 37) "#" 45 POUND@[36; 37) "#"
44 TOKEN_TREE@[37; 40) 46 L_BRACK@[37; 38) "["
45 L_BRACK@[37; 38) "[" 47 PATH@[38; 39)
46 IDENT@[38; 39) "B" 48 PATH_SEGMENT@[38; 39)
47 R_BRACK@[39; 40) "]" 49 NAME_REF@[38; 39)
50 IDENT@[38; 39) "B"
51 R_BRACK@[39; 40) "]"
48 WHITESPACE@[40; 41) " " 52 WHITESPACE@[40; 41) " "
49 AMP@[41; 42) "&" 53 AMP@[41; 42) "&"
50 TUPLE_EXPR@[42; 44) 54 TUPLE_EXPR@[42; 44)
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt
index eac4f6f30..8f2e91bdf 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt
@@ -29,14 +29,16 @@ SOURCE_FILE@[0; 56)
29 WHITESPACE@[24; 28) "\n " 29 WHITESPACE@[24; 28) "\n "
30 ATTR@[28; 40) 30 ATTR@[28; 40)
31 POUND@[28; 29) "#" 31 POUND@[28; 29) "#"
32 TOKEN_TREE@[29; 40) 32 L_BRACK@[29; 30) "["
33 L_BRACK@[29; 30) "[" 33 PATH@[30; 33)
34 IDENT@[30; 33) "cfg" 34 PATH_SEGMENT@[30; 33)
35 TOKEN_TREE@[33; 39) 35 NAME_REF@[30; 33)
36 L_PAREN@[33; 34) "(" 36 IDENT@[30; 33) "cfg"
37 IDENT@[34; 38) "test" 37 TOKEN_TREE@[33; 39)
38 R_PAREN@[38; 39) ")" 38 L_PAREN@[33; 34) "("
39 R_BRACK@[39; 40) "]" 39 IDENT@[34; 38) "test"
40 R_PAREN@[38; 39) ")"
41 R_BRACK@[39; 40) "]"
40 WHITESPACE@[40; 44) "\n " 42 WHITESPACE@[40; 44) "\n "
41 LITERAL@[44; 45) 43 LITERAL@[44; 45)
42 INT_NUMBER@[44; 45) "1" 44 INT_NUMBER@[44; 45) "1"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
index 6fa1b42d9..41914eb8e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
@@ -33,14 +33,16 @@ SOURCE_FILE@[0; 56)
33 WHITESPACE@[30; 34) "\n " 33 WHITESPACE@[30; 34) "\n "
34 ATTR@[34; 46) 34 ATTR@[34; 46)
35 POUND@[34; 35) "#" 35 POUND@[34; 35) "#"
36 TOKEN_TREE@[35; 46) 36 L_BRACK@[35; 36) "["
37 L_BRACK@[35; 36) "[" 37 PATH@[36; 39)
38 IDENT@[36; 39) "cfg" 38 PATH_SEGMENT@[36; 39)
39 TOKEN_TREE@[39; 45) 39 NAME_REF@[36; 39)
40 L_PAREN@[39; 40) "(" 40 IDENT@[36; 39) "cfg"
41 IDENT@[40; 44) "test" 41 TOKEN_TREE@[39; 45)
42 R_PAREN@[44; 45) ")" 42 L_PAREN@[39; 40) "("
43 R_BRACK@[45; 46) "]" 43 IDENT@[40; 44) "test"
44 R_PAREN@[44; 45) ")"
45 R_BRACK@[45; 46) "]"
44 WHITESPACE@[46; 50) "\n " 46 WHITESPACE@[46; 50) "\n "
45 LITERAL@[50; 51) 47 LITERAL@[50; 51)
46 INT_NUMBER@[50; 51) "2" 48 INT_NUMBER@[50; 51) "2"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt
index 708fa4773..e627b9746 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt
@@ -8,10 +8,12 @@ SOURCE_FILE@[0; 26)
8 L_PAREN@[4; 5) "(" 8 L_PAREN@[4; 5) "("
9 ATTR@[5; 16) 9 ATTR@[5; 16)
10 POUND@[5; 6) "#" 10 POUND@[5; 6) "#"
11 TOKEN_TREE@[6; 16) 11 L_BRACK@[6; 7) "["
12 L_BRACK@[6; 7) "[" 12 PATH@[7; 15)
13 IDENT@[7; 15) "must_use" 13 PATH_SEGMENT@[7; 15)
14 R_BRACK@[15; 16) "]" 14 NAME_REF@[7; 15)
15 IDENT@[7; 15) "must_use"
16 R_BRACK@[15; 16) "]"
15 WHITESPACE@[16; 17) " " 17 WHITESPACE@[16; 17) " "
16 SELF_PARAM@[17; 21) 18 SELF_PARAM@[17; 21)
17 SELF_KW@[17; 21) "self" 19 SELF_KW@[17; 21) "self"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt
index 9c0a0d20b..cf202c94b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt
@@ -8,10 +8,12 @@ SOURCE_FILE@[0; 28)
8 L_PAREN@[4; 5) "(" 8 L_PAREN@[4; 5) "("
9 ATTR@[5; 13) 9 ATTR@[5; 13)
10 POUND@[5; 6) "#" 10 POUND@[5; 6) "#"
11 TOKEN_TREE@[6; 13) 11 L_BRACK@[6; 7) "["
12 L_BRACK@[6; 7) "[" 12 PATH@[7; 12)
13 IDENT@[7; 12) "attr1" 13 PATH_SEGMENT@[7; 12)
14 R_BRACK@[12; 13) "]" 14 NAME_REF@[7; 12)
15 IDENT@[7; 12) "attr1"
16 R_BRACK@[12; 13) "]"
15 WHITESPACE@[13; 14) " " 17 WHITESPACE@[13; 14) " "
16 PARAM@[14; 23) 18 PARAM@[14; 23)
17 BIND_PAT@[14; 17) 19 BIND_PAT@[14; 17)
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rs b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rs
new file mode 100644
index 000000000..a06dec1fa
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rs
@@ -0,0 +1,3 @@
1fn foo() {
2 let _ = &1 as *const i32;
3}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.txt b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.txt
new file mode 100644
index 000000000..9e3767fb7
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.txt
@@ -0,0 +1,43 @@
1SOURCE_FILE@[0; 43)
2 FN_DEF@[0; 42)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " "
11 BLOCK_EXPR@[9; 42)
12 BLOCK@[9; 42)
13 L_CURLY@[9; 10) "{"
14 WHITESPACE@[10; 15) "\n "
15 LET_STMT@[15; 40)
16 LET_KW@[15; 18) "let"
17 WHITESPACE@[18; 19) " "
18 PLACEHOLDER_PAT@[19; 20)
19 UNDERSCORE@[19; 20) "_"
20 WHITESPACE@[20; 21) " "
21 EQ@[21; 22) "="
22 WHITESPACE@[22; 23) " "
23 CAST_EXPR@[23; 39)
24 REF_EXPR@[23; 25)
25 AMP@[23; 24) "&"
26 LITERAL@[24; 25)
27 INT_NUMBER@[24; 25) "1"
28 WHITESPACE@[25; 26) " "
29 AS_KW@[26; 28) "as"
30 WHITESPACE@[28; 29) " "
31 POINTER_TYPE@[29; 39)
32 STAR@[29; 30) "*"
33 CONST_KW@[30; 35) "const"
34 WHITESPACE@[35; 36) " "
35 PATH_TYPE@[36; 39)
36 PATH@[36; 39)
37 PATH_SEGMENT@[36; 39)
38 NAME_REF@[36; 39)
39 IDENT@[36; 39) "i32"
40 SEMI@[39; 40) ";"
41 WHITESPACE@[40; 41) "\n"
42 R_CURLY@[41; 42) "}"
43 WHITESPACE@[42; 43) "\n"
diff --git a/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt b/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt
index d8cabc9af..d72b72561 100644
--- a/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt
@@ -2,163 +2,183 @@ SOURCE_FILE@[0; 236)
2 ATTR@[0; 8) 2 ATTR@[0; 8)
3 POUND@[0; 1) "#" 3 POUND@[0; 1) "#"
4 EXCL@[1; 2) "!" 4 EXCL@[1; 2) "!"
5 TOKEN_TREE@[2; 8) 5 L_BRACK@[2; 3) "["
6 L_BRACK@[2; 3) "[" 6 PATH@[3; 7)
7 IDENT@[3; 7) "attr" 7 PATH_SEGMENT@[3; 7)
8 R_BRACK@[7; 8) "]" 8 NAME_REF@[3; 7)
9 IDENT@[3; 7) "attr"
10 R_BRACK@[7; 8) "]"
9 WHITESPACE@[8; 9) "\n" 11 WHITESPACE@[8; 9) "\n"
10 ATTR@[9; 23) 12 ATTR@[9; 23)
11 POUND@[9; 10) "#" 13 POUND@[9; 10) "#"
12 EXCL@[10; 11) "!" 14 EXCL@[10; 11) "!"
13 TOKEN_TREE@[11; 23) 15 L_BRACK@[11; 12) "["
14 L_BRACK@[11; 12) "[" 16 PATH@[12; 16)
15 IDENT@[12; 16) "attr" 17 PATH_SEGMENT@[12; 16)
16 TOKEN_TREE@[16; 22) 18 NAME_REF@[12; 16)
17 L_PAREN@[16; 17) "(" 19 IDENT@[12; 16) "attr"
18 TRUE_KW@[17; 21) "true" 20 TOKEN_TREE@[16; 22)
19 R_PAREN@[21; 22) ")" 21 L_PAREN@[16; 17) "("
20 R_BRACK@[22; 23) "]" 22 TRUE_KW@[17; 21) "true"
23 R_PAREN@[21; 22) ")"
24 R_BRACK@[22; 23) "]"
21 WHITESPACE@[23; 24) "\n" 25 WHITESPACE@[23; 24) "\n"
22 ATTR@[24; 39) 26 ATTR@[24; 39)
23 POUND@[24; 25) "#" 27 POUND@[24; 25) "#"
24 EXCL@[25; 26) "!" 28 EXCL@[25; 26) "!"
25 TOKEN_TREE@[26; 39) 29 L_BRACK@[26; 27) "["
26 L_BRACK@[26; 27) "[" 30 PATH@[27; 31)
27 IDENT@[27; 31) "attr" 31 PATH_SEGMENT@[27; 31)
28 TOKEN_TREE@[31; 38) 32 NAME_REF@[27; 31)
29 L_PAREN@[31; 32) "(" 33 IDENT@[27; 31) "attr"
30 IDENT@[32; 37) "ident" 34 TOKEN_TREE@[31; 38)
31 R_PAREN@[37; 38) ")" 35 L_PAREN@[31; 32) "("
32 R_BRACK@[38; 39) "]" 36 IDENT@[32; 37) "ident"
37 R_PAREN@[37; 38) ")"
38 R_BRACK@[38; 39) "]"
33 WHITESPACE@[39; 40) "\n" 39 WHITESPACE@[39; 40) "\n"
34 ATTR@[40; 116) 40 ATTR@[40; 116)
35 POUND@[40; 41) "#" 41 POUND@[40; 41) "#"
36 EXCL@[41; 42) "!" 42 EXCL@[41; 42) "!"
37 TOKEN_TREE@[42; 116) 43 L_BRACK@[42; 43) "["
38 L_BRACK@[42; 43) "[" 44 PATH@[43; 47)
39 IDENT@[43; 47) "attr" 45 PATH_SEGMENT@[43; 47)
40 TOKEN_TREE@[47; 115) 46 NAME_REF@[43; 47)
41 L_PAREN@[47; 48) "(" 47 IDENT@[43; 47) "attr"
42 IDENT@[48; 53) "ident" 48 TOKEN_TREE@[47; 115)
43 COMMA@[53; 54) "," 49 L_PAREN@[47; 48) "("
44 WHITESPACE@[54; 55) " " 50 IDENT@[48; 53) "ident"
45 INT_NUMBER@[55; 58) "100" 51 COMMA@[53; 54) ","
46 COMMA@[58; 59) "," 52 WHITESPACE@[54; 55) " "
47 WHITESPACE@[59; 60) " " 53 INT_NUMBER@[55; 58) "100"
48 TRUE_KW@[60; 64) "true" 54 COMMA@[58; 59) ","
49 COMMA@[64; 65) "," 55 WHITESPACE@[59; 60) " "
50 WHITESPACE@[65; 66) " " 56 TRUE_KW@[60; 64) "true"
51 STRING@[66; 72) "\"true\"" 57 COMMA@[64; 65) ","
52 COMMA@[72; 73) "," 58 WHITESPACE@[65; 66) " "
53 WHITESPACE@[73; 74) " " 59 STRING@[66; 72) "\"true\""
54 IDENT@[74; 79) "ident" 60 COMMA@[72; 73) ","
55 WHITESPACE@[79; 80) " " 61 WHITESPACE@[73; 74) " "
56 EQ@[80; 81) "=" 62 IDENT@[74; 79) "ident"
57 WHITESPACE@[81; 82) " " 63 WHITESPACE@[79; 80) " "
58 INT_NUMBER@[82; 85) "100" 64 EQ@[80; 81) "="
59 COMMA@[85; 86) "," 65 WHITESPACE@[81; 82) " "
60 WHITESPACE@[86; 87) " " 66 INT_NUMBER@[82; 85) "100"
61 IDENT@[87; 92) "ident" 67 COMMA@[85; 86) ","
62 WHITESPACE@[92; 93) " " 68 WHITESPACE@[86; 87) " "
63 EQ@[93; 94) "=" 69 IDENT@[87; 92) "ident"
64 WHITESPACE@[94; 95) " " 70 WHITESPACE@[92; 93) " "
65 STRING@[95; 102) "\"hello\"" 71 EQ@[93; 94) "="
66 COMMA@[102; 103) "," 72 WHITESPACE@[94; 95) " "
67 WHITESPACE@[103; 104) " " 73 STRING@[95; 102) "\"hello\""
68 IDENT@[104; 109) "ident" 74 COMMA@[102; 103) ","
69 TOKEN_TREE@[109; 114) 75 WHITESPACE@[103; 104) " "
70 L_PAREN@[109; 110) "(" 76 IDENT@[104; 109) "ident"
71 INT_NUMBER@[110; 113) "100" 77 TOKEN_TREE@[109; 114)
72 R_PAREN@[113; 114) ")" 78 L_PAREN@[109; 110) "("
73 R_PAREN@[114; 115) ")" 79 INT_NUMBER@[110; 113) "100"
74 R_BRACK@[115; 116) "]" 80 R_PAREN@[113; 114) ")"
81 R_PAREN@[114; 115) ")"
82 R_BRACK@[115; 116) "]"
75 WHITESPACE@[116; 117) "\n" 83 WHITESPACE@[116; 117) "\n"
76 ATTR@[117; 130) 84 ATTR@[117; 130)
77 POUND@[117; 118) "#" 85 POUND@[117; 118) "#"
78 EXCL@[118; 119) "!" 86 EXCL@[118; 119) "!"
79 TOKEN_TREE@[119; 130) 87 L_BRACK@[119; 120) "["
80 L_BRACK@[119; 120) "[" 88 PATH@[120; 124)
81 IDENT@[120; 124) "attr" 89 PATH_SEGMENT@[120; 124)
82 TOKEN_TREE@[124; 129) 90 NAME_REF@[120; 124)
83 L_PAREN@[124; 125) "(" 91 IDENT@[120; 124) "attr"
84 INT_NUMBER@[125; 128) "100" 92 TOKEN_TREE@[124; 129)
85 R_PAREN@[128; 129) ")" 93 L_PAREN@[124; 125) "("
86 R_BRACK@[129; 130) "]" 94 INT_NUMBER@[125; 128) "100"
95 R_PAREN@[128; 129) ")"
96 R_BRACK@[129; 130) "]"
87 WHITESPACE@[130; 131) "\n" 97 WHITESPACE@[130; 131) "\n"
88 ATTR@[131; 155) 98 ATTR@[131; 155)
89 POUND@[131; 132) "#" 99 POUND@[131; 132) "#"
90 EXCL@[132; 133) "!" 100 EXCL@[132; 133) "!"
91 TOKEN_TREE@[133; 155) 101 L_BRACK@[133; 134) "["
92 L_BRACK@[133; 134) "[" 102 PATH@[134; 138)
93 IDENT@[134; 138) "attr" 103 PATH_SEGMENT@[134; 138)
94 TOKEN_TREE@[138; 154) 104 NAME_REF@[134; 138)
95 L_PAREN@[138; 139) "(" 105 IDENT@[134; 138) "attr"
96 IDENT@[139; 146) "enabled" 106 TOKEN_TREE@[138; 154)
97 WHITESPACE@[146; 147) " " 107 L_PAREN@[138; 139) "("
98 EQ@[147; 148) "=" 108 IDENT@[139; 146) "enabled"
99 WHITESPACE@[148; 149) " " 109 WHITESPACE@[146; 147) " "
100 TRUE_KW@[149; 153) "true" 110 EQ@[147; 148) "="
101 R_PAREN@[153; 154) ")" 111 WHITESPACE@[148; 149) " "
102 R_BRACK@[154; 155) "]" 112 TRUE_KW@[149; 153) "true"
113 R_PAREN@[153; 154) ")"
114 R_BRACK@[154; 155) "]"
103 WHITESPACE@[155; 156) "\n" 115 WHITESPACE@[155; 156) "\n"
104 ATTR@[156; 173) 116 ATTR@[156; 173)
105 POUND@[156; 157) "#" 117 POUND@[156; 157) "#"
106 EXCL@[157; 158) "!" 118 EXCL@[157; 158) "!"
107 TOKEN_TREE@[158; 173) 119 L_BRACK@[158; 159) "["
108 L_BRACK@[158; 159) "[" 120 PATH@[159; 166)
109 IDENT@[159; 166) "enabled" 121 PATH_SEGMENT@[159; 166)
110 TOKEN_TREE@[166; 172) 122 NAME_REF@[159; 166)
111 L_PAREN@[166; 167) "(" 123 IDENT@[159; 166) "enabled"
112 TRUE_KW@[167; 171) "true" 124 TOKEN_TREE@[166; 172)
113 R_PAREN@[171; 172) ")" 125 L_PAREN@[166; 167) "("
114 R_BRACK@[172; 173) "]" 126 TRUE_KW@[167; 171) "true"
127 R_PAREN@[171; 172) ")"
128 R_BRACK@[172; 173) "]"
115 WHITESPACE@[173; 174) "\n" 129 WHITESPACE@[173; 174) "\n"
116 ATTR@[174; 191) 130 ATTR@[174; 191)
117 POUND@[174; 175) "#" 131 POUND@[174; 175) "#"
118 EXCL@[175; 176) "!" 132 EXCL@[175; 176) "!"
119 TOKEN_TREE@[176; 191) 133 L_BRACK@[176; 177) "["
120 L_BRACK@[176; 177) "[" 134 PATH@[177; 181)
121 IDENT@[177; 181) "attr" 135 PATH_SEGMENT@[177; 181)
122 TOKEN_TREE@[181; 190) 136 NAME_REF@[177; 181)
123 L_PAREN@[181; 182) "(" 137 IDENT@[177; 181) "attr"
124 STRING@[182; 189) "\"hello\"" 138 TOKEN_TREE@[181; 190)
125 R_PAREN@[189; 190) ")" 139 L_PAREN@[181; 182) "("
126 R_BRACK@[190; 191) "]" 140 STRING@[182; 189) "\"hello\""
141 R_PAREN@[189; 190) ")"
142 R_BRACK@[190; 191) "]"
127 WHITESPACE@[191; 192) "\n" 143 WHITESPACE@[191; 192) "\n"
128 ATTR@[192; 214) 144 ATTR@[192; 214)
129 POUND@[192; 193) "#" 145 POUND@[192; 193) "#"
130 EXCL@[193; 194) "!" 146 EXCL@[193; 194) "!"
131 TOKEN_TREE@[194; 214) 147 L_BRACK@[194; 195) "["
132 L_BRACK@[194; 195) "[" 148 PATH@[195; 199)
133 IDENT@[195; 199) "repr" 149 PATH_SEGMENT@[195; 199)
134 TOKEN_TREE@[199; 213) 150 NAME_REF@[195; 199)
135 L_PAREN@[199; 200) "(" 151 IDENT@[195; 199) "repr"
136 IDENT@[200; 201) "C" 152 TOKEN_TREE@[199; 213)
137 COMMA@[201; 202) "," 153 L_PAREN@[199; 200) "("
138 WHITESPACE@[202; 203) " " 154 IDENT@[200; 201) "C"
139 IDENT@[203; 208) "align" 155 COMMA@[201; 202) ","
140 WHITESPACE@[208; 209) " " 156 WHITESPACE@[202; 203) " "
141 EQ@[209; 210) "=" 157 IDENT@[203; 208) "align"
142 WHITESPACE@[210; 211) " " 158 WHITESPACE@[208; 209) " "
143 INT_NUMBER@[211; 212) "4" 159 EQ@[209; 210) "="
144 R_PAREN@[212; 213) ")" 160 WHITESPACE@[210; 211) " "
145 R_BRACK@[213; 214) "]" 161 INT_NUMBER@[211; 212) "4"
162 R_PAREN@[212; 213) ")"
163 R_BRACK@[213; 214) "]"
146 WHITESPACE@[214; 215) "\n" 164 WHITESPACE@[214; 215) "\n"
147 ATTR@[215; 236) 165 ATTR@[215; 236)
148 POUND@[215; 216) "#" 166 POUND@[215; 216) "#"
149 EXCL@[216; 217) "!" 167 EXCL@[216; 217) "!"
150 TOKEN_TREE@[217; 236) 168 L_BRACK@[217; 218) "["
151 L_BRACK@[217; 218) "[" 169 PATH@[218; 222)
152 IDENT@[218; 222) "repr" 170 PATH_SEGMENT@[218; 222)
153 TOKEN_TREE@[222; 235) 171 NAME_REF@[218; 222)
154 L_PAREN@[222; 223) "(" 172 IDENT@[218; 222) "repr"
155 IDENT@[223; 224) "C" 173 TOKEN_TREE@[222; 235)
156 COMMA@[224; 225) "," 174 L_PAREN@[222; 223) "("
157 WHITESPACE@[225; 226) " " 175 IDENT@[223; 224) "C"
158 IDENT@[226; 231) "align" 176 COMMA@[224; 225) ","
159 TOKEN_TREE@[231; 234) 177 WHITESPACE@[225; 226) " "
160 L_PAREN@[231; 232) "(" 178 IDENT@[226; 231) "align"
161 INT_NUMBER@[232; 233) "4" 179 TOKEN_TREE@[231; 234)
162 R_PAREN@[233; 234) ")" 180 L_PAREN@[231; 232) "("
163 R_PAREN@[234; 235) ")" 181 INT_NUMBER@[232; 233) "4"
164 R_BRACK@[235; 236) "]" 182 R_PAREN@[233; 234) ")"
183 R_PAREN@[234; 235) ")"
184 R_BRACK@[235; 236) "]"
diff --git a/crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt b/crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt
index 35465632d..061019a73 100644
--- a/crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt
@@ -65,10 +65,12 @@ SOURCE_FILE@[0; 118)
65 ATTR@[79; 87) 65 ATTR@[79; 87)
66 POUND@[79; 80) "#" 66 POUND@[79; 80) "#"
67 EXCL@[80; 81) "!" 67 EXCL@[80; 81) "!"
68 TOKEN_TREE@[81; 87) 68 L_BRACK@[81; 82) "["
69 L_BRACK@[81; 82) "[" 69 PATH@[82; 86)
70 IDENT@[82; 86) "attr" 70 PATH_SEGMENT@[82; 86)
71 R_BRACK@[86; 87) "]" 71 NAME_REF@[82; 86)
72 IDENT@[82; 86) "attr"
73 R_BRACK@[86; 87) "]"
72 WHITESPACE@[87; 92) "\n " 74 WHITESPACE@[87; 92) "\n "
73 MODULE@[92; 98) 75 MODULE@[92; 98)
74 MOD_KW@[92; 95) "mod" 76 MOD_KW@[92; 95) "mod"
diff --git a/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rs b/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rs
index 8b80c0d90..3d2e01d5c 100644
--- a/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rs
+++ b/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rs
@@ -1,3 +1,6 @@
1#[cfg(test)] 1#[cfg(test)]
2#[ignore] 2#[ignore]
3fn foo() {} 3fn foo() {}
4
5#[path = "a.rs"]
6mod b;
diff --git a/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt b/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt
index a845c5c24..f7aa8afe4 100644
--- a/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt
@@ -1,22 +1,26 @@
1SOURCE_FILE@[0; 35) 1SOURCE_FILE@[0; 60)
2 FN_DEF@[0; 34) 2 FN_DEF@[0; 34)
3 ATTR@[0; 12) 3 ATTR@[0; 12)
4 POUND@[0; 1) "#" 4 POUND@[0; 1) "#"
5 TOKEN_TREE@[1; 12) 5 L_BRACK@[1; 2) "["
6 L_BRACK@[1; 2) "[" 6 PATH@[2; 5)
7 IDENT@[2; 5) "cfg" 7 PATH_SEGMENT@[2; 5)
8 TOKEN_TREE@[5; 11) 8 NAME_REF@[2; 5)
9 L_PAREN@[5; 6) "(" 9 IDENT@[2; 5) "cfg"
10 IDENT@[6; 10) "test" 10 TOKEN_TREE@[5; 11)
11 R_PAREN@[10; 11) ")" 11 L_PAREN@[5; 6) "("
12 R_BRACK@[11; 12) "]" 12 IDENT@[6; 10) "test"
13 R_PAREN@[10; 11) ")"
14 R_BRACK@[11; 12) "]"
13 WHITESPACE@[12; 13) "\n" 15 WHITESPACE@[12; 13) "\n"
14 ATTR@[13; 22) 16 ATTR@[13; 22)
15 POUND@[13; 14) "#" 17 POUND@[13; 14) "#"
16 TOKEN_TREE@[14; 22) 18 L_BRACK@[14; 15) "["
17 L_BRACK@[14; 15) "[" 19 PATH@[15; 21)
18 IDENT@[15; 21) "ignore" 20 PATH_SEGMENT@[15; 21)
19 R_BRACK@[21; 22) "]" 21 NAME_REF@[15; 21)
22 IDENT@[15; 21) "ignore"
23 R_BRACK@[21; 22) "]"
20 WHITESPACE@[22; 23) "\n" 24 WHITESPACE@[22; 23) "\n"
21 FN_KW@[23; 25) "fn" 25 FN_KW@[23; 25) "fn"
22 WHITESPACE@[25; 26) " " 26 WHITESPACE@[25; 26) " "
@@ -30,4 +34,25 @@ SOURCE_FILE@[0; 35)
30 BLOCK@[32; 34) 34 BLOCK@[32; 34)
31 L_CURLY@[32; 33) "{" 35 L_CURLY@[32; 33) "{"
32 R_CURLY@[33; 34) "}" 36 R_CURLY@[33; 34) "}"
33 WHITESPACE@[34; 35) "\n" 37 WHITESPACE@[34; 36) "\n\n"
38 MODULE@[36; 59)
39 ATTR@[36; 52)
40 POUND@[36; 37) "#"
41 L_BRACK@[37; 38) "["
42 PATH@[38; 42)
43 PATH_SEGMENT@[38; 42)
44 NAME_REF@[38; 42)
45 IDENT@[38; 42) "path"
46 WHITESPACE@[42; 43) " "
47 EQ@[43; 44) "="
48 WHITESPACE@[44; 45) " "
49 LITERAL@[45; 51)
50 STRING@[45; 51) "\"a.rs\""
51 R_BRACK@[51; 52) "]"
52 WHITESPACE@[52; 53) "\n"
53 MOD_KW@[53; 56) "mod"
54 WHITESPACE@[56; 57) " "
55 NAME@[57; 58)
56 IDENT@[57; 58) "b"
57 SEMI@[58; 59) ";"
58 WHITESPACE@[59; 60) "\n"
diff --git a/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt b/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt
index a1084b221..1d65b0d6e 100644
--- a/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt
@@ -2,15 +2,17 @@ SOURCE_FILE@[0; 23)
2 FN_DEF@[0; 22) 2 FN_DEF@[0; 22)
3 ATTR@[0; 10) 3 ATTR@[0; 10)
4 POUND@[0; 1) "#" 4 POUND@[0; 1) "#"
5 TOKEN_TREE@[1; 10) 5 L_BRACK@[1; 2) "["
6 L_BRACK@[1; 2) "[" 6 PATH@[2; 5)
7 IDENT@[2; 5) "foo" 7 PATH_SEGMENT@[2; 5)
8 TOKEN_TREE@[5; 9) 8 NAME_REF@[2; 5)
9 L_PAREN@[5; 6) "(" 9 IDENT@[2; 5) "foo"
10 IDENT@[6; 7) "a" 10 TOKEN_TREE@[5; 9)
11 COMMA@[7; 8) "," 11 L_PAREN@[5; 6) "("
12 R_PAREN@[8; 9) ")" 12 IDENT@[6; 7) "a"
13 R_BRACK@[9; 10) "]" 13 COMMA@[7; 8) ","
14 R_PAREN@[8; 9) ")"
15 R_BRACK@[9; 10) "]"
14 WHITESPACE@[10; 11) "\n" 16 WHITESPACE@[10; 11) "\n"
15 FN_KW@[11; 13) "fn" 17 FN_KW@[11; 13) "fn"
16 WHITESPACE@[13; 14) " " 18 WHITESPACE@[13; 14) " "
diff --git a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt
index 3326ab2ae..3260cc589 100644
--- a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt
@@ -10,62 +10,73 @@ SOURCE_FILE@[0; 3813)
10 ATTR@[271; 302) 10 ATTR@[271; 302)
11 POUND@[271; 272) "#" 11 POUND@[271; 272) "#"
12 EXCL@[272; 273) "!" 12 EXCL@[272; 273) "!"
13 TOKEN_TREE@[273; 302) 13 L_BRACK@[273; 274) "["
14 L_BRACK@[273; 274) "[" 14 PATH@[274; 279)
15 IDENT@[274; 279) "allow" 15 PATH_SEGMENT@[274; 279)
16 TOKEN_TREE@[279; 301) 16 NAME_REF@[274; 279)
17 L_PAREN@[279; 280) "(" 17 IDENT@[274; 279) "allow"
18 IDENT@[280; 300) "non_camel_case_types" 18 TOKEN_TREE@[279; 301)
19 R_PAREN@[300; 301) ")" 19 L_PAREN@[279; 280) "("
20 R_BRACK@[301; 302) "]" 20 IDENT@[280; 300) "non_camel_case_types"
21 R_PAREN@[300; 301) ")"
22 R_BRACK@[301; 302) "]"
21 WHITESPACE@[302; 303) "\n" 23 WHITESPACE@[302; 303) "\n"
22 ATTR@[303; 323) 24 ATTR@[303; 323)
23 POUND@[303; 304) "#" 25 POUND@[303; 304) "#"
24 EXCL@[304; 305) "!" 26 EXCL@[304; 305) "!"
25 TOKEN_TREE@[305; 323) 27 L_BRACK@[305; 306) "["
26 L_BRACK@[305; 306) "[" 28 PATH@[306; 311)
27 IDENT@[306; 311) "allow" 29 PATH_SEGMENT@[306; 311)
28 TOKEN_TREE@[311; 322) 30 NAME_REF@[306; 311)
29 L_PAREN@[311; 312) "(" 31 IDENT@[306; 311) "allow"
30 IDENT@[312; 321) "dead_code" 32 TOKEN_TREE@[311; 322)
31 R_PAREN@[321; 322) ")" 33 L_PAREN@[311; 312) "("
32 R_BRACK@[322; 323) "]" 34 IDENT@[312; 321) "dead_code"
35 R_PAREN@[321; 322) ")"
36 R_BRACK@[322; 323) "]"
33 WHITESPACE@[323; 324) "\n" 37 WHITESPACE@[323; 324) "\n"
34 ATTR@[324; 351) 38 ATTR@[324; 351)
35 POUND@[324; 325) "#" 39 POUND@[324; 325) "#"
36 EXCL@[325; 326) "!" 40 EXCL@[325; 326) "!"
37 TOKEN_TREE@[326; 351) 41 L_BRACK@[326; 327) "["
38 L_BRACK@[326; 327) "[" 42 PATH@[327; 332)
39 IDENT@[327; 332) "allow" 43 PATH_SEGMENT@[327; 332)
40 TOKEN_TREE@[332; 350) 44 NAME_REF@[327; 332)
41 L_PAREN@[332; 333) "(" 45 IDENT@[327; 332) "allow"
42 IDENT@[333; 349) "unreachable_code" 46 TOKEN_TREE@[332; 350)
43 R_PAREN@[349; 350) ")" 47 L_PAREN@[332; 333) "("
44 R_BRACK@[350; 351) "]" 48 IDENT@[333; 349) "unreachable_code"
49 R_PAREN@[349; 350) ")"
50 R_BRACK@[350; 351) "]"
45 WHITESPACE@[351; 352) "\n" 51 WHITESPACE@[351; 352) "\n"
46 ATTR@[352; 376) 52 ATTR@[352; 376)
47 POUND@[352; 353) "#" 53 POUND@[352; 353) "#"
48 EXCL@[353; 354) "!" 54 EXCL@[353; 354) "!"
49 TOKEN_TREE@[354; 376) 55 L_BRACK@[354; 355) "["
50 L_BRACK@[354; 355) "[" 56 PATH@[355; 360)
51 IDENT@[355; 360) "allow" 57 PATH_SEGMENT@[355; 360)
52 TOKEN_TREE@[360; 375) 58 NAME_REF@[355; 360)
53 L_PAREN@[360; 361) "(" 59 IDENT@[355; 360) "allow"
54 IDENT@[361; 374) "unused_parens" 60 TOKEN_TREE@[360; 375)
55 R_PAREN@[374; 375) ")" 61 L_PAREN@[360; 361) "("
56 R_BRACK@[375; 376) "]" 62 IDENT@[361; 374) "unused_parens"
63 R_PAREN@[374; 375) ")"
64 R_BRACK@[375; 376) "]"
57 WHITESPACE@[376; 378) "\n\n" 65 WHITESPACE@[376; 378) "\n\n"
58 ATTR@[378; 405) 66 ATTR@[378; 405)
59 POUND@[378; 379) "#" 67 POUND@[378; 379) "#"
60 EXCL@[379; 380) "!" 68 EXCL@[379; 380) "!"
61 TOKEN_TREE@[380; 405) 69 L_BRACK@[380; 381) "["
62 L_BRACK@[380; 381) "[" 70 PATH@[381; 396)
63 IDENT@[381; 396) "recursion_limit" 71 PATH_SEGMENT@[381; 396)
64 WHITESPACE@[396; 397) " " 72 NAME_REF@[381; 396)
65 EQ@[397; 398) "=" 73 IDENT@[381; 396) "recursion_limit"
66 WHITESPACE@[398; 399) " " 74 WHITESPACE@[396; 397) " "
75 EQ@[397; 398) "="
76 WHITESPACE@[398; 399) " "
77 LITERAL@[399; 404)
67 STRING@[399; 404) "\"128\"" 78 STRING@[399; 404) "\"128\""
68 R_BRACK@[404; 405) "]" 79 R_BRACK@[404; 405) "]"
69 WHITESPACE@[405; 407) "\n\n" 80 WHITESPACE@[405; 407) "\n\n"
70 USE_ITEM@[407; 427) 81 USE_ITEM@[407; 427)
71 USE_KW@[407; 410) "use" 82 USE_KW@[407; 410) "use"
diff --git a/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt b/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt
index 7dabe535f..bfc793dc1 100644
--- a/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt
@@ -17,18 +17,20 @@ SOURCE_FILE@[0; 166)
17 LET_STMT@[77; 163) 17 LET_STMT@[77; 163)
18 ATTR@[77; 106) 18 ATTR@[77; 106)
19 POUND@[77; 78) "#" 19 POUND@[77; 78) "#"
20 TOKEN_TREE@[78; 106) 20 L_BRACK@[78; 79) "["
21 L_BRACK@[78; 79) "[" 21 PATH@[79; 82)
22 IDENT@[79; 82) "cfg" 22 PATH_SEGMENT@[79; 82)
23 TOKEN_TREE@[82; 105) 23 NAME_REF@[79; 82)
24 L_PAREN@[82; 83) "(" 24 IDENT@[79; 82) "cfg"
25 IDENT@[83; 90) "feature" 25 TOKEN_TREE@[82; 105)
26 WHITESPACE@[90; 91) " " 26 L_PAREN@[82; 83) "("
27 EQ@[91; 92) "=" 27 IDENT@[83; 90) "feature"
28 WHITESPACE@[92; 93) " " 28 WHITESPACE@[90; 91) " "
29 STRING@[93; 104) "\"backtrace\"" 29 EQ@[91; 92) "="
30 R_PAREN@[104; 105) ")" 30 WHITESPACE@[92; 93) " "
31 R_BRACK@[105; 106) "]" 31 STRING@[93; 104) "\"backtrace\""
32 R_PAREN@[104; 105) ")"
33 R_BRACK@[105; 106) "]"
32 WHITESPACE@[106; 111) "\n " 34 WHITESPACE@[106; 111) "\n "
33 LET_KW@[111; 114) "let" 35 LET_KW@[111; 114) "let"
34 WHITESPACE@[114; 115) " " 36 WHITESPACE@[114; 115) " "
diff --git a/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt b/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt
index e8be8203b..3d9aab500 100644
--- a/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt
@@ -15,14 +15,16 @@ SOURCE_FILE@[0; 686)
15 ATTR@[17; 57) 15 ATTR@[17; 57)
16 POUND@[17; 18) "#" 16 POUND@[17; 18) "#"
17 EXCL@[18; 19) "!" 17 EXCL@[18; 19) "!"
18 TOKEN_TREE@[19; 57) 18 L_BRACK@[19; 20) "["
19 L_BRACK@[19; 20) "[" 19 PATH@[20; 23)
20 IDENT@[20; 23) "doc" 20 PATH_SEGMENT@[20; 23)
21 TOKEN_TREE@[23; 56) 21 NAME_REF@[20; 23)
22 L_PAREN@[23; 24) "(" 22 IDENT@[20; 23) "doc"
23 STRING@[24; 55) "\"Inner attributes all ..." 23 TOKEN_TREE@[23; 56)
24 R_PAREN@[55; 56) ")" 24 L_PAREN@[23; 24) "("
25 R_BRACK@[56; 57) "]" 25 STRING@[24; 55) "\"Inner attributes all ..."
26 R_PAREN@[55; 56) ")"
27 R_BRACK@[56; 57) "]"
26 WHITESPACE@[57; 62) "\n " 28 WHITESPACE@[57; 62) "\n "
27 COMMENT@[62; 97) "//! As are ModuleDoc ..." 29 COMMENT@[62; 97) "//! As are ModuleDoc ..."
28 WHITESPACE@[97; 102) "\n " 30 WHITESPACE@[97; 102) "\n "
@@ -34,26 +36,30 @@ SOURCE_FILE@[0; 686)
34 ATTR@[112; 180) 36 ATTR@[112; 180)
35 POUND@[112; 113) "#" 37 POUND@[112; 113) "#"
36 EXCL@[113; 114) "!" 38 EXCL@[113; 114) "!"
37 TOKEN_TREE@[114; 180) 39 L_BRACK@[114; 115) "["
38 L_BRACK@[114; 115) "[" 40 PATH@[115; 118)
39 IDENT@[115; 118) "doc" 41 PATH_SEGMENT@[115; 118)
40 TOKEN_TREE@[118; 179) 42 NAME_REF@[115; 118)
41 L_PAREN@[118; 119) "(" 43 IDENT@[115; 118) "doc"
42 STRING@[119; 178) "\"Inner attributes are ..." 44 TOKEN_TREE@[118; 179)
43 R_PAREN@[178; 179) ")" 45 L_PAREN@[118; 119) "("
44 R_BRACK@[179; 180) "]" 46 STRING@[119; 178) "\"Inner attributes are ..."
47 R_PAREN@[178; 179) ")"
48 R_BRACK@[179; 180) "]"
45 WHITESPACE@[180; 189) "\n " 49 WHITESPACE@[180; 189) "\n "
46 ATTR@[189; 244) 50 ATTR@[189; 244)
47 POUND@[189; 190) "#" 51 POUND@[189; 190) "#"
48 EXCL@[190; 191) "!" 52 EXCL@[190; 191) "!"
49 TOKEN_TREE@[191; 244) 53 L_BRACK@[191; 192) "["
50 L_BRACK@[191; 192) "[" 54 PATH@[192; 195)
51 IDENT@[192; 195) "doc" 55 PATH_SEGMENT@[192; 195)
52 TOKEN_TREE@[195; 243) 56 NAME_REF@[192; 195)
53 L_PAREN@[195; 196) "(" 57 IDENT@[192; 195) "doc"
54 STRING@[196; 242) "\"Being validated is n ..." 58 TOKEN_TREE@[195; 243)
55 R_PAREN@[242; 243) ")" 59 L_PAREN@[195; 196) "("
56 R_BRACK@[243; 244) "]" 60 STRING@[196; 242) "\"Being validated is n ..."
61 R_PAREN@[242; 243) ")"
62 R_BRACK@[243; 244) "]"
57 WHITESPACE@[244; 253) "\n " 63 WHITESPACE@[244; 253) "\n "
58 COMMENT@[253; 288) "//! As are ModuleDoc ..." 64 COMMENT@[253; 288) "//! As are ModuleDoc ..."
59 WHITESPACE@[288; 293) "\n " 65 WHITESPACE@[288; 293) "\n "
@@ -67,14 +73,16 @@ SOURCE_FILE@[0; 686)
67 ATTR@[310; 409) 73 ATTR@[310; 409)
68 POUND@[310; 311) "#" 74 POUND@[310; 311) "#"
69 EXCL@[311; 312) "!" 75 EXCL@[311; 312) "!"
70 TOKEN_TREE@[312; 409) 76 L_BRACK@[312; 313) "["
71 L_BRACK@[312; 313) "[" 77 PATH@[313; 316)
72 IDENT@[313; 316) "doc" 78 PATH_SEGMENT@[313; 316)
73 TOKEN_TREE@[316; 408) 79 NAME_REF@[313; 316)
74 L_PAREN@[316; 317) "(" 80 IDENT@[313; 316) "doc"
75 STRING@[317; 407) "\"Inner attributes are ..." 81 TOKEN_TREE@[316; 408)
76 R_PAREN@[407; 408) ")" 82 L_PAREN@[316; 317) "("
77 R_BRACK@[408; 409) "]" 83 STRING@[317; 407) "\"Inner attributes are ..."
84 R_PAREN@[407; 408) ")"
85 R_BRACK@[408; 409) "]"
78 WHITESPACE@[409; 418) "\n " 86 WHITESPACE@[409; 418) "\n "
79 COMMENT@[418; 453) "//! As are ModuleDoc ..." 87 COMMENT@[418; 453) "//! As are ModuleDoc ..."
80 WHITESPACE@[453; 458) "\n " 88 WHITESPACE@[453; 458) "\n "
@@ -154,14 +162,16 @@ SOURCE_FILE@[0; 686)
154 ATTR@[612; 639) 162 ATTR@[612; 639)
155 POUND@[612; 613) "#" 163 POUND@[612; 613) "#"
156 EXCL@[613; 614) "!" 164 EXCL@[613; 614) "!"
157 TOKEN_TREE@[614; 639) 165 L_BRACK@[614; 615) "["
158 L_BRACK@[614; 615) "[" 166 PATH@[615; 620)
159 IDENT@[615; 620) "allow" 167 PATH_SEGMENT@[615; 620)
160 TOKEN_TREE@[620; 638) 168 NAME_REF@[615; 620)
161 L_PAREN@[620; 621) "(" 169 IDENT@[615; 620) "allow"
162 IDENT@[621; 637) "unused_variables" 170 TOKEN_TREE@[620; 638)
163 R_PAREN@[637; 638) ")" 171 L_PAREN@[620; 621) "("
164 R_BRACK@[638; 639) "]" 172 IDENT@[621; 637) "unused_variables"
173 R_PAREN@[637; 638) ")"
174 R_BRACK@[638; 639) "]"
165 WHITESPACE@[639; 640) " " 175 WHITESPACE@[639; 640) " "
166 COMMENT@[640; 677) "// this is `inner_at ..." 176 COMMENT@[640; 677) "// this is `inner_at ..."
167 WHITESPACE@[677; 682) "\n " 177 WHITESPACE@[677; 682) "\n "
diff --git a/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt b/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt
index 4487a6e2e..8f192124b 100644
--- a/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt
@@ -13,14 +13,16 @@ SOURCE_FILE@[0; 87)
13 ATTR@[47; 84) 13 ATTR@[47; 84)
14 POUND@[47; 48) "#" 14 POUND@[47; 48) "#"
15 EXCL@[48; 49) "!" 15 EXCL@[48; 49) "!"
16 TOKEN_TREE@[49; 84) 16 L_BRACK@[49; 50) "["
17 L_BRACK@[49; 50) "[" 17 PATH@[50; 53)
18 IDENT@[50; 53) "doc" 18 PATH_SEGMENT@[50; 53)
19 TOKEN_TREE@[53; 83) 19 NAME_REF@[50; 53)
20 L_PAREN@[53; 54) "(" 20 IDENT@[50; 53) "doc"
21 STRING@[54; 82) "\"This is also a doc c ..." 21 TOKEN_TREE@[53; 83)
22 R_PAREN@[82; 83) ")" 22 L_PAREN@[53; 54) "("
23 R_BRACK@[83; 84) "]" 23 STRING@[54; 82) "\"This is also a doc c ..."
24 R_PAREN@[82; 83) ")"
25 R_BRACK@[83; 84) "]"
24 WHITESPACE@[84; 85) "\n" 26 WHITESPACE@[84; 85) "\n"
25 R_CURLY@[85; 86) "}" 27 R_CURLY@[85; 86) "}"
26 WHITESPACE@[86; 87) "\n" 28 WHITESPACE@[86; 87) "\n"
diff --git a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt
index e08fb4988..bfd47d2e1 100644
--- a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt
@@ -8,17 +8,21 @@ SOURCE_FILE@[0; 519)
8 L_PAREN@[5; 6) "(" 8 L_PAREN@[5; 6) "("
9 ATTR@[6; 14) 9 ATTR@[6; 14)
10 POUND@[6; 7) "#" 10 POUND@[6; 7) "#"
11 TOKEN_TREE@[7; 14) 11 L_BRACK@[7; 8) "["
12 L_BRACK@[7; 8) "[" 12 PATH@[8; 13)
13 IDENT@[8; 13) "attr1" 13 PATH_SEGMENT@[8; 13)
14 R_BRACK@[13; 14) "]" 14 NAME_REF@[8; 13)
15 IDENT@[8; 13) "attr1"
16 R_BRACK@[13; 14) "]"
15 WHITESPACE@[14; 15) " " 17 WHITESPACE@[14; 15) " "
16 ATTR@[15; 23) 18 ATTR@[15; 23)
17 POUND@[15; 16) "#" 19 POUND@[15; 16) "#"
18 TOKEN_TREE@[16; 23) 20 L_BRACK@[16; 17) "["
19 L_BRACK@[16; 17) "[" 21 PATH@[17; 22)
20 IDENT@[17; 22) "attr2" 22 PATH_SEGMENT@[17; 22)
21 R_BRACK@[22; 23) "]" 23 NAME_REF@[17; 22)
24 IDENT@[17; 22) "attr2"
25 R_BRACK@[22; 23) "]"
22 WHITESPACE@[23; 24) " " 26 WHITESPACE@[23; 24) " "
23 PARAM@[24; 33) 27 PARAM@[24; 33)
24 BIND_PAT@[24; 27) 28 BIND_PAT@[24; 27)
@@ -47,10 +51,12 @@ SOURCE_FILE@[0; 519)
47 L_PAREN@[43; 44) "(" 51 L_PAREN@[43; 44) "("
48 ATTR@[44; 52) 52 ATTR@[44; 52)
49 POUND@[44; 45) "#" 53 POUND@[44; 45) "#"
50 TOKEN_TREE@[45; 52) 54 L_BRACK@[45; 46) "["
51 L_BRACK@[45; 46) "[" 55 PATH@[46; 51)
52 IDENT@[46; 51) "attr1" 56 PATH_SEGMENT@[46; 51)
53 R_BRACK@[51; 52) "]" 57 NAME_REF@[46; 51)
58 IDENT@[46; 51) "attr1"
59 R_BRACK@[51; 52) "]"
54 WHITESPACE@[52; 53) " " 60 WHITESPACE@[52; 53) " "
55 PARAM@[53; 58) 61 PARAM@[53; 58)
56 BIND_PAT@[53; 54) 62 BIND_PAT@[53; 54)
@@ -105,10 +111,12 @@ SOURCE_FILE@[0; 519)
105 WHITESPACE@[105; 106) " " 111 WHITESPACE@[105; 106) " "
106 ATTR@[106; 113) 112 ATTR@[106; 113)
107 POUND@[106; 107) "#" 113 POUND@[106; 107) "#"
108 TOKEN_TREE@[107; 113) 114 L_BRACK@[107; 108) "["
109 L_BRACK@[107; 108) "[" 115 PATH@[108; 112)
110 IDENT@[108; 112) "attr" 116 PATH_SEGMENT@[108; 112)
111 R_BRACK@[112; 113) "]" 117 NAME_REF@[108; 112)
118 IDENT@[108; 112) "attr"
119 R_BRACK@[112; 113) "]"
112 WHITESPACE@[113; 114) " " 120 WHITESPACE@[113; 114) " "
113 DOTDOTDOT@[114; 117) "..." 121 DOTDOTDOT@[114; 117) "..."
114 R_PAREN@[117; 118) ")" 122 R_PAREN@[117; 118) ")"
@@ -148,10 +156,12 @@ SOURCE_FILE@[0; 519)
148 L_PAREN@[145; 146) "(" 156 L_PAREN@[145; 146) "("
149 ATTR@[146; 153) 157 ATTR@[146; 153)
150 POUND@[146; 147) "#" 158 POUND@[146; 147) "#"
151 TOKEN_TREE@[147; 153) 159 L_BRACK@[147; 148) "["
152 L_BRACK@[147; 148) "[" 160 PATH@[148; 152)
153 IDENT@[148; 152) "attr" 161 PATH_SEGMENT@[148; 152)
154 R_BRACK@[152; 153) "]" 162 NAME_REF@[148; 152)
163 IDENT@[148; 152) "attr"
164 R_BRACK@[152; 153) "]"
155 WHITESPACE@[153; 154) " " 165 WHITESPACE@[153; 154) " "
156 PARAM@[154; 166) 166 PARAM@[154; 166)
157 REFERENCE_TYPE@[154; 166) 167 REFERENCE_TYPE@[154; 166)
@@ -196,10 +206,12 @@ SOURCE_FILE@[0; 519)
196 L_PAREN@[196; 197) "(" 206 L_PAREN@[196; 197) "("
197 ATTR@[197; 204) 207 ATTR@[197; 204)
198 POUND@[197; 198) "#" 208 POUND@[197; 198) "#"
199 TOKEN_TREE@[198; 204) 209 L_BRACK@[198; 199) "["
200 L_BRACK@[198; 199) "[" 210 PATH@[199; 203)
201 IDENT@[199; 203) "attr" 211 PATH_SEGMENT@[199; 203)
202 R_BRACK@[203; 204) "]" 212 NAME_REF@[199; 203)
213 IDENT@[199; 203) "attr"
214 R_BRACK@[203; 204) "]"
203 WHITESPACE@[204; 205) " " 215 WHITESPACE@[204; 205) " "
204 PARAM@[205; 211) 216 PARAM@[205; 211)
205 PLACEHOLDER_PAT@[205; 206) 217 PLACEHOLDER_PAT@[205; 206)
@@ -216,10 +228,12 @@ SOURCE_FILE@[0; 519)
216 ATTR@[213; 221) 228 ATTR@[213; 221)
217 POUND@[213; 214) "#" 229 POUND@[213; 214) "#"
218 WHITESPACE@[214; 215) " " 230 WHITESPACE@[214; 215) " "
219 TOKEN_TREE@[215; 221) 231 L_BRACK@[215; 216) "["
220 L_BRACK@[215; 216) "[" 232 PATH@[216; 220)
221 IDENT@[216; 220) "attr" 233 PATH_SEGMENT@[216; 220)
222 R_BRACK@[220; 221) "]" 234 NAME_REF@[216; 220)
235 IDENT@[216; 220) "attr"
236 R_BRACK@[220; 221) "]"
223 WHITESPACE@[221; 222) " " 237 WHITESPACE@[221; 222) " "
224 PARAM@[222; 232) 238 PARAM@[222; 232)
225 BIND_PAT@[222; 227) 239 BIND_PAT@[222; 227)
@@ -260,10 +274,12 @@ SOURCE_FILE@[0; 519)
260 L_PAREN@[256; 257) "(" 274 L_PAREN@[256; 257) "("
261 ATTR@[257; 268) 275 ATTR@[257; 268)
262 POUND@[257; 258) "#" 276 POUND@[257; 258) "#"
263 TOKEN_TREE@[258; 268) 277 L_BRACK@[258; 259) "["
264 L_BRACK@[258; 259) "[" 278 PATH@[259; 267)
265 IDENT@[259; 267) "must_use" 279 PATH_SEGMENT@[259; 267)
266 R_BRACK@[267; 268) "]" 280 NAME_REF@[259; 267)
281 IDENT@[259; 267) "must_use"
282 R_BRACK@[267; 268) "]"
267 WHITESPACE@[268; 269) " " 283 WHITESPACE@[268; 269) " "
268 SELF_PARAM@[269; 273) 284 SELF_PARAM@[269; 273)
269 SELF_KW@[269; 273) "self" 285 SELF_KW@[269; 273) "self"
@@ -283,10 +299,12 @@ SOURCE_FILE@[0; 519)
283 L_PAREN@[288; 289) "(" 299 L_PAREN@[288; 289) "("
284 ATTR@[289; 296) 300 ATTR@[289; 296)
285 POUND@[289; 290) "#" 301 POUND@[289; 290) "#"
286 TOKEN_TREE@[290; 296) 302 L_BRACK@[290; 291) "["
287 L_BRACK@[290; 291) "[" 303 PATH@[291; 295)
288 IDENT@[291; 295) "attr" 304 PATH_SEGMENT@[291; 295)
289 R_BRACK@[295; 296) "]" 305 NAME_REF@[291; 295)
306 IDENT@[291; 295) "attr"
307 R_BRACK@[295; 296) "]"
290 WHITESPACE@[296; 297) " " 308 WHITESPACE@[296; 297) " "
291 SELF_PARAM@[297; 301) 309 SELF_PARAM@[297; 301)
292 SELF_KW@[297; 301) "self" 310 SELF_KW@[297; 301) "self"
@@ -306,10 +324,12 @@ SOURCE_FILE@[0; 519)
306 L_PAREN@[316; 317) "(" 324 L_PAREN@[316; 317) "("
307 ATTR@[317; 324) 325 ATTR@[317; 324)
308 POUND@[317; 318) "#" 326 POUND@[317; 318) "#"
309 TOKEN_TREE@[318; 324) 327 L_BRACK@[318; 319) "["
310 L_BRACK@[318; 319) "[" 328 PATH@[319; 323)
311 IDENT@[319; 323) "attr" 329 PATH_SEGMENT@[319; 323)
312 R_BRACK@[323; 324) "]" 330 NAME_REF@[319; 323)
331 IDENT@[319; 323) "attr"
332 R_BRACK@[323; 324) "]"
313 WHITESPACE@[324; 325) " " 333 WHITESPACE@[324; 325) " "
314 SELF_PARAM@[325; 330) 334 SELF_PARAM@[325; 330)
315 AMP@[325; 326) "&" 335 AMP@[325; 326) "&"
@@ -335,10 +355,12 @@ SOURCE_FILE@[0; 519)
335 L_PAREN@[349; 350) "(" 355 L_PAREN@[349; 350) "("
336 ATTR@[350; 357) 356 ATTR@[350; 357)
337 POUND@[350; 351) "#" 357 POUND@[350; 351) "#"
338 TOKEN_TREE@[351; 357) 358 L_BRACK@[351; 352) "["
339 L_BRACK@[351; 352) "[" 359 PATH@[352; 356)
340 IDENT@[352; 356) "attr" 360 PATH_SEGMENT@[352; 356)
341 R_BRACK@[356; 357) "]" 361 NAME_REF@[352; 356)
362 IDENT@[352; 356) "attr"
363 R_BRACK@[356; 357) "]"
342 WHITESPACE@[357; 358) " " 364 WHITESPACE@[357; 358) " "
343 SELF_PARAM@[358; 367) 365 SELF_PARAM@[358; 367)
344 AMP@[358; 359) "&" 366 AMP@[358; 359) "&"
@@ -366,10 +388,12 @@ SOURCE_FILE@[0; 519)
366 L_PAREN@[386; 387) "(" 388 L_PAREN@[386; 387) "("
367 ATTR@[387; 394) 389 ATTR@[387; 394)
368 POUND@[387; 388) "#" 390 POUND@[387; 388) "#"
369 TOKEN_TREE@[388; 394) 391 L_BRACK@[388; 389) "["
370 L_BRACK@[388; 389) "[" 392 PATH@[389; 393)
371 IDENT@[389; 393) "attr" 393 PATH_SEGMENT@[389; 393)
372 R_BRACK@[393; 394) "]" 394 NAME_REF@[389; 393)
395 IDENT@[389; 393) "attr"
396 R_BRACK@[393; 394) "]"
373 WHITESPACE@[394; 395) " " 397 WHITESPACE@[394; 395) " "
374 SELF_PARAM@[395; 403) 398 SELF_PARAM@[395; 403)
375 AMP@[395; 396) "&" 399 AMP@[395; 396) "&"
@@ -397,10 +421,12 @@ SOURCE_FILE@[0; 519)
397 L_PAREN@[422; 423) "(" 421 L_PAREN@[422; 423) "("
398 ATTR@[423; 430) 422 ATTR@[423; 430)
399 POUND@[423; 424) "#" 423 POUND@[423; 424) "#"
400 TOKEN_TREE@[424; 430) 424 L_BRACK@[424; 425) "["
401 L_BRACK@[424; 425) "[" 425 PATH@[425; 429)
402 IDENT@[425; 429) "attr" 426 PATH_SEGMENT@[425; 429)
403 R_BRACK@[429; 430) "]" 427 NAME_REF@[425; 429)
428 IDENT@[425; 429) "attr"
429 R_BRACK@[429; 430) "]"
404 WHITESPACE@[430; 431) " " 430 WHITESPACE@[430; 431) " "
405 SELF_PARAM@[431; 443) 431 SELF_PARAM@[431; 443)
406 AMP@[431; 432) "&" 432 AMP@[431; 432) "&"
@@ -425,10 +451,12 @@ SOURCE_FILE@[0; 519)
425 L_PAREN@[457; 458) "(" 451 L_PAREN@[457; 458) "("
426 ATTR@[458; 465) 452 ATTR@[458; 465)
427 POUND@[458; 459) "#" 453 POUND@[458; 459) "#"
428 TOKEN_TREE@[459; 465) 454 L_BRACK@[459; 460) "["
429 L_BRACK@[459; 460) "[" 455 PATH@[460; 464)
430 IDENT@[460; 464) "attr" 456 PATH_SEGMENT@[460; 464)
431 R_BRACK@[464; 465) "]" 457 NAME_REF@[460; 464)
458 IDENT@[460; 464) "attr"
459 R_BRACK@[464; 465) "]"
432 WHITESPACE@[465; 466) " " 460 WHITESPACE@[465; 466) " "
433 SELF_PARAM@[466; 476) 461 SELF_PARAM@[466; 476)
434 SELF_KW@[466; 470) "self" 462 SELF_KW@[466; 470) "self"
@@ -455,10 +483,12 @@ SOURCE_FILE@[0; 519)
455 L_PAREN@[490; 491) "(" 483 L_PAREN@[490; 491) "("
456 ATTR@[491; 498) 484 ATTR@[491; 498)
457 POUND@[491; 492) "#" 485 POUND@[491; 492) "#"
458 TOKEN_TREE@[492; 498) 486 L_BRACK@[492; 493) "["
459 L_BRACK@[492; 493) "[" 487 PATH@[493; 497)
460 IDENT@[493; 497) "attr" 488 PATH_SEGMENT@[493; 497)
461 R_BRACK@[497; 498) "]" 489 NAME_REF@[493; 497)
490 IDENT@[493; 497) "attr"
491 R_BRACK@[497; 498) "]"
462 WHITESPACE@[498; 499) " " 492 WHITESPACE@[498; 499) " "
463 SELF_PARAM@[499; 513) 493 SELF_PARAM@[499; 513)
464 SELF_KW@[499; 503) "self" 494 SELF_KW@[499; 503) "self"
diff --git a/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt b/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt
index f77221f76..04ff0e2ff 100644
--- a/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt
@@ -4,10 +4,12 @@ SOURCE_FILE@[0; 65)
4 WHITESPACE@[13; 14) "\n" 4 WHITESPACE@[13; 14) "\n"
5 ATTR@[14; 29) 5 ATTR@[14; 29)
6 POUND@[14; 15) "#" 6 POUND@[14; 15) "#"
7 TOKEN_TREE@[15; 29) 7 L_BRACK@[15; 16) "["
8 L_BRACK@[15; 16) "[" 8 PATH@[16; 28)
9 IDENT@[16; 28) "macro_export" 9 PATH_SEGMENT@[16; 28)
10 R_BRACK@[28; 29) "]" 10 NAME_REF@[16; 28)
11 IDENT@[16; 28) "macro_export"
12 R_BRACK@[28; 29) "]"
11 WHITESPACE@[29; 30) "\n" 13 WHITESPACE@[29; 30) "\n"
12 PATH@[30; 41) 14 PATH@[30; 41)
13 PATH_SEGMENT@[30; 41) 15 PATH_SEGMENT@[30; 41)
diff --git a/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rs b/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rs
new file mode 100644
index 000000000..100fccc64
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rs
@@ -0,0 +1,7 @@
1fn foo() {
2 1 + *&2 + 3;
3 *&1 as u64;
4 *x(1);
5 &x[1];
6 -1..2;
7}
diff --git a/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.txt b/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.txt
new file mode 100644
index 000000000..d30cb63ff
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.txt
@@ -0,0 +1,97 @@
1SOURCE_FILE@[0; 79)
2 FN_DEF@[0; 78)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " "
11 BLOCK_EXPR@[9; 78)
12 BLOCK@[9; 78)
13 L_CURLY@[9; 10) "{"
14 WHITESPACE@[10; 15) "\n "
15 EXPR_STMT@[15; 27)
16 BIN_EXPR@[15; 26)
17 BIN_EXPR@[15; 22)
18 LITERAL@[15; 16)
19 INT_NUMBER@[15; 16) "1"
20 WHITESPACE@[16; 17) " "
21 PLUS@[17; 18) "+"
22 WHITESPACE@[18; 19) " "
23 PREFIX_EXPR@[19; 22)
24 STAR@[19; 20) "*"
25 REF_EXPR@[20; 22)
26 AMP@[20; 21) "&"
27 LITERAL@[21; 22)
28 INT_NUMBER@[21; 22) "2"
29 WHITESPACE@[22; 23) " "
30 PLUS@[23; 24) "+"
31 WHITESPACE@[24; 25) " "
32 LITERAL@[25; 26)
33 INT_NUMBER@[25; 26) "3"
34 SEMI@[26; 27) ";"
35 WHITESPACE@[27; 32) "\n "
36 EXPR_STMT@[32; 43)
37 CAST_EXPR@[32; 42)
38 PREFIX_EXPR@[32; 35)
39 STAR@[32; 33) "*"
40 REF_EXPR@[33; 35)
41 AMP@[33; 34) "&"
42 LITERAL@[34; 35)
43 INT_NUMBER@[34; 35) "1"
44 WHITESPACE@[35; 36) " "
45 AS_KW@[36; 38) "as"
46 WHITESPACE@[38; 39) " "
47 PATH_TYPE@[39; 42)
48 PATH@[39; 42)
49 PATH_SEGMENT@[39; 42)
50 NAME_REF@[39; 42)
51 IDENT@[39; 42) "u64"
52 SEMI@[42; 43) ";"
53 WHITESPACE@[43; 48) "\n "
54 EXPR_STMT@[48; 54)
55 PREFIX_EXPR@[48; 53)
56 STAR@[48; 49) "*"
57 CALL_EXPR@[49; 53)
58 PATH_EXPR@[49; 50)
59 PATH@[49; 50)
60 PATH_SEGMENT@[49; 50)
61 NAME_REF@[49; 50)
62 IDENT@[49; 50) "x"
63 ARG_LIST@[50; 53)
64 L_PAREN@[50; 51) "("
65 LITERAL@[51; 52)
66 INT_NUMBER@[51; 52) "1"
67 R_PAREN@[52; 53) ")"
68 SEMI@[53; 54) ";"
69 WHITESPACE@[54; 59) "\n "
70 EXPR_STMT@[59; 65)
71 REF_EXPR@[59; 64)
72 AMP@[59; 60) "&"
73 INDEX_EXPR@[60; 64)
74 PATH_EXPR@[60; 61)
75 PATH@[60; 61)
76 PATH_SEGMENT@[60; 61)
77 NAME_REF@[60; 61)
78 IDENT@[60; 61) "x"
79 L_BRACK@[61; 62) "["
80 LITERAL@[62; 63)
81 INT_NUMBER@[62; 63) "1"
82 R_BRACK@[63; 64) "]"
83 SEMI@[64; 65) ";"
84 WHITESPACE@[65; 70) "\n "
85 EXPR_STMT@[70; 76)
86 RANGE_EXPR@[70; 75)
87 PREFIX_EXPR@[70; 72)
88 MINUS@[70; 71) "-"
89 LITERAL@[71; 72)
90 INT_NUMBER@[71; 72) "1"
91 DOTDOT@[72; 74) ".."
92 LITERAL@[74; 75)
93 INT_NUMBER@[74; 75) "2"
94 SEMI@[75; 76) ";"
95 WHITESPACE@[76; 77) "\n"
96 R_CURLY@[77; 78) "}"
97 WHITESPACE@[78; 79) "\n"