diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_ide_api/Cargo.toml | 3 | ||||
-rw-r--r-- | crates/ra_ide_api/src/change.rs | 20 | ||||
-rw-r--r-- | crates/ra_ide_api/src/db.rs | 10 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide_api/src/symbol_index.rs | 37 | ||||
-rw-r--r-- | crates/ra_ide_api/src/wasm_shims.rs | 17 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 1 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 15 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt | 75 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rs | 5 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.txt | 59 | ||||
-rw-r--r-- | crates/ra_tools/src/main.rs | 2 |
13 files changed, 233 insertions, 16 deletions
diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide_api/Cargo.toml index 000694620..6bbf9d5dd 100644 --- a/crates/ra_ide_api/Cargo.toml +++ b/crates/ra_ide_api/Cargo.toml | |||
@@ -4,6 +4,9 @@ name = "ra_ide_api" | |||
4 | version = "0.1.0" | 4 | version = "0.1.0" |
5 | authors = ["rust-analyzer developers"] | 5 | authors = ["rust-analyzer developers"] |
6 | 6 | ||
7 | [features] | ||
8 | wasm = [] | ||
9 | |||
7 | [dependencies] | 10 | [dependencies] |
8 | format-buf = "1.0.0" | 11 | format-buf = "1.0.0" |
9 | itertools = "0.8.0" | 12 | itertools = "0.8.0" |
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 0d52f5ffb..cc476a237 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs | |||
@@ -6,6 +6,7 @@ use ra_db::{ | |||
6 | }; | 6 | }; |
7 | use ra_prof::{memory_usage, profile, Bytes}; | 7 | use ra_prof::{memory_usage, profile, Bytes}; |
8 | use ra_syntax::SourceFile; | 8 | use ra_syntax::SourceFile; |
9 | #[cfg(not(feature = "wasm"))] | ||
9 | use rayon::prelude::*; | 10 | use rayon::prelude::*; |
10 | use relative_path::RelativePathBuf; | 11 | use relative_path::RelativePathBuf; |
11 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
@@ -143,7 +144,12 @@ impl LibraryData { | |||
143 | root_id: SourceRootId, | 144 | root_id: SourceRootId, |
144 | files: Vec<(FileId, RelativePathBuf, Arc<String>)>, | 145 | files: Vec<(FileId, RelativePathBuf, Arc<String>)>, |
145 | ) -> LibraryData { | 146 | ) -> LibraryData { |
146 | let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| { | 147 | #[cfg(not(feature = "wasm"))] |
148 | let iter = files.par_iter(); | ||
149 | #[cfg(feature = "wasm")] | ||
150 | let iter = files.iter(); | ||
151 | |||
152 | let symbol_index = SymbolIndex::for_files(iter.map(|(file_id, _, text)| { | ||
147 | let parse = SourceFile::parse(text); | 153 | let parse = SourceFile::parse(text); |
148 | (*file_id, parse) | 154 | (*file_id, parse) |
149 | })); | 155 | })); |
@@ -234,8 +240,12 @@ impl RootDatabase { | |||
234 | } | 240 | } |
235 | 241 | ||
236 | pub(crate) fn maybe_collect_garbage(&mut self) { | 242 | pub(crate) fn maybe_collect_garbage(&mut self) { |
243 | if cfg!(feature = "wasm") { | ||
244 | return; | ||
245 | } | ||
246 | |||
237 | if self.last_gc_check.elapsed() > GC_COOLDOWN { | 247 | if self.last_gc_check.elapsed() > GC_COOLDOWN { |
238 | self.last_gc_check = time::Instant::now(); | 248 | self.last_gc_check = crate::wasm_shims::Instant::now(); |
239 | let retained_trees = syntax_tree_stats(self).retained; | 249 | let retained_trees = syntax_tree_stats(self).retained; |
240 | if retained_trees > 100 { | 250 | if retained_trees > 100 { |
241 | log::info!("automatic garbadge collection, {} retained trees", retained_trees); | 251 | log::info!("automatic garbadge collection, {} retained trees", retained_trees); |
@@ -245,8 +255,12 @@ impl RootDatabase { | |||
245 | } | 255 | } |
246 | 256 | ||
247 | pub(crate) fn collect_garbage(&mut self) { | 257 | pub(crate) fn collect_garbage(&mut self) { |
258 | if cfg!(feature = "wasm") { | ||
259 | return; | ||
260 | } | ||
261 | |||
248 | let _p = profile("RootDatabase::collect_garbage"); | 262 | let _p = profile("RootDatabase::collect_garbage"); |
249 | self.last_gc = time::Instant::now(); | 263 | self.last_gc = crate::wasm_shims::Instant::now(); |
250 | 264 | ||
251 | let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); | 265 | let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); |
252 | 266 | ||
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index 4c5159d61..afd9022ce 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::{sync::Arc, time}; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_db::{ | 3 | use ra_db::{ |
4 | salsa::{self, Database, Durability}, | 4 | salsa::{self, Database, Durability}, |
@@ -25,8 +25,8 @@ pub(crate) struct RootDatabase { | |||
25 | runtime: salsa::Runtime<RootDatabase>, | 25 | runtime: salsa::Runtime<RootDatabase>, |
26 | pub(crate) feature_flags: Arc<FeatureFlags>, | 26 | pub(crate) feature_flags: Arc<FeatureFlags>, |
27 | pub(crate) debug_data: Arc<DebugData>, | 27 | pub(crate) debug_data: Arc<DebugData>, |
28 | pub(crate) last_gc: time::Instant, | 28 | pub(crate) last_gc: crate::wasm_shims::Instant, |
29 | pub(crate) last_gc_check: time::Instant, | 29 | pub(crate) last_gc_check: crate::wasm_shims::Instant, |
30 | } | 30 | } |
31 | 31 | ||
32 | impl hir::debug::HirDebugHelper for RootDatabase { | 32 | impl hir::debug::HirDebugHelper for RootDatabase { |
@@ -69,8 +69,8 @@ impl RootDatabase { | |||
69 | pub fn new(lru_capacity: Option<usize>, feature_flags: FeatureFlags) -> RootDatabase { | 69 | pub fn new(lru_capacity: Option<usize>, feature_flags: FeatureFlags) -> RootDatabase { |
70 | let mut db = RootDatabase { | 70 | let mut db = RootDatabase { |
71 | runtime: salsa::Runtime::default(), | 71 | runtime: salsa::Runtime::default(), |
72 | last_gc: time::Instant::now(), | 72 | last_gc: crate::wasm_shims::Instant::now(), |
73 | last_gc_check: time::Instant::now(), | 73 | last_gc_check: crate::wasm_shims::Instant::now(), |
74 | feature_flags: Arc::new(feature_flags), | 74 | feature_flags: Arc::new(feature_flags), |
75 | debug_data: Default::default(), | 75 | debug_data: Default::default(), |
76 | }; | 76 | }; |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 412dc4d71..44d1ec77b 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -40,6 +40,7 @@ mod typing; | |||
40 | mod matching_brace; | 40 | mod matching_brace; |
41 | mod display; | 41 | mod display; |
42 | mod inlay_hints; | 42 | mod inlay_hints; |
43 | mod wasm_shims; | ||
43 | 44 | ||
44 | #[cfg(test)] | 45 | #[cfg(test)] |
45 | mod marks; | 46 | mod marks; |
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index a5729c368..02cdfbc60 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -38,6 +38,7 @@ use ra_syntax::{ | |||
38 | SyntaxKind::{self, *}, | 38 | SyntaxKind::{self, *}, |
39 | SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent, | 39 | SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent, |
40 | }; | 40 | }; |
41 | #[cfg(not(feature = "wasm"))] | ||
41 | use rayon::prelude::*; | 42 | use rayon::prelude::*; |
42 | 43 | ||
43 | use crate::{db::RootDatabase, FileId, Query}; | 44 | use crate::{db::RootDatabase, FileId, Query}; |
@@ -79,10 +80,17 @@ pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> | |||
79 | 80 | ||
80 | let buf: Vec<Arc<SymbolIndex>> = if query.libs { | 81 | let buf: Vec<Arc<SymbolIndex>> = if query.libs { |
81 | let snap = Snap(db.snapshot()); | 82 | let snap = Snap(db.snapshot()); |
82 | db.library_roots() | 83 | #[cfg(not(feature = "wasm"))] |
84 | let buf = db | ||
85 | .library_roots() | ||
83 | .par_iter() | 86 | .par_iter() |
84 | .map_with(snap, |db, &lib_id| db.0.library_symbols(lib_id)) | 87 | .map_with(snap, |db, &lib_id| db.0.library_symbols(lib_id)) |
85 | .collect() | 88 | .collect(); |
89 | |||
90 | #[cfg(feature = "wasm")] | ||
91 | let buf = db.library_roots().iter().map(|&lib_id| snap.0.library_symbols(lib_id)).collect(); | ||
92 | |||
93 | buf | ||
86 | } else { | 94 | } else { |
87 | let mut files = Vec::new(); | 95 | let mut files = Vec::new(); |
88 | for &root in db.local_roots().iter() { | 96 | for &root in db.local_roots().iter() { |
@@ -91,7 +99,14 @@ pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> | |||
91 | } | 99 | } |
92 | 100 | ||
93 | let snap = Snap(db.snapshot()); | 101 | let snap = Snap(db.snapshot()); |
94 | files.par_iter().map_with(snap, |db, &file_id| db.0.file_symbols(file_id)).collect() | 102 | #[cfg(not(feature = "wasm"))] |
103 | let buf = | ||
104 | files.par_iter().map_with(snap, |db, &file_id| db.0.file_symbols(file_id)).collect(); | ||
105 | |||
106 | #[cfg(feature = "wasm")] | ||
107 | let buf = files.iter().map(|&file_id| snap.0.file_symbols(file_id)).collect(); | ||
108 | |||
109 | buf | ||
95 | }; | 110 | }; |
96 | query.search(&buf) | 111 | query.search(&buf) |
97 | } | 112 | } |
@@ -135,9 +150,12 @@ impl SymbolIndex { | |||
135 | fn cmp_key<'a>(s1: &'a FileSymbol) -> impl Ord + 'a { | 150 | fn cmp_key<'a>(s1: &'a FileSymbol) -> impl Ord + 'a { |
136 | unicase::Ascii::new(s1.name.as_str()) | 151 | unicase::Ascii::new(s1.name.as_str()) |
137 | } | 152 | } |
138 | 153 | #[cfg(not(feature = "wasm"))] | |
139 | symbols.par_sort_by(|s1, s2| cmp_key(s1).cmp(&cmp_key(s2))); | 154 | symbols.par_sort_by(|s1, s2| cmp_key(s1).cmp(&cmp_key(s2))); |
140 | 155 | ||
156 | #[cfg(feature = "wasm")] | ||
157 | symbols.sort_by(|s1, s2| cmp_key(s1).cmp(&cmp_key(s2))); | ||
158 | |||
141 | let mut builder = fst::MapBuilder::memory(); | 159 | let mut builder = fst::MapBuilder::memory(); |
142 | 160 | ||
143 | let mut last_batch_start = 0; | 161 | let mut last_batch_start = 0; |
@@ -169,6 +187,7 @@ impl SymbolIndex { | |||
169 | self.map.as_fst().size() + self.symbols.len() * mem::size_of::<FileSymbol>() | 187 | self.map.as_fst().size() + self.symbols.len() * mem::size_of::<FileSymbol>() |
170 | } | 188 | } |
171 | 189 | ||
190 | #[cfg(not(feature = "wasm"))] | ||
172 | pub(crate) fn for_files( | 191 | pub(crate) fn for_files( |
173 | files: impl ParallelIterator<Item = (FileId, Parse<ast::SourceFile>)>, | 192 | files: impl ParallelIterator<Item = (FileId, Parse<ast::SourceFile>)>, |
174 | ) -> SymbolIndex { | 193 | ) -> SymbolIndex { |
@@ -178,6 +197,16 @@ impl SymbolIndex { | |||
178 | SymbolIndex::new(symbols) | 197 | SymbolIndex::new(symbols) |
179 | } | 198 | } |
180 | 199 | ||
200 | #[cfg(feature = "wasm")] | ||
201 | pub(crate) fn for_files( | ||
202 | files: impl Iterator<Item = (FileId, Parse<ast::SourceFile>)>, | ||
203 | ) -> SymbolIndex { | ||
204 | let symbols = files | ||
205 | .flat_map(|(file_id, file)| source_file_to_file_symbols(&file.tree(), file_id)) | ||
206 | .collect::<Vec<_>>(); | ||
207 | SymbolIndex::new(symbols) | ||
208 | } | ||
209 | |||
181 | fn range_to_map_value(start: usize, end: usize) -> u64 { | 210 | fn range_to_map_value(start: usize, end: usize) -> u64 { |
182 | debug_assert![start <= (std::u32::MAX as usize)]; | 211 | debug_assert![start <= (std::u32::MAX as usize)]; |
183 | debug_assert![end <= (std::u32::MAX as usize)]; | 212 | debug_assert![end <= (std::u32::MAX as usize)]; |
diff --git a/crates/ra_ide_api/src/wasm_shims.rs b/crates/ra_ide_api/src/wasm_shims.rs new file mode 100644 index 000000000..592dddf44 --- /dev/null +++ b/crates/ra_ide_api/src/wasm_shims.rs | |||
@@ -0,0 +1,17 @@ | |||
1 | #[cfg(not(feature = "wasm"))] | ||
2 | pub use std::time::Instant; | ||
3 | |||
4 | #[cfg(feature = "wasm")] | ||
5 | #[derive(Clone, Copy, Debug)] | ||
6 | pub struct Instant; | ||
7 | |||
8 | #[cfg(feature = "wasm")] | ||
9 | impl Instant { | ||
10 | pub fn now() -> Self { | ||
11 | Self | ||
12 | } | ||
13 | |||
14 | pub fn elapsed(&self) -> std::time::Duration { | ||
15 | std::time::Duration::new(0, 0) | ||
16 | } | ||
17 | } | ||
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 6c7fdc2cd..457f42a26 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -54,6 +54,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = | |||
54 | LIFETIME, | 54 | LIFETIME, |
55 | ASYNC_KW, | 55 | ASYNC_KW, |
56 | TRY_KW, | 56 | TRY_KW, |
57 | LOOP_KW | ||
57 | ]); | 58 | ]); |
58 | 59 | ||
59 | const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; | 60 | const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; |
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index a4ffd6960..aa9a6d18e 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -167,7 +167,7 @@ fn record_field_pat_list(p: &mut Parser) { | |||
167 | // A trailing `..` is *not* treated as a DOT_DOT_PAT. | 167 | // A trailing `..` is *not* treated as a DOT_DOT_PAT. |
168 | T![.] if p.at(T![..]) => p.bump(T![..]), | 168 | T![.] if p.at(T![..]) => p.bump(T![..]), |
169 | 169 | ||
170 | IDENT if p.nth(1) == T![:] => record_field_pat(p), | 170 | IDENT | INT_NUMBER if p.nth(1) == T![:] => record_field_pat(p), |
171 | T!['{'] => error_block(p, "expected ident"), | 171 | T!['{'] => error_block(p, "expected ident"), |
172 | T![box] => { | 172 | T![box] => { |
173 | box_pat(p); | 173 | box_pat(p); |
@@ -184,12 +184,21 @@ fn record_field_pat_list(p: &mut Parser) { | |||
184 | m.complete(p, RECORD_FIELD_PAT_LIST); | 184 | m.complete(p, RECORD_FIELD_PAT_LIST); |
185 | } | 185 | } |
186 | 186 | ||
187 | // test record_field_pat | ||
188 | // fn foo() { | ||
189 | // let S { 0: 1 } = (); | ||
190 | // let S { x: 1 } = (); | ||
191 | // } | ||
187 | fn record_field_pat(p: &mut Parser) { | 192 | fn record_field_pat(p: &mut Parser) { |
188 | assert!(p.at(IDENT)); | 193 | assert!(p.at(IDENT) || p.at(INT_NUMBER)); |
189 | assert!(p.nth(1) == T![:]); | 194 | assert!(p.nth(1) == T![:]); |
190 | 195 | ||
191 | let m = p.start(); | 196 | let m = p.start(); |
192 | name(p); | 197 | |
198 | if !p.eat(INT_NUMBER) { | ||
199 | name(p) | ||
200 | } | ||
201 | |||
193 | p.bump_any(); | 202 | p.bump_any(); |
194 | pattern(p); | 203 | pattern(p); |
195 | m.complete(p, RECORD_FIELD_PAT); | 204 | m.complete(p, RECORD_FIELD_PAT); |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs new file mode 100644 index 000000000..26b1d5f89 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | let S { 0: 1 } = (); | ||
3 | let S { x: 1 } = (); | ||
4 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt new file mode 100644 index 000000000..06fbdfabf --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt | |||
@@ -0,0 +1,75 @@ | |||
1 | SOURCE_FILE@[0; 63) | ||
2 | FN_DEF@[0; 62) | ||
3 | FN_KW@[0; 2) "fn" | ||
4 | WHITESPACE@[2; 3) " " | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) "(" | ||
9 | R_PAREN@[7; 8) ")" | ||
10 | WHITESPACE@[8; 9) " " | ||
11 | BLOCK_EXPR@[9; 62) | ||
12 | BLOCK@[9; 62) | ||
13 | L_CURLY@[9; 10) "{" | ||
14 | WHITESPACE@[10; 15) "\n " | ||
15 | LET_STMT@[15; 35) | ||
16 | LET_KW@[15; 18) "let" | ||
17 | WHITESPACE@[18; 19) " " | ||
18 | RECORD_PAT@[19; 29) | ||
19 | PATH@[19; 20) | ||
20 | PATH_SEGMENT@[19; 20) | ||
21 | NAME_REF@[19; 20) | ||
22 | IDENT@[19; 20) "S" | ||
23 | WHITESPACE@[20; 21) " " | ||
24 | RECORD_FIELD_PAT_LIST@[21; 29) | ||
25 | L_CURLY@[21; 22) "{" | ||
26 | WHITESPACE@[22; 23) " " | ||
27 | RECORD_FIELD_PAT@[23; 27) | ||
28 | INT_NUMBER@[23; 24) "0" | ||
29 | COLON@[24; 25) ":" | ||
30 | WHITESPACE@[25; 26) " " | ||
31 | LITERAL_PAT@[26; 27) | ||
32 | LITERAL@[26; 27) | ||
33 | INT_NUMBER@[26; 27) "1" | ||
34 | WHITESPACE@[27; 28) " " | ||
35 | R_CURLY@[28; 29) "}" | ||
36 | WHITESPACE@[29; 30) " " | ||
37 | EQ@[30; 31) "=" | ||
38 | WHITESPACE@[31; 32) " " | ||
39 | TUPLE_EXPR@[32; 34) | ||
40 | L_PAREN@[32; 33) "(" | ||
41 | R_PAREN@[33; 34) ")" | ||
42 | SEMI@[34; 35) ";" | ||
43 | WHITESPACE@[35; 40) "\n " | ||
44 | LET_STMT@[40; 60) | ||
45 | LET_KW@[40; 43) "let" | ||
46 | WHITESPACE@[43; 44) " " | ||
47 | RECORD_PAT@[44; 54) | ||
48 | PATH@[44; 45) | ||
49 | PATH_SEGMENT@[44; 45) | ||
50 | NAME_REF@[44; 45) | ||
51 | IDENT@[44; 45) "S" | ||
52 | WHITESPACE@[45; 46) " " | ||
53 | RECORD_FIELD_PAT_LIST@[46; 54) | ||
54 | L_CURLY@[46; 47) "{" | ||
55 | WHITESPACE@[47; 48) " " | ||
56 | RECORD_FIELD_PAT@[48; 52) | ||
57 | NAME@[48; 49) | ||
58 | IDENT@[48; 49) "x" | ||
59 | COLON@[49; 50) ":" | ||
60 | WHITESPACE@[50; 51) " " | ||
61 | LITERAL_PAT@[51; 52) | ||
62 | LITERAL@[51; 52) | ||
63 | INT_NUMBER@[51; 52) "1" | ||
64 | WHITESPACE@[52; 53) " " | ||
65 | R_CURLY@[53; 54) "}" | ||
66 | WHITESPACE@[54; 55) " " | ||
67 | EQ@[55; 56) "=" | ||
68 | WHITESPACE@[56; 57) " " | ||
69 | TUPLE_EXPR@[57; 59) | ||
70 | L_PAREN@[57; 58) "(" | ||
71 | R_PAREN@[58; 59) ")" | ||
72 | SEMI@[59; 60) ";" | ||
73 | WHITESPACE@[60; 61) "\n" | ||
74 | R_CURLY@[61; 62) "}" | ||
75 | WHITESPACE@[62; 63) "\n" | ||
diff --git a/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rs b/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rs new file mode 100644 index 000000000..31c12522f --- /dev/null +++ b/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn foo(x: i32) {} | ||
2 | |||
3 | fn main() { | ||
4 | foo(loop {}); | ||
5 | } \ No newline at end of file | ||
diff --git a/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.txt b/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.txt new file mode 100644 index 000000000..cc8c3f7ec --- /dev/null +++ b/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | SOURCE_FILE@[0; 50) | ||
2 | FN_DEF@[0; 17) | ||
3 | FN_KW@[0; 2) "fn" | ||
4 | WHITESPACE@[2; 3) " " | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 14) | ||
8 | L_PAREN@[6; 7) "(" | ||
9 | PARAM@[7; 13) | ||
10 | BIND_PAT@[7; 8) | ||
11 | NAME@[7; 8) | ||
12 | IDENT@[7; 8) "x" | ||
13 | COLON@[8; 9) ":" | ||
14 | WHITESPACE@[9; 10) " " | ||
15 | PATH_TYPE@[10; 13) | ||
16 | PATH@[10; 13) | ||
17 | PATH_SEGMENT@[10; 13) | ||
18 | NAME_REF@[10; 13) | ||
19 | IDENT@[10; 13) "i32" | ||
20 | R_PAREN@[13; 14) ")" | ||
21 | WHITESPACE@[14; 15) " " | ||
22 | BLOCK_EXPR@[15; 17) | ||
23 | BLOCK@[15; 17) | ||
24 | L_CURLY@[15; 16) "{" | ||
25 | R_CURLY@[16; 17) "}" | ||
26 | WHITESPACE@[17; 19) "\n\n" | ||
27 | FN_DEF@[19; 50) | ||
28 | FN_KW@[19; 21) "fn" | ||
29 | WHITESPACE@[21; 22) " " | ||
30 | NAME@[22; 26) | ||
31 | IDENT@[22; 26) "main" | ||
32 | PARAM_LIST@[26; 28) | ||
33 | L_PAREN@[26; 27) "(" | ||
34 | R_PAREN@[27; 28) ")" | ||
35 | WHITESPACE@[28; 29) " " | ||
36 | BLOCK_EXPR@[29; 50) | ||
37 | BLOCK@[29; 50) | ||
38 | L_CURLY@[29; 30) "{" | ||
39 | WHITESPACE@[30; 35) "\n " | ||
40 | EXPR_STMT@[35; 48) | ||
41 | CALL_EXPR@[35; 47) | ||
42 | PATH_EXPR@[35; 38) | ||
43 | PATH@[35; 38) | ||
44 | PATH_SEGMENT@[35; 38) | ||
45 | NAME_REF@[35; 38) | ||
46 | IDENT@[35; 38) "foo" | ||
47 | ARG_LIST@[38; 47) | ||
48 | L_PAREN@[38; 39) "(" | ||
49 | LOOP_EXPR@[39; 46) | ||
50 | LOOP_KW@[39; 43) "loop" | ||
51 | WHITESPACE@[43; 44) " " | ||
52 | BLOCK_EXPR@[44; 46) | ||
53 | BLOCK@[44; 46) | ||
54 | L_CURLY@[44; 45) "{" | ||
55 | R_CURLY@[45; 46) "}" | ||
56 | R_PAREN@[46; 47) ")" | ||
57 | SEMI@[47; 48) ";" | ||
58 | WHITESPACE@[48; 49) "\n" | ||
59 | R_CURLY@[49; 50) "}" | ||
diff --git a/crates/ra_tools/src/main.rs b/crates/ra_tools/src/main.rs index 65d211b44..a951ce427 100644 --- a/crates/ra_tools/src/main.rs +++ b/crates/ra_tools/src/main.rs | |||
@@ -167,7 +167,7 @@ fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> { | |||
167 | } | 167 | } |
168 | .run()?; | 168 | .run()?; |
169 | 169 | ||
170 | let code_binary = ["code", "code-insiders"].iter().find(|bin| { | 170 | let code_binary = ["code", "code-insiders", "codium"].iter().find(|bin| { |
171 | Cmd { | 171 | Cmd { |
172 | unix: &format!("{} --version", bin), | 172 | unix: &format!("{} --version", bin), |
173 | windows: &format!("cmd.exe /c {}.cmd --version", bin), | 173 | windows: &format!("cmd.exe /c {}.cmd --version", bin), |