aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock40
-rw-r--r--crates/ra_assists/src/assist_context.rs4
-rw-r--r--crates/ra_assists/src/handlers/expand_glob_import.rs391
-rw-r--r--crates/ra_assists/src/handlers/introduce_named_lifetime.rs2
-rw-r--r--crates/ra_assists/src/handlers/raw_string.rs2
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs42
-rw-r--r--crates/ra_assists/src/lib.rs2
-rw-r--r--crates/ra_assists/src/tests/generated.rs27
-rw-r--r--crates/ra_assists/src/utils/insert_use.rs3
-rw-r--r--crates/ra_db/Cargo.toml2
-rw-r--r--crates/ra_hir/src/db.rs9
-rw-r--r--crates/ra_hir_def/src/type_ref.rs6
-rw-r--r--crates/ra_hir_expand/src/proc_macro.rs2
-rw-r--r--crates/ra_ide/src/folding_ranges.rs23
-rw-r--r--crates/ra_ide/src/references/rename.rs2
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs2
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tests.rs3
-rw-r--r--crates/ra_ide/test_data/highlighting.html5
-rw-r--r--crates/ra_ide_db/src/change.rs24
-rw-r--r--crates/ra_ide_db/src/defs.rs25
-rw-r--r--crates/ra_parser/src/grammar/types.rs6
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs6
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs80
-rw-r--r--crates/ra_syntax/src/ast/make.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast6
-rw-r--r--crates/ra_syntax/test_data/parser/err/0044_unexpected_for_type.rast18
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast8
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast6
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast8
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0031_extern.rast32
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast2
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast6
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0067_where_for_pred.rast20
-rw-r--r--crates/rust-analyzer/src/bin/args.rs32
-rw-r--r--crates/rust-analyzer/src/bin/main.rs19
-rw-r--r--crates/rust-analyzer/src/handlers.rs5
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs40
-rw-r--r--crates/rust-analyzer/src/main_loop.rs14
-rw-r--r--docs/dev/README.md351
-rw-r--r--docs/dev/style.md212
-rw-r--r--xtask/Cargo.toml2
-rw-r--r--xtask/src/ast_src.rs6
-rw-r--r--xtask/src/codegen/gen_syntax.rs11
60 files changed, 1050 insertions, 506 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c974022a2..451928c27 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -279,9 +279,9 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
279 279
280[[package]] 280[[package]]
281name = "drop_bomb" 281name = "drop_bomb"
282version = "0.1.4" 282version = "0.1.5"
283source = "registry+https://github.com/rust-lang/crates.io-index" 283source = "registry+https://github.com/rust-lang/crates.io-index"
284checksum = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f" 284checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1"
285 285
286[[package]] 286[[package]]
287name = "either" 287name = "either"
@@ -318,9 +318,9 @@ dependencies = [
318 318
319[[package]] 319[[package]]
320name = "filetime" 320name = "filetime"
321version = "0.2.11" 321version = "0.2.12"
322source = "registry+https://github.com/rust-lang/crates.io-index" 322source = "registry+https://github.com/rust-lang/crates.io-index"
323checksum = "e500da2fab70bdc43f8f0e0b350a227f31c72311c56aba48f01d5cd62bb0345b" 323checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
324dependencies = [ 324dependencies = [
325 "cfg-if", 325 "cfg-if",
326 "libc", 326 "libc",
@@ -1371,9 +1371,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
1371 1371
1372[[package]] 1372[[package]]
1373name = "salsa" 1373name = "salsa"
1374version = "0.15.1" 1374version = "0.15.2"
1375source = "registry+https://github.com/rust-lang/crates.io-index" 1375source = "registry+https://github.com/rust-lang/crates.io-index"
1376checksum = "d4cdc109fcc9e9450c7ef47fb7474e99bffd51799da03ed0a6c7f0e2cb3848a6" 1376checksum = "9ab29056d4fb4048a5f0d169c9b6e5526160c9ec37aded5a6879c2c9c445a8e4"
1377dependencies = [ 1377dependencies = [
1378 "crossbeam-utils", 1378 "crossbeam-utils",
1379 "indexmap", 1379 "indexmap",
@@ -1388,9 +1388,9 @@ dependencies = [
1388 1388
1389[[package]] 1389[[package]]
1390name = "salsa-macros" 1390name = "salsa-macros"
1391version = "0.15.0" 1391version = "0.15.2"
1392source = "registry+https://github.com/rust-lang/crates.io-index" 1392source = "registry+https://github.com/rust-lang/crates.io-index"
1393checksum = "2c280ac85b15ac214b86ac4b407626a48e6a1c4f90769a582fec74aa57942b9f" 1393checksum = "a1c3aec007c63c4ed4cd7a018529fb0b5575c4562575fc6a40d6cd2ae0b792ef"
1394dependencies = [ 1394dependencies = [
1395 "heck", 1395 "heck",
1396 "proc-macro2", 1396 "proc-macro2",
@@ -1533,9 +1533,9 @@ version = "0.1.0"
1533 1533
1534[[package]] 1534[[package]]
1535name = "syn" 1535name = "syn"
1536version = "1.0.36" 1536version = "1.0.38"
1537source = "registry+https://github.com/rust-lang/crates.io-index" 1537source = "registry+https://github.com/rust-lang/crates.io-index"
1538checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250" 1538checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4"
1539dependencies = [ 1539dependencies = [
1540 "proc-macro2", 1540 "proc-macro2",
1541 "quote", 1541 "quote",
@@ -1622,9 +1622,9 @@ checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
1622 1622
1623[[package]] 1623[[package]]
1624name = "tracing" 1624name = "tracing"
1625version = "0.1.17" 1625version = "0.1.18"
1626source = "registry+https://github.com/rust-lang/crates.io-index" 1626source = "registry+https://github.com/rust-lang/crates.io-index"
1627checksum = "dbdf4ccd1652592b01286a5dbe1e2a77d78afaa34beadd9872a5f7396f92aaa9" 1627checksum = "f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178"
1628dependencies = [ 1628dependencies = [
1629 "cfg-if", 1629 "cfg-if",
1630 "tracing-attributes", 1630 "tracing-attributes",
@@ -1644,9 +1644,9 @@ dependencies = [
1644 1644
1645[[package]] 1645[[package]]
1646name = "tracing-core" 1646name = "tracing-core"
1647version = "0.1.11" 1647version = "0.1.13"
1648source = "registry+https://github.com/rust-lang/crates.io-index" 1648source = "registry+https://github.com/rust-lang/crates.io-index"
1649checksum = "94ae75f0d28ae10786f3b1895c55fe72e79928fd5ccdebb5438c75e93fec178f" 1649checksum = "d593f98af59ebc017c0648f0117525db358745a8894a8d684e185ba3f45954f9"
1650dependencies = [ 1650dependencies = [
1651 "lazy_static", 1651 "lazy_static",
1652] 1652]
@@ -1674,9 +1674,9 @@ dependencies = [
1674 1674
1675[[package]] 1675[[package]]
1676name = "tracing-subscriber" 1676name = "tracing-subscriber"
1677version = "0.2.9" 1677version = "0.2.10"
1678source = "registry+https://github.com/rust-lang/crates.io-index" 1678source = "registry+https://github.com/rust-lang/crates.io-index"
1679checksum = "e4f5dd7095c2481b7b3cbed71c8de53085fb3542bc3c2b4c73cba43e8f11c7ba" 1679checksum = "f7b33f8b2ef2ab0c3778c12646d9c42a24f7772bee4cdafc72199644a9f58fdc"
1680dependencies = [ 1680dependencies = [
1681 "ansi_term", 1681 "ansi_term",
1682 "chrono", 1682 "chrono",
@@ -1708,9 +1708,9 @@ dependencies = [
1708 1708
1709[[package]] 1709[[package]]
1710name = "ungrammar" 1710name = "ungrammar"
1711version = "0.1.0" 1711version = "1.1.1"
1712source = "registry+https://github.com/rust-lang/crates.io-index" 1712source = "registry+https://github.com/rust-lang/crates.io-index"
1713checksum = "0ee12e4891ab3acc2d95d5023022ace22020247bb8a8d1ece875a443f7dab37d" 1713checksum = "c4e20e58a08ee1bcf8a4695cf74550cf054d6c489105f594beacb2c684210aad"
1714 1714
1715[[package]] 1715[[package]]
1716name = "unicode-bidi" 1716name = "unicode-bidi"
@@ -1833,9 +1833,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1833 1833
1834[[package]] 1834[[package]]
1835name = "write-json" 1835name = "write-json"
1836version = "0.1.0" 1836version = "0.1.2"
1837source = "registry+https://github.com/rust-lang/crates.io-index" 1837source = "registry+https://github.com/rust-lang/crates.io-index"
1838checksum = "8b3f9a784c809a99e38d2e825907617cb03bd880d5421153bc4548e9317f59d0" 1838checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3"
1839 1839
1840[[package]] 1840[[package]]
1841name = "ws2_32-sys" 1841name = "ws2_32-sys"
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs
index 3407df856..afd3fd4b9 100644
--- a/crates/ra_assists/src/assist_context.rs
+++ b/crates/ra_assists/src/assist_context.rs
@@ -73,6 +73,10 @@ impl<'a> AssistContext<'a> {
73 self.sema.db 73 self.sema.db
74 } 74 }
75 75
76 pub(crate) fn source_file(&self) -> &SourceFile {
77 &self.source_file
78 }
79
76 // NB, this ignores active selection. 80 // NB, this ignores active selection.
77 pub(crate) fn offset(&self) -> TextSize { 81 pub(crate) fn offset(&self) -> TextSize {
78 self.frange.range.start() 82 self.frange.range.start()
diff --git a/crates/ra_assists/src/handlers/expand_glob_import.rs b/crates/ra_assists/src/handlers/expand_glob_import.rs
new file mode 100644
index 000000000..69f6b3674
--- /dev/null
+++ b/crates/ra_assists/src/handlers/expand_glob_import.rs
@@ -0,0 +1,391 @@
1use hir::{AssocItem, MacroDef, ModuleDef, Name, PathResolution, ScopeDef, SemanticsScope};
2use ra_ide_db::{
3 defs::{classify_name_ref, Definition, NameRefClass},
4 RootDatabase,
5};
6use ra_syntax::{algo, ast, match_ast, AstNode, SyntaxNode, SyntaxToken, T};
7
8use crate::{
9 assist_context::{AssistBuilder, AssistContext, Assists},
10 AssistId, AssistKind,
11};
12
13use either::Either;
14
15// Assist: expand_glob_import
16//
17// Expands glob imports.
18//
19// ```
20// mod foo {
21// pub struct Bar;
22// pub struct Baz;
23// }
24//
25// use foo::*<|>;
26//
27// fn qux(bar: Bar, baz: Baz) {}
28// ```
29// ->
30// ```
31// mod foo {
32// pub struct Bar;
33// pub struct Baz;
34// }
35//
36// use foo::{Baz, Bar};
37//
38// fn qux(bar: Bar, baz: Baz) {}
39// ```
40pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
41 let star = ctx.find_token_at_offset(T![*])?;
42 let mod_path = find_mod_path(&star)?;
43
44 let source_file = ctx.source_file();
45 let scope = ctx.sema.scope_at_offset(source_file.syntax(), ctx.offset());
46
47 let defs_in_mod = find_defs_in_mod(ctx, scope, &mod_path)?;
48 let name_refs_in_source_file =
49 source_file.syntax().descendants().filter_map(ast::NameRef::cast).collect();
50 let used_names = find_used_names(ctx, defs_in_mod, name_refs_in_source_file);
51
52 let parent = star.parent().parent()?;
53 acc.add(
54 AssistId("expand_glob_import", AssistKind::RefactorRewrite),
55 "Expand glob import",
56 parent.text_range(),
57 |builder| {
58 replace_ast(builder, &parent, mod_path, used_names);
59 },
60 )
61}
62
63fn find_mod_path(star: &SyntaxToken) -> Option<ast::Path> {
64 star.ancestors().find_map(|n| ast::UseTree::cast(n).and_then(|u| u.path()))
65}
66
67#[derive(PartialEq)]
68enum Def {
69 ModuleDef(ModuleDef),
70 MacroDef(MacroDef),
71}
72
73impl Def {
74 fn name(&self, db: &RootDatabase) -> Option<Name> {
75 match self {
76 Def::ModuleDef(def) => def.name(db),
77 Def::MacroDef(def) => def.name(db),
78 }
79 }
80}
81
82fn find_defs_in_mod(
83 ctx: &AssistContext,
84 from: SemanticsScope<'_>,
85 path: &ast::Path,
86) -> Option<Vec<Def>> {
87 let hir_path = ctx.sema.lower_path(&path)?;
88 let module = if let Some(PathResolution::Def(ModuleDef::Module(module))) =
89 from.resolve_hir_path_qualifier(&hir_path)
90 {
91 module
92 } else {
93 return None;
94 };
95
96 let module_scope = module.scope(ctx.db(), from.module());
97
98 let mut defs = vec![];
99 for (_, def) in module_scope {
100 match def {
101 ScopeDef::ModuleDef(def) => defs.push(Def::ModuleDef(def)),
102 ScopeDef::MacroDef(def) => defs.push(Def::MacroDef(def)),
103 _ => continue,
104 }
105 }
106
107 Some(defs)
108}
109
110fn find_used_names(
111 ctx: &AssistContext,
112 defs_in_mod: Vec<Def>,
113 name_refs_in_source_file: Vec<ast::NameRef>,
114) -> Vec<Name> {
115 let defs_in_source_file = name_refs_in_source_file
116 .iter()
117 .filter_map(|r| classify_name_ref(&ctx.sema, r))
118 .filter_map(|rc| match rc {
119 NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)),
120 NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)),
121 _ => None,
122 })
123 .collect::<Vec<Def>>();
124
125 defs_in_mod
126 .iter()
127 .filter(|def| {
128 if let Def::ModuleDef(ModuleDef::Trait(tr)) = def {
129 for item in tr.items(ctx.db()) {
130 if let AssocItem::Function(f) = item {
131 if defs_in_source_file.contains(&Def::ModuleDef(ModuleDef::Function(f))) {
132 return true;
133 }
134 }
135 }
136 }
137
138 defs_in_source_file.contains(def)
139 })
140 .filter_map(|d| d.name(ctx.db()))
141 .collect()
142}
143
144fn replace_ast(
145 builder: &mut AssistBuilder,
146 node: &SyntaxNode,
147 path: ast::Path,
148 used_names: Vec<Name>,
149) {
150 let replacement: Either<ast::UseTree, ast::UseTreeList> = match used_names.as_slice() {
151 [name] => Either::Left(ast::make::use_tree(
152 ast::make::path_from_text(&format!("{}::{}", path, name)),
153 None,
154 None,
155 false,
156 )),
157 names => Either::Right(ast::make::use_tree_list(names.iter().map(|n| {
158 ast::make::use_tree(ast::make::path_from_text(&n.to_string()), None, None, false)
159 }))),
160 };
161
162 let mut replace_node = |replacement: Either<ast::UseTree, ast::UseTreeList>| {
163 algo::diff(node, &replacement.either(|u| u.syntax().clone(), |ut| ut.syntax().clone()))
164 .into_text_edit(builder.text_edit_builder());
165 };
166
167 match_ast! {
168 match node {
169 ast::UseTree(use_tree) => {
170 replace_node(replacement);
171 },
172 ast::UseTreeList(use_tree_list) => {
173 replace_node(replacement);
174 },
175 ast::Use(use_item) => {
176 builder.replace_ast(use_item, ast::make::use_item(replacement.left_or_else(|ut| ast::make::use_tree(path, Some(ut), None, false))));
177 },
178 _ => {},
179 }
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use crate::tests::{check_assist, check_assist_not_applicable};
186
187 use super::*;
188
189 #[test]
190 fn expanding_glob_import() {
191 check_assist(
192 expand_glob_import,
193 r"
194mod foo {
195 pub struct Bar;
196 pub struct Baz;
197 pub struct Qux;
198
199 pub fn f() {}
200}
201
202use foo::*<|>;
203
204fn qux(bar: Bar, baz: Baz) {
205 f();
206}
207",
208 r"
209mod foo {
210 pub struct Bar;
211 pub struct Baz;
212 pub struct Qux;
213
214 pub fn f() {}
215}
216
217use foo::{Baz, Bar, f};
218
219fn qux(bar: Bar, baz: Baz) {
220 f();
221}
222",
223 )
224 }
225
226 #[test]
227 fn expanding_glob_import_with_existing_explicit_names() {
228 check_assist(
229 expand_glob_import,
230 r"
231mod foo {
232 pub struct Bar;
233 pub struct Baz;
234 pub struct Qux;
235
236 pub fn f() {}
237}
238
239use foo::{*<|>, f};
240
241fn qux(bar: Bar, baz: Baz) {
242 f();
243}
244",
245 r"
246mod foo {
247 pub struct Bar;
248 pub struct Baz;
249 pub struct Qux;
250
251 pub fn f() {}
252}
253
254use foo::{Baz, Bar, f};
255
256fn qux(bar: Bar, baz: Baz) {
257 f();
258}
259",
260 )
261 }
262
263 #[test]
264 fn expanding_nested_glob_import() {
265 check_assist(
266 expand_glob_import,
267 r"
268mod foo {
269 mod bar {
270 pub struct Bar;
271 pub struct Baz;
272 pub struct Qux;
273
274 pub fn f() {}
275 }
276
277 mod baz {
278 pub fn g() {}
279 }
280}
281
282use foo::{bar::{*<|>, f}, baz::*};
283
284fn qux(bar: Bar, baz: Baz) {
285 f();
286 g();
287}
288",
289 r"
290mod foo {
291 mod bar {
292 pub struct Bar;
293 pub struct Baz;
294 pub struct Qux;
295
296 pub fn f() {}
297 }
298
299 mod baz {
300 pub fn g() {}
301 }
302}
303
304use foo::{bar::{Baz, Bar, f}, baz::*};
305
306fn qux(bar: Bar, baz: Baz) {
307 f();
308 g();
309}
310",
311 )
312 }
313
314 #[test]
315 fn expanding_glob_import_with_macro_defs() {
316 check_assist(
317 expand_glob_import,
318 r"
319//- /lib.rs crate:foo
320#[macro_export]
321macro_rules! bar {
322 () => ()
323}
324
325pub fn baz() {}
326
327//- /main.rs crate:main deps:foo
328use foo::*<|>;
329
330fn main() {
331 bar!();
332 baz();
333}
334",
335 r"
336use foo::{bar, baz};
337
338fn main() {
339 bar!();
340 baz();
341}
342",
343 )
344 }
345
346 #[test]
347 fn expanding_glob_import_with_trait_method_uses() {
348 check_assist(
349 expand_glob_import,
350 r"
351//- /lib.rs crate:foo
352pub trait Tr {
353 fn method(&self) {}
354}
355impl Tr for () {}
356
357//- /main.rs crate:main deps:foo
358use foo::*<|>;
359
360fn main() {
361 ().method();
362}
363",
364 r"
365use foo::Tr;
366
367fn main() {
368 ().method();
369}
370",
371 )
372 }
373
374 #[test]
375 fn expanding_is_not_applicable_if_cursor_is_not_in_star_token() {
376 check_assist_not_applicable(
377 expand_glob_import,
378 r"
379 mod foo {
380 pub struct Bar;
381 pub struct Baz;
382 pub struct Qux;
383 }
384
385 use foo::Bar<|>;
386
387 fn qux(bar: Bar, baz: Baz) {}
388 ",
389 )
390 }
391}
diff --git a/crates/ra_assists/src/handlers/introduce_named_lifetime.rs b/crates/ra_assists/src/handlers/introduce_named_lifetime.rs
index 4537c73a1..fbaf3c06b 100644
--- a/crates/ra_assists/src/handlers/introduce_named_lifetime.rs
+++ b/crates/ra_assists/src/handlers/introduce_named_lifetime.rs
@@ -68,7 +68,7 @@ fn generate_fn_def_assist(
68 let fn_params_without_lifetime: Vec<_> = param_list 68 let fn_params_without_lifetime: Vec<_> = param_list
69 .params() 69 .params()
70 .filter_map(|param| match param.ty() { 70 .filter_map(|param| match param.ty() {
71 Some(ast::Type::ReferenceType(ascribed_type)) 71 Some(ast::Type::RefType(ascribed_type))
72 if ascribed_type.lifetime_token() == None => 72 if ascribed_type.lifetime_token() == None =>
73 { 73 {
74 Some(ascribed_type.amp_token()?.text_range().end()) 74 Some(ascribed_type.amp_token()?.text_range().end())
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs
index 4e8a0c2db..4c797178f 100644
--- a/crates/ra_assists/src/handlers/raw_string.rs
+++ b/crates/ra_assists/src/handlers/raw_string.rs
@@ -173,7 +173,7 @@ fn test_required_hashes() {
173} 173}
174 174
175#[cfg(test)] 175#[cfg(test)]
176mod test { 176mod tests {
177 use test_utils::mark; 177 use test_utils::mark;
178 178
179 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 179 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
index 53496ede1..da0a860c5 100644
--- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -643,4 +643,46 @@ fn main() {
643 ", 643 ",
644 ); 644 );
645 } 645 }
646
647 #[test]
648 fn does_not_replace_pub_use() {
649 check_assist(
650 replace_qualified_name_with_use,
651 r"
652pub use std::fmt;
653
654impl std::io<|> for Foo {
655}
656 ",
657 r"
658use std::io;
659
660pub use std::fmt;
661
662impl io for Foo {
663}
664 ",
665 );
666 }
667
668 #[test]
669 fn does_not_replace_pub_crate_use() {
670 check_assist(
671 replace_qualified_name_with_use,
672 r"
673pub(crate) use std::fmt;
674
675impl std::io<|> for Foo {
676}
677 ",
678 r"
679use std::io;
680
681pub(crate) use std::fmt;
682
683impl io for Foo {
684}
685 ",
686 );
687 }
646} 688}
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 465b90415..507646cc8 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -140,6 +140,7 @@ mod handlers {
140 mod change_return_type_to_result; 140 mod change_return_type_to_result;
141 mod change_visibility; 141 mod change_visibility;
142 mod early_return; 142 mod early_return;
143 mod expand_glob_import;
143 mod extract_struct_from_enum_variant; 144 mod extract_struct_from_enum_variant;
144 mod extract_variable; 145 mod extract_variable;
145 mod fill_match_arms; 146 mod fill_match_arms;
@@ -181,6 +182,7 @@ mod handlers {
181 change_return_type_to_result::change_return_type_to_result, 182 change_return_type_to_result::change_return_type_to_result,
182 change_visibility::change_visibility, 183 change_visibility::change_visibility,
183 early_return::convert_to_guarded_return, 184 early_return::convert_to_guarded_return,
185 expand_glob_import::expand_glob_import,
184 extract_struct_from_enum_variant::extract_struct_from_enum_variant, 186 extract_struct_from_enum_variant::extract_struct_from_enum_variant,
185 extract_variable::extract_variable, 187 extract_variable::extract_variable,
186 fill_match_arms::fill_match_arms, 188 fill_match_arms::fill_match_arms,
diff --git a/crates/ra_assists/src/tests/generated.rs b/crates/ra_assists/src/tests/generated.rs
index eff7feded..97978e7a2 100644
--- a/crates/ra_assists/src/tests/generated.rs
+++ b/crates/ra_assists/src/tests/generated.rs
@@ -229,6 +229,33 @@ fn main() {
229} 229}
230 230
231#[test] 231#[test]
232fn doctest_expand_glob_import() {
233 check_doc_test(
234 "expand_glob_import",
235 r#####"
236mod foo {
237 pub struct Bar;
238 pub struct Baz;
239}
240
241use foo::*<|>;
242
243fn qux(bar: Bar, baz: Baz) {}
244"#####,
245 r#####"
246mod foo {
247 pub struct Bar;
248 pub struct Baz;
249}
250
251use foo::{Baz, Bar};
252
253fn qux(bar: Bar, baz: Baz) {}
254"#####,
255 )
256}
257
258#[test]
232fn doctest_extract_struct_from_enum_variant() { 259fn doctest_extract_struct_from_enum_variant() {
233 check_doc_test( 260 check_doc_test(
234 "extract_struct_from_enum_variant", 261 "extract_struct_from_enum_variant",
diff --git a/crates/ra_assists/src/utils/insert_use.rs b/crates/ra_assists/src/utils/insert_use.rs
index 617afe2e9..32780fceb 100644
--- a/crates/ra_assists/src/utils/insert_use.rs
+++ b/crates/ra_assists/src/utils/insert_use.rs
@@ -4,7 +4,7 @@
4 4
5use hir::{self, ModPath}; 5use hir::{self, ModPath};
6use ra_syntax::{ 6use ra_syntax::{
7 ast::{self, NameOwner}, 7 ast::{self, NameOwner, VisibilityOwner},
8 AstNode, Direction, SmolStr, 8 AstNode, Direction, SmolStr,
9 SyntaxKind::{PATH, PATH_SEGMENT}, 9 SyntaxKind::{PATH, PATH_SEGMENT},
10 SyntaxNode, T, 10 SyntaxNode, T,
@@ -378,6 +378,7 @@ fn best_action_for_target(
378 let best_action = container 378 let best_action = container
379 .children() 379 .children()
380 .filter_map(ast::Use::cast) 380 .filter_map(ast::Use::cast)
381 .filter(|u| u.visibility().is_none())
381 .filter_map(|it| it.use_tree()) 382 .filter_map(|it| it.use_tree())
382 .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target)) 383 .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target))
383 .fold(None, |best, a| match best { 384 .fold(None, |best, a| match best {
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
index 5f334d04f..fe73dc015 100644
--- a/crates/ra_db/Cargo.toml
+++ b/crates/ra_db/Cargo.toml
@@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
9doctest = false 9doctest = false
10 10
11[dependencies] 11[dependencies]
12salsa = "0.15.0" 12salsa = "0.15.2"
13rustc-hash = "1.1.0" 13rustc-hash = "1.1.0"
14 14
15ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index a2b9f3e35..07333c453 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -13,14 +13,7 @@ pub use hir_expand::db::{
13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery, 13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,
14 MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery, 14 MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery,
15}; 15};
16pub use hir_ty::db::{ 16pub use hir_ty::db::*;
17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery,
18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase,
19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, InferQueryQuery,
20 InherentImplsInCrateQuery, InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery,
21 TraitDatumQuery, TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery,
22 ValueTyQuery,
23};
24 17
25#[test] 18#[test]
26fn hir_database_is_object_safe() { 19fn hir_database_is_object_safe() {
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs
index fe6619d9f..6f7884ffe 100644
--- a/crates/ra_hir_def/src/type_ref.rs
+++ b/crates/ra_hir_def/src/type_ref.rs
@@ -94,7 +94,7 @@ impl TypeRef {
94 .map(TypeRef::Path) 94 .map(TypeRef::Path)
95 .unwrap_or(TypeRef::Error) 95 .unwrap_or(TypeRef::Error)
96 } 96 }
97 ast::Type::PointerType(inner) => { 97 ast::Type::PtrType(inner) => {
98 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty()); 98 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
99 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 99 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
100 TypeRef::RawPtr(Box::new(inner_ty), mutability) 100 TypeRef::RawPtr(Box::new(inner_ty), mutability)
@@ -105,13 +105,13 @@ impl TypeRef {
105 ast::Type::SliceType(inner) => { 105 ast::Type::SliceType(inner) => {
106 TypeRef::Slice(Box::new(TypeRef::from_ast_opt(&ctx, inner.ty()))) 106 TypeRef::Slice(Box::new(TypeRef::from_ast_opt(&ctx, inner.ty())))
107 } 107 }
108 ast::Type::ReferenceType(inner) => { 108 ast::Type::RefType(inner) => {
109 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty()); 109 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
110 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 110 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
111 TypeRef::Reference(Box::new(inner_ty), mutability) 111 TypeRef::Reference(Box::new(inner_ty), mutability)
112 } 112 }
113 ast::Type::InferType(_inner) => TypeRef::Placeholder, 113 ast::Type::InferType(_inner) => TypeRef::Placeholder,
114 ast::Type::FnPointerType(inner) => { 114 ast::Type::FnPtrType(inner) => {
115 let ret_ty = inner 115 let ret_ty = inner
116 .ret_type() 116 .ret_type()
117 .and_then(|rt| rt.ty()) 117 .and_then(|rt| rt.ty())
diff --git a/crates/ra_hir_expand/src/proc_macro.rs b/crates/ra_hir_expand/src/proc_macro.rs
index 04c026004..2c0ec41d2 100644
--- a/crates/ra_hir_expand/src/proc_macro.rs
+++ b/crates/ra_hir_expand/src/proc_macro.rs
@@ -101,7 +101,7 @@ fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> {
101} 101}
102 102
103#[cfg(test)] 103#[cfg(test)]
104mod test { 104mod tests {
105 use super::*; 105 use super::*;
106 use test_utils::assert_eq_text; 106 use test_utils::assert_eq_text;
107 107
diff --git a/crates/ra_ide/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs
index 903c34996..0fbc9babd 100644
--- a/crates/ra_ide/src/folding_ranges.rs
+++ b/crates/ra_ide/src/folding_ranges.rs
@@ -85,7 +85,8 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
85 COMMENT => Some(FoldKind::Comment), 85 COMMENT => Some(FoldKind::Comment),
86 USE => Some(FoldKind::Imports), 86 USE => Some(FoldKind::Imports),
87 ARG_LIST | PARAM_LIST => Some(FoldKind::ArgList), 87 ARG_LIST | PARAM_LIST => Some(FoldKind::ArgList),
88 RECORD_FIELD_LIST 88 ASSOC_ITEM_LIST
89 | RECORD_FIELD_LIST
89 | RECORD_PAT_FIELD_LIST 90 | RECORD_PAT_FIELD_LIST
90 | RECORD_EXPR_FIELD_LIST 91 | RECORD_EXPR_FIELD_LIST
91 | ITEM_LIST 92 | ITEM_LIST
@@ -337,6 +338,26 @@ fn main() <fold block>{
337 } 338 }
338 339
339 #[test] 340 #[test]
341 fn test_folds_structs() {
342 check(
343 r#"
344struct Foo <fold block>{
345}</fold>
346"#,
347 );
348 }
349
350 #[test]
351 fn test_folds_traits() {
352 check(
353 r#"
354trait Foo <fold block>{
355}</fold>
356"#,
357 );
358 }
359
360 #[test]
340 fn test_folds_macros() { 361 fn test_folds_macros() {
341 check( 362 check(
342 r#" 363 r#"
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index 3cd6c815b..c8d80fcf7 100644
--- a/crates/ra_ide/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
@@ -157,7 +157,7 @@ fn rename_to_self(
157 } 157 }
158 let first_param = params.params().next()?; 158 let first_param = params.params().next()?;
159 let mutable = match first_param.ty() { 159 let mutable = match first_param.ty() {
160 Some(ast::Type::ReferenceType(rt)) => rt.mut_token().is_some(), 160 Some(ast::Type::RefType(rt)) => rt.mut_token().is_some(),
161 _ => return None, // not renaming other types 161 _ => return None, // not renaming other types
162 }; 162 };
163 163
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 32f34ef10..a32ae0165 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -546,7 +546,7 @@ fn highlight_element(
546 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { 546 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
547 HighlightTag::Macro.into() 547 HighlightTag::Macro.into()
548 } 548 }
549 T![*] if element.parent().and_then(ast::PointerType::cast).is_some() => { 549 T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => {
550 HighlightTag::Keyword.into() 550 HighlightTag::Keyword.into()
551 } 551 }
552 T![*] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { 552 T![*] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => {
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index 87a6e2523..2deee404c 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -9,6 +9,9 @@ use crate::{mock_analysis::single_file, FileRange, TextRange};
9fn test_highlighting() { 9fn test_highlighting() {
10 check_highlighting( 10 check_highlighting(
11 r#" 11 r#"
12use inner::{self as inner_mod};
13mod inner {}
14
12#[derive(Clone, Debug)] 15#[derive(Clone, Debug)]
13struct Foo { 16struct Foo {
14 pub x: i32, 17 pub x: i32,
diff --git a/crates/ra_ide/test_data/highlighting.html b/crates/ra_ide/test_data/highlighting.html
index 345a2f023..23c25ad8c 100644
--- a/crates/ra_ide/test_data/highlighting.html
+++ b/crates/ra_ide/test_data/highlighting.html
@@ -35,7 +35,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
35 35
36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; } 36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
37</style> 37</style>
38<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span> 38<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span>
39<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span>
40
41<span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span>
39<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> 42<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span>
40 <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> 43 <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span>
41 <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> 44 <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span>
diff --git a/crates/ra_ide_db/src/change.rs b/crates/ra_ide_db/src/change.rs
index 32d9a8d1f..b13df8b85 100644
--- a/crates/ra_ide_db/src/change.rs
+++ b/crates/ra_ide_db/src/change.rs
@@ -190,11 +190,24 @@ impl RootDatabase {
190 let q: $q = Default::default(); 190 let q: $q = Default::default();
191 let name = format!("{:?} (deps)", q); 191 let name = format!("{:?} (deps)", q);
192 acc.push((name, before - after)); 192 acc.push((name, before - after));
193
194 let before = memory_usage().allocated;
195 $q.in_db(self).purge();
196 let after = memory_usage().allocated;
197 let q: $q = Default::default();
198 let name = format!("{:?} (purge)", q);
199 acc.push((name, before - after));
193 )*} 200 )*}
194 } 201 }
195 sweep_each_query![ 202 sweep_each_query![
196 // SourceDatabase 203 // SourceDatabase
197 ra_db::ParseQuery 204 ra_db::ParseQuery
205 ra_db::CrateGraphQuery
206
207 // SourceDatabaseExt
208 ra_db::FileTextQuery
209 ra_db::FileSourceRootQuery
210 ra_db::SourceRootQuery
198 ra_db::SourceRootCratesQuery 211 ra_db::SourceRootCratesQuery
199 212
200 // AstDatabase 213 // AstDatabase
@@ -242,15 +255,24 @@ impl RootDatabase {
242 hir::db::TraitImplsInCrateQuery 255 hir::db::TraitImplsInCrateQuery
243 hir::db::TraitImplsInDepsQuery 256 hir::db::TraitImplsInDepsQuery
244 hir::db::AssociatedTyDataQuery 257 hir::db::AssociatedTyDataQuery
258 hir::db::AssociatedTyDataQuery
245 hir::db::TraitDatumQuery 259 hir::db::TraitDatumQuery
246 hir::db::StructDatumQuery 260 hir::db::StructDatumQuery
247 hir::db::ImplDatumQuery 261 hir::db::ImplDatumQuery
262 hir::db::FnDefDatumQuery
263 hir::db::ReturnTypeImplTraitsQuery
264 hir::db::InternCallableDefQuery
265 hir::db::InternTypeParamIdQuery
266 hir::db::InternImplTraitIdQuery
267 hir::db::InternClosureQuery
248 hir::db::AssociatedTyValueQuery 268 hir::db::AssociatedTyValueQuery
249 hir::db::TraitSolveQuery 269 hir::db::TraitSolveQuery
250 hir::db::ReturnTypeImplTraitsQuery
251 270
252 // SymbolsDatabase 271 // SymbolsDatabase
253 crate::symbol_index::FileSymbolsQuery 272 crate::symbol_index::FileSymbolsQuery
273 crate::symbol_index::LibrarySymbolsQuery
274 crate::symbol_index::LocalRootsQuery
275 crate::symbol_index::LibraryRootsQuery
254 276
255 // LineIndexDatabase 277 // LineIndexDatabase
256 crate::LineIndexQuery 278 crate::LineIndexQuery
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 66c048714..b51000b03 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -12,7 +12,7 @@ use hir::{
12use ra_prof::profile; 12use ra_prof::profile;
13use ra_syntax::{ 13use ra_syntax::{
14 ast::{self, AstNode}, 14 ast::{self, AstNode},
15 match_ast, 15 match_ast, SyntaxNode,
16}; 16};
17 17
18use crate::RootDatabase; 18use crate::RootDatabase;
@@ -123,8 +123,27 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
123 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; 123 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?;
124 let path = use_tree.path()?; 124 let path = use_tree.path()?;
125 let path_segment = path.segment()?; 125 let path_segment = path.segment()?;
126 let name_ref = path_segment.name_ref()?; 126 let name_ref_class = path_segment
127 let name_ref_class = classify_name_ref(sema, &name_ref)?; 127 .name_ref()
128 // The rename might be from a `self` token, so fallback to the name higher
129 // in the use tree.
130 .or_else(||{
131 if path_segment.self_token().is_none() {
132 return None;
133 }
134
135 let use_tree = use_tree
136 .syntax()
137 .parent()
138 .as_ref()
139 // Skip over UseTreeList
140 .and_then(SyntaxNode::parent)
141 .and_then(ast::UseTree::cast)?;
142 let path = use_tree.path()?;
143 let path_segment = path.segment()?;
144 path_segment.name_ref()
145 })
146 .and_then(|name_ref| classify_name_ref(sema, &name_ref))?;
128 147
129 Some(NameClass::Definition(name_ref_class.definition())) 148 Some(NameClass::Definition(name_ref_class.definition()))
130 }, 149 },
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index e9a20fbf1..0aa173a52 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -117,7 +117,7 @@ fn pointer_type(p: &mut Parser) {
117 }; 117 };
118 118
119 type_no_bounds(p); 119 type_no_bounds(p);
120 m.complete(p, POINTER_TYPE); 120 m.complete(p, PTR_TYPE);
121} 121}
122 122
123fn array_or_slice_type(p: &mut Parser) { 123fn array_or_slice_type(p: &mut Parser) {
@@ -163,7 +163,7 @@ fn reference_type(p: &mut Parser) {
163 p.eat(LIFETIME); 163 p.eat(LIFETIME);
164 p.eat(T![mut]); 164 p.eat(T![mut]);
165 type_no_bounds(p); 165 type_no_bounds(p);
166 m.complete(p, REFERENCE_TYPE); 166 m.complete(p, REF_TYPE);
167} 167}
168 168
169// test placeholder_type 169// test placeholder_type
@@ -201,7 +201,7 @@ fn fn_pointer_type(p: &mut Parser) {
201 // test fn_pointer_type_with_ret 201 // test fn_pointer_type_with_ret
202 // type F = fn() -> (); 202 // type F = fn() -> ();
203 opt_fn_ret_type(p); 203 opt_fn_ret_type(p);
204 m.complete(p, FN_POINTER_TYPE); 204 m.complete(p, FN_PTR_TYPE);
205} 205}
206 206
207pub(super) fn for_binder(p: &mut Parser) { 207pub(super) fn for_binder(p: &mut Parser) {
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index b18653aa5..192ecd864 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -143,12 +143,12 @@ pub enum SyntaxKind {
143 TUPLE_TYPE, 143 TUPLE_TYPE,
144 NEVER_TYPE, 144 NEVER_TYPE,
145 PATH_TYPE, 145 PATH_TYPE,
146 POINTER_TYPE, 146 PTR_TYPE,
147 ARRAY_TYPE, 147 ARRAY_TYPE,
148 SLICE_TYPE, 148 SLICE_TYPE,
149 REFERENCE_TYPE, 149 REF_TYPE,
150 INFER_TYPE, 150 INFER_TYPE,
151 FN_POINTER_TYPE, 151 FN_PTR_TYPE,
152 FOR_TYPE, 152 FOR_TYPE,
153 IMPL_TRAIT_TYPE, 153 IMPL_TRAIT_TYPE,
154 DYN_TRAIT_TYPE, 154 DYN_TRAIT_TYPE,
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index 5f51c7536..3d49309d1 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -1006,10 +1006,10 @@ impl DynTraitType {
1006 pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) } 1006 pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
1007} 1007}
1008#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1008#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1009pub struct FnPointerType { 1009pub struct FnPtrType {
1010 pub(crate) syntax: SyntaxNode, 1010 pub(crate) syntax: SyntaxNode,
1011} 1011}
1012impl FnPointerType { 1012impl FnPtrType {
1013 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) } 1013 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
1014 pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) } 1014 pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
1015 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) } 1015 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
@@ -1059,20 +1059,20 @@ impl ParenType {
1059 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } 1059 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
1060} 1060}
1061#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1061#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1062pub struct PointerType { 1062pub struct PtrType {
1063 pub(crate) syntax: SyntaxNode, 1063 pub(crate) syntax: SyntaxNode,
1064} 1064}
1065impl PointerType { 1065impl PtrType {
1066 pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) } 1066 pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
1067 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) } 1067 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
1068 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } 1068 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
1069 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } 1069 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
1070} 1070}
1071#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1071#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1072pub struct ReferenceType { 1072pub struct RefType {
1073 pub(crate) syntax: SyntaxNode, 1073 pub(crate) syntax: SyntaxNode,
1074} 1074}
1075impl ReferenceType { 1075impl RefType {
1076 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } 1076 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
1077 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 1077 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
1078 support::token(&self.syntax, T![lifetime]) 1078 support::token(&self.syntax, T![lifetime])
@@ -1263,15 +1263,15 @@ pub enum GenericArg {
1263pub enum Type { 1263pub enum Type {
1264 ArrayType(ArrayType), 1264 ArrayType(ArrayType),
1265 DynTraitType(DynTraitType), 1265 DynTraitType(DynTraitType),
1266 FnPointerType(FnPointerType), 1266 FnPtrType(FnPtrType),
1267 ForType(ForType), 1267 ForType(ForType),
1268 ImplTraitType(ImplTraitType), 1268 ImplTraitType(ImplTraitType),
1269 InferType(InferType), 1269 InferType(InferType),
1270 NeverType(NeverType), 1270 NeverType(NeverType),
1271 ParenType(ParenType), 1271 ParenType(ParenType),
1272 PathType(PathType), 1272 PathType(PathType),
1273 PointerType(PointerType), 1273 PtrType(PtrType),
1274 ReferenceType(ReferenceType), 1274 RefType(RefType),
1275 SliceType(SliceType), 1275 SliceType(SliceType),
1276 TupleType(TupleType), 1276 TupleType(TupleType),
1277} 1277}
@@ -1377,8 +1377,8 @@ impl ast::NameOwner for AssocItem {}
1377#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1377#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1378pub enum ExternItem { 1378pub enum ExternItem {
1379 Fn(Fn), 1379 Fn(Fn),
1380 Static(Static),
1381 MacroCall(MacroCall), 1380 MacroCall(MacroCall),
1381 Static(Static),
1382} 1382}
1383impl ast::AttrsOwner for ExternItem {} 1383impl ast::AttrsOwner for ExternItem {}
1384impl ast::NameOwner for ExternItem {} 1384impl ast::NameOwner for ExternItem {}
@@ -2434,8 +2434,8 @@ impl AstNode for DynTraitType {
2434 } 2434 }
2435 fn syntax(&self) -> &SyntaxNode { &self.syntax } 2435 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2436} 2436}
2437impl AstNode for FnPointerType { 2437impl AstNode for FnPtrType {
2438 fn can_cast(kind: SyntaxKind) -> bool { kind == FN_POINTER_TYPE } 2438 fn can_cast(kind: SyntaxKind) -> bool { kind == FN_PTR_TYPE }
2439 fn cast(syntax: SyntaxNode) -> Option<Self> { 2439 fn cast(syntax: SyntaxNode) -> Option<Self> {
2440 if Self::can_cast(syntax.kind()) { 2440 if Self::can_cast(syntax.kind()) {
2441 Some(Self { syntax }) 2441 Some(Self { syntax })
@@ -2500,8 +2500,8 @@ impl AstNode for ParenType {
2500 } 2500 }
2501 fn syntax(&self) -> &SyntaxNode { &self.syntax } 2501 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2502} 2502}
2503impl AstNode for PointerType { 2503impl AstNode for PtrType {
2504 fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE } 2504 fn can_cast(kind: SyntaxKind) -> bool { kind == PTR_TYPE }
2505 fn cast(syntax: SyntaxNode) -> Option<Self> { 2505 fn cast(syntax: SyntaxNode) -> Option<Self> {
2506 if Self::can_cast(syntax.kind()) { 2506 if Self::can_cast(syntax.kind()) {
2507 Some(Self { syntax }) 2507 Some(Self { syntax })
@@ -2511,8 +2511,8 @@ impl AstNode for PointerType {
2511 } 2511 }
2512 fn syntax(&self) -> &SyntaxNode { &self.syntax } 2512 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2513} 2513}
2514impl AstNode for ReferenceType { 2514impl AstNode for RefType {
2515 fn can_cast(kind: SyntaxKind) -> bool { kind == REFERENCE_TYPE } 2515 fn can_cast(kind: SyntaxKind) -> bool { kind == REF_TYPE }
2516 fn cast(syntax: SyntaxNode) -> Option<Self> { 2516 fn cast(syntax: SyntaxNode) -> Option<Self> {
2517 if Self::can_cast(syntax.kind()) { 2517 if Self::can_cast(syntax.kind()) {
2518 Some(Self { syntax }) 2518 Some(Self { syntax })
@@ -2786,8 +2786,8 @@ impl From<ArrayType> for Type {
2786impl From<DynTraitType> for Type { 2786impl From<DynTraitType> for Type {
2787 fn from(node: DynTraitType) -> Type { Type::DynTraitType(node) } 2787 fn from(node: DynTraitType) -> Type { Type::DynTraitType(node) }
2788} 2788}
2789impl From<FnPointerType> for Type { 2789impl From<FnPtrType> for Type {
2790 fn from(node: FnPointerType) -> Type { Type::FnPointerType(node) } 2790 fn from(node: FnPtrType) -> Type { Type::FnPtrType(node) }
2791} 2791}
2792impl From<ForType> for Type { 2792impl From<ForType> for Type {
2793 fn from(node: ForType) -> Type { Type::ForType(node) } 2793 fn from(node: ForType) -> Type { Type::ForType(node) }
@@ -2807,11 +2807,11 @@ impl From<ParenType> for Type {
2807impl From<PathType> for Type { 2807impl From<PathType> for Type {
2808 fn from(node: PathType) -> Type { Type::PathType(node) } 2808 fn from(node: PathType) -> Type { Type::PathType(node) }
2809} 2809}
2810impl From<PointerType> for Type { 2810impl From<PtrType> for Type {
2811 fn from(node: PointerType) -> Type { Type::PointerType(node) } 2811 fn from(node: PtrType) -> Type { Type::PtrType(node) }
2812} 2812}
2813impl From<ReferenceType> for Type { 2813impl From<RefType> for Type {
2814 fn from(node: ReferenceType) -> Type { Type::ReferenceType(node) } 2814 fn from(node: RefType) -> Type { Type::RefType(node) }
2815} 2815}
2816impl From<SliceType> for Type { 2816impl From<SliceType> for Type {
2817 fn from(node: SliceType) -> Type { Type::SliceType(node) } 2817 fn from(node: SliceType) -> Type { Type::SliceType(node) }
@@ -2822,9 +2822,9 @@ impl From<TupleType> for Type {
2822impl AstNode for Type { 2822impl AstNode for Type {
2823 fn can_cast(kind: SyntaxKind) -> bool { 2823 fn can_cast(kind: SyntaxKind) -> bool {
2824 match kind { 2824 match kind {
2825 ARRAY_TYPE | DYN_TRAIT_TYPE | FN_POINTER_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE 2825 ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE
2826 | INFER_TYPE | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | POINTER_TYPE | REFERENCE_TYPE 2826 | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE | SLICE_TYPE
2827 | SLICE_TYPE | TUPLE_TYPE => true, 2827 | TUPLE_TYPE => true,
2828 _ => false, 2828 _ => false,
2829 } 2829 }
2830 } 2830 }
@@ -2832,15 +2832,15 @@ impl AstNode for Type {
2832 let res = match syntax.kind() { 2832 let res = match syntax.kind() {
2833 ARRAY_TYPE => Type::ArrayType(ArrayType { syntax }), 2833 ARRAY_TYPE => Type::ArrayType(ArrayType { syntax }),
2834 DYN_TRAIT_TYPE => Type::DynTraitType(DynTraitType { syntax }), 2834 DYN_TRAIT_TYPE => Type::DynTraitType(DynTraitType { syntax }),
2835 FN_POINTER_TYPE => Type::FnPointerType(FnPointerType { syntax }), 2835 FN_PTR_TYPE => Type::FnPtrType(FnPtrType { syntax }),
2836 FOR_TYPE => Type::ForType(ForType { syntax }), 2836 FOR_TYPE => Type::ForType(ForType { syntax }),
2837 IMPL_TRAIT_TYPE => Type::ImplTraitType(ImplTraitType { syntax }), 2837 IMPL_TRAIT_TYPE => Type::ImplTraitType(ImplTraitType { syntax }),
2838 INFER_TYPE => Type::InferType(InferType { syntax }), 2838 INFER_TYPE => Type::InferType(InferType { syntax }),
2839 NEVER_TYPE => Type::NeverType(NeverType { syntax }), 2839 NEVER_TYPE => Type::NeverType(NeverType { syntax }),
2840 PAREN_TYPE => Type::ParenType(ParenType { syntax }), 2840 PAREN_TYPE => Type::ParenType(ParenType { syntax }),
2841 PATH_TYPE => Type::PathType(PathType { syntax }), 2841 PATH_TYPE => Type::PathType(PathType { syntax }),
2842 POINTER_TYPE => Type::PointerType(PointerType { syntax }), 2842 PTR_TYPE => Type::PtrType(PtrType { syntax }),
2843 REFERENCE_TYPE => Type::ReferenceType(ReferenceType { syntax }), 2843 REF_TYPE => Type::RefType(RefType { syntax }),
2844 SLICE_TYPE => Type::SliceType(SliceType { syntax }), 2844 SLICE_TYPE => Type::SliceType(SliceType { syntax }),
2845 TUPLE_TYPE => Type::TupleType(TupleType { syntax }), 2845 TUPLE_TYPE => Type::TupleType(TupleType { syntax }),
2846 _ => return None, 2846 _ => return None,
@@ -2851,15 +2851,15 @@ impl AstNode for Type {
2851 match self { 2851 match self {
2852 Type::ArrayType(it) => &it.syntax, 2852 Type::ArrayType(it) => &it.syntax,
2853 Type::DynTraitType(it) => &it.syntax, 2853 Type::DynTraitType(it) => &it.syntax,
2854 Type::FnPointerType(it) => &it.syntax, 2854 Type::FnPtrType(it) => &it.syntax,
2855 Type::ForType(it) => &it.syntax, 2855 Type::ForType(it) => &it.syntax,
2856 Type::ImplTraitType(it) => &it.syntax, 2856 Type::ImplTraitType(it) => &it.syntax,
2857 Type::InferType(it) => &it.syntax, 2857 Type::InferType(it) => &it.syntax,
2858 Type::NeverType(it) => &it.syntax, 2858 Type::NeverType(it) => &it.syntax,
2859 Type::ParenType(it) => &it.syntax, 2859 Type::ParenType(it) => &it.syntax,
2860 Type::PathType(it) => &it.syntax, 2860 Type::PathType(it) => &it.syntax,
2861 Type::PointerType(it) => &it.syntax, 2861 Type::PtrType(it) => &it.syntax,
2862 Type::ReferenceType(it) => &it.syntax, 2862 Type::RefType(it) => &it.syntax,
2863 Type::SliceType(it) => &it.syntax, 2863 Type::SliceType(it) => &it.syntax,
2864 Type::TupleType(it) => &it.syntax, 2864 Type::TupleType(it) => &it.syntax,
2865 } 2865 }
@@ -3332,24 +3332,24 @@ impl AstNode for AssocItem {
3332impl From<Fn> for ExternItem { 3332impl From<Fn> for ExternItem {
3333 fn from(node: Fn) -> ExternItem { ExternItem::Fn(node) } 3333 fn from(node: Fn) -> ExternItem { ExternItem::Fn(node) }
3334} 3334}
3335impl From<Static> for ExternItem {
3336 fn from(node: Static) -> ExternItem { ExternItem::Static(node) }
3337}
3338impl From<MacroCall> for ExternItem { 3335impl From<MacroCall> for ExternItem {
3339 fn from(node: MacroCall) -> ExternItem { ExternItem::MacroCall(node) } 3336 fn from(node: MacroCall) -> ExternItem { ExternItem::MacroCall(node) }
3340} 3337}
3338impl From<Static> for ExternItem {
3339 fn from(node: Static) -> ExternItem { ExternItem::Static(node) }
3340}
3341impl AstNode for ExternItem { 3341impl AstNode for ExternItem {
3342 fn can_cast(kind: SyntaxKind) -> bool { 3342 fn can_cast(kind: SyntaxKind) -> bool {
3343 match kind { 3343 match kind {
3344 FN | STATIC | MACRO_CALL => true, 3344 FN | MACRO_CALL | STATIC => true,
3345 _ => false, 3345 _ => false,
3346 } 3346 }
3347 } 3347 }
3348 fn cast(syntax: SyntaxNode) -> Option<Self> { 3348 fn cast(syntax: SyntaxNode) -> Option<Self> {
3349 let res = match syntax.kind() { 3349 let res = match syntax.kind() {
3350 FN => ExternItem::Fn(Fn { syntax }), 3350 FN => ExternItem::Fn(Fn { syntax }),
3351 STATIC => ExternItem::Static(Static { syntax }),
3352 MACRO_CALL => ExternItem::MacroCall(MacroCall { syntax }), 3351 MACRO_CALL => ExternItem::MacroCall(MacroCall { syntax }),
3352 STATIC => ExternItem::Static(Static { syntax }),
3353 _ => return None, 3353 _ => return None,
3354 }; 3354 };
3355 Some(res) 3355 Some(res)
@@ -3357,8 +3357,8 @@ impl AstNode for ExternItem {
3357 fn syntax(&self) -> &SyntaxNode { 3357 fn syntax(&self) -> &SyntaxNode {
3358 match self { 3358 match self {
3359 ExternItem::Fn(it) => &it.syntax, 3359 ExternItem::Fn(it) => &it.syntax,
3360 ExternItem::Static(it) => &it.syntax,
3361 ExternItem::MacroCall(it) => &it.syntax, 3360 ExternItem::MacroCall(it) => &it.syntax,
3361 ExternItem::Static(it) => &it.syntax,
3362 } 3362 }
3363 } 3363 }
3364} 3364}
@@ -3925,7 +3925,7 @@ impl std::fmt::Display for DynTraitType {
3925 std::fmt::Display::fmt(self.syntax(), f) 3925 std::fmt::Display::fmt(self.syntax(), f)
3926 } 3926 }
3927} 3927}
3928impl std::fmt::Display for FnPointerType { 3928impl std::fmt::Display for FnPtrType {
3929 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3929 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3930 std::fmt::Display::fmt(self.syntax(), f) 3930 std::fmt::Display::fmt(self.syntax(), f)
3931 } 3931 }
@@ -3955,12 +3955,12 @@ impl std::fmt::Display for ParenType {
3955 std::fmt::Display::fmt(self.syntax(), f) 3955 std::fmt::Display::fmt(self.syntax(), f)
3956 } 3956 }
3957} 3957}
3958impl std::fmt::Display for PointerType { 3958impl std::fmt::Display for PtrType {
3959 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3959 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3960 std::fmt::Display::fmt(self.syntax(), f) 3960 std::fmt::Display::fmt(self.syntax(), f)
3961 } 3961 }
3962} 3962}
3963impl std::fmt::Display for ReferenceType { 3963impl std::fmt::Display for RefType {
3964 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3964 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3965 std::fmt::Display::fmt(self.syntax(), f) 3965 std::fmt::Display::fmt(self.syntax(), f)
3966 } 3966 }
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index 673777015..3cb1d35ee 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -30,7 +30,7 @@ pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
30pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path { 30pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
31 path_from_text(&format!("{}::{}", qual, segment)) 31 path_from_text(&format!("{}::{}", qual, segment))
32} 32}
33fn path_from_text(text: &str) -> ast::Path { 33pub fn path_from_text(text: &str) -> ast::Path {
34 ast_from_text(text) 34 ast_from_text(text)
35} 35}
36 36
diff --git a/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast b/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast
index c131b79a7..f31c27633 100644
--- a/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast
+++ b/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast
@@ -39,7 +39,7 @@ [email protected]
39 [email protected] "builder" 39 [email protected] "builder"
40 [email protected] 40 [email protected]
41 [email protected] 41 [email protected]
42 REFERENCE[email protected] 42 [email protected]
43 [email protected] 43 [email protected]
44 [email protected] 44 [email protected]
45 [email protected] 45 [email protected]
@@ -56,7 +56,7 @@ [email protected]
56 [email protected] "tokens" 56 [email protected] "tokens"
57 [email protected] 57 [email protected]
58 [email protected] 58 [email protected]
59 REFERENCE[email protected] 59 [email protected]
60 [email protected] 60 [email protected]
61 [email protected] 61 [email protected]
62 [email protected] 62 [email protected]
@@ -126,7 +126,7 @@ [email protected]
126 [email protected] "idx" 126 [email protected] "idx"
127 [email protected] 127 [email protected]
128 [email protected] 128 [email protected]
129 REFERENCE[email protected] 129 [email protected]
130 [email protected] 130 [email protected]
131 [email protected] 131 [email protected]
132 [email protected] 132 [email protected]
diff --git a/crates/ra_syntax/test_data/parser/err/0044_unexpected_for_type.rast b/crates/ra_syntax/test_data/parser/err/0044_unexpected_for_type.rast
index 082625c13..71aa86494 100644
--- a/crates/ra_syntax/test_data/parser/err/0044_unexpected_for_type.rast
+++ b/crates/ra_syntax/test_data/parser/err/0044_unexpected_for_type.rast
@@ -15,7 +15,7 @@ [email protected]
15 [email protected] "\'a" 15 [email protected] "\'a"
16 [email protected] ">" 16 [email protected] ">"
17 [email protected] " " 17 [email protected] " "
18 REFERENCE[email protected] 18 [email protected]
19 [email protected] "&" 19 [email protected] "&"
20 [email protected] "\'a" 20 [email protected] "\'a"
21 [email protected] " " 21 [email protected] " "
@@ -44,7 +44,7 @@ [email protected]
44 [email protected] " " 44 [email protected] " "
45 [email protected] 45 [email protected]
46 [email protected] "(" 46 [email protected] "("
47 REFERENCE[email protected] 47 [email protected]
48 [email protected] "&" 48 [email protected] "&"
49 [email protected] "\'a" 49 [email protected] "\'a"
50 [email protected] " " 50 [email protected] " "
@@ -107,12 +107,12 @@ [email protected]
107 [email protected] "\'b" 107 [email protected] "\'b"
108 [email protected] ">" 108 [email protected] ">"
109 [email protected] " " 109 [email protected] " "
110 FN_POINTE[email protected] 110 [email protected]
111 [email protected] "fn" 111 [email protected] "fn"
112 [email protected] 112 [email protected]
113 [email protected] "(" 113 [email protected] "("
114 [email protected] 114 [email protected]
115 REFERENCE[email protected] 115 [email protected]
116 [email protected] "&" 116 [email protected] "&"
117 [email protected] "\'a" 117 [email protected] "\'a"
118 [email protected] " " 118 [email protected] " "
@@ -124,7 +124,7 @@ [email protected]
124 [email protected] "," 124 [email protected] ","
125 [email protected] " " 125 [email protected] " "
126 [email protected] 126 [email protected]
127 REFERENCE[email protected] 127 [email protected]
128 [email protected] "&" 128 [email protected] "&"
129 [email protected] "\'b" 129 [email protected] "\'b"
130 [email protected] " " 130 [email protected] " "
@@ -178,12 +178,12 @@ [email protected]
178 [email protected] "\'c" 178 [email protected] "\'c"
179 [email protected] ">" 179 [email protected] ">"
180 [email protected] " " 180 [email protected] " "
181 FN_POINTE[email protected] 181 [email protected]
182 [email protected] "fn" 182 [email protected] "fn"
183 [email protected] 183 [email protected]
184 [email protected] "(" 184 [email protected] "("
185 [email protected] 185 [email protected]
186 REFERENCE[email protected] 186 [email protected]
187 [email protected] "&" 187 [email protected] "&"
188 [email protected] "\'a" 188 [email protected] "\'a"
189 [email protected] " " 189 [email protected] " "
@@ -195,7 +195,7 @@ [email protected]
195 [email protected] "," 195 [email protected] ","
196 [email protected] " " 196 [email protected] " "
197 [email protected] 197 [email protected]
198 REFERENCE[email protected] 198 [email protected]
199 [email protected] "&" 199 [email protected] "&"
200 [email protected] "\'b" 200 [email protected] "\'b"
201 [email protected] " " 201 [email protected] " "
@@ -207,7 +207,7 @@ [email protected]
207 [email protected] "," 207 [email protected] ","
208 [email protected] " " 208 [email protected] " "
209 [email protected] 209 [email protected]
210 REFERENCE[email protected] 210 [email protected]
211 [email protected] "&" 211 [email protected] "&"
212 [email protected] "\'c" 212 [email protected] "\'c"
213 [email protected] " " 213 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast b/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast
index 2409eefe7..0d8bf6dd6 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast
+++ b/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast
@@ -7,7 +7,7 @@ [email protected]
7 [email protected] " " 7 [email protected] " "
8 [email protected] "=" 8 [email protected] "="
9 [email protected] " " 9 [email protected] " "
10 POINTE[email protected] 10 [email protected]
11 [email protected] "*" 11 [email protected] "*"
12 [email protected] 12 [email protected]
13 [email protected] "(" 13 [email protected] "("
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast b/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
index b0f2b5888..62da7b887 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
@@ -42,7 +42,7 @@ [email protected]
42 [email protected] 42 [email protected]
43 [email protected] "(" 43 [email protected] "("
44 [email protected] 44 [email protected]
45 REFERENCE[email protected] 45 [email protected]
46 [email protected] "&" 46 [email protected] "&"
47 [email protected] "\'a" 47 [email protected] "\'a"
48 [email protected] " " 48 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast
index 44d92aedb..b650735ba 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast
@@ -31,7 +31,7 @@ [email protected]
31 [email protected] "," 31 [email protected] ","
32 [email protected] " " 32 [email protected] " "
33 [email protected] 33 [email protected]
34 REFERENCE[email protected] 34 [email protected]
35 [email protected] "&" 35 [email protected] "&"
36 [email protected] 36 [email protected]
37 [email protected] 37 [email protected]
@@ -41,7 +41,7 @@ [email protected]
41 [email protected] "," 41 [email protected] ","
42 [email protected] " " 42 [email protected] " "
43 [email protected] 43 [email protected]
44 REFERENCE[email protected] 44 [email protected]
45 [email protected] "&" 45 [email protected] "&"
46 [email protected] 46 [email protected]
47 [email protected] 47 [email protected]
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast b/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast
index 845b32e6d..d33215b50 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast
@@ -7,7 +7,7 @@ [email protected]
7 [email protected] " " 7 [email protected] " "
8 [email protected] "=" 8 [email protected] "="
9 [email protected] " " 9 [email protected] " "
10 POINTE[email protected] 10 [email protected]
11 [email protected] "*" 11 [email protected] "*"
12 [email protected] "mut" 12 [email protected] "mut"
13 [email protected] " " 13 [email protected] " "
@@ -24,7 +24,7 @@ [email protected]
24 [email protected] " " 24 [email protected] " "
25 [email protected] "=" 25 [email protected] "="
26 [email protected] " " 26 [email protected] " "
27 POINTE[email protected] 27 [email protected]
28 [email protected] "*" 28 [email protected] "*"
29 [email protected] "mut" 29 [email protected] "mut"
30 [email protected] " " 30 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast b/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast
index 1b31aa95a..ddbd66588 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast
@@ -22,7 +22,7 @@ [email protected]
22 [email protected] "self" 22 [email protected] "self"
23 [email protected] ":" 23 [email protected] ":"
24 [email protected] " " 24 [email protected] " "
25 REFERENCE[email protected] 25 [email protected]
26 [email protected] "&" 26 [email protected] "&"
27 [email protected] 27 [email protected]
28 [email protected] 28 [email protected]
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast b/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast
index 79a5ee339..dda6577ed 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast
@@ -7,7 +7,7 @@ [email protected]
7 [email protected] " " 7 [email protected] " "
8 [email protected] "=" 8 [email protected] "="
9 [email protected] " " 9 [email protected] " "
10 FN_POINTE[email protected] 10 [email protected]
11 [email protected] "fn" 11 [email protected] "fn"
12 [email protected] 12 [email protected]
13 [email protected] "(" 13 [email protected] "("
@@ -22,7 +22,7 @@ [email protected]
22 [email protected] " " 22 [email protected] " "
23 [email protected] "=" 23 [email protected] "="
24 [email protected] " " 24 [email protected] " "
25 FN_POINTE[email protected] 25 [email protected]
26 [email protected] "unsafe" 26 [email protected] "unsafe"
27 [email protected] " " 27 [email protected] " "
28 [email protected] "fn" 28 [email protected] "fn"
@@ -39,7 +39,7 @@ [email protected]
39 [email protected] " " 39 [email protected] " "
40 [email protected] "=" 40 [email protected] "="
41 [email protected] " " 41 [email protected] " "
42 FN_POINTE[email protected] 42 [email protected]
43 [email protected] "unsafe" 43 [email protected] "unsafe"
44 [email protected] " " 44 [email protected] " "
45 [email protected] 45 [email protected]
@@ -61,7 +61,7 @@ [email protected]
61 [email protected] " " 61 [email protected] " "
62 [email protected] "=" 62 [email protected] "="
63 [email protected] " " 63 [email protected] " "
64 FN_POINTE[email protected] 64 [email protected]
65 [email protected] 65 [email protected]
66 [email protected] "extern" 66 [email protected] "extern"
67 [email protected] " " 67 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast b/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast
index c522f76cf..974df9f9a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast
@@ -7,7 +7,7 @@ [email protected]
7 [email protected] " " 7 [email protected] " "
8 [email protected] "=" 8 [email protected] "="
9 [email protected] " " 9 [email protected] " "
10 REFERENCE[email protected] 10 [email protected]
11 [email protected] "&" 11 [email protected] "&"
12 [email protected] 12 [email protected]
13 [email protected] "(" 13 [email protected] "("
@@ -22,7 +22,7 @@ [email protected]
22 [email protected] " " 22 [email protected] " "
23 [email protected] "=" 23 [email protected] "="
24 [email protected] " " 24 [email protected] " "
25 REFERENCE[email protected] 25 [email protected]
26 [email protected] "&" 26 [email protected] "&"
27 [email protected] "\'static" 27 [email protected] "\'static"
28 [email protected] " " 28 [email protected] " "
@@ -39,7 +39,7 @@ [email protected]
39 [email protected] " " 39 [email protected] " "
40 [email protected] "=" 40 [email protected] "="
41 [email protected] " " 41 [email protected] " "
42 REFERENCE[email protected] 42 [email protected]
43 [email protected] "&" 43 [email protected] "&"
44 [email protected] "mut" 44 [email protected] "mut"
45 [email protected] " " 45 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast b/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
index c100d1c71..6baea6e3c 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
@@ -21,7 +21,7 @@ [email protected]
21 [email protected] 21 [email protected]
22 [email protected] "(" 22 [email protected] "("
23 [email protected] 23 [email protected]
24 REFERENCE[email protected] 24 [email protected]
25 [email protected] "&" 25 [email protected] "&"
26 [email protected] "mut" 26 [email protected] "mut"
27 [email protected] " " 27 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast b/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast
index 5f4807522..f319d5141 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast
@@ -15,7 +15,7 @@ [email protected]
15 [email protected] "\'a" 15 [email protected] "\'a"
16 [email protected] ">" 16 [email protected] ">"
17 [email protected] " " 17 [email protected] " "
18 FN_POINTE[email protected] 18 [email protected]
19 [email protected] "fn" 19 [email protected] "fn"
20 [email protected] 20 [email protected]
21 [email protected] "(" 21 [email protected] "("
@@ -45,7 +45,7 @@ [email protected]
45 [email protected] "\'a" 45 [email protected] "\'a"
46 [email protected] ">" 46 [email protected] ">"
47 [email protected] " " 47 [email protected] " "
48 FN_POINTE[email protected] 48 [email protected]
49 [email protected] "unsafe" 49 [email protected] "unsafe"
50 [email protected] " " 50 [email protected] " "
51 [email protected] 51 [email protected]
@@ -57,7 +57,7 @@ [email protected]
57 [email protected] 57 [email protected]
58 [email protected] "(" 58 [email protected] "("
59 [email protected] 59 [email protected]
60 REFERENCE[email protected] 60 [email protected]
61 [email protected] "&" 61 [email protected] "&"
62 [email protected] "\'a" 62 [email protected] "\'a"
63 [email protected] " " 63 [email protected] " "
@@ -98,7 +98,7 @@ [email protected]
98 [email protected] 98 [email protected]
99 [email protected] "<" 99 [email protected] "<"
100 [email protected] 100 [email protected]
101 REFERENCE[email protected] 101 [email protected]
102 [email protected] "&" 102 [email protected] "&"
103 [email protected] "\'a" 103 [email protected] "\'a"
104 [email protected] " " 104 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast b/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast
index 95686977f..f80326465 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast
@@ -7,7 +7,7 @@ [email protected]
7 [email protected] " " 7 [email protected] " "
8 [email protected] "=" 8 [email protected] "="
9 [email protected] " " 9 [email protected] " "
10 FN_POINTE[email protected] 10 [email protected]
11 [email protected] "fn" 11 [email protected] "fn"
12 [email protected] 12 [email protected]
13 [email protected] "(" 13 [email protected] "("
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast b/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
index 8d029b592..570b95205 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
@@ -47,7 +47,7 @@ [email protected]
47 [email protected] "_" 47 [email protected] "_"
48 [email protected] ":" 48 [email protected] ":"
49 [email protected] " " 49 [email protected] " "
50 REFERENCE[email protected] 50 [email protected]
51 [email protected] "&" 51 [email protected] "&"
52 [email protected] "\'a" 52 [email protected] "\'a"
53 [email protected] " " 53 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast b/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast
index 27c4f141f..7cdec6634 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast
@@ -21,7 +21,7 @@ [email protected]
21 [email protected] "format" 21 [email protected] "format"
22 [email protected] ":" 22 [email protected] ":"
23 [email protected] " " 23 [email protected] " "
24 POINTE[email protected] 24 [email protected]
25 [email protected] "*" 25 [email protected] "*"
26 [email protected] "const" 26 [email protected] "const"
27 [email protected] " " 27 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast
index ca739825a..a36cc8dab 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast
@@ -27,7 +27,7 @@ [email protected]
27 [email protected] " " 27 [email protected] " "
28 [email protected] "as" 28 [email protected] "as"
29 [email protected] " " 29 [email protected] " "
30 POINTE[email protected] 30 [email protected]
31 [email protected] "*" 31 [email protected] "*"
32 [email protected] "const" 32 [email protected] "const"
33 [email protected] " " 33 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast b/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast
index 0c35bf2b7..f284aafcd 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast
@@ -6,7 +6,7 @@ [email protected]
6 [email protected] "A" 6 [email protected] "A"
7 [email protected] ":" 7 [email protected] ":"
8 [email protected] " " 8 [email protected] " "
9 REFERENCE[email protected] 9 [email protected]
10 [email protected] "&" 10 [email protected] "&"
11 [email protected] 11 [email protected]
12 [email protected] "[" 12 [email protected] "["
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast
index c48fed03e..e6aff7b37 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast
@@ -7,7 +7,7 @@ [email protected]
7 [email protected] " " 7 [email protected] " "
8 [email protected] "=" 8 [email protected] "="
9 [email protected] " " 9 [email protected] " "
10 FN_POINTE[email protected] 10 [email protected]
11 [email protected] "fn" 11 [email protected] "fn"
12 [email protected] 12 [email protected]
13 [email protected] "(" 13 [email protected] "("
@@ -33,7 +33,7 @@ [email protected]
33 [email protected] " " 33 [email protected] " "
34 [email protected] "=" 34 [email protected] "="
35 [email protected] " " 35 [email protected] " "
36 FN_POINTE[email protected] 36 [email protected]
37 [email protected] "fn" 37 [email protected] "fn"
38 [email protected] 38 [email protected]
39 [email protected] "(" 39 [email protected] "("
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast
index 3079e5bf8..6abb4fe5a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast
@@ -7,7 +7,7 @@ [email protected]
7 [email protected] " " 7 [email protected] " "
8 [email protected] "=" 8 [email protected] "="
9 [email protected] " " 9 [email protected] " "
10 FN_POINTE[email protected] 10 [email protected]
11 [email protected] "fn" 11 [email protected] "fn"
12 [email protected] 12 [email protected]
13 [email protected] "(" 13 [email protected] "("
diff --git a/crates/ra_syntax/test_data/parser/ok/0031_extern.rast b/crates/ra_syntax/test_data/parser/ok/0031_extern.rast
index 79ea098a2..8150d445f 100644
--- a/crates/ra_syntax/test_data/parser/ok/0031_extern.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0031_extern.rast
@@ -99,7 +99,7 @@ [email protected]
99 [email protected] "addr" 99 [email protected] "addr"
100 [email protected] ":" 100 [email protected] ":"
101 [email protected] " " 101 [email protected] " "
102 POINTE[email protected] 102 [email protected]
103 [email protected] "*" 103 [email protected] "*"
104 [email protected] "const" 104 [email protected] "const"
105 [email protected] " " 105 [email protected] " "
@@ -164,7 +164,7 @@ [email protected]
164 [email protected] "address" 164 [email protected] "address"
165 [email protected] ":" 165 [email protected] ":"
166 [email protected] " " 166 [email protected] " "
167 POINTE[email protected] 167 [email protected]
168 [email protected] "*" 168 [email protected] "*"
169 [email protected] "const" 169 [email protected] "const"
170 [email protected] " " 170 [email protected] " "
@@ -278,7 +278,7 @@ [email protected]
278 [email protected] "address" 278 [email protected] "address"
279 [email protected] ":" 279 [email protected] ":"
280 [email protected] " " 280 [email protected] " "
281 POINTE[email protected] 281 [email protected]
282 [email protected] "*" 282 [email protected] "*"
283 [email protected] "mut" 283 [email protected] "mut"
284 [email protected] " " 284 [email protected] " "
@@ -295,7 +295,7 @@ [email protected]
295 [email protected] "address_len" 295 [email protected] "address_len"
296 [email protected] ":" 296 [email protected] ":"
297 [email protected] " " 297 [email protected] " "
298 POINTE[email protected] 298 [email protected]
299 [email protected] "*" 299 [email protected] "*"
300 [email protected] "mut" 300 [email protected] "mut"
301 [email protected] " " 301 [email protected] " "
@@ -375,7 +375,7 @@ [email protected]
375 [email protected] "optval" 375 [email protected] "optval"
376 [email protected] ":" 376 [email protected] ":"
377 [email protected] " " 377 [email protected] " "
378 POINTE[email protected] 378 [email protected]
379 [email protected] "*" 379 [email protected] "*"
380 [email protected] "mut" 380 [email protected] "mut"
381 [email protected] " " 381 [email protected] " "
@@ -393,7 +393,7 @@ [email protected]
393 [email protected] "optlen" 393 [email protected] "optlen"
394 [email protected] ":" 394 [email protected] ":"
395 [email protected] " " 395 [email protected] " "
396 POINTE[email protected] 396 [email protected]
397 [email protected] "*" 397 [email protected] "*"
398 [email protected] "mut" 398 [email protected] "mut"
399 [email protected] " " 399 [email protected] " "
@@ -474,7 +474,7 @@ [email protected]
474 [email protected] "value" 474 [email protected] "value"
475 [email protected] ":" 475 [email protected] ":"
476 [email protected] " " 476 [email protected] " "
477 POINTE[email protected] 477 [email protected]
478 [email protected] "*" 478 [email protected] "*"
479 [email protected] "const" 479 [email protected] "const"
480 [email protected] " " 480 [email protected] " "
@@ -540,7 +540,7 @@ [email protected]
540 [email protected] "address" 540 [email protected] "address"
541 [email protected] ":" 541 [email protected] ":"
542 [email protected] " " 542 [email protected] " "
543 POINTE[email protected] 543 [email protected]
544 [email protected] "*" 544 [email protected] "*"
545 [email protected] "mut" 545 [email protected] "mut"
546 [email protected] " " 546 [email protected] " "
@@ -557,7 +557,7 @@ [email protected]
557 [email protected] "address_len" 557 [email protected] "address_len"
558 [email protected] ":" 558 [email protected] ":"
559 [email protected] " " 559 [email protected] " "
560 POINTE[email protected] 560 [email protected]
561 [email protected] "*" 561 [email protected] "*"
562 [email protected] "mut" 562 [email protected] "mut"
563 [email protected] " " 563 [email protected] " "
@@ -609,7 +609,7 @@ [email protected]
609 [email protected] "buf" 609 [email protected] "buf"
610 [email protected] ":" 610 [email protected] ":"
611 [email protected] " " 611 [email protected] " "
612 POINTE[email protected] 612 [email protected]
613 [email protected] "*" 613 [email protected] "*"
614 [email protected] "const" 614 [email protected] "const"
615 [email protected] " " 615 [email protected] " "
@@ -655,7 +655,7 @@ [email protected]
655 [email protected] "addr" 655 [email protected] "addr"
656 [email protected] ":" 656 [email protected] ":"
657 [email protected] " " 657 [email protected] " "
658 POINTE[email protected] 658 [email protected]
659 [email protected] "*" 659 [email protected] "*"
660 [email protected] "const" 660 [email protected] "const"
661 [email protected] " " 661 [email protected] " "
@@ -720,7 +720,7 @@ [email protected]
720 [email protected] "buf" 720 [email protected] "buf"
721 [email protected] ":" 721 [email protected] ":"
722 [email protected] " " 722 [email protected] " "
723 POINTE[email protected] 723 [email protected]
724 [email protected] "*" 724 [email protected] "*"
725 [email protected] "const" 725 [email protected] "const"
726 [email protected] " " 726 [email protected] " "
@@ -801,7 +801,7 @@ [email protected]
801 [email protected] "buf" 801 [email protected] "buf"
802 [email protected] ":" 802 [email protected] ":"
803 [email protected] " " 803 [email protected] " "
804 POINTE[email protected] 804 [email protected]
805 [email protected] "*" 805 [email protected] "*"
806 [email protected] "mut" 806 [email protected] "mut"
807 [email protected] " " 807 [email protected] " "
@@ -847,7 +847,7 @@ [email protected]
847 [email protected] "addr" 847 [email protected] "addr"
848 [email protected] ":" 848 [email protected] ":"
849 [email protected] " " 849 [email protected] " "
850 POINTE[email protected] 850 [email protected]
851 [email protected] "*" 851 [email protected] "*"
852 [email protected] "mut" 852 [email protected] "mut"
853 [email protected] " " 853 [email protected] " "
@@ -865,7 +865,7 @@ [email protected]
865 [email protected] "addrlen" 865 [email protected] "addrlen"
866 [email protected] ":" 866 [email protected] ":"
867 [email protected] " " 867 [email protected] " "
868 POINTE[email protected] 868 [email protected]
869 [email protected] "*" 869 [email protected] "*"
870 [email protected] "mut" 870 [email protected] "mut"
871 [email protected] " " 871 [email protected] " "
@@ -918,7 +918,7 @@ [email protected]
918 [email protected] "buf" 918 [email protected] "buf"
919 [email protected] ":" 919 [email protected] ":"
920 [email protected] " " 920 [email protected] " "
921 POINTE[email protected] 921 [email protected]
922 [email protected] "*" 922 [email protected] "*"
923 [email protected] "mut" 923 [email protected] "mut"
924 [email protected] " " 924 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast
index 5bb9363a8..7c61b5006 100644
--- a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast
@@ -242,7 +242,7 @@ [email protected]
242 [email protected] "x" 242 [email protected] "x"
243 [email protected] ":" 243 [email protected] ":"
244 [email protected] " " 244 [email protected] " "
245 REFERENCE[email protected] 245 [email protected]
246 [email protected] "&" 246 [email protected] "&"
247 [email protected] 247 [email protected]
248 [email protected] 248 [email protected]
@@ -1579,7 +1579,7 @@ [email protected]
1579 [email protected] "union" 1579 [email protected] "union"
1580 [email protected] ":" 1580 [email protected] ":"
1581 [email protected] " " 1581 [email protected] " "
1582 REFERENCE[email protected] 1582 [email protected]
1583 [email protected] "&" 1583 [email protected] "&"
1584 [email protected] "\'union" 1584 [email protected] "\'union"
1585 [email protected] " " 1585 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast
index 0303b198f..d4f05f279 100644
--- a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast
@@ -96,7 +96,7 @@ [email protected]
96 [email protected] "format" 96 [email protected] "format"
97 [email protected] ":" 97 [email protected] ":"
98 [email protected] " " 98 [email protected] " "
99 POINTE[email protected] 99 [email protected]
100 [email protected] "*" 100 [email protected] "*"
101 [email protected] "const" 101 [email protected] "const"
102 [email protected] " " 102 [email protected] " "
@@ -163,7 +163,7 @@ [email protected]
163 [email protected] "]" 163 [email protected] "]"
164 [email protected] " " 164 [email protected] " "
165 [email protected] 165 [email protected]
166 REFERENCE[email protected] 166 [email protected]
167 [email protected] "&" 167 [email protected] "&"
168 [email protected] "mut" 168 [email protected] "mut"
169 [email protected] " " 169 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast b/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast
index f71ceecd7..f25c9ac36 100644
--- a/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast
@@ -102,7 +102,7 @@ [email protected]
102 [email protected] 102 [email protected]
103 [email protected] "(" 103 [email protected] "("
104 [email protected] 104 [email protected]
105 REFERENCE[email protected] 105 [email protected]
106 [email protected] "&" 106 [email protected] "&"
107 [email protected] 107 [email protected]
108 [email protected] 108 [email protected]
diff --git a/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast
index 42680b283..8eda59976 100644
--- a/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast
@@ -140,9 +140,9 @@ [email protected]
140 [email protected] "a" 140 [email protected] "a"
141 [email protected] ":" 141 [email protected] ":"
142 [email protected] " " 142 [email protected] " "
143 REFERENCE[email protected] 143 [email protected]
144 [email protected] "&" 144 [email protected] "&"
145 REFERENCE[email protected] 145 [email protected]
146 [email protected] "&" 146 [email protected] "&"
147 [email protected] 147 [email protected]
148 [email protected] 148 [email protected]
diff --git a/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast
index a132591f0..4009b3ff8 100644
--- a/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast
@@ -20,7 +20,7 @@ [email protected]
20 [email protected] "_" 20 [email protected] "_"
21 [email protected] ":" 21 [email protected] ":"
22 [email protected] " " 22 [email protected] " "
23 POINTE[email protected] 23 [email protected]
24 [email protected] "*" 24 [email protected] "*"
25 [email protected] "mut" 25 [email protected] "mut"
26 [email protected] " " 26 [email protected] " "
@@ -49,7 +49,7 @@ [email protected]
49 [email protected] "_" 49 [email protected] "_"
50 [email protected] ":" 50 [email protected] ":"
51 [email protected] " " 51 [email protected] " "
52 POINTE[email protected] 52 [email protected]
53 [email protected] "*" 53 [email protected] "*"
54 [email protected] "mut" 54 [email protected] "mut"
55 [email protected] " " 55 [email protected] " "
@@ -81,7 +81,7 @@ [email protected]
81 [email protected] "_" 81 [email protected] "_"
82 [email protected] ":" 82 [email protected] ":"
83 [email protected] " " 83 [email protected] " "
84 POINTE[email protected] 84 [email protected]
85 [email protected] "*" 85 [email protected] "*"
86 [email protected] "mut" 86 [email protected] "mut"
87 [email protected] " " 87 [email protected] " "
diff --git a/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast
index 94260db7c..a3c6ed82e 100644
--- a/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast
@@ -143,9 +143,9 @@ [email protected]
143 [email protected] "a" 143 [email protected] "a"
144 [email protected] ":" 144 [email protected] ":"
145 [email protected] " " 145 [email protected] " "
146 REFERENCE[email protected] 146 [email protected]
147 [email protected] "&" 147 [email protected] "&"
148 REFERENCE[email protected] 148 [email protected]
149 [email protected] "&" 149 [email protected] "&"
150 [email protected] 150 [email protected]
151 [email protected] 151 [email protected]
diff --git a/crates/ra_syntax/test_data/parser/ok/0067_where_for_pred.rast b/crates/ra_syntax/test_data/parser/ok/0067_where_for_pred.rast
index fae9467fc..8f8639a37 100644
--- a/crates/ra_syntax/test_data/parser/ok/0067_where_for_pred.rast
+++ b/crates/ra_syntax/test_data/parser/ok/0067_where_for_pred.rast
@@ -42,7 +42,7 @@ [email protected]
42 [email protected] 42 [email protected]
43 [email protected] "(" 43 [email protected] "("
44 [email protected] 44 [email protected]
45 REFERENCE[email protected] 45 [email protected]
46 [email protected] "&" 46 [email protected] "&"
47 [email protected] "\'a" 47 [email protected] "\'a"
48 [email protected] " " 48 [email protected] " "
@@ -85,7 +85,7 @@ [email protected]
85 [email protected] "\'a" 85 [email protected] "\'a"
86 [email protected] ">" 86 [email protected] ">"
87 [email protected] " " 87 [email protected] " "
88 REFERENCE[email protected] 88 [email protected]
89 [email protected] "&" 89 [email protected] "&"
90 [email protected] "\'a" 90 [email protected] "\'a"
91 [email protected] " " 91 [email protected] " "
@@ -138,7 +138,7 @@ [email protected]
138 [email protected] " " 138 [email protected] " "
139 [email protected] 139 [email protected]
140 [email protected] "(" 140 [email protected] "("
141 REFERENCE[email protected] 141 [email protected]
142 [email protected] "&" 142 [email protected] "&"
143 [email protected] "\'a" 143 [email protected] "\'a"
144 [email protected] " " 144 [email protected] " "
@@ -160,7 +160,7 @@ [email protected]
160 [email protected] 160 [email protected]
161 [email protected] "(" 161 [email protected] "("
162 [email protected] 162 [email protected]
163 REFERENCE[email protected] 163 [email protected]
164 [email protected] "&" 164 [email protected] "&"
165 [email protected] "\'a" 165 [email protected] "\'a"
166 [email protected] " " 166 [email protected] " "
@@ -205,7 +205,7 @@ [email protected]
205 [email protected] " " 205 [email protected] " "
206 [email protected] 206 [email protected]
207 [email protected] "[" 207 [email protected] "["
208 REFERENCE[email protected] 208 [email protected]
209 [email protected] "&" 209 [email protected] "&"
210 [email protected] "\'a" 210 [email protected] "\'a"
211 [email protected] " " 211 [email protected] " "
@@ -250,7 +250,7 @@ [email protected]
250 [email protected] "_t" 250 [email protected] "_t"
251 [email protected] ":" 251 [email protected] ":"
252 [email protected] " " 252 [email protected] " "
253 REFERENCE[email protected] 253 [email protected]
254 [email protected] "&" 254 [email protected] "&"
255 [email protected] 255 [email protected]
256 [email protected] 256 [email protected]
@@ -275,7 +275,7 @@ [email protected]
275 [email protected] 275 [email protected]
276 [email protected] 276 [email protected]
277 [email protected] "<" 277 [email protected] "<"
278 REFERENCE[email protected] 278 [email protected]
279 [email protected] "&" 279 [email protected] "&"
280 [email protected] "\'a" 280 [email protected] "\'a"
281 [email protected] " " 281 [email protected] " "
@@ -347,12 +347,12 @@ [email protected]
347 [email protected] "\'b" 347 [email protected] "\'b"
348 [email protected] ">" 348 [email protected] ">"
349 [email protected] " " 349 [email protected] " "
350 FN_POINTE[email protected] 350 [email protected]
351 [email protected] "fn" 351 [email protected] "fn"
352 [email protected] 352 [email protected]
353 [email protected] "(" 353 [email protected] "("
354 [email protected] 354 [email protected]
355 REFERENCE[email protected] 355 [email protected]
356 [email protected] "&" 356 [email protected] "&"
357 [email protected] "\'a" 357 [email protected] "\'a"
358 [email protected] " " 358 [email protected] " "
@@ -364,7 +364,7 @@ [email protected]
364 [email protected] "," 364 [email protected] ","
365 [email protected] " " 365 [email protected] " "
366 [email protected] 366 [email protected]
367 REFERENCE[email protected] 367 [email protected]
368 [email protected] "&" 368 [email protected] "&"
369 [email protected] "\'b" 369 [email protected] "\'b"
370 [email protected] " " 370 [email protected] " "
diff --git a/crates/rust-analyzer/src/bin/args.rs b/crates/rust-analyzer/src/bin/args.rs
index f16e35d86..d3081e88b 100644
--- a/crates/rust-analyzer/src/bin/args.rs
+++ b/crates/rust-analyzer/src/bin/args.rs
@@ -44,15 +44,16 @@ pub(crate) enum Command {
44 ProcMacro, 44 ProcMacro,
45 RunServer, 45 RunServer,
46 Version, 46 Version,
47 Help,
47} 48}
48 49
49impl Args { 50impl Args {
50 pub(crate) fn parse() -> Result<Result<Args, HelpPrinted>> { 51 pub(crate) fn parse() -> Result<Args> {
51 let mut matches = Arguments::from_env(); 52 let mut matches = Arguments::from_env();
52 53
53 if matches.contains("--version") { 54 if matches.contains("--version") {
54 matches.finish().or_else(handle_extra_flags)?; 55 matches.finish().or_else(handle_extra_flags)?;
55 return Ok(Ok(Args { verbosity: Verbosity::Normal, command: Command::Version })); 56 return Ok(Args { verbosity: Verbosity::Normal, command: Command::Version });
56 } 57 }
57 58
58 let verbosity = match ( 59 let verbosity = match (
@@ -68,15 +69,16 @@ impl Args {
68 (false, true, true) => bail!("Invalid flags: -q conflicts with -v"), 69 (false, true, true) => bail!("Invalid flags: -q conflicts with -v"),
69 }; 70 };
70 71
72 let help = Ok(Args { verbosity, command: Command::Help });
71 let subcommand = match matches.subcommand()? { 73 let subcommand = match matches.subcommand()? {
72 Some(it) => it, 74 Some(it) => it,
73 None => { 75 None => {
74 if matches.contains(["-h", "--help"]) { 76 if matches.contains(["-h", "--help"]) {
75 print_subcommands(); 77 print_subcommands();
76 return Ok(Err(HelpPrinted)); 78 return help;
77 } 79 }
78 matches.finish().or_else(handle_extra_flags)?; 80 matches.finish().or_else(handle_extra_flags)?;
79 return Ok(Ok(Args { verbosity, command: Command::RunServer })); 81 return Ok(Args { verbosity, command: Command::RunServer });
80 } 82 }
81 }; 83 };
82 let command = match subcommand.as_str() { 84 let command = match subcommand.as_str() {
@@ -93,7 +95,7 @@ FLAGS:
93 -h, --help Prints help information 95 -h, --help Prints help information
94 --no-dump" 96 --no-dump"
95 ); 97 );
96 return Ok(Err(HelpPrinted)); 98 return help;
97 } 99 }
98 100
99 let no_dump = matches.contains("--no-dump"); 101 let no_dump = matches.contains("--no-dump");
@@ -112,7 +114,7 @@ USAGE:
112FLAGS: 114FLAGS:
113 -h, --help Prints help inforamtion" 115 -h, --help Prints help inforamtion"
114 ); 116 );
115 return Ok(Err(HelpPrinted)); 117 return help;
116 } 118 }
117 119
118 matches.finish().or_else(handle_extra_flags)?; 120 matches.finish().or_else(handle_extra_flags)?;
@@ -132,7 +134,7 @@ FLAGS:
132 -h, --help Prints help information 134 -h, --help Prints help information
133 -r, --rainbow" 135 -r, --rainbow"
134 ); 136 );
135 return Ok(Err(HelpPrinted)); 137 return help;
136 } 138 }
137 139
138 let rainbow = matches.contains(["-r", "--rainbow"]); 140 let rainbow = matches.contains(["-r", "--rainbow"]);
@@ -166,7 +168,7 @@ OPTIONS:
166ARGS: 168ARGS:
167 <PATH>" 169 <PATH>"
168 ); 170 );
169 return Ok(Err(HelpPrinted)); 171 return help;
170 } 172 }
171 173
172 let randomize = matches.contains("--randomize"); 174 let randomize = matches.contains("--randomize");
@@ -220,7 +222,7 @@ OPTIONS:
220ARGS: 222ARGS:
221 <PATH> Project to analyse" 223 <PATH> Project to analyse"
222 ); 224 );
223 return Ok(Err(HelpPrinted)); 225 return help;
224 } 226 }
225 227
226 let path: PathBuf = matches.opt_value_from_str("--project")?.unwrap_or_default(); 228 let path: PathBuf = matches.opt_value_from_str("--project")?.unwrap_or_default();
@@ -266,7 +268,7 @@ FLAGS:
266ARGS: 268ARGS:
267 <PATH>" 269 <PATH>"
268 ); 270 );
269 return Ok(Err(HelpPrinted)); 271 return help;
270 } 272 }
271 273
272 let load_output_dirs = matches.contains("--load-output-dirs"); 274 let load_output_dirs = matches.contains("--load-output-dirs");
@@ -302,7 +304,7 @@ FLAGS:
302ARGS: 304ARGS:
303 <RULE> A structured search replace rule" 305 <RULE> A structured search replace rule"
304 ); 306 );
305 return Ok(Err(HelpPrinted)); 307 return help;
306 } 308 }
307 let mut rules = Vec::new(); 309 let mut rules = Vec::new();
308 while let Some(rule) = matches.free_from_str()? { 310 while let Some(rule) = matches.free_from_str()? {
@@ -329,7 +331,7 @@ FLAGS:
329ARGS: 331ARGS:
330 <PATTERN> A structured search pattern" 332 <PATTERN> A structured search pattern"
331 ); 333 );
332 return Ok(Err(HelpPrinted)); 334 return help;
333 } 335 }
334 let debug_snippet = matches.opt_value_from_str("--debug")?; 336 let debug_snippet = matches.opt_value_from_str("--debug")?;
335 let mut patterns = Vec::new(); 337 let mut patterns = Vec::new();
@@ -340,10 +342,10 @@ ARGS:
340 } 342 }
341 _ => { 343 _ => {
342 print_subcommands(); 344 print_subcommands();
343 return Ok(Err(HelpPrinted)); 345 return help;
344 } 346 }
345 }; 347 };
346 Ok(Ok(Args { verbosity, command })) 348 Ok(Args { verbosity, command })
347 } 349 }
348} 350}
349 351
@@ -371,8 +373,6 @@ SUBCOMMANDS:
371 ) 373 )
372} 374}
373 375
374pub(crate) struct HelpPrinted;
375
376fn handle_extra_flags(e: pico_args::Error) -> Result<()> { 376fn handle_extra_flags(e: pico_args::Error) -> Result<()> {
377 if let pico_args::Error::UnusedArgsLeft(flags) = e { 377 if let pico_args::Error::UnusedArgsLeft(flags) = e {
378 let mut invalid_flags = String::new(); 378 let mut invalid_flags = String::new();
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index ff8234495..fc7f8b01d 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -3,7 +3,7 @@
3//! Based on cli flags, either spawns an LSP server, or runs a batch analysis 3//! Based on cli flags, either spawns an LSP server, or runs a batch analysis
4mod args; 4mod args;
5 5
6use std::convert::TryFrom; 6use std::{convert::TryFrom, process};
7 7
8use lsp_server::Connection; 8use lsp_server::Connection;
9use ra_project_model::ProjectManifest; 9use ra_project_model::ProjectManifest;
@@ -14,18 +14,20 @@ use rust_analyzer::{
14}; 14};
15use vfs::AbsPathBuf; 15use vfs::AbsPathBuf;
16 16
17use crate::args::HelpPrinted;
18
19#[cfg(all(feature = "mimalloc"))] 17#[cfg(all(feature = "mimalloc"))]
20#[global_allocator] 18#[global_allocator]
21static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; 19static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
22 20
23fn main() -> Result<()> { 21fn main() {
22 if let Err(err) = try_main() {
23 eprintln!("{}", err);
24 process::exit(101);
25 }
26}
27
28fn try_main() -> Result<()> {
24 setup_logging()?; 29 setup_logging()?;
25 let args = match args::Args::parse()? { 30 let args = args::Args::parse()?;
26 Ok(it) => it,
27 Err(HelpPrinted) => return Ok(()),
28 };
29 match args.command { 31 match args.command {
30 args::Command::RunServer => run_server()?, 32 args::Command::RunServer => run_server()?,
31 args::Command::ProcMacro => ra_proc_macro_srv::cli::run()?, 33 args::Command::ProcMacro => ra_proc_macro_srv::cli::run()?,
@@ -45,6 +47,7 @@ fn main() -> Result<()> {
45 cli::search_for_patterns(patterns, debug_snippet)?; 47 cli::search_for_patterns(patterns, debug_snippet)?;
46 } 48 }
47 args::Command::Version => println!("rust-analyzer {}", env!("REV")), 49 args::Command::Version => println!("rust-analyzer {}", env!("REV")),
50 args::Command::Help => {}
48 } 51 }
49 Ok(()) 52 Ok(())
50} 53}
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index e73b3a211..82f6de5da 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -709,11 +709,6 @@ pub(crate) fn handle_formatting(
709 } 709 }
710 }; 710 };
711 711
712 if let Ok(path) = params.text_document.uri.to_file_path() {
713 if let Some(parent) = path.parent() {
714 rustfmt.current_dir(parent);
715 }
716 }
717 let mut rustfmt = rustfmt.stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?; 712 let mut rustfmt = rustfmt.stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
718 713
719 rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?; 714 rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index d4cc9dd04..0bc3ff115 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -1,5 +1,5 @@
1//! Utilities for LSP-related boilerplate code. 1//! Utilities for LSP-related boilerplate code.
2use std::{borrow::Cow, error::Error, ops::Range}; 2use std::{error::Error, ops::Range};
3 3
4use lsp_server::Notification; 4use lsp_server::Notification;
5use ra_db::Canceled; 5use ra_db::Canceled;
@@ -84,8 +84,8 @@ impl GlobalState {
84pub(crate) fn apply_document_changes( 84pub(crate) fn apply_document_changes(
85 old_text: &mut String, 85 old_text: &mut String,
86 content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>, 86 content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>,
87 mut line_index: Cow<'_, LineIndex>,
88) { 87) {
88 let mut line_index = LineIndex::new(old_text);
89 // The changes we got must be applied sequentially, but can cross lines so we 89 // The changes we got must be applied sequentially, but can cross lines so we
90 // have to keep our line index updated. 90 // have to keep our line index updated.
91 // Some clients (e.g. Code) sort the ranges in reverse. As an optimization, we 91 // Some clients (e.g. Code) sort the ranges in reverse. As an optimization, we
@@ -110,7 +110,7 @@ pub(crate) fn apply_document_changes(
110 match change.range { 110 match change.range {
111 Some(range) => { 111 Some(range) => {
112 if !index_valid.covers(range.end.line) { 112 if !index_valid.covers(range.end.line) {
113 line_index = Cow::Owned(LineIndex::new(old_text)); 113 line_index = LineIndex::new(&old_text);
114 } 114 }
115 index_valid = IndexValid::UpToLineExclusive(range.start.line); 115 index_valid = IndexValid::UpToLineExclusive(range.start.line);
116 let range = from_proto::text_range(&line_index, range); 116 let range = from_proto::text_range(&line_index, range);
@@ -145,15 +145,10 @@ mod tests {
145 }; 145 };
146 } 146 }
147 147
148 fn run(text: &mut String, changes: Vec<TextDocumentContentChangeEvent>) {
149 let line_index = Cow::Owned(LineIndex::new(&text));
150 super::apply_document_changes(text, changes, line_index);
151 }
152
153 let mut text = String::new(); 148 let mut text = String::new();
154 run(&mut text, vec![]); 149 apply_document_changes(&mut text, vec![]);
155 assert_eq!(text, ""); 150 assert_eq!(text, "");
156 run( 151 apply_document_changes(
157 &mut text, 152 &mut text,
158 vec![TextDocumentContentChangeEvent { 153 vec![TextDocumentContentChangeEvent {
159 range: None, 154 range: None,
@@ -162,36 +157,39 @@ mod tests {
162 }], 157 }],
163 ); 158 );
164 assert_eq!(text, "the"); 159 assert_eq!(text, "the");
165 run(&mut text, c![0, 3; 0, 3 => " quick"]); 160 apply_document_changes(&mut text, c![0, 3; 0, 3 => " quick"]);
166 assert_eq!(text, "the quick"); 161 assert_eq!(text, "the quick");
167 run(&mut text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]); 162 apply_document_changes(&mut text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]);
168 assert_eq!(text, "quick foxes"); 163 assert_eq!(text, "quick foxes");
169 run(&mut text, c![0, 11; 0, 11 => "\ndream"]); 164 apply_document_changes(&mut text, c![0, 11; 0, 11 => "\ndream"]);
170 assert_eq!(text, "quick foxes\ndream"); 165 assert_eq!(text, "quick foxes\ndream");
171 run(&mut text, c![1, 0; 1, 0 => "have "]); 166 apply_document_changes(&mut text, c![1, 0; 1, 0 => "have "]);
172 assert_eq!(text, "quick foxes\nhave dream"); 167 assert_eq!(text, "quick foxes\nhave dream");
173 run(&mut text, c![0, 0; 0, 0 => "the ", 1, 4; 1, 4 => " quiet", 1, 16; 1, 16 => "s\n"]); 168 apply_document_changes(
169 &mut text,
170 c![0, 0; 0, 0 => "the ", 1, 4; 1, 4 => " quiet", 1, 16; 1, 16 => "s\n"],
171 );
174 assert_eq!(text, "the quick foxes\nhave quiet dreams\n"); 172 assert_eq!(text, "the quick foxes\nhave quiet dreams\n");
175 run(&mut text, c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"]); 173 apply_document_changes(&mut text, c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"]);
176 assert_eq!(text, "the quick foxes\n\nhave quiet dreams\n\n"); 174 assert_eq!(text, "the quick foxes\n\nhave quiet dreams\n\n");
177 run( 175 apply_document_changes(
178 &mut text, 176 &mut text,
179 c![1, 0; 1, 0 => "DREAM", 2, 0; 2, 0 => "they ", 3, 0; 3, 0 => "DON'T THEY?"], 177 c![1, 0; 1, 0 => "DREAM", 2, 0; 2, 0 => "they ", 3, 0; 3, 0 => "DON'T THEY?"],
180 ); 178 );
181 assert_eq!(text, "the quick foxes\nDREAM\nthey have quiet dreams\nDON'T THEY?\n"); 179 assert_eq!(text, "the quick foxes\nDREAM\nthey have quiet dreams\nDON'T THEY?\n");
182 run(&mut text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]); 180 apply_document_changes(&mut text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]);
183 assert_eq!(text, "the quick \nthey have quiet dreams\n"); 181 assert_eq!(text, "the quick \nthey have quiet dreams\n");
184 182
185 text = String::from("❤️"); 183 text = String::from("❤️");
186 run(&mut text, c![0, 0; 0, 0 => "a"]); 184 apply_document_changes(&mut text, c![0, 0; 0, 0 => "a"]);
187 assert_eq!(text, "a❤️"); 185 assert_eq!(text, "a❤️");
188 186
189 text = String::from("a\nb"); 187 text = String::from("a\nb");
190 run(&mut text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]); 188 apply_document_changes(&mut text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]);
191 assert_eq!(text, "adcb"); 189 assert_eq!(text, "adcb");
192 190
193 text = String::from("a\nb"); 191 text = String::from("a\nb");
194 run(&mut text, c![0, 1; 1, 0 => "ț\nc", 0, 2; 0, 2 => "c"]); 192 apply_document_changes(&mut text, c![0, 1; 1, 0 => "ț\nc", 0, 2; 0, 2 => "c"]);
195 assert_eq!(text, "ațc\ncb"); 193 assert_eq!(text, "ațc\ncb");
196 } 194 }
197} 195}
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 0ace4cb45..51626fcd5 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -1,14 +1,13 @@
1//! The main loop of `rust-analyzer` responsible for dispatching LSP 1//! The main loop of `rust-analyzer` responsible for dispatching LSP
2//! requests/replies and notifications back to the client. 2//! requests/replies and notifications back to the client.
3use std::{ 3use std::{
4 borrow::Cow,
5 env, fmt, panic, 4 env, fmt, panic,
6 time::{Duration, Instant}, 5 time::{Duration, Instant},
7}; 6};
8 7
9use crossbeam_channel::{select, Receiver}; 8use crossbeam_channel::{select, Receiver};
10use lsp_server::{Connection, Notification, Request, Response}; 9use lsp_server::{Connection, Notification, Request, Response};
11use lsp_types::{notification::Notification as _, DidChangeTextDocumentParams}; 10use lsp_types::notification::Notification as _;
12use ra_db::VfsPath; 11use ra_db::VfsPath;
13use ra_ide::{Canceled, FileId}; 12use ra_ide::{Canceled, FileId};
14use ra_prof::profile; 13use ra_prof::profile;
@@ -422,20 +421,15 @@ impl GlobalState {
422 })? 421 })?
423 .on::<lsp_types::notification::DidChangeTextDocument>(|this, params| { 422 .on::<lsp_types::notification::DidChangeTextDocument>(|this, params| {
424 if let Ok(path) = from_proto::vfs_path(&params.text_document.uri) { 423 if let Ok(path) = from_proto::vfs_path(&params.text_document.uri) {
425 let DidChangeTextDocumentParams { text_document, content_changes } = params; 424 let doc = this.mem_docs.get_mut(&path).unwrap();
426 let vfs = &mut this.vfs.write().0; 425 let vfs = &mut this.vfs.write().0;
427 let world = this.snapshot();
428 let file_id = vfs.file_id(&path).unwrap(); 426 let file_id = vfs.file_id(&path).unwrap();
429
430 // let file_id = vfs.file_id(&path).unwrap();
431 let mut text = String::from_utf8(vfs.file_contents(file_id).to_vec()).unwrap(); 427 let mut text = String::from_utf8(vfs.file_contents(file_id).to_vec()).unwrap();
432 let line_index = world.analysis.file_line_index(file_id)?; 428 apply_document_changes(&mut text, params.content_changes);
433 apply_document_changes(&mut text, content_changes, Cow::Borrowed(&line_index));
434 429
435 // The version passed in DidChangeTextDocument is the version after all edits are applied 430 // The version passed in DidChangeTextDocument is the version after all edits are applied
436 // so we should apply it before the vfs is notified. 431 // so we should apply it before the vfs is notified.
437 let doc = this.mem_docs.get_mut(&path).unwrap(); 432 doc.version = params.text_document.version;
438 doc.version = text_document.version;
439 433
440 vfs.set_file_contents(path.clone(), Some(text.into_bytes())); 434 vfs.set_file_contents(path.clone(), Some(text.into_bytes()));
441 } 435 }
diff --git a/docs/dev/README.md b/docs/dev/README.md
index 2896d333e..67813a9c0 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -50,277 +50,85 @@ We use bors-ng to enforce the [not rocket science](https://graydon2.dreamwidth.o
50 50
51You can run `cargo xtask install-pre-commit-hook` to install git-hook to run rustfmt on commit. 51You can run `cargo xtask install-pre-commit-hook` to install git-hook to run rustfmt on commit.
52 52
53# Code organization
54
55All Rust code lives in the `crates` top-level directory, and is organized as a
56single Cargo workspace. The `editors` top-level directory contains code for
57integrating with editors. Currently, it contains the plugin for VS Code (in
58TypeScript). The `docs` top-level directory contains both developer and user
59documentation.
60
61We have some automation infra in Rust in the `xtask` package. It contains
62stuff like formatting checking, code generation and powers `cargo xtask install`.
63The latter syntax is achieved with the help of cargo aliases (see `.cargo`
64directory).
65
66# Launching rust-analyzer 53# Launching rust-analyzer
67 54
68Debugging the language server can be tricky: LSP is rather chatty, so driving it 55Debugging the language server can be tricky.
69from the command line is not really feasible, driving it via VS Code requires 56LSP is rather chatty, so driving it from the command line is not really feasible, driving it via VS Code requires interacting with two processes.
70interacting with two processes.
71 57
72For this reason, the best way to see how rust-analyzer works is to find a 58For this reason, the best way to see how rust-analyzer works is to find a relevant test and execute it.
73relevant test and execute it (VS Code includes an action for running a single 59VS Code & Emacs include an action for running a single test.
74test).
75 60
76However, launching a VS Code instance with a locally built language server is 61Launching a VS Code instance with a locally built language server is also possible.
77possible. There's **"Run Extension (Debug Build)"** launch configuration for this. 62There's **"Run Extension (Debug Build)"** launch configuration for this in VS Code.
78 63
79In general, I use one of the following workflows for fixing bugs and 64In general, I use one of the following workflows for fixing bugs and implementing features:
80implementing features.
81 65
82If the problem concerns only internal parts of rust-analyzer (i.e. I don't need 66If the problem concerns only internal parts of rust-analyzer (i.e. I don't need to touch the `rust-analyzer` crate or TypeScript code), there is a unit-test for it.
83to touch the `rust-analyzer` crate or TypeScript code), there is a unit-test for it. 67So, I use **Rust Analyzer: Run** action in VS Code to run this single test, and then just do printf-driven development/debugging.
84So, I use **Rust Analyzer: Run** action in VS Code to run this single test, and 68As a sanity check after I'm done, I use `cargo xtask install --server` and **Reload Window** action in VS Code to verify that the thing works as I expect.
85then just do printf-driven development/debugging. As a sanity check after I'm
86done, I use `cargo xtask install --server` and **Reload Window** action in VS
87Code to sanity check that the thing works as I expect.
88 69
89If the problem concerns only the VS Code extension, I use **Run Installed Extension** 70If the problem concerns only the VS Code extension, I use **Run Installed Extension** launch configuration from `launch.json`.
90launch configuration from `launch.json`. Notably, this uses the usual 71Notably, this uses the usual `rust-analyzer` binary from `PATH`.
91`rust-analyzer` binary from `PATH`. For this, it is important to have the following 72For this, it is important to have the following in your `settings.json` file:
92in your `settings.json` file:
93```json 73```json
94{ 74{
95 "rust-analyzer.serverPath": "rust-analyzer" 75 "rust-analyzer.serverPath": "rust-analyzer"
96} 76}
97``` 77```
98After I am done with the fix, I use `cargo 78After I am done with the fix, I use `cargo xtask install --client-code` to try the new extension for real.
99xtask install --client-code` to try the new extension for real.
100
101If I need to fix something in the `rust-analyzer` crate, I feel sad because it's
102on the boundary between the two processes, and working there is slow. I usually
103just `cargo xtask install --server` and poke changes from my live environment.
104Note that this uses `--release`, which is usually faster overall, because
105loading stdlib into debug version of rust-analyzer takes a lot of time. To speed
106things up, sometimes I open a temporary hello-world project which has
107`"rust-analyzer.withSysroot": false` in `.code/settings.json`. This flag causes
108rust-analyzer to skip loading the sysroot, which greatly reduces the amount of
109things rust-analyzer needs to do, and makes printf's more useful. Note that you
110should only use the `eprint!` family of macros for debugging: stdout is used for LSP
111communication, and `print!` would break it.
112
113If I need to fix something simultaneously in the server and in the client, I
114feel even more sad. I don't have a specific workflow for this case.
115
116Additionally, I use `cargo run --release -p rust-analyzer -- analysis-stats
117path/to/some/rust/crate` to run a batch analysis. This is primarily useful for
118performance optimizations, or for bug minimization.
119
120# Code Style & Review Process
121
122Our approach to "clean code" is two-fold:
123
124* We generally don't block PRs on style changes.
125* At the same time, all code in rust-analyzer is constantly refactored.
126
127It is explicitly OK for a reviewer to flag only some nits in the PR, and then send a follow-up cleanup PR for things which are easier to explain by example, cc-ing the original author.
128Sending small cleanup PRs (like renaming a single local variable) is encouraged.
129
130## Scale of Changes
131
132Everyone knows that it's better to send small & focused pull requests.
133The problem is, sometimes you *have* to, eg, rewrite the whole compiler, and that just doesn't fit into a set of isolated PRs.
134
135The main things to keep an eye on are the boundaries between various components.
136There are three kinds of changes:
137
1381. Internals of a single component are changed.
139 Specifically, you don't change any `pub` items.
140 A good example here would be an addition of a new assist.
141
1422. API of a component is expanded.
143 Specifically, you add a new `pub` function which wasn't there before.
144 A good example here would be expansion of assist API, for example, to implement lazy assists or assists groups.
145
1463. A new dependency between components is introduced.
147 Specifically, you add a `pub use` reexport from another crate or you add a new line to the `[dependencies]` section of `Cargo.toml`.
148 A good example here would be adding reference search capability to the assists crates.
149
150For the first group, the change is generally merged as long as:
151
152* it works for the happy case,
153* it has tests,
154* it doesn't panic for the unhappy case.
155
156For the second group, the change would be subjected to quite a bit of scrutiny and iteration.
157The new API needs to be right (or at least easy to change later).
158The actual implementation doesn't matter that much.
159It's very important to minimize the amount of changed lines of code for changes of the second kind.
160Often, you start doing a change of the first kind, only to realise that you need to elevate to a change of the second kind.
161In this case, we'll probably ask you to split API changes into a separate PR.
162
163Changes of the third group should be pretty rare, so we don't specify any specific process for them.
164That said, adding an innocent-looking `pub use` is a very simple way to break encapsulation, keep an eye on it!
165
166Note: if you enjoyed this abstract hand-waving about boundaries, you might appreciate
167https://www.tedinski.com/2018/02/06/system-boundaries.html
168
169## Crates.io Dependencies
170
171We try to be very conservative with usage of crates.io dependencies.
172Don't use small "helper" crates (exception: `itertools` is allowed).
173If there's some general reusable bit of code you need, consider adding it to the `stdx` crate.
174
175## Minimal Tests
176
177Most tests in rust-analyzer start with a snippet of Rust code.
178This snippets should be minimal -- if you copy-paste a snippet of real code into the tests, make sure to remove everything which could be removed.
179There are many benefits to this:
180
181* less to read or to scroll past
182* easier to understand what exactly is tested
183* less stuff printed during printf-debugging
184* less time to run test
185
186It also makes sense to format snippets more compactly (for example, by placing enum defitions like `enum E { Foo, Bar }` on a single line),
187as long as they are still readable.
188
189## Order of Imports
190
191We separate import groups with blank lines
192
193```rust
194mod x;
195mod y;
196
197use std::{ ... }
198
199use crate_foo::{ ... }
200use crate_bar::{ ... }
201
202use crate::{}
203
204use super::{} // but prefer `use crate::`
205```
206
207## Import Style
208
209Items from `hir` and `ast` should be used qualified:
210
211```rust
212// Good
213use ra_syntax::ast;
214
215fn frobnicate(func: hir::Function, strukt: ast::StructDef) {}
216
217// Not as good
218use hir::Function;
219use ra_syntax::ast::StructDef;
220
221fn frobnicate(func: Function, strukt: StructDef) {}
222```
223
224Avoid local `use MyEnum::*` imports.
225
226Prefer `use crate::foo::bar` to `use super::bar`.
227
228## Order of Items
229
230Optimize for the reader who sees the file for the first time, and wants to get the general idea about what's going on.
231People read things from top to bottom, so place most important things first.
232
233Specifically, if all items except one are private, always put the non-private item on top.
234
235Put `struct`s and `enum`s first, functions and impls last.
236
237Do
238
239```rust
240// Good
241struct Foo {
242 bars: Vec<Bar>
243}
244
245struct Bar;
246```
247
248rather than
249 79
250```rust 80If I need to fix something in the `rust-analyzer` crate, I feel sad because it's on the boundary between the two processes, and working there is slow.
251// Not as good 81I usually just `cargo xtask install --server` and poke changes from my live environment.
252struct Bar; 82Note that this uses `--release`, which is usually faster overall, because loading stdlib into debug version of rust-analyzer takes a lot of time.
83To speed things up, sometimes I open a temporary hello-world project which has `"rust-analyzer.withSysroot": false` in `.code/settings.json`.
84This flag causes rust-analyzer to skip loading the sysroot, which greatly reduces the amount of things rust-analyzer needs to do, and makes printf's more useful.
85Note that you should only use the `eprint!` family of macros for debugging: stdout is used for LSP communication, and `print!` would break it.
253 86
254struct Foo { 87If I need to fix something simultaneously in the server and in the client, I feel even more sad.
255 bars: Vec<Bar> 88I don't have a specific workflow for this case.
256}
257```
258 89
259## Variable Naming 90Additionally, I use `cargo run --release -p rust-analyzer -- analysis-stats path/to/some/rust/crate` to run a batch analysis.
91This is primarily useful for performance optimizations, or for bug minimization.
260 92
261We generally use boring and long names for local variables ([yay code completion](https://github.com/rust-analyzer/rust-analyzer/pull/4162#discussion_r417130973)). 93## Parser Tests
262The default name is a lowercased name of the type: `global_state: GlobalState`.
263Avoid ad-hoc acronyms and contractions, but use the ones that exist consistently (`db`, `ctx`, `acc`).
264The default name for "result of the function" local variable is `res`.
265
266## Collection types
267 94
268We prefer `rustc_hash::FxHashMap` and `rustc_hash::FxHashSet` instead of the ones in `std::collections`. 95Tests for the parser (`ra_parser`) live in the `ra_syntax` crate (see `test_data` directory).
269They use a hasher that's slightly faster and using them consistently will reduce code size by some small amount. 96There are two kinds of tests:
270 97
271## Preconditions 98* Manually written test cases in `parser/ok` and `parser/err`
99* "Inline" tests in `parser/inline` (these are generated) from comments in `ra_parser` crate.
272 100
273Function preconditions should generally be expressed in types and provided by the caller (rather than checked by callee): 101The purpose of inline tests is not to achieve full coverage by test cases, but to explain to the reader of the code what each particular `if` and `match` is responsible for.
102If you are tempted to add a large inline test, it might be a good idea to leave only the simplest example in place, and move the test to a manual `parser/ok` test.
274 103
275```rust 104To update test data, run with `UPDATE_EXPECT` variable:
276// Good
277fn frbonicate(walrus: Walrus) {
278 ...
279}
280 105
281// Not as good 106```bash
282fn frobnicate(walrus: Option<Walrus>) { 107env UPDATE_EXPECT=1 cargo qt
283 let walrus = match walrus {
284 Some(it) => it,
285 None => return,
286 };
287 ...
288}
289``` 108```
290 109
291## Premature Pessimization 110After adding a new inline test you need to run `cargo xtest codegen` and also update the test data as described above.
292
293While we don't specifically optimize code yet, avoid writing code which is slower than it needs to be.
294Don't allocate a `Vec` where an iterator would do, don't allocate strings needlessly.
295 111
296```rust 112## TypeScript Tests
297// Good
298use itertools::Itertools;
299 113
300let (first_word, second_word) = match text.split_ascii_whitespace().collect_tuple() { 114If you change files under `editors/code` and would like to run the tests and linter, install npm and run:
301 Some(it) => it,
302 None => return,
303}
304 115
305// Not as good 116```bash
306let words = text.split_ascii_whitespace().collect::<Vec<_>>(); 117cd editors/code
307if words.len() != 2 { 118npm ci
308 return 119npm run lint
309}
310``` 120```
311 121
312## Documentation 122# Code organization
313
314For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines.
315If the line is too long, you want to split the sentence in two :-)
316
317## Commit Style
318 123
319We don't have specific rules around git history hygiene. 124All Rust code lives in the `crates` top-level directory, and is organized as a single Cargo workspace.
320Maintaining clean git history is encouraged, but not enforced. 125The `editors` top-level directory contains code for integrating with editors.
321We use rebase workflow, it's OK to rewrite history during PR review process. 126Currently, it contains the plugin for VS Code (in TypeScript).
127The `docs` top-level directory contains both developer and user documentation.
322 128
323Avoid @mentioning people in commit messages and pull request descriptions (they are added to commit message by bors), as such messages create a lot of duplicate notification traffic during rebases. 129We have some automation infra in Rust in the `xtask` package.
130It contains stuff like formatting checking, code generation and powers `cargo xtask install`.
131The latter syntax is achieved with the help of cargo aliases (see `.cargo` directory).
324 132
325# Architecture Invariants 133# Architecture Invariants
326 134
@@ -355,35 +163,11 @@ The main IDE crate (`ra_ide`) uses "Plain Old Data" for the API.
355Rather than talking in definitions and references, it talks in Strings and textual offsets. 163Rather than talking in definitions and references, it talks in Strings and textual offsets.
356In general, API is centered around UI concerns -- the result of the call is what the user sees in the editor, and not what the compiler sees underneath. 164In general, API is centered around UI concerns -- the result of the call is what the user sees in the editor, and not what the compiler sees underneath.
357The results are 100% Rust specific though. 165The results are 100% Rust specific though.
166Shout outs to LSP developers for popularizing the idea that "UI" is a good place to draw a boundary at.
358 167
359## Parser Tests 168# Code Style & Review Process
360
361Tests for the parser (`ra_parser`) live in the `ra_syntax` crate (see `test_data` directory).
362There are two kinds of tests:
363
364* Manually written test cases in `parser/ok` and `parser/err`
365* "Inline" tests in `parser/inline` (these are generated) from comments in `ra_parser` crate.
366
367The purpose of inline tests is not to achieve full coverage by test cases, but to explain to the reader of the code what each particular `if` and `match` is responsible for.
368If you are tempted to add a large inline test, it might be a good idea to leave only the simplest example in place, and move the test to a manual `parser/ok` test.
369
370To update test data, run with `UPDATE_EXPECT` variable:
371
372```bash
373env UPDATE_EXPECT=1 cargo qt
374```
375
376After adding a new inline test you need to run `cargo xtest codegen` and also update the test data as described above.
377
378## TypeScript Tests
379
380If you change files under `editors/code` and would like to run the tests and linter, install npm and run:
381 169
382```bash 170Do see [./style.md](./style.md).
383cd editors/code
384npm ci
385npm run lint
386```
387 171
388# Logging 172# Logging
389 173
@@ -451,3 +235,34 @@ For measuring time of incremental analysis, use either of these:
451$ cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --highlight ../chalk/chalk-engine/src/logic.rs 235$ cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --highlight ../chalk/chalk-engine/src/logic.rs
452$ cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --complete ../chalk/chalk-engine/src/logic.rs:94:0 236$ cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --complete ../chalk/chalk-engine/src/logic.rs:94:0
453``` 237```
238
239# Release Process
240
241Release process is handled by `release`, `dist` and `promote` xtasks, `release` being the main one.
242
243`release` assumes that you have checkouts of `rust-analyzer`, `rust-analyzer.github.io`, and `rust-lang/rust` in the same directory:
244
245```
246./rust-analyzer
247./rust-analyzer.github.io
248./rust-rust-analyzer # Note the name!
249```
250
251Additionally, it assumes that remote for `rust-analyzer` is called `upstream` (I use `origin` to point to my fork).
252
253Release steps:
254
2551. Inside rust-analyzer, run `cargo xtask release`. This will:
256 * checkout the `release` branch
257 * reset it to `upstream/nightly`
258 * push it to `upstream`. This triggers GitHub Actions which:
259 ** runs `cargo xtask dist` to package binaries and VS Code extension
260 ** makes a GitHub release
261 ** pushes VS Code extension to the marketplace
262 * create new changelog in `rust-analyzer.github.io`
263 * create `rust-analyzer.github.io/git.log` file with the log of merge commits since last release
2642. While the release is in progress, fill-in the changelog using `git.log`
2653. Commit & push the changelog
2664. Tweet
2675. Inside `rust-analyzer`, run `cargo xtask promote` -- this will create a PR to rust-lang/rust updating rust-analyzer's submodule.
268 Self-approve the PR.
diff --git a/docs/dev/style.md b/docs/dev/style.md
new file mode 100644
index 000000000..1c68f5702
--- /dev/null
+++ b/docs/dev/style.md
@@ -0,0 +1,212 @@
1Our approach to "clean code" is two-fold:
2
3* We generally don't block PRs on style changes.
4* At the same time, all code in rust-analyzer is constantly refactored.
5
6It is explicitly OK for a reviewer to flag only some nits in the PR, and then send a follow-up cleanup PR for things which are easier to explain by example, cc-ing the original author.
7Sending small cleanup PRs (like renaming a single local variable) is encouraged.
8
9# Scale of Changes
10
11Everyone knows that it's better to send small & focused pull requests.
12The problem is, sometimes you *have* to, eg, rewrite the whole compiler, and that just doesn't fit into a set of isolated PRs.
13
14The main things to keep an eye on are the boundaries between various components.
15There are three kinds of changes:
16
171. Internals of a single component are changed.
18 Specifically, you don't change any `pub` items.
19 A good example here would be an addition of a new assist.
20
212. API of a component is expanded.
22 Specifically, you add a new `pub` function which wasn't there before.
23 A good example here would be expansion of assist API, for example, to implement lazy assists or assists groups.
24
253. A new dependency between components is introduced.
26 Specifically, you add a `pub use` reexport from another crate or you add a new line to the `[dependencies]` section of `Cargo.toml`.
27 A good example here would be adding reference search capability to the assists crates.
28
29For the first group, the change is generally merged as long as:
30
31* it works for the happy case,
32* it has tests,
33* it doesn't panic for the unhappy case.
34
35For the second group, the change would be subjected to quite a bit of scrutiny and iteration.
36The new API needs to be right (or at least easy to change later).
37The actual implementation doesn't matter that much.
38It's very important to minimize the amount of changed lines of code for changes of the second kind.
39Often, you start doing a change of the first kind, only to realise that you need to elevate to a change of the second kind.
40In this case, we'll probably ask you to split API changes into a separate PR.
41
42Changes of the third group should be pretty rare, so we don't specify any specific process for them.
43That said, adding an innocent-looking `pub use` is a very simple way to break encapsulation, keep an eye on it!
44
45Note: if you enjoyed this abstract hand-waving about boundaries, you might appreciate
46https://www.tedinski.com/2018/02/06/system-boundaries.html
47
48# Crates.io Dependencies
49
50We try to be very conservative with usage of crates.io dependencies.
51Don't use small "helper" crates (exception: `itertools` is allowed).
52If there's some general reusable bit of code you need, consider adding it to the `stdx` crate.
53
54# Minimal Tests
55
56Most tests in rust-analyzer start with a snippet of Rust code.
57This snippets should be minimal -- if you copy-paste a snippet of real code into the tests, make sure to remove everything which could be removed.
58There are many benefits to this:
59
60* less to read or to scroll past
61* easier to understand what exactly is tested
62* less stuff printed during printf-debugging
63* less time to run test
64
65It also makes sense to format snippets more compactly (for example, by placing enum definitions like `enum E { Foo, Bar }` on a single line),
66as long as they are still readable.
67
68## Order of Imports
69
70Separate import groups with blank lines.
71Use one `use` per crate.
72
73```rust
74mod x;
75mod y;
76
77// First std.
78use std::{ ... }
79
80// Second, external crates (both crates.io crates and other rust-analyzer crates).
81use crate_foo::{ ... }
82use crate_bar::{ ... }
83
84// Then current crate.
85use crate::{}
86
87// Finally, parent and child modules, but prefer `use crate::`.
88use super::{}
89```
90
91Module declarations come before the imports.
92Order them in "suggested reading order" for a person new to the code base.
93
94## Import Style
95
96Qualify items from `hir` and `ast`.
97
98```rust
99// Good
100use ra_syntax::ast;
101
102fn frobnicate(func: hir::Function, strukt: ast::StructDef) {}
103
104// Not as good
105use hir::Function;
106use ra_syntax::ast::StructDef;
107
108fn frobnicate(func: Function, strukt: StructDef) {}
109```
110
111Avoid local `use MyEnum::*` imports.
112
113Prefer `use crate::foo::bar` to `use super::bar`.
114
115## Order of Items
116
117Optimize for the reader who sees the file for the first time, and wants to get a general idea about what's going on.
118People read things from top to bottom, so place most important things first.
119
120Specifically, if all items except one are private, always put the non-private item on top.
121
122Put `struct`s and `enum`s first, functions and impls last.
123
124Do
125
126```rust
127// Good
128struct Foo {
129 bars: Vec<Bar>
130}
131
132struct Bar;
133```
134
135rather than
136
137```rust
138// Not as good
139struct Bar;
140
141struct Foo {
142 bars: Vec<Bar>
143}
144```
145
146## Variable Naming
147
148Use boring and long names for local variables ([yay code completion](https://github.com/rust-analyzer/rust-analyzer/pull/4162#discussion_r417130973)).
149The default name is a lowercased name of the type: `global_state: GlobalState`.
150Avoid ad-hoc acronyms and contractions, but use the ones that exist consistently (`db`, `ctx`, `acc`).
151The default name for "result of the function" local variable is `res`.
152The default name for "I don't really care about the name" variable is `it`.
153
154## Collection types
155
156Prefer `rustc_hash::FxHashMap` and `rustc_hash::FxHashSet` instead of the ones in `std::collections`.
157They use a hasher that's slightly faster and using them consistently will reduce code size by some small amount.
158
159## Preconditions
160
161Express function preconditions in types and force the caller to provide them (rather than checking in callee):
162
163```rust
164// Good
165fn frbonicate(walrus: Walrus) {
166 ...
167}
168
169// Not as good
170fn frobnicate(walrus: Option<Walrus>) {
171 let walrus = match walrus {
172 Some(it) => it,
173 None => return,
174 };
175 ...
176}
177```
178
179## Premature Pessimization
180
181Avoid writing code which is slower than it needs to be.
182Don't allocate a `Vec` where an iterator would do, don't allocate strings needlessly.
183
184```rust
185// Good
186use itertools::Itertools;
187
188let (first_word, second_word) = match text.split_ascii_whitespace().collect_tuple() {
189 Some(it) => it,
190 None => return,
191}
192
193// Not as good
194let words = text.split_ascii_whitespace().collect::<Vec<_>>();
195if words.len() != 2 {
196 return
197}
198```
199
200## Documentation
201
202For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines.
203If the line is too long, you want to split the sentence in two :-)
204
205## Commit Style
206
207We don't have specific rules around git history hygiene.
208Maintaining clean git history is encouraged, but not enforced.
209Use rebase workflow, it's OK to rewrite history during PR review process.
210
211Avoid @mentioning people in commit messages and pull request descriptions(they are added to commit message by bors).
212Such messages create a lot of duplicate notification traffic during rebases.
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 72a2ae26b..1a1140b04 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -15,6 +15,6 @@ flate2 = "1.0"
15pico-args = "0.3.1" 15pico-args = "0.3.1"
16proc-macro2 = "1.0.8" 16proc-macro2 = "1.0.8"
17quote = "1.0.2" 17quote = "1.0.2"
18ungrammar = "0.1.0" 18ungrammar = "1.1.1"
19walkdir = "2.3.1" 19walkdir = "2.3.1"
20write-json = "0.1.0" 20write-json = "0.1.0"
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 1386fc4e7..adc191254 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -113,12 +113,12 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
113 "TUPLE_TYPE", 113 "TUPLE_TYPE",
114 "NEVER_TYPE", 114 "NEVER_TYPE",
115 "PATH_TYPE", 115 "PATH_TYPE",
116 "POINTER_TYPE", 116 "PTR_TYPE",
117 "ARRAY_TYPE", 117 "ARRAY_TYPE",
118 "SLICE_TYPE", 118 "SLICE_TYPE",
119 "REFERENCE_TYPE", 119 "REF_TYPE",
120 "INFER_TYPE", 120 "INFER_TYPE",
121 "FN_POINTER_TYPE", 121 "FN_PTR_TYPE",
122 "FOR_TYPE", 122 "FOR_TYPE",
123 "IMPL_TRAIT_TYPE", 123 "IMPL_TRAIT_TYPE",
124 "DYN_TRAIT_TYPE", 124 "DYN_TRAIT_TYPE",
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 4602ff1d7..cafad8070 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -10,7 +10,7 @@ use std::{
10 10
11use proc_macro2::{Punct, Spacing}; 11use proc_macro2::{Punct, Spacing};
12use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
13use ungrammar::{Grammar, Rule}; 13use ungrammar::{rust_grammar, Grammar, Rule};
14 14
15use crate::{ 15use crate::{
16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC}, 16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC},
@@ -19,9 +19,7 @@ use crate::{
19}; 19};
20 20
21pub fn generate_syntax(mode: Mode) -> Result<()> { 21pub fn generate_syntax(mode: Mode) -> Result<()> {
22 let grammar = include_str!("rust.ungram") 22 let grammar = rust_grammar();
23 .parse::<Grammar>()
24 .unwrap_or_else(|err| panic!("\n \x1b[91merror\x1b[0m: {}\n", err));
25 let ast = lower(&grammar); 23 let ast = lower(&grammar);
26 24
27 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS); 25 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS);
@@ -538,6 +536,7 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
538 for alternative in alternatives { 536 for alternative in alternatives {
539 match alternative { 537 match alternative {
540 Rule::Node(it) => variants.push(grammar[*it].name.clone()), 538 Rule::Node(it) => variants.push(grammar[*it].name.clone()),
539 Rule::Token(it) if grammar[*it].name == ";" => (),
541 _ => return None, 540 _ => return None,
542 } 541 }
543 } 542 }
@@ -591,8 +590,8 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, r
591 | "index" 590 | "index"
592 | "base" 591 | "base"
593 | "value" 592 | "value"
594 | "target_type" 593 | "trait"
595 | "target_trait" 594 | "self_ty"
596 ); 595 );
597 if manually_implemented { 596 if manually_implemented {
598 return; 597 return;