aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api')
-rw-r--r--crates/ra_ide_api/src/completion.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs447
-rw-r--r--crates/ra_ide_api/src/completion/complete_snippet.rs77
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs7
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs203
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap23
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap31
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap32
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap30
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap24
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap16
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap16
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap24
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap15
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap23
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap22
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap24
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap24
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap16
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap30
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap23
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap23
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap23
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path.snap5
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path2.snap5
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap22
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap23
-rw-r--r--crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap191
-rw-r--r--crates/ra_ide_api/src/display/structure.rs188
-rw-r--r--crates/ra_ide_api/src/inlay_hints.rs470
-rw-r--r--crates/ra_ide_api/src/lib.rs86
-rw-r--r--crates/ra_ide_api/src/references.rs72
-rw-r--r--crates/ra_ide_api/src/runnables.rs72
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__highlights_code_inside_macros.snap44
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__rename_mod.snap38
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap38
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__runnables.snap24
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__runnables_module.snap20
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap20
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap20
-rw-r--r--crates/ra_ide_api/src/syntax_tree.rs14
-rw-r--r--crates/ra_ide_api/src/typing.rs4
42 files changed, 1322 insertions, 1189 deletions
diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs
index 85160358a..a6b68be75 100644
--- a/crates/ra_ide_api/src/completion.rs
+++ b/crates/ra_ide_api/src/completion.rs
@@ -16,7 +16,7 @@ mod complete_postfix;
16use ra_db::SourceDatabase; 16use ra_db::SourceDatabase;
17 17
18#[cfg(test)] 18#[cfg(test)]
19use crate::completion::completion_item::{check_completion, do_completion}; 19use crate::completion::completion_item::do_completion;
20use crate::{ 20use crate::{
21 completion::{ 21 completion::{
22 completion_context::CompletionContext, 22 completion_context::CompletionContext,
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs
index f92034055..2000d953a 100644
--- a/crates/ra_ide_api/src/completion/complete_scope.rs
+++ b/crates/ra_ide_api/src/completion/complete_scope.rs
@@ -121,172 +121,413 @@ impl ImportResolver {
121 121
122#[cfg(test)] 122#[cfg(test)]
123mod tests { 123mod tests {
124 use crate::completion::{check_completion, CompletionKind}; 124 use crate::completion::{do_completion, CompletionItem, CompletionKind};
125 use insta::assert_debug_snapshot_matches;
125 126
126 fn check_reference_completion(name: &str, code: &str) { 127 fn do_reference_completion(code: &str) -> Vec<CompletionItem> {
127 check_completion(name, code, CompletionKind::Reference); 128 do_completion(code, CompletionKind::Reference)
128 } 129 }
129 130
130 #[test] 131 #[test]
131 fn completes_bindings_from_let() { 132 fn completes_bindings_from_let() {
132 check_reference_completion( 133 assert_debug_snapshot_matches!(
133 "bindings_from_let", 134 do_reference_completion(
134 r" 135 r"
135 fn quux(x: i32) { 136 fn quux(x: i32) {
136 let y = 92; 137 let y = 92;
137 1 + <|>; 138 1 + <|>;
138 let z = (); 139 let z = ();
139 } 140 }
140 ", 141 "
142 ),
143 @r###"[
144 CompletionItem {
145 label: "quux",
146 source_range: [91; 91),
147 delete: [91; 91),
148 insert: "quux($0)",
149 kind: Function,
150 detail: "fn quux(x: i32)",
151 },
152 CompletionItem {
153 label: "x",
154 source_range: [91; 91),
155 delete: [91; 91),
156 insert: "x",
157 kind: Binding,
158 detail: "i32",
159 },
160 CompletionItem {
161 label: "y",
162 source_range: [91; 91),
163 delete: [91; 91),
164 insert: "y",
165 kind: Binding,
166 detail: "i32",
167 },
168]"###
141 ); 169 );
142 } 170 }
143 171
144 #[test] 172 #[test]
145 fn completes_bindings_from_if_let() { 173 fn completes_bindings_from_if_let() {
146 check_reference_completion( 174 assert_debug_snapshot_matches!(
147 "bindings_from_if_let", 175 do_reference_completion(
148 r" 176 r"
149 fn quux() { 177 fn quux() {
150 if let Some(x) = foo() { 178 if let Some(x) = foo() {
151 let y = 92; 179 let y = 92;
152 }; 180 };
153 if let Some(a) = bar() { 181 if let Some(a) = bar() {
154 let b = 62; 182 let b = 62;
155 1 + <|> 183 1 + <|>
184 }
156 } 185 }
157 } 186 "
158 ", 187 ),
188 @r###"[
189 CompletionItem {
190 label: "a",
191 source_range: [242; 242),
192 delete: [242; 242),
193 insert: "a",
194 kind: Binding,
195 },
196 CompletionItem {
197 label: "b",
198 source_range: [242; 242),
199 delete: [242; 242),
200 insert: "b",
201 kind: Binding,
202 detail: "i32",
203 },
204 CompletionItem {
205 label: "quux",
206 source_range: [242; 242),
207 delete: [242; 242),
208 insert: "quux()$0",
209 kind: Function,
210 detail: "fn quux()",
211 },
212]"###
159 ); 213 );
160 } 214 }
161 215
162 #[test] 216 #[test]
163 fn completes_bindings_from_for() { 217 fn completes_bindings_from_for() {
164 check_reference_completion( 218 assert_debug_snapshot_matches!(
165 "bindings_from_for", 219 do_reference_completion(
166 r" 220 r"
167 fn quux() { 221 fn quux() {
168 for x in &[1, 2, 3] { 222 for x in &[1, 2, 3] {
169 <|> 223 <|>
224 }
170 } 225 }
171 } 226 "
172 ", 227 ),
228 @r###"[
229 CompletionItem {
230 label: "quux",
231 source_range: [95; 95),
232 delete: [95; 95),
233 insert: "quux()$0",
234 kind: Function,
235 detail: "fn quux()",
236 },
237 CompletionItem {
238 label: "x",
239 source_range: [95; 95),
240 delete: [95; 95),
241 insert: "x",
242 kind: Binding,
243 },
244]"###
173 ); 245 );
174 } 246 }
175 247
176 #[test] 248 #[test]
177 fn completes_generic_params() { 249 fn completes_generic_params() {
178 check_reference_completion( 250 assert_debug_snapshot_matches!(
179 "generic_params", 251 do_reference_completion(
180 r" 252 r"
181 fn quux<T>() { 253 fn quux<T>() {
182 <|> 254 <|>
183 } 255 }
184 ", 256 "
257 ),
258 @r###"[
259 CompletionItem {
260 label: "T",
261 source_range: [52; 52),
262 delete: [52; 52),
263 insert: "T",
264 kind: TypeParam,
265 },
266 CompletionItem {
267 label: "quux",
268 source_range: [52; 52),
269 delete: [52; 52),
270 insert: "quux()$0",
271 kind: Function,
272 detail: "fn quux<T>()",
273 },
274]"###
185 ); 275 );
186 } 276 }
187 277
188 #[test] 278 #[test]
189 fn completes_generic_params_in_struct() { 279 fn completes_generic_params_in_struct() {
190 check_reference_completion( 280 assert_debug_snapshot_matches!(
191 "generic_params_in_struct", 281 do_reference_completion(
192 r" 282 r"
193 struct X<T> { 283 struct X<T> {
194 x: <|> 284 x: <|>
195 } 285 }
196 ", 286 "
287 ),
288 @r###"[
289 CompletionItem {
290 label: "T",
291 source_range: [54; 54),
292 delete: [54; 54),
293 insert: "T",
294 kind: TypeParam,
295 },
296 CompletionItem {
297 label: "X",
298 source_range: [54; 54),
299 delete: [54; 54),
300 insert: "X",
301 kind: Struct,
302 },
303]"###
197 ); 304 );
198 } 305 }
199 306
200 #[test] 307 #[test]
201 fn completes_module_items() { 308 fn completes_module_items() {
202 check_reference_completion( 309 assert_debug_snapshot_matches!(
203 "module_items", 310 do_reference_completion(
204 r" 311 r"
205 struct Foo; 312 struct Foo;
206 enum Baz {} 313 enum Baz {}
207 fn quux() { 314 fn quux() {
208 <|> 315 <|>
209 } 316 }
210 ", 317 "
211 ); 318 ),
319 @r###"[
320 CompletionItem {
321 label: "Baz",
322 source_range: [105; 105),
323 delete: [105; 105),
324 insert: "Baz",
325 kind: Enum,
326 },
327 CompletionItem {
328 label: "Foo",
329 source_range: [105; 105),
330 delete: [105; 105),
331 insert: "Foo",
332 kind: Struct,
333 },
334 CompletionItem {
335 label: "quux",
336 source_range: [105; 105),
337 delete: [105; 105),
338 insert: "quux()$0",
339 kind: Function,
340 detail: "fn quux()",
341 },
342]"###
343 );
212 } 344 }
213 345
214 #[test] 346 #[test]
215 fn completes_extern_prelude() { 347 fn completes_extern_prelude() {
216 check_reference_completion( 348 assert_debug_snapshot_matches!(
217 "extern_prelude", 349 do_reference_completion(
218 r" 350 r"
219 //- /lib.rs 351 //- /lib.rs
220 use <|>; 352 use <|>;
221 353
222 //- /other_crate/lib.rs 354 //- /other_crate/lib.rs
223 // nothing here 355 // nothing here
224 ", 356 "
357 ),
358 @r#"[
359 CompletionItem {
360 label: "other_crate",
361 source_range: [4; 4),
362 delete: [4; 4),
363 insert: "other_crate",
364 kind: Module,
365 },
366]"#
225 ); 367 );
226 } 368 }
227 369
228 #[test] 370 #[test]
229 fn completes_module_items_in_nested_modules() { 371 fn completes_module_items_in_nested_modules() {
230 check_reference_completion( 372 assert_debug_snapshot_matches!(
231 "module_items_in_nested_modules", 373 do_reference_completion(
232 r" 374 r"
233 struct Foo; 375 struct Foo;
234 mod m { 376 mod m {
235 struct Bar; 377 struct Bar;
236 fn quux() { <|> } 378 fn quux() { <|> }
237 } 379 }
238 ", 380 "
381 ),
382 @r###"[
383 CompletionItem {
384 label: "Bar",
385 source_range: [117; 117),
386 delete: [117; 117),
387 insert: "Bar",
388 kind: Struct,
389 },
390 CompletionItem {
391 label: "quux",
392 source_range: [117; 117),
393 delete: [117; 117),
394 insert: "quux()$0",
395 kind: Function,
396 detail: "fn quux()",
397 },
398]"###
239 ); 399 );
240 } 400 }
241 401
242 #[test] 402 #[test]
243 fn completes_return_type() { 403 fn completes_return_type() {
244 check_reference_completion( 404 assert_debug_snapshot_matches!(
245 "return_type", 405 do_reference_completion(
246 r" 406 r"
247 struct Foo; 407 struct Foo;
248 fn x() -> <|> 408 fn x() -> <|>
249 ", 409 "
250 ) 410 ),
411 @r###"[
412 CompletionItem {
413 label: "Foo",
414 source_range: [55; 55),
415 delete: [55; 55),
416 insert: "Foo",
417 kind: Struct,
418 },
419 CompletionItem {
420 label: "x",
421 source_range: [55; 55),
422 delete: [55; 55),
423 insert: "x()$0",
424 kind: Function,
425 detail: "fn x()",
426 },
427]"###
428 );
251 } 429 }
252 430
253 #[test] 431 #[test]
254 fn dont_show_both_completions_for_shadowing() { 432 fn dont_show_both_completions_for_shadowing() {
255 check_reference_completion( 433 assert_debug_snapshot_matches!(
256 "dont_show_both_completions_for_shadowing", 434 do_reference_completion(
257 r" 435 r"
258 fn foo() { 436 fn foo() {
259 let bar = 92; 437 let bar = 92;
260 { 438 {
261 let bar = 62; 439 let bar = 62;
262 <|> 440 <|>
441 }
263 } 442 }
264 } 443 "
265 ", 444 ),
266 ) 445 @r###"[
446 CompletionItem {
447 label: "bar",
448 source_range: [146; 146),
449 delete: [146; 146),
450 insert: "bar",
451 kind: Binding,
452 detail: "i32",
453 },
454 CompletionItem {
455 label: "foo",
456 source_range: [146; 146),
457 delete: [146; 146),
458 insert: "foo()$0",
459 kind: Function,
460 detail: "fn foo()",
461 },
462]"###
463 );
267 } 464 }
268 465
269 #[test] 466 #[test]
270 fn completes_self_in_methods() { 467 fn completes_self_in_methods() {
271 check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }") 468 assert_debug_snapshot_matches!(
469 do_reference_completion(r"impl S { fn foo(&self) { <|> } }"),
470 @r#"[
471 CompletionItem {
472 label: "Self",
473 source_range: [25; 25),
474 delete: [25; 25),
475 insert: "Self",
476 kind: TypeParam,
477 },
478 CompletionItem {
479 label: "self",
480 source_range: [25; 25),
481 delete: [25; 25),
482 insert: "self",
483 kind: Binding,
484 detail: "&{unknown}",
485 },
486]"#
487 );
272 } 488 }
273 489
274 #[test] 490 #[test]
275 fn completes_prelude() { 491 fn completes_prelude() {
276 check_reference_completion( 492 assert_debug_snapshot_matches!(
277 "completes_prelude", 493 do_reference_completion(
278 " 494 "
279 //- /main.rs 495 //- /main.rs
280 fn foo() { let x: <|> } 496 fn foo() { let x: <|> }
281 497
282 //- /std/lib.rs 498 //- /std/lib.rs
283 #[prelude_import] 499 #[prelude_import]
284 use prelude::*; 500 use prelude::*;
285 501
286 mod prelude { 502 mod prelude {
287 struct Option; 503 struct Option;
288 } 504 }
289 ", 505 "
506 ),
507 @r#"[
508 CompletionItem {
509 label: "Option",
510 source_range: [18; 18),
511 delete: [18; 18),
512 insert: "Option",
513 kind: Struct,
514 },
515 CompletionItem {
516 label: "foo",
517 source_range: [18; 18),
518 delete: [18; 18),
519 insert: "foo()$0",
520 kind: Function,
521 detail: "fn foo()",
522 },
523 CompletionItem {
524 label: "std",
525 source_range: [18; 18),
526 delete: [18; 18),
527 insert: "std",
528 kind: Module,
529 },
530]"#
290 ); 531 );
291 } 532 }
292} 533}
diff --git a/crates/ra_ide_api/src/completion/complete_snippet.rs b/crates/ra_ide_api/src/completion/complete_snippet.rs
index d2d364b57..a35f31511 100644
--- a/crates/ra_ide_api/src/completion/complete_snippet.rs
+++ b/crates/ra_ide_api/src/completion/complete_snippet.rs
@@ -39,39 +39,76 @@ fn ${1:feature}() {
39 39
40#[cfg(test)] 40#[cfg(test)]
41mod tests { 41mod tests {
42 use crate::completion::{check_completion, CompletionKind}; 42 use crate::completion::{do_completion, CompletionItem, CompletionKind};
43 use insta::assert_debug_snapshot_matches;
43 44
44 fn check_snippet_completion(name: &str, code: &str) { 45 fn do_snippet_completion(code: &str) -> Vec<CompletionItem> {
45 check_completion(name, code, CompletionKind::Snippet); 46 do_completion(code, CompletionKind::Snippet)
46 } 47 }
47 48
48 #[test] 49 #[test]
49 fn completes_snippets_in_expressions() { 50 fn completes_snippets_in_expressions() {
50 check_snippet_completion("snippets_in_expressions", r"fn foo(x: i32) { <|> }"); 51 assert_debug_snapshot_matches!(
52 do_snippet_completion(r"fn foo(x: i32) { <|> }"),
53 @r#"[
54 CompletionItem {
55 label: "pd",
56 source_range: [17; 17),
57 delete: [17; 17),
58 insert: "eprintln!(\"$0 = {:?}\", $0);",
59 kind: Snippet,
60 },
61 CompletionItem {
62 label: "ppd",
63 source_range: [17; 17),
64 delete: [17; 17),
65 insert: "eprintln!(\"$0 = {:#?}\", $0);",
66 kind: Snippet,
67 },
68]"#
69 );
51 } 70 }
52 71
53 #[test] 72 #[test]
54 fn should_not_complete_snippets_in_path() { 73 fn should_not_complete_snippets_in_path() {
55 check_snippet_completion( 74 assert_debug_snapshot_matches!(
56 "should_not_complete_snippets_in_path", 75 do_snippet_completion(r"fn foo(x: i32) { ::foo<|> }"),
57 r"fn foo(x: i32) { ::foo<|> }", 76 @r#"[]"#
58 ); 77 );
59 check_snippet_completion( 78 assert_debug_snapshot_matches!(
60 "should_not_complete_snippets_in_path2", 79 do_snippet_completion(r"fn foo(x: i32) { ::<|> }"),
61 r"fn foo(x: i32) { ::<|> }", 80 @r#"[]"#
62 ); 81 );
63 } 82 }
64 83
65 #[test] 84 #[test]
66 fn completes_snippets_in_items() { 85 fn completes_snippets_in_items() {
67 check_snippet_completion( 86 assert_debug_snapshot_matches!(
68 "snippets_in_items", 87 do_snippet_completion(
69 r" 88 r"
70 #[cfg(test)] 89 #[cfg(test)]
71 mod tests { 90 mod tests {
72 <|> 91 <|>
73 } 92 }
74 ", 93 "
94 ),
95 @r###"[
96 CompletionItem {
97 label: "Test function",
98 source_range: [78; 78),
99 delete: [78; 78),
100 insert: "#[test]\nfn ${1:feature}() {\n $0\n}",
101 kind: Snippet,
102 lookup: "tfn",
103 },
104 CompletionItem {
105 label: "pub(crate)",
106 source_range: [78; 78),
107 delete: [78; 78),
108 insert: "pub(crate) $0",
109 kind: Snippet,
110 },
111]"###
75 ); 112 );
76 } 113 }
77} 114}
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index f78c4c877..d787bb69e 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -299,10 +299,3 @@ pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionI
299 kind_completions.sort_by_key(|c| c.label.clone()); 299 kind_completions.sort_by_key(|c| c.label.clone());
300 kind_completions 300 kind_completions
301} 301}
302
303#[cfg(test)]
304pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind) {
305 use insta::assert_debug_snapshot_matches;
306 let kind_completions = do_completion(code, kind);
307 assert_debug_snapshot_matches!(test_name, kind_completions);
308}
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index 5cf55a496..6878008d3 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -182,80 +182,169 @@ impl Completions {
182 182
183#[cfg(test)] 183#[cfg(test)]
184mod tests { 184mod tests {
185 use crate::completion::{do_completion, CompletionItem, CompletionKind};
186 use insta::assert_debug_snapshot_matches;
185 use test_utils::covers; 187 use test_utils::covers;
186 188
187 use crate::completion::{check_completion, CompletionKind}; 189 fn do_reference_completion(code: &str) -> Vec<CompletionItem> {
188 190 do_completion(code, CompletionKind::Reference)
189 fn check_reference_completion(code: &str, expected_completions: &str) {
190 check_completion(code, expected_completions, CompletionKind::Reference);
191 } 191 }
192 192
193 #[test] 193 #[test]
194 fn inserts_parens_for_function_calls() { 194 fn inserts_parens_for_function_calls() {
195 covers!(inserts_parens_for_function_calls); 195 covers!(inserts_parens_for_function_calls);
196 check_reference_completion( 196 assert_debug_snapshot_matches!(
197 "inserts_parens_for_function_calls1", 197 do_reference_completion(
198 r" 198 r"
199 fn no_args() {} 199 fn no_args() {}
200 fn main() { no_<|> } 200 fn main() { no_<|> }
201 ", 201 "
202 ),
203 @r###"[
204 CompletionItem {
205 label: "main",
206 source_range: [61; 64),
207 delete: [61; 64),
208 insert: "main()$0",
209 kind: Function,
210 detail: "fn main()",
211 },
212 CompletionItem {
213 label: "no_args",
214 source_range: [61; 64),
215 delete: [61; 64),
216 insert: "no_args()$0",
217 kind: Function,
218 detail: "fn no_args()",
219 },
220]"###
202 ); 221 );
203 check_reference_completion( 222 assert_debug_snapshot_matches!(
204 "inserts_parens_for_function_calls2", 223 do_reference_completion(
205 r" 224 r"
206 fn with_args(x: i32, y: String) {} 225 fn with_args(x: i32, y: String) {}
207 fn main() { with_<|> } 226 fn main() { with_<|> }
208 ", 227 "
228 ),
229 @r###"[
230 CompletionItem {
231 label: "main",
232 source_range: [80; 85),
233 delete: [80; 85),
234 insert: "main()$0",
235 kind: Function,
236 detail: "fn main()",
237 },
238 CompletionItem {
239 label: "with_args",
240 source_range: [80; 85),
241 delete: [80; 85),
242 insert: "with_args($0)",
243 kind: Function,
244 detail: "fn with_args(x: i32, y: String)",
245 },
246]"###
247 );
248 assert_debug_snapshot_matches!(
249 do_reference_completion(
250 r"
251 struct S {}
252 impl S {
253 fn foo(&self) {}
254 }
255 fn bar(s: &S) {
256 s.f<|>
257 }
258 "
259 ),
260 @r###"[
261 CompletionItem {
262 label: "foo",
263 source_range: [163; 164),
264 delete: [163; 164),
265 insert: "foo()$0",
266 kind: Method,
267 detail: "fn foo(&self)",
268 },
269]"###
209 ); 270 );
210 check_reference_completion(
211 "inserts_parens_for_function_calls3",
212 r"
213 struct S {}
214 impl S {
215 fn foo(&self) {}
216 }
217 fn bar(s: &S) {
218 s.f<|>
219 }
220 ",
221 )
222 } 271 }
223 272
224 #[test] 273 #[test]
225 fn dont_render_function_parens_in_use_item() { 274 fn dont_render_function_parens_in_use_item() {
226 check_reference_completion( 275 assert_debug_snapshot_matches!(
227 "dont_render_function_parens_in_use_item", 276 do_reference_completion(
228 " 277 "
229 //- /lib.rs 278 //- /lib.rs
230 mod m { pub fn foo() {} } 279 mod m { pub fn foo() {} }
231 use crate::m::f<|>; 280 use crate::m::f<|>;
232 ", 281 "
233 ) 282 ),
283 @r#"[
284 CompletionItem {
285 label: "foo",
286 source_range: [40; 41),
287 delete: [40; 41),
288 insert: "foo",
289 kind: Function,
290 detail: "pub fn foo()",
291 },
292]"#
293 );
234 } 294 }
235 295
236 #[test] 296 #[test]
237 fn dont_render_function_parens_if_already_call() { 297 fn dont_render_function_parens_if_already_call() {
238 check_reference_completion( 298 assert_debug_snapshot_matches!(
239 "dont_render_function_parens_if_already_call", 299 do_reference_completion(
240 " 300 "
241 //- /lib.rs 301 //- /lib.rs
242 fn frobnicate() {} 302 fn frobnicate() {}
243 fn main() { 303 fn main() {
244 frob<|>(); 304 frob<|>();
245 } 305 }
246 ", 306 "
307 ),
308 @r#"[
309 CompletionItem {
310 label: "frobnicate",
311 source_range: [35; 39),
312 delete: [35; 39),
313 insert: "frobnicate",
314 kind: Function,
315 detail: "fn frobnicate()",
316 },
317 CompletionItem {
318 label: "main",
319 source_range: [35; 39),
320 delete: [35; 39),
321 insert: "main",
322 kind: Function,
323 detail: "fn main()",
324 },
325]"#
326 );
327 assert_debug_snapshot_matches!(
328 do_reference_completion(
329 "
330 //- /lib.rs
331 struct Foo {}
332 impl Foo { fn new() -> Foo {} }
333 fn main() {
334 Foo::ne<|>();
335 }
336 "
337 ),
338 @r#"[
339 CompletionItem {
340 label: "new",
341 source_range: [67; 69),
342 delete: [67; 69),
343 insert: "new",
344 kind: Function,
345 detail: "fn new() -> Foo",
346 },
347]"#
247 ); 348 );
248 check_reference_completion(
249 "dont_render_function_parens_if_already_call_assoc_fn",
250 "
251 //- /lib.rs
252 struct Foo {}
253 impl Foo { fn new() -> Foo {} }
254 fn main() {
255 Foo::ne<|>();
256 }
257 ",
258 )
259 } 349 }
260
261} 350}
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap
deleted file mode 100644
index e9b717a45..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap
+++ /dev/null
@@ -1,23 +0,0 @@
1---
2created: "2019-05-23T22:23:35.119822026Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "quux",
10 source_range: [83; 83),
11 delete: [83; 83),
12 insert: "quux()$0",
13 kind: Function,
14 detail: "fn quux()",
15 },
16 CompletionItem {
17 label: "x",
18 source_range: [83; 83),
19 delete: [83; 83),
20 insert: "x",
21 kind: Binding,
22 },
23]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap
deleted file mode 100644
index f94477b43..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap
+++ /dev/null
@@ -1,31 +0,0 @@
1---
2created: "2019-07-23T16:11:48.828805910Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "a",
10 source_range: [214; 214),
11 delete: [214; 214),
12 insert: "a",
13 kind: Binding,
14 },
15 CompletionItem {
16 label: "b",
17 source_range: [214; 214),
18 delete: [214; 214),
19 insert: "b",
20 kind: Binding,
21 detail: "i32",
22 },
23 CompletionItem {
24 label: "quux",
25 source_range: [214; 214),
26 delete: [214; 214),
27 insert: "quux()$0",
28 kind: Function,
29 detail: "fn quux()",
30 },
31]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap
deleted file mode 100644
index 590e2a820..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap
+++ /dev/null
@@ -1,32 +0,0 @@
1---
2created: "2019-07-23T16:11:48.828811567Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "quux",
10 source_range: [79; 79),
11 delete: [79; 79),
12 insert: "quux($0)",
13 kind: Function,
14 detail: "fn quux(x: i32)",
15 },
16 CompletionItem {
17 label: "x",
18 source_range: [79; 79),
19 delete: [79; 79),
20 insert: "x",
21 kind: Binding,
22 detail: "i32",
23 },
24 CompletionItem {
25 label: "y",
26 source_range: [79; 79),
27 delete: [79; 79),
28 insert: "y",
29 kind: Binding,
30 detail: "i32",
31 },
32]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap
deleted file mode 100644
index b339c6c5f..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap
+++ /dev/null
@@ -1,30 +0,0 @@
1---
2created: "2019-05-23T22:23:35.139262926Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "Option",
10 source_range: [18; 18),
11 delete: [18; 18),
12 insert: "Option",
13 kind: Struct,
14 },
15 CompletionItem {
16 label: "foo",
17 source_range: [18; 18),
18 delete: [18; 18),
19 insert: "foo()$0",
20 kind: Function,
21 detail: "fn foo()",
22 },
23 CompletionItem {
24 label: "std",
25 source_range: [18; 18),
26 delete: [18; 18),
27 insert: "std",
28 kind: Module,
29 },
30]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap
deleted file mode 100644
index 46bea2ccd..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap
+++ /dev/null
@@ -1,24 +0,0 @@
1---
2created: "2019-05-23T22:23:35.158296242Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "frobnicate",
10 source_range: [35; 39),
11 delete: [35; 39),
12 insert: "frobnicate",
13 kind: Function,
14 detail: "fn frobnicate()",
15 },
16 CompletionItem {
17 label: "main",
18 source_range: [35; 39),
19 delete: [35; 39),
20 insert: "main",
21 kind: Function,
22 detail: "fn main()",
23 },
24]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap
deleted file mode 100644
index b09a6745e..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap
+++ /dev/null
@@ -1,16 +0,0 @@
1---
2created: "2019-05-23T22:44:10.920136527Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "new",
10 source_range: [67; 69),
11 delete: [67; 69),
12 insert: "new",
13 kind: Function,
14 detail: "fn new() -> Foo",
15 },
16]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap
deleted file mode 100644
index 84ccc8160..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap
+++ /dev/null
@@ -1,16 +0,0 @@
1---
2created: "2019-05-23T22:23:35.154795561Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "foo",
10 source_range: [40; 41),
11 delete: [40; 41),
12 insert: "foo",
13 kind: Function,
14 detail: "pub fn foo()",
15 },
16]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap
deleted file mode 100644
index 158a2e5b9..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap
+++ /dev/null
@@ -1,24 +0,0 @@
1---
2created: "2019-07-23T16:11:48.860949870Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "bar",
10 source_range: [126; 126),
11 delete: [126; 126),
12 insert: "bar",
13 kind: Binding,
14 detail: "i32",
15 },
16 CompletionItem {
17 label: "foo",
18 source_range: [126; 126),
19 delete: [126; 126),
20 insert: "foo()$0",
21 kind: Function,
22 detail: "fn foo()",
23 },
24]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap
deleted file mode 100644
index b9449a76c..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap
+++ /dev/null
@@ -1,15 +0,0 @@
1---
2created: "2019-05-23T22:23:35.123197049Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "other_crate",
10 source_range: [4; 4),
11 delete: [4; 4),
12 insert: "other_crate",
13 kind: Module,
14 },
15]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap
deleted file mode 100644
index eb1a4151a..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap
+++ /dev/null
@@ -1,23 +0,0 @@
1---
2created: "2019-05-23T22:23:35.123825399Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "T",
10 source_range: [44; 44),
11 delete: [44; 44),
12 insert: "T",
13 kind: TypeParam,
14 },
15 CompletionItem {
16 label: "quux",
17 source_range: [44; 44),
18 delete: [44; 44),
19 insert: "quux()$0",
20 kind: Function,
21 detail: "fn quux<T>()",
22 },
23]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap
deleted file mode 100644
index 52f08267f..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap
+++ /dev/null
@@ -1,22 +0,0 @@
1---
2created: "2019-05-23T22:23:35.130778739Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "T",
10 source_range: [46; 46),
11 delete: [46; 46),
12 insert: "T",
13 kind: TypeParam,
14 },
15 CompletionItem {
16 label: "X",
17 source_range: [46; 46),
18 delete: [46; 46),
19 insert: "X",
20 kind: Struct,
21 },
22]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap
deleted file mode 100644
index c795b9aae..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap
+++ /dev/null
@@ -1,24 +0,0 @@
1---
2created: "2019-05-23T22:23:35.156115632Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "main",
10 source_range: [53; 56),
11 delete: [53; 56),
12 insert: "main()$0",
13 kind: Function,
14 detail: "fn main()",
15 },
16 CompletionItem {
17 label: "no_args",
18 source_range: [53; 56),
19 delete: [53; 56),
20 insert: "no_args()$0",
21 kind: Function,
22 detail: "fn no_args()",
23 },
24]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap
deleted file mode 100644
index b49a838e0..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap
+++ /dev/null
@@ -1,24 +0,0 @@
1---
2created: "2019-05-23T22:44:10.916806744Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "main",
10 source_range: [72; 77),
11 delete: [72; 77),
12 insert: "main()$0",
13 kind: Function,
14 detail: "fn main()",
15 },
16 CompletionItem {
17 label: "with_args",
18 source_range: [72; 77),
19 delete: [72; 77),
20 insert: "with_args($0)",
21 kind: Function,
22 detail: "fn with_args(x: i32, y: String)",
23 },
24]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap
deleted file mode 100644
index b62cb7aa1..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap
+++ /dev/null
@@ -1,16 +0,0 @@
1---
2created: "2019-05-23T22:44:40.543731193Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "foo",
10 source_range: [139; 140),
11 delete: [139; 140),
12 insert: "foo()$0",
13 kind: Method,
14 detail: "fn foo(&self)",
15 },
16]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap
deleted file mode 100644
index cee4898c3..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap
+++ /dev/null
@@ -1,30 +0,0 @@
1---
2created: "2019-05-23T22:23:35.133106898Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "Baz",
10 source_range: [89; 89),
11 delete: [89; 89),
12 insert: "Baz",
13 kind: Enum,
14 },
15 CompletionItem {
16 label: "Foo",
17 source_range: [89; 89),
18 delete: [89; 89),
19 insert: "Foo",
20 kind: Struct,
21 },
22 CompletionItem {
23 label: "quux",
24 source_range: [89; 89),
25 delete: [89; 89),
26 insert: "quux()$0",
27 kind: Function,
28 detail: "fn quux()",
29 },
30]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap
deleted file mode 100644
index ce18e5bb7..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap
+++ /dev/null
@@ -1,23 +0,0 @@
1---
2created: "2019-05-23T22:23:35.134417551Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "Bar",
10 source_range: [101; 101),
11 delete: [101; 101),
12 insert: "Bar",
13 kind: Struct,
14 },
15 CompletionItem {
16 label: "quux",
17 source_range: [101; 101),
18 delete: [101; 101),
19 insert: "quux()$0",
20 kind: Function,
21 detail: "fn quux()",
22 },
23]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap
deleted file mode 100644
index 16dd18431..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap
+++ /dev/null
@@ -1,23 +0,0 @@
1---
2created: "2019-05-23T22:23:35.140648630Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "Foo",
10 source_range: [47; 47),
11 delete: [47; 47),
12 insert: "Foo",
13 kind: Struct,
14 },
15 CompletionItem {
16 label: "x",
17 source_range: [47; 47),
18 delete: [47; 47),
19 insert: "x()$0",
20 kind: Function,
21 detail: "fn x()",
22 },
23]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
deleted file mode 100644
index b7bcbe864..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
+++ /dev/null
@@ -1,23 +0,0 @@
1---
2created: "2019-07-23T16:11:48.859812318Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "Self",
10 source_range: [25; 25),
11 delete: [25; 25),
12 insert: "Self",
13 kind: TypeParam,
14 },
15 CompletionItem {
16 label: "self",
17 source_range: [25; 25),
18 delete: [25; 25),
19 insert: "self",
20 kind: Binding,
21 detail: "&{unknown}",
22 },
23]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path.snap
deleted file mode 100644
index cb3278edf..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path.snap
+++ /dev/null
@@ -1,5 +0,0 @@
1Created: 2019-01-23T05:19:36.475253+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path2.snap
deleted file mode 100644
index 62c8e3de9..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__should_not_complete_snippets_in_path2.snap
+++ /dev/null
@@ -1,5 +0,0 @@
1Created: 2019-01-23T05:19:36.476869+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap
deleted file mode 100644
index 6f41bf76f..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap
+++ /dev/null
@@ -1,22 +0,0 @@
1---
2created: "2019-05-23T22:23:35.141901047Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "pd",
10 source_range: [17; 17),
11 delete: [17; 17),
12 insert: "eprintln!(\"$0 = {:?}\", $0);",
13 kind: Snippet,
14 },
15 CompletionItem {
16 label: "ppd",
17 source_range: [17; 17),
18 delete: [17; 17),
19 insert: "eprintln!(\"$0 = {:#?}\", $0);",
20 kind: Snippet,
21 },
22]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap
deleted file mode 100644
index 1eb0adebe..000000000
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap
+++ /dev/null
@@ -1,23 +0,0 @@
1---
2created: "2019-05-23T22:23:35.149234118Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 label: "Test function",
10 source_range: [66; 66),
11 delete: [66; 66),
12 insert: "#[test]\nfn ${1:feature}() {\n $0\n}",
13 kind: Snippet,
14 lookup: "tfn",
15 },
16 CompletionItem {
17 label: "pub(crate)",
18 source_range: [66; 66),
19 delete: [66; 66),
20 insert: "pub(crate) $0",
21 kind: Snippet,
22 },
23]
diff --git a/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap b/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap
deleted file mode 100644
index 102efc026..000000000
--- a/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap
+++ /dev/null
@@ -1,191 +0,0 @@
1---
2created: "2019-06-28T20:46:18.274464142Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/display/structure.rs
5expression: structure
6---
7[
8 StructureNode {
9 parent: None,
10 label: "Foo",
11 navigation_range: [8; 11),
12 node_range: [1; 26),
13 kind: STRUCT_DEF,
14 detail: None,
15 deprecated: false,
16 },
17 StructureNode {
18 parent: Some(
19 0,
20 ),
21 label: "x",
22 navigation_range: [18; 19),
23 node_range: [18; 24),
24 kind: NAMED_FIELD_DEF,
25 detail: Some(
26 "i32",
27 ),
28 deprecated: false,
29 },
30 StructureNode {
31 parent: None,
32 label: "m",
33 navigation_range: [32; 33),
34 node_range: [28; 158),
35 kind: MODULE,
36 detail: None,
37 deprecated: false,
38 },
39 StructureNode {
40 parent: Some(
41 2,
42 ),
43 label: "bar1",
44 navigation_range: [43; 47),
45 node_range: [40; 52),
46 kind: FN_DEF,
47 detail: Some(
48 "fn()",
49 ),
50 deprecated: false,
51 },
52 StructureNode {
53 parent: Some(
54 2,
55 ),
56 label: "bar2",
57 navigation_range: [60; 64),
58 node_range: [57; 81),
59 kind: FN_DEF,
60 detail: Some(
61 "fn<T>(t: T) -> T",
62 ),
63 deprecated: false,
64 },
65 StructureNode {
66 parent: Some(
67 2,
68 ),
69 label: "bar3",
70 navigation_range: [89; 93),
71 node_range: [86; 156),
72 kind: FN_DEF,
73 detail: Some(
74 "fn<A, B>(a: A, b: B) -> Vec< u32 >",
75 ),
76 deprecated: false,
77 },
78 StructureNode {
79 parent: None,
80 label: "E",
81 navigation_range: [165; 166),
82 node_range: [160; 180),
83 kind: ENUM_DEF,
84 detail: None,
85 deprecated: false,
86 },
87 StructureNode {
88 parent: Some(
89 6,
90 ),
91 label: "X",
92 navigation_range: [169; 170),
93 node_range: [169; 170),
94 kind: ENUM_VARIANT,
95 detail: None,
96 deprecated: false,
97 },
98 StructureNode {
99 parent: Some(
100 6,
101 ),
102 label: "Y",
103 navigation_range: [172; 173),
104 node_range: [172; 178),
105 kind: ENUM_VARIANT,
106 detail: None,
107 deprecated: false,
108 },
109 StructureNode {
110 parent: None,
111 label: "T",
112 navigation_range: [186; 187),
113 node_range: [181; 193),
114 kind: TYPE_ALIAS_DEF,
115 detail: Some(
116 "()",
117 ),
118 deprecated: false,
119 },
120 StructureNode {
121 parent: None,
122 label: "S",
123 navigation_range: [201; 202),
124 node_range: [194; 213),
125 kind: STATIC_DEF,
126 detail: Some(
127 "i32",
128 ),
129 deprecated: false,
130 },
131 StructureNode {
132 parent: None,
133 label: "C",
134 navigation_range: [220; 221),
135 node_range: [214; 232),
136 kind: CONST_DEF,
137 detail: Some(
138 "i32",
139 ),
140 deprecated: false,
141 },
142 StructureNode {
143 parent: None,
144 label: "impl E",
145 navigation_range: [239; 240),
146 node_range: [234; 243),
147 kind: IMPL_BLOCK,
148 detail: None,
149 deprecated: false,
150 },
151 StructureNode {
152 parent: None,
153 label: "impl fmt::Debug for E",
154 navigation_range: [265; 266),
155 node_range: [245; 269),
156 kind: IMPL_BLOCK,
157 detail: None,
158 deprecated: false,
159 },
160 StructureNode {
161 parent: None,
162 label: "mc",
163 navigation_range: [284; 286),
164 node_range: [271; 303),
165 kind: MACRO_CALL,
166 detail: None,
167 deprecated: false,
168 },
169 StructureNode {
170 parent: None,
171 label: "obsolete",
172 navigation_range: [322; 330),
173 node_range: [305; 335),
174 kind: FN_DEF,
175 detail: Some(
176 "fn()",
177 ),
178 deprecated: true,
179 },
180 StructureNode {
181 parent: None,
182 label: "very_obsolete",
183 navigation_range: [375; 388),
184 node_range: [337; 393),
185 kind: FN_DEF,
186 detail: Some(
187 "fn()",
188 ),
189 deprecated: true,
190 },
191]
diff --git a/crates/ra_ide_api/src/display/structure.rs b/crates/ra_ide_api/src/display/structure.rs
index 2ba10b2ef..b026dfa59 100644
--- a/crates/ra_ide_api/src/display/structure.rs
+++ b/crates/ra_ide_api/src/display/structure.rs
@@ -204,6 +204,192 @@ fn very_obsolete() {}
204 .ok() 204 .ok()
205 .unwrap(); 205 .unwrap();
206 let structure = file_structure(&file); 206 let structure = file_structure(&file);
207 assert_debug_snapshot_matches!("file_structure", structure); 207 assert_debug_snapshot_matches!(structure,
208 @r#"[
209 StructureNode {
210 parent: None,
211 label: "Foo",
212 navigation_range: [8; 11),
213 node_range: [1; 26),
214 kind: STRUCT_DEF,
215 detail: None,
216 deprecated: false,
217 },
218 StructureNode {
219 parent: Some(
220 0,
221 ),
222 label: "x",
223 navigation_range: [18; 19),
224 node_range: [18; 24),
225 kind: NAMED_FIELD_DEF,
226 detail: Some(
227 "i32",
228 ),
229 deprecated: false,
230 },
231 StructureNode {
232 parent: None,
233 label: "m",
234 navigation_range: [32; 33),
235 node_range: [28; 158),
236 kind: MODULE,
237 detail: None,
238 deprecated: false,
239 },
240 StructureNode {
241 parent: Some(
242 2,
243 ),
244 label: "bar1",
245 navigation_range: [43; 47),
246 node_range: [40; 52),
247 kind: FN_DEF,
248 detail: Some(
249 "fn()",
250 ),
251 deprecated: false,
252 },
253 StructureNode {
254 parent: Some(
255 2,
256 ),
257 label: "bar2",
258 navigation_range: [60; 64),
259 node_range: [57; 81),
260 kind: FN_DEF,
261 detail: Some(
262 "fn<T>(t: T) -> T",
263 ),
264 deprecated: false,
265 },
266 StructureNode {
267 parent: Some(
268 2,
269 ),
270 label: "bar3",
271 navigation_range: [89; 93),
272 node_range: [86; 156),
273 kind: FN_DEF,
274 detail: Some(
275 "fn<A, B>(a: A, b: B) -> Vec< u32 >",
276 ),
277 deprecated: false,
278 },
279 StructureNode {
280 parent: None,
281 label: "E",
282 navigation_range: [165; 166),
283 node_range: [160; 180),
284 kind: ENUM_DEF,
285 detail: None,
286 deprecated: false,
287 },
288 StructureNode {
289 parent: Some(
290 6,
291 ),
292 label: "X",
293 navigation_range: [169; 170),
294 node_range: [169; 170),
295 kind: ENUM_VARIANT,
296 detail: None,
297 deprecated: false,
298 },
299 StructureNode {
300 parent: Some(
301 6,
302 ),
303 label: "Y",
304 navigation_range: [172; 173),
305 node_range: [172; 178),
306 kind: ENUM_VARIANT,
307 detail: None,
308 deprecated: false,
309 },
310 StructureNode {
311 parent: None,
312 label: "T",
313 navigation_range: [186; 187),
314 node_range: [181; 193),
315 kind: TYPE_ALIAS_DEF,
316 detail: Some(
317 "()",
318 ),
319 deprecated: false,
320 },
321 StructureNode {
322 parent: None,
323 label: "S",
324 navigation_range: [201; 202),
325 node_range: [194; 213),
326 kind: STATIC_DEF,
327 detail: Some(
328 "i32",
329 ),
330 deprecated: false,
331 },
332 StructureNode {
333 parent: None,
334 label: "C",
335 navigation_range: [220; 221),
336 node_range: [214; 232),
337 kind: CONST_DEF,
338 detail: Some(
339 "i32",
340 ),
341 deprecated: false,
342 },
343 StructureNode {
344 parent: None,
345 label: "impl E",
346 navigation_range: [239; 240),
347 node_range: [234; 243),
348 kind: IMPL_BLOCK,
349 detail: None,
350 deprecated: false,
351 },
352 StructureNode {
353 parent: None,
354 label: "impl fmt::Debug for E",
355 navigation_range: [265; 266),
356 node_range: [245; 269),
357 kind: IMPL_BLOCK,
358 detail: None,
359 deprecated: false,
360 },
361 StructureNode {
362 parent: None,
363 label: "mc",
364 navigation_range: [284; 286),
365 node_range: [271; 303),
366 kind: MACRO_CALL,
367 detail: None,
368 deprecated: false,
369 },
370 StructureNode {
371 parent: None,
372 label: "obsolete",
373 navigation_range: [322; 330),
374 node_range: [305; 335),
375 kind: FN_DEF,
376 detail: Some(
377 "fn()",
378 ),
379 deprecated: true,
380 },
381 StructureNode {
382 parent: None,
383 label: "very_obsolete",
384 navigation_range: [375; 388),
385 node_range: [337; 393),
386 kind: FN_DEF,
387 detail: Some(
388 "fn()",
389 ),
390 deprecated: true,
391 },
392]"#
393 );
208 } 394 }
209} 395}
diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs
index 174662beb..a524e014f 100644
--- a/crates/ra_ide_api/src/inlay_hints.rs
+++ b/crates/ra_ide_api/src/inlay_hints.rs
@@ -1,16 +1,22 @@
1use crate::{db::RootDatabase, FileId}; 1use crate::{db::RootDatabase, FileId};
2use hir::{HirDisplay, Ty}; 2use hir::{HirDisplay, SourceAnalyzer, Ty};
3use ra_syntax::ast::Pat;
4use ra_syntax::{ 3use ra_syntax::{
5 algo::visit::{visitor, Visitor}, 4 algo::visit::{visitor, Visitor},
6 ast::{self, PatKind, TypeAscriptionOwner}, 5 ast::{
7 AstNode, SmolStr, SourceFile, SyntaxNode, TextRange, 6 AstNode, ForExpr, IfExpr, LambdaExpr, LetStmt, MatchArmList, Pat, PatKind, SourceFile,
7 TypeAscriptionOwner, WhileExpr,
8 },
9 SmolStr, SyntaxKind, SyntaxNode, TextRange,
8}; 10};
9 11
10#[derive(Debug, PartialEq, Eq)] 12#[derive(Debug, PartialEq, Eq, Clone)]
11pub enum InlayKind { 13pub enum InlayKind {
12 LetBindingType, 14 LetBindingType,
13 ClosureParameterType, 15 ClosureParameterType,
16 ForExpressionBindingType,
17 IfExpressionType,
18 WhileLetExpressionType,
19 MatchArmType,
14} 20}
15 21
16#[derive(Debug)] 22#[derive(Debug)]
@@ -34,68 +40,142 @@ fn get_inlay_hints(
34 node: &SyntaxNode, 40 node: &SyntaxNode,
35) -> Option<Vec<InlayHint>> { 41) -> Option<Vec<InlayHint>> {
36 visitor() 42 visitor()
37 .visit(|let_statement: ast::LetStmt| { 43 .visit(|let_statement: LetStmt| {
38 let let_syntax = let_statement.syntax();
39
40 if let_statement.ascribed_type().is_some() { 44 if let_statement.ascribed_type().is_some() {
41 return None; 45 return None;
42 } 46 }
43 47 let pat = let_statement.pat()?;
44 let let_pat = let_statement.pat()?; 48 let analyzer = SourceAnalyzer::new(db, file_id, let_statement.syntax(), None);
45 let inlay_type_string = get_node_displayable_type(db, file_id, let_syntax, &let_pat)? 49 Some(get_pat_hints(db, &analyzer, pat, InlayKind::LetBindingType, false))
46 .display(db)
47 .to_string()
48 .into();
49
50 let pat_range = match let_pat.kind() {
51 PatKind::BindPat(bind_pat) => bind_pat.syntax().text_range(),
52 PatKind::TuplePat(tuple_pat) => tuple_pat.syntax().text_range(),
53 _ => return None,
54 };
55
56 Some(vec![InlayHint {
57 range: pat_range,
58 kind: InlayKind::LetBindingType,
59 label: inlay_type_string,
60 }])
61 }) 50 })
62 .visit(|closure_parameter: ast::LambdaExpr| match closure_parameter.param_list() { 51 .visit(|closure_parameter: LambdaExpr| {
63 Some(param_list) => Some( 52 let analyzer = SourceAnalyzer::new(db, file_id, closure_parameter.syntax(), None);
53 closure_parameter.param_list().map(|param_list| {
64 param_list 54 param_list
65 .params() 55 .params()
66 .filter(|closure_param| closure_param.ascribed_type().is_none()) 56 .filter(|closure_param| closure_param.ascribed_type().is_none())
67 .filter_map(|closure_param| { 57 .filter_map(|closure_param| closure_param.pat())
68 let closure_param_syntax = closure_param.syntax(); 58 .map(|root_pat| {
69 let inlay_type_string = get_node_displayable_type( 59 get_pat_hints(
70 db, 60 db,
71 file_id, 61 &analyzer,
72 closure_param_syntax, 62 root_pat,
73 &closure_param.pat()?, 63 InlayKind::ClosureParameterType,
74 )? 64 false,
75 .display(db) 65 )
76 .to_string()
77 .into();
78
79 Some(InlayHint {
80 range: closure_param_syntax.text_range(),
81 kind: InlayKind::ClosureParameterType,
82 label: inlay_type_string,
83 })
84 }) 66 })
67 .flatten()
68 .collect()
69 })
70 })
71 .visit(|for_expression: ForExpr| {
72 let pat = for_expression.pat()?;
73 let analyzer = SourceAnalyzer::new(db, file_id, for_expression.syntax(), None);
74 Some(get_pat_hints(db, &analyzer, pat, InlayKind::ForExpressionBindingType, false))
75 })
76 .visit(|if_expr: IfExpr| {
77 let pat = if_expr.condition()?.pat()?;
78 let analyzer = SourceAnalyzer::new(db, file_id, if_expr.syntax(), None);
79 Some(get_pat_hints(db, &analyzer, pat, InlayKind::IfExpressionType, true))
80 })
81 .visit(|while_expr: WhileExpr| {
82 let pat = while_expr.condition()?.pat()?;
83 let analyzer = SourceAnalyzer::new(db, file_id, while_expr.syntax(), None);
84 Some(get_pat_hints(db, &analyzer, pat, InlayKind::WhileLetExpressionType, true))
85 })
86 .visit(|match_arm_list: MatchArmList| {
87 let analyzer = SourceAnalyzer::new(db, file_id, match_arm_list.syntax(), None);
88 Some(
89 match_arm_list
90 .arms()
91 .map(|match_arm| match_arm.pats())
92 .flatten()
93 .map(|root_pat| {
94 get_pat_hints(db, &analyzer, root_pat, InlayKind::MatchArmType, true)
95 })
96 .flatten()
85 .collect(), 97 .collect(),
86 ), 98 )
87 None => None,
88 }) 99 })
89 .accept(&node)? 100 .accept(&node)?
90} 101}
91 102
103fn get_pat_hints(
104 db: &RootDatabase,
105 analyzer: &SourceAnalyzer,
106 root_pat: Pat,
107 kind: InlayKind,
108 skip_root_pat_hint: bool,
109) -> Vec<InlayHint> {
110 let original_pat = &root_pat.clone();
111
112 get_leaf_pats(root_pat)
113 .into_iter()
114 .filter(|pat| !skip_root_pat_hint || pat != original_pat)
115 .filter_map(|pat| {
116 get_node_displayable_type(db, &analyzer, &pat)
117 .map(|pat_type| (pat.syntax().text_range(), pat_type))
118 })
119 .map(|(range, pat_type)| InlayHint {
120 range,
121 kind: kind.clone(),
122 label: pat_type.display(db).to_string().into(),
123 })
124 .collect()
125}
126
127fn get_leaf_pats(root_pat: Pat) -> Vec<Pat> {
128 let mut pats_to_process = std::collections::VecDeque::<Pat>::new();
129 pats_to_process.push_back(root_pat);
130
131 let mut leaf_pats = Vec::new();
132
133 while let Some(maybe_leaf_pat) = pats_to_process.pop_front() {
134 match maybe_leaf_pat.kind() {
135 PatKind::BindPat(bind_pat) => {
136 if let Some(pat) = bind_pat.pat() {
137 pats_to_process.push_back(pat);
138 } else {
139 leaf_pats.push(maybe_leaf_pat);
140 }
141 }
142 PatKind::TuplePat(tuple_pat) => {
143 for arg_pat in tuple_pat.args() {
144 pats_to_process.push_back(arg_pat);
145 }
146 }
147 PatKind::StructPat(struct_pat) => {
148 if let Some(pat_list) = struct_pat.field_pat_list() {
149 pats_to_process.extend(
150 pat_list
151 .field_pats()
152 .filter_map(|field_pat| {
153 field_pat
154 .pat()
155 .filter(|pat| pat.syntax().kind() != SyntaxKind::BIND_PAT)
156 })
157 .chain(pat_list.bind_pats().map(|bind_pat| {
158 bind_pat.pat().unwrap_or_else(|| Pat::from(bind_pat))
159 })),
160 );
161 }
162 }
163 PatKind::TupleStructPat(tuple_struct_pat) => {
164 for arg_pat in tuple_struct_pat.args() {
165 pats_to_process.push_back(arg_pat);
166 }
167 }
168 _ => (),
169 }
170 }
171 leaf_pats
172}
173
92fn get_node_displayable_type( 174fn get_node_displayable_type(
93 db: &RootDatabase, 175 db: &RootDatabase,
94 file_id: FileId, 176 analyzer: &SourceAnalyzer,
95 node_syntax: &SyntaxNode,
96 node_pat: &Pat, 177 node_pat: &Pat,
97) -> Option<Ty> { 178) -> Option<Ty> {
98 let analyzer = hir::SourceAnalyzer::new(db, file_id, node_syntax, None);
99 analyzer.type_of_pat(db, node_pat).and_then(|resolved_type| { 179 analyzer.type_of_pat(db, node_pat).and_then(|resolved_type| {
100 if let Ty::Apply(_) = resolved_type { 180 if let Ty::Apply(_) = resolved_type {
101 Some(resolved_type) 181 Some(resolved_type)
@@ -111,68 +191,306 @@ mod tests {
111 use insta::assert_debug_snapshot_matches; 191 use insta::assert_debug_snapshot_matches;
112 192
113 #[test] 193 #[test]
114 fn test_inlay_hints() { 194 fn let_statement() {
115 let (analysis, file_id) = single_file( 195 let (analysis, file_id) = single_file(
116 r#" 196 r#"
117struct OuterStruct {} 197#[derive(PartialEq)]
198enum CustomOption<T> {
199 None,
200 Some(T),
201}
202
203#[derive(PartialEq)]
204struct Test {
205 a: CustomOption<u32>,
206 b: u8,
207}
118 208
119fn main() { 209fn main() {
120 struct InnerStruct {} 210 struct InnerStruct {}
121 211
122 let test = 54; 212 let test = 54;
123 let test = InnerStruct {}; 213 let test: i32 = 33;
124 let test = OuterStruct {};
125 let test = vec![222];
126 let mut test = Vec::new();
127 test.push(333);
128 let test = test.into_iter().map(|i| i * i).collect::<Vec<_>>();
129 let mut test = 33; 214 let mut test = 33;
130 let _ = 22; 215 let _ = 22;
131 let test: Vec<_> = (0..3).collect(); 216 let test = "test";
217 let test = InnerStruct {};
132 218
133 let _ = (0..23).map(|i: u32| { 219 let test = vec![222];
134 let i_squared = i * i; 220 let test: Vec<_> = (0..3).collect();
135 i_squared 221 let test = (0..3).collect::<Vec<i128>>();
136 }); 222 let test = (0..3).collect::<Vec<_>>();
137 223
138 let test: i32 = 33; 224 let mut test = Vec::new();
225 test.push(333);
139 226
140 let (x, c) = (42, 'a');
141 let test = (42, 'a'); 227 let test = (42, 'a');
142} 228 let (a, (b, c, (d, e), f)) = (2, (3, 4, (6.6, 7.7), 5));
143"#, 229}"#,
144 ); 230 );
145 231
146 assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ 232 assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
147 InlayHint { 233 InlayHint {
148 range: [71; 75), 234 range: [193; 197),
149 kind: LetBindingType, 235 kind: LetBindingType,
150 label: "i32", 236 label: "i32",
151 }, 237 },
152 InlayHint { 238 InlayHint {
153 range: [121; 125), 239 range: [236; 244),
154 kind: LetBindingType, 240 kind: LetBindingType,
155 label: "OuterStruct", 241 label: "i32",
156 }, 242 },
157 InlayHint { 243 InlayHint {
158 range: [297; 305), 244 range: [275; 279),
245 kind: LetBindingType,
246 label: "&str",
247 },
248 InlayHint {
249 range: [539; 543),
250 kind: LetBindingType,
251 label: "(i32, char)",
252 },
253 InlayHint {
254 range: [566; 567),
159 kind: LetBindingType, 255 kind: LetBindingType,
160 label: "i32", 256 label: "i32",
161 }, 257 },
162 InlayHint { 258 InlayHint {
163 range: [417; 426), 259 range: [570; 571),
164 kind: LetBindingType, 260 kind: LetBindingType,
165 label: "u32", 261 label: "i32",
166 }, 262 },
167 InlayHint { 263 InlayHint {
168 range: [496; 502), 264 range: [573; 574),
169 kind: LetBindingType, 265 kind: LetBindingType,
170 label: "(i32, char)", 266 label: "i32",
171 }, 267 },
172 InlayHint { 268 InlayHint {
173 range: [524; 528), 269 range: [584; 585),
174 kind: LetBindingType, 270 kind: LetBindingType,
175 label: "(i32, char)", 271 label: "i32",
272 },
273 InlayHint {
274 range: [577; 578),
275 kind: LetBindingType,
276 label: "f64",
277 },
278 InlayHint {
279 range: [580; 581),
280 kind: LetBindingType,
281 label: "f64",
282 },
283]"#
284 );
285 }
286
287 #[test]
288 fn closure_parameter() {
289 let (analysis, file_id) = single_file(
290 r#"
291fn main() {
292 let mut start = 0;
293 (0..2).for_each(|increment| {
294 start += increment;
295 })
296}"#,
297 );
298
299 assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
300 InlayHint {
301 range: [21; 30),
302 kind: LetBindingType,
303 label: "i32",
304 },
305 InlayHint {
306 range: [57; 66),
307 kind: ClosureParameterType,
308 label: "i32",
309 },
310]"#
311 );
312 }
313
314 #[test]
315 fn for_expression() {
316 let (analysis, file_id) = single_file(
317 r#"
318fn main() {
319 let mut start = 0;
320 for increment in 0..2 {
321 start += increment;
322 }
323}"#,
324 );
325
326 assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
327 InlayHint {
328 range: [21; 30),
329 kind: LetBindingType,
330 label: "i32",
331 },
332 InlayHint {
333 range: [44; 53),
334 kind: ForExpressionBindingType,
335 label: "i32",
336 },
337]"#
338 );
339 }
340
341 #[test]
342 fn if_expr() {
343 let (analysis, file_id) = single_file(
344 r#"
345#[derive(PartialEq)]
346enum CustomOption<T> {
347 None,
348 Some(T),
349}
350
351#[derive(PartialEq)]
352struct Test {
353 a: CustomOption<u32>,
354 b: u8,
355}
356
357fn main() {
358 let test = CustomOption::Some(Test { a: CustomOption::Some(3), b: 1 });
359 if let CustomOption::None = &test {};
360 if let test = &test {};
361 if let CustomOption::Some(test) = &test {};
362 if let CustomOption::Some(Test { a, b }) = &test {};
363 if let CustomOption::Some(Test { a: x, b: y }) = &test {};
364 if let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {};
365 if let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {};
366 if let CustomOption::Some(Test { b: y, .. }) = &test {};
367
368 if test == CustomOption::None {}
369}"#,
370 );
371
372 assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
373 InlayHint {
374 range: [166; 170),
375 kind: LetBindingType,
376 label: "CustomOption<Test>",
377 },
378 InlayHint {
379 range: [334; 338),
380 kind: IfExpressionType,
381 label: "&Test",
382 },
383 InlayHint {
384 range: [389; 390),
385 kind: IfExpressionType,
386 label: "&CustomOption<u32>",
387 },
388 InlayHint {
389 range: [392; 393),
390 kind: IfExpressionType,
391 label: "&u8",
392 },
393 InlayHint {
394 range: [531; 532),
395 kind: IfExpressionType,
396 label: "&u32",
397 },
398]"#
399 );
400 }
401
402 #[test]
403 fn while_expr() {
404 let (analysis, file_id) = single_file(
405 r#"
406#[derive(PartialEq)]
407enum CustomOption<T> {
408 None,
409 Some(T),
410}
411
412#[derive(PartialEq)]
413struct Test {
414 a: CustomOption<u32>,
415 b: u8,
416}
417
418fn main() {
419 let test = CustomOption::Some(Test { a: CustomOption::Some(3), b: 1 });
420 while let CustomOption::None = &test {};
421 while let test = &test {};
422 while let CustomOption::Some(test) = &test {};
423 while let CustomOption::Some(Test { a, b }) = &test {};
424 while let CustomOption::Some(Test { a: x, b: y }) = &test {};
425 while let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {};
426 while let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {};
427 while let CustomOption::Some(Test { b: y, .. }) = &test {};
428
429 while test == CustomOption::None {}
430}"#,
431 );
432
433 assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
434 InlayHint {
435 range: [166; 170),
436 kind: LetBindingType,
437 label: "CustomOption<Test>",
438 },
439]"#
440 );
441 }
442
443 #[test]
444 fn match_arm_list() {
445 let (analysis, file_id) = single_file(
446 r#"
447#[derive(PartialEq)]
448enum CustomOption<T> {
449 None,
450 Some(T),
451}
452
453#[derive(PartialEq)]
454struct Test {
455 a: CustomOption<u32>,
456 b: u8,
457}
458
459fn main() {
460 match CustomOption::Some(Test { a: CustomOption::Some(3), b: 1 }) {
461 CustomOption::None => (),
462 test => (),
463 CustomOption::Some(test) => (),
464 CustomOption::Some(Test { a, b }) => (),
465 CustomOption::Some(Test { a: x, b: y }) => (),
466 CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) => (),
467 CustomOption::Some(Test { a: CustomOption::None, b: y }) => (),
468 CustomOption::Some(Test { b: y, .. }) => (),
469 _ => {}
470 }
471}"#,
472 );
473
474 assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
475 InlayHint {
476 range: [312; 316),
477 kind: MatchArmType,
478 label: "Test",
479 },
480 InlayHint {
481 range: [359; 360),
482 kind: MatchArmType,
483 label: "CustomOption<u32>",
484 },
485 InlayHint {
486 range: [362; 363),
487 kind: MatchArmType,
488 label: "u8",
489 },
490 InlayHint {
491 range: [485; 486),
492 kind: MatchArmType,
493 label: "u32",
176 }, 494 },
177]"# 495]"#
178 ); 496 );
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 16ffb03ce..edb646c11 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -317,24 +317,24 @@ impl Analysis {
317 } 317 }
318 318
319 /// Debug info about the current state of the analysis 319 /// Debug info about the current state of the analysis
320 pub fn status(&self) -> String { 320 pub fn status(&self) -> Cancelable<String> {
321 status::status(&*self.db) 321 self.with_db(|db| status::status(&*db))
322 } 322 }
323 323
324 /// Gets the text of the source file. 324 /// Gets the text of the source file.
325 pub fn file_text(&self, file_id: FileId) -> Arc<String> { 325 pub fn file_text(&self, file_id: FileId) -> Cancelable<Arc<String>> {
326 self.db.file_text(file_id) 326 self.with_db(|db| db.file_text(file_id))
327 } 327 }
328 328
329 /// Gets the syntax tree of the file. 329 /// Gets the syntax tree of the file.
330 pub fn parse(&self, file_id: FileId) -> SourceFile { 330 pub fn parse(&self, file_id: FileId) -> Cancelable<SourceFile> {
331 self.db.parse(file_id).tree() 331 self.with_db(|db| db.parse(file_id).tree())
332 } 332 }
333 333
334 /// Gets the file's `LineIndex`: data structure to convert between absolute 334 /// Gets the file's `LineIndex`: data structure to convert between absolute
335 /// offsets and line/column representation. 335 /// offsets and line/column representation.
336 pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { 336 pub fn file_line_index(&self, file_id: FileId) -> Cancelable<Arc<LineIndex>> {
337 self.db.line_index(file_id) 337 self.with_db(|db| db.line_index(file_id))
338 } 338 }
339 339
340 /// Selects the next syntactic nodes encompassing the range. 340 /// Selects the next syntactic nodes encompassing the range.
@@ -344,58 +344,67 @@ impl Analysis {
344 344
345 /// Returns position of the matching brace (all types of braces are 345 /// Returns position of the matching brace (all types of braces are
346 /// supported). 346 /// supported).
347 pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { 347 pub fn matching_brace(&self, position: FilePosition) -> Cancelable<Option<TextUnit>> {
348 let parse = self.db.parse(position.file_id); 348 self.with_db(|db| {
349 let file = parse.tree(); 349 let parse = db.parse(position.file_id);
350 matching_brace::matching_brace(&file, position.offset) 350 let file = parse.tree();
351 matching_brace::matching_brace(&file, position.offset)
352 })
351 } 353 }
352 354
353 /// Returns a syntax tree represented as `String`, for debug purposes. 355 /// Returns a syntax tree represented as `String`, for debug purposes.
354 // FIXME: use a better name here. 356 // FIXME: use a better name here.
355 pub fn syntax_tree(&self, file_id: FileId, text_range: Option<TextRange>) -> String { 357 pub fn syntax_tree(
356 syntax_tree::syntax_tree(&self.db, file_id, text_range) 358 &self,
359 file_id: FileId,
360 text_range: Option<TextRange>,
361 ) -> Cancelable<String> {
362 self.with_db(|db| syntax_tree::syntax_tree(&db, file_id, text_range))
357 } 363 }
358 364
359 /// Returns an edit to remove all newlines in the range, cleaning up minor 365 /// Returns an edit to remove all newlines in the range, cleaning up minor
360 /// stuff like trailing commas. 366 /// stuff like trailing commas.
361 pub fn join_lines(&self, frange: FileRange) -> SourceChange { 367 pub fn join_lines(&self, frange: FileRange) -> Cancelable<SourceChange> {
362 let parse = self.db.parse(frange.file_id); 368 self.with_db(|db| {
363 let file_edit = SourceFileEdit { 369 let parse = db.parse(frange.file_id);
364 file_id: frange.file_id, 370 let file_edit = SourceFileEdit {
365 edit: join_lines::join_lines(&parse.tree(), frange.range), 371 file_id: frange.file_id,
366 }; 372 edit: join_lines::join_lines(&parse.tree(), frange.range),
367 SourceChange::source_file_edit("join lines", file_edit) 373 };
374 SourceChange::source_file_edit("join lines", file_edit)
375 })
368 } 376 }
369 377
370 /// Returns an edit which should be applied when opening a new line, fixing 378 /// Returns an edit which should be applied when opening a new line, fixing
371 /// up minor stuff like continuing the comment. 379 /// up minor stuff like continuing the comment.
372 pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { 380 pub fn on_enter(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
373 typing::on_enter(&self.db, position) 381 self.with_db(|db| typing::on_enter(&db, position))
374 } 382 }
375 383
376 /// Returns an edit which should be applied after `=` was typed. Primarily, 384 /// Returns an edit which should be applied after `=` was typed. Primarily,
377 /// this works when adding `let =`. 385 /// this works when adding `let =`.
378 // FIXME: use a snippet completion instead of this hack here. 386 // FIXME: use a snippet completion instead of this hack here.
379 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { 387 pub fn on_eq_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
380 let parse = self.db.parse(position.file_id); 388 self.with_db(|db| {
381 let file = parse.tree(); 389 let parse = db.parse(position.file_id);
382 let edit = typing::on_eq_typed(&file, position.offset)?; 390 let file = parse.tree();
383 Some(SourceChange::source_file_edit( 391 let edit = typing::on_eq_typed(&file, position.offset)?;
384 "add semicolon", 392 Some(SourceChange::source_file_edit(
385 SourceFileEdit { edit, file_id: position.file_id }, 393 "add semicolon",
386 )) 394 SourceFileEdit { edit, file_id: position.file_id },
395 ))
396 })
387 } 397 }
388 398
389 /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. 399 /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
390 pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> { 400 pub fn on_dot_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
391 typing::on_dot_typed(&self.db, position) 401 self.with_db(|db| typing::on_dot_typed(&db, position))
392 } 402 }
393 403
394 /// Returns a tree representation of symbols in the file. Useful to draw a 404 /// Returns a tree representation of symbols in the file. Useful to draw a
395 /// file outline. 405 /// file outline.
396 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { 406 pub fn file_structure(&self, file_id: FileId) -> Cancelable<Vec<StructureNode>> {
397 let parse = self.db.parse(file_id); 407 self.with_db(|db| file_structure(&db.parse(file_id).tree()))
398 file_structure(&parse.tree())
399 } 408 }
400 409
401 /// Returns a list of the places in the file where type hints can be displayed. 410 /// Returns a list of the places in the file where type hints can be displayed.
@@ -404,9 +413,8 @@ impl Analysis {
404 } 413 }
405 414
406 /// Returns the set of folding ranges. 415 /// Returns the set of folding ranges.
407 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { 416 pub fn folding_ranges(&self, file_id: FileId) -> Cancelable<Vec<Fold>> {
408 let parse = self.db.parse(file_id); 417 self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree()))
409 folding_ranges::folding_ranges(&parse.tree())
410 } 418 }
411 419
412 /// Fuzzy searches for a symbol. 420 /// Fuzzy searches for a symbol.
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index 5c74d3e36..2118e7ad3 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -341,7 +341,39 @@ mod tests {
341 ); 341 );
342 let new_name = "foo2"; 342 let new_name = "foo2";
343 let source_change = analysis.rename(position, new_name).unwrap(); 343 let source_change = analysis.rename(position, new_name).unwrap();
344 assert_debug_snapshot_matches!("rename_mod", &source_change); 344 assert_debug_snapshot_matches!(&source_change,
345@r#"Some(
346 SourceChange {
347 label: "rename",
348 source_file_edits: [
349 SourceFileEdit {
350 file_id: FileId(
351 2,
352 ),
353 edit: TextEdit {
354 atoms: [
355 AtomTextEdit {
356 delete: [4; 7),
357 insert: "foo2",
358 },
359 ],
360 },
361 },
362 ],
363 file_system_edits: [
364 MoveFile {
365 src: FileId(
366 3,
367 ),
368 dst_source_root: SourceRootId(
369 0,
370 ),
371 dst_path: "bar/foo2.rs",
372 },
373 ],
374 cursor_position: None,
375 },
376)"#);
345 } 377 }
346 378
347 #[test] 379 #[test]
@@ -356,7 +388,40 @@ mod tests {
356 ); 388 );
357 let new_name = "foo2"; 389 let new_name = "foo2";
358 let source_change = analysis.rename(position, new_name).unwrap(); 390 let source_change = analysis.rename(position, new_name).unwrap();
359 assert_debug_snapshot_matches!("rename_mod_in_dir", &source_change); 391 assert_debug_snapshot_matches!(&source_change,
392 @r###"Some(
393 SourceChange {
394 label: "rename",
395 source_file_edits: [
396 SourceFileEdit {
397 file_id: FileId(
398 1,
399 ),
400 edit: TextEdit {
401 atoms: [
402 AtomTextEdit {
403 delete: [4; 7),
404 insert: "foo2",
405 },
406 ],
407 },
408 },
409 ],
410 file_system_edits: [
411 MoveFile {
412 src: FileId(
413 2,
414 ),
415 dst_source_root: SourceRootId(
416 0,
417 ),
418 dst_path: "foo2/mod.rs",
419 },
420 ],
421 cursor_position: None,
422 },
423)"###
424 );
360 } 425 }
361 426
362 fn test_rename(text: &str, new_name: &str, expected: &str) { 427 fn test_rename(text: &str, new_name: &str, expected: &str) {
@@ -372,7 +437,8 @@ mod tests {
372 } 437 }
373 } 438 }
374 } 439 }
375 let result = text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap())); 440 let result =
441 text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap()).unwrap());
376 assert_eq_text!(expected, &*result); 442 assert_eq_text!(expected, &*result);
377 } 443 }
378} 444}
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs
index 07412a9ef..09c082de9 100644
--- a/crates/ra_ide_api/src/runnables.rs
+++ b/crates/ra_ide_api/src/runnables.rs
@@ -92,7 +92,26 @@ mod tests {
92 "#, 92 "#,
93 ); 93 );
94 let runnables = analysis.runnables(pos.file_id).unwrap(); 94 let runnables = analysis.runnables(pos.file_id).unwrap();
95 assert_debug_snapshot_matches!("runnables", &runnables) 95 assert_debug_snapshot_matches!(&runnables,
96 @r#"[
97 Runnable {
98 range: [1; 21),
99 kind: Bin,
100 },
101 Runnable {
102 range: [22; 46),
103 kind: Test {
104 name: "test_foo",
105 },
106 },
107 Runnable {
108 range: [47; 81),
109 kind: Test {
110 name: "test_foo",
111 },
112 },
113]"#
114 );
96 } 115 }
97 116
98 #[test] 117 #[test]
@@ -108,7 +127,22 @@ mod tests {
108 "#, 127 "#,
109 ); 128 );
110 let runnables = analysis.runnables(pos.file_id).unwrap(); 129 let runnables = analysis.runnables(pos.file_id).unwrap();
111 assert_debug_snapshot_matches!("runnables_module", &runnables) 130 assert_debug_snapshot_matches!(&runnables,
131 @r#"[
132 Runnable {
133 range: [1; 59),
134 kind: TestMod {
135 path: "test_mod",
136 },
137 },
138 Runnable {
139 range: [28; 57),
140 kind: Test {
141 name: "test_foo1",
142 },
143 },
144]"#
145 );
112 } 146 }
113 147
114 #[test] 148 #[test]
@@ -126,7 +160,22 @@ mod tests {
126 "#, 160 "#,
127 ); 161 );
128 let runnables = analysis.runnables(pos.file_id).unwrap(); 162 let runnables = analysis.runnables(pos.file_id).unwrap();
129 assert_debug_snapshot_matches!("runnables_one_depth_layer_module", &runnables) 163 assert_debug_snapshot_matches!(&runnables,
164 @r#"[
165 Runnable {
166 range: [23; 85),
167 kind: TestMod {
168 path: "foo::test_mod",
169 },
170 },
171 Runnable {
172 range: [46; 79),
173 kind: Test {
174 name: "test_foo1",
175 },
176 },
177]"#
178 );
130 } 179 }
131 180
132 #[test] 181 #[test]
@@ -146,7 +195,22 @@ mod tests {
146 "#, 195 "#,
147 ); 196 );
148 let runnables = analysis.runnables(pos.file_id).unwrap(); 197 let runnables = analysis.runnables(pos.file_id).unwrap();
149 assert_debug_snapshot_matches!("runnables_multiple_depth_module", &runnables) 198 assert_debug_snapshot_matches!(&runnables,
199 @r#"[
200 Runnable {
201 range: [41; 115),
202 kind: TestMod {
203 path: "foo::bar::test_mod",
204 },
205 },
206 Runnable {
207 range: [68; 105),
208 kind: Test {
209 name: "test_foo1",
210 },
211 },
212]"#
213 );
150 } 214 }
151 215
152 #[test] 216 #[test]
diff --git a/crates/ra_ide_api/src/snapshots/tests__highlights_code_inside_macros.snap b/crates/ra_ide_api/src/snapshots/tests__highlights_code_inside_macros.snap
deleted file mode 100644
index ae8923e75..000000000
--- a/crates/ra_ide_api/src/snapshots/tests__highlights_code_inside_macros.snap
+++ /dev/null
@@ -1,44 +0,0 @@
1---
2created: "2019-02-01T07:46:59.130146403+00:00"
3creator: [email protected]
4expression: "&highlights"
5source: crates/ra_ide_api/src/syntax_highlighting.rs
6---
7[
8 HighlightedRange {
9 range: [13; 15),
10 tag: "keyword"
11 },
12 HighlightedRange {
13 range: [16; 20),
14 tag: "function"
15 },
16 HighlightedRange {
17 range: [41; 45),
18 tag: "macro"
19 },
20 HighlightedRange {
21 range: [48; 51),
22 tag: "keyword"
23 },
24 HighlightedRange {
25 range: [56; 58),
26 tag: "literal"
27 },
28 HighlightedRange {
29 range: [48; 51),
30 tag: "keyword"
31 },
32 HighlightedRange {
33 range: [52; 53),
34 tag: "function"
35 },
36 HighlightedRange {
37 range: [56; 58),
38 tag: "literal"
39 },
40 HighlightedRange {
41 range: [60; 61),
42 tag: "text"
43 }
44]
diff --git a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap b/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
deleted file mode 100644
index 431de5c55..000000000
--- a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
+++ /dev/null
@@ -1,38 +0,0 @@
1---
2created: "2019-05-23T22:23:35.215905447Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/references.rs
5expression: "&source_change"
6---
7Some(
8 SourceChange {
9 label: "rename",
10 source_file_edits: [
11 SourceFileEdit {
12 file_id: FileId(
13 2,
14 ),
15 edit: TextEdit {
16 atoms: [
17 AtomTextEdit {
18 delete: [4; 7),
19 insert: "foo2",
20 },
21 ],
22 },
23 },
24 ],
25 file_system_edits: [
26 MoveFile {
27 src: FileId(
28 3,
29 ),
30 dst_source_root: SourceRootId(
31 0,
32 ),
33 dst_path: "bar/foo2.rs",
34 },
35 ],
36 cursor_position: None,
37 },
38)
diff --git a/crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap b/crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap
deleted file mode 100644
index aaff9b4b5..000000000
--- a/crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap
+++ /dev/null
@@ -1,38 +0,0 @@
1---
2created: "2019-05-23T22:23:35.213830371Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/references.rs
5expression: "&source_change"
6---
7Some(
8 SourceChange {
9 label: "rename",
10 source_file_edits: [
11 SourceFileEdit {
12 file_id: FileId(
13 1,
14 ),
15 edit: TextEdit {
16 atoms: [
17 AtomTextEdit {
18 delete: [4; 7),
19 insert: "foo2",
20 },
21 ],
22 },
23 },
24 ],
25 file_system_edits: [
26 MoveFile {
27 src: FileId(
28 2,
29 ),
30 dst_source_root: SourceRootId(
31 0,
32 ),
33 dst_path: "foo2/mod.rs",
34 },
35 ],
36 cursor_position: None,
37 },
38)
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables.snap b/crates/ra_ide_api/src/snapshots/tests__runnables.snap
deleted file mode 100644
index de2fadd7f..000000000
--- a/crates/ra_ide_api/src/snapshots/tests__runnables.snap
+++ /dev/null
@@ -1,24 +0,0 @@
1---
2created: "2019-05-23T22:23:35.217100106Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/runnables.rs
5expression: "&runnables"
6---
7[
8 Runnable {
9 range: [1; 21),
10 kind: Bin,
11 },
12 Runnable {
13 range: [22; 46),
14 kind: Test {
15 name: "test_foo",
16 },
17 },
18 Runnable {
19 range: [47; 81),
20 kind: Test {
21 name: "test_foo",
22 },
23 },
24]
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables_module.snap b/crates/ra_ide_api/src/snapshots/tests__runnables_module.snap
deleted file mode 100644
index 23993a97f..000000000
--- a/crates/ra_ide_api/src/snapshots/tests__runnables_module.snap
+++ /dev/null
@@ -1,20 +0,0 @@
1---
2created: "2019-05-23T22:23:35.219258850Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/runnables.rs
5expression: "&runnables"
6---
7[
8 Runnable {
9 range: [1; 59),
10 kind: TestMod {
11 path: "test_mod",
12 },
13 },
14 Runnable {
15 range: [28; 57),
16 kind: Test {
17 name: "test_foo1",
18 },
19 },
20]
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap b/crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap
deleted file mode 100644
index c516a61df..000000000
--- a/crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap
+++ /dev/null
@@ -1,20 +0,0 @@
1---
2created: "2019-05-23T22:23:35.219671663Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/runnables.rs
5expression: "&runnables"
6---
7[
8 Runnable {
9 range: [41; 115),
10 kind: TestMod {
11 path: "foo::bar::test_mod",
12 },
13 },
14 Runnable {
15 range: [68; 105),
16 kind: Test {
17 name: "test_foo1",
18 },
19 },
20]
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap b/crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap
deleted file mode 100644
index b02e6707e..000000000
--- a/crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap
+++ /dev/null
@@ -1,20 +0,0 @@
1---
2created: "2019-05-23T22:23:35.224315047Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/runnables.rs
5expression: "&runnables"
6---
7[
8 Runnable {
9 range: [23; 85),
10 kind: TestMod {
11 path: "foo::test_mod",
12 },
13 },
14 Runnable {
15 range: [46; 79),
16 kind: Test {
17 name: "test_foo1",
18 },
19 },
20]
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs
index a07e670fa..dd31b9093 100644
--- a/crates/ra_ide_api/src/syntax_tree.rs
+++ b/crates/ra_ide_api/src/syntax_tree.rs
@@ -101,7 +101,7 @@ mod tests {
101 fn test_syntax_tree_without_range() { 101 fn test_syntax_tree_without_range() {
102 // Basic syntax 102 // Basic syntax
103 let (analysis, file_id) = single_file(r#"fn foo() {}"#); 103 let (analysis, file_id) = single_file(r#"fn foo() {}"#);
104 let syn = analysis.syntax_tree(file_id, None); 104 let syn = analysis.syntax_tree(file_id, None).unwrap();
105 105
106 assert_eq_text!( 106 assert_eq_text!(
107 syn.trim(), 107 syn.trim(),
@@ -133,7 +133,7 @@ fn test() {
133}"# 133}"#
134 .trim(), 134 .trim(),
135 ); 135 );
136 let syn = analysis.syntax_tree(file_id, None); 136 let syn = analysis.syntax_tree(file_id, None).unwrap();
137 137
138 assert_eq_text!( 138 assert_eq_text!(
139 syn.trim(), 139 syn.trim(),
@@ -176,7 +176,7 @@ SOURCE_FILE@[0; 60)
176 #[test] 176 #[test]
177 fn test_syntax_tree_with_range() { 177 fn test_syntax_tree_with_range() {
178 let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim()); 178 let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
179 let syn = analysis.syntax_tree(range.file_id, Some(range.range)); 179 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
180 180
181 assert_eq_text!( 181 assert_eq_text!(
182 syn.trim(), 182 syn.trim(),
@@ -206,7 +206,7 @@ FN_DEF@[0; 11)
206}"# 206}"#
207 .trim(), 207 .trim(),
208 ); 208 );
209 let syn = analysis.syntax_tree(range.file_id, Some(range.range)); 209 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
210 210
211 assert_eq_text!( 211 assert_eq_text!(
212 syn.trim(), 212 syn.trim(),
@@ -244,7 +244,7 @@ fn bar() {
244}"# 244}"#
245 .trim(), 245 .trim(),
246 ); 246 );
247 let syn = analysis.syntax_tree(range.file_id, Some(range.range)); 247 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
248 assert_eq_text!( 248 assert_eq_text!(
249 syn.trim(), 249 syn.trim(),
250 r#" 250 r#"
@@ -278,7 +278,7 @@ fn bar() {
278}"### 278}"###
279 .trim(), 279 .trim(),
280 ); 280 );
281 let syn = analysis.syntax_tree(range.file_id, Some(range.range)); 281 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
282 assert_eq_text!( 282 assert_eq_text!(
283 syn.trim(), 283 syn.trim(),
284 r#" 284 r#"
@@ -311,7 +311,7 @@ fn bar() {
311}"### 311}"###
312 .trim(), 312 .trim(),
313 ); 313 );
314 let syn = analysis.syntax_tree(range.file_id, Some(range.range)); 314 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
315 assert_eq_text!( 315 assert_eq_text!(
316 syn.trim(), 316 syn.trim(),
317 r#" 317 r#"
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index 6b3fd5904..2d4491442 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -195,7 +195,7 @@ fn foo() {
195 edit.insert(offset, ".".to_string()); 195 edit.insert(offset, ".".to_string());
196 let before = edit.finish().apply(&before); 196 let before = edit.finish().apply(&before);
197 let (analysis, file_id) = single_file(&before); 197 let (analysis, file_id) = single_file(&before);
198 if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }) { 198 if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }).unwrap() {
199 assert_eq!(result.source_file_edits.len(), 1); 199 assert_eq!(result.source_file_edits.len(), 1);
200 let actual = result.source_file_edits[0].edit.apply(&before); 200 let actual = result.source_file_edits[0].edit.apply(&before);
201 assert_eq_text!(after, &actual); 201 assert_eq_text!(after, &actual);
@@ -377,7 +377,7 @@ fn foo() {
377 fn apply_on_enter(before: &str) -> Option<String> { 377 fn apply_on_enter(before: &str) -> Option<String> {
378 let (offset, before) = extract_offset(before); 378 let (offset, before) = extract_offset(before);
379 let (analysis, file_id) = single_file(&before); 379 let (analysis, file_id) = single_file(&before);
380 let result = analysis.on_enter(FilePosition { offset, file_id })?; 380 let result = analysis.on_enter(FilePosition { offset, file_id }).unwrap()?;
381 381
382 assert_eq!(result.source_file_edits.len(), 1); 382 assert_eq!(result.source_file_edits.len(), 1);
383 let actual = result.source_file_edits[0].edit.apply(&before); 383 let actual = result.source_file_edits[0].edit.apply(&before);