aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--crates/paths/src/lib.rs26
-rw-r--r--crates/ra_db/src/fixture.rs40
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs33
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs57
-rw-r--r--crates/ra_ide/src/call_info.rs6
-rw-r--r--crates/ra_ide/src/completion/complete_attribute.rs312
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs116
-rw-r--r--crates/ra_ide/src/completion/complete_fn_param.rs12
-rw-r--r--crates/ra_ide/src/completion/complete_pattern.rs28
-rw-r--r--crates/ra_ide/src/completion/complete_postfix.rs220
-rw-r--r--crates/ra_ide/src/completion/complete_qualified_path.rs68
-rw-r--r--crates/ra_ide/src/completion/complete_record.rs314
-rw-r--r--crates/ra_ide/src/completion/complete_snippet.rs16
-rw-r--r--crates/ra_ide/src/completion/complete_trait_impl.rs44
-rw-r--r--crates/ra_ide/src/completion/complete_unqualified_path.rs262
-rw-r--r--crates/ra_ide/src/completion/presentation.rs217
-rw-r--r--crates/ra_ide/src/completion/test_utils.rs6
-rw-r--r--crates/ra_ide/src/diagnostics.rs46
-rw-r--r--crates/ra_ide/src/extend_selection.rs12
-rw-r--r--crates/ra_ide/src/hover.rs50
-rw-r--r--crates/ra_ide/src/inlay_hints.rs178
-rw-r--r--crates/ra_ide/src/mock_analysis.rs178
-rw-r--r--crates/ra_ide/src/parent_module.rs12
-rw-r--r--crates/ra_ide/src/references.rs490
-rw-r--r--crates/ra_ide/src/references/rename.rs14
-rw-r--r--crates/ra_ide/src/snapshots/highlight_doctest.html32
-rw-r--r--crates/ra_ide/src/snapshots/highlight_injection.html2
-rw-r--r--crates/ra_ide/src/snapshots/highlight_strings.html2
-rw-r--r--crates/ra_ide/src/snapshots/highlight_unsafe.html2
-rw-r--r--crates/ra_ide/src/snapshots/highlighting.html2
-rw-r--r--crates/ra_ide/src/snapshots/rainbow_highlighting.html2
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs64
-rw-r--r--crates/ra_ide/src/syntax_highlighting/html.rs2
-rw-r--r--crates/ra_ide/src/syntax_highlighting/injection.rs10
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tags.rs5
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tests.rs24
-rw-r--r--crates/ra_ide/src/syntax_tree.rs12
-rw-r--r--crates/ra_ide/src/typing/on_enter.rs15
-rw-r--r--crates/ra_project_model/Cargo.toml1
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs42
-rw-r--r--crates/ra_project_model/src/lib.rs51
-rw-r--r--crates/ra_project_model/src/sysroot.rs23
-rw-r--r--crates/rust-analyzer/src/bin/main.rs37
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs2
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs22
-rw-r--r--crates/rust-analyzer/src/global_state.rs7
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs6
-rw-r--r--crates/rust-analyzer/src/to_proto.rs2
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/support.rs22
-rw-r--r--crates/test_utils/src/fixture.rs8
-rw-r--r--crates/vfs/src/vfs_path.rs19
-rw-r--r--editors/code/rollup.config.js7
54 files changed, 1635 insertions, 1548 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 9ea1765cb..91a932549 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1174,6 +1174,7 @@ dependencies = [
1174 "anyhow", 1174 "anyhow",
1175 "cargo_metadata", 1175 "cargo_metadata",
1176 "log", 1176 "log",
1177 "paths",
1177 "ra_arena", 1178 "ra_arena",
1178 "ra_cfg", 1179 "ra_cfg",
1179 "ra_db", 1180 "ra_db",
diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs
index 45b19c45a..1b259682d 100644
--- a/crates/paths/src/lib.rs
+++ b/crates/paths/src/lib.rs
@@ -28,6 +28,12 @@ impl AsRef<Path> for AbsPathBuf {
28 } 28 }
29} 29}
30 30
31impl AsRef<AbsPath> for AbsPathBuf {
32 fn as_ref(&self) -> &AbsPath {
33 self.as_path()
34 }
35}
36
31impl TryFrom<PathBuf> for AbsPathBuf { 37impl TryFrom<PathBuf> for AbsPathBuf {
32 type Error = PathBuf; 38 type Error = PathBuf;
33 fn try_from(path_buf: PathBuf) -> Result<AbsPathBuf, PathBuf> { 39 fn try_from(path_buf: PathBuf) -> Result<AbsPathBuf, PathBuf> {
@@ -45,9 +51,19 @@ impl TryFrom<&str> for AbsPathBuf {
45 } 51 }
46} 52}
47 53
54impl PartialEq<AbsPath> for AbsPathBuf {
55 fn eq(&self, other: &AbsPath) -> bool {
56 self.as_path() == other
57 }
58}
59
48impl AbsPathBuf { 60impl AbsPathBuf {
61 pub fn assert(path: PathBuf) -> AbsPathBuf {
62 AbsPathBuf::try_from(path)
63 .unwrap_or_else(|path| panic!("expected absolute path, got {}", path.display()))
64 }
49 pub fn as_path(&self) -> &AbsPath { 65 pub fn as_path(&self) -> &AbsPath {
50 AbsPath::new_unchecked(self.0.as_path()) 66 AbsPath::assert(self.0.as_path())
51 } 67 }
52 pub fn pop(&mut self) -> bool { 68 pub fn pop(&mut self) -> bool {
53 self.0.pop() 69 self.0.pop()
@@ -77,15 +93,19 @@ impl<'a> TryFrom<&'a Path> for &'a AbsPath {
77 if !path.is_absolute() { 93 if !path.is_absolute() {
78 return Err(path); 94 return Err(path);
79 } 95 }
80 Ok(AbsPath::new_unchecked(path)) 96 Ok(AbsPath::assert(path))
81 } 97 }
82} 98}
83 99
84impl AbsPath { 100impl AbsPath {
85 fn new_unchecked(path: &Path) -> &AbsPath { 101 pub fn assert(path: &Path) -> &AbsPath {
102 assert!(path.is_absolute());
86 unsafe { &*(path as *const Path as *const AbsPath) } 103 unsafe { &*(path as *const Path as *const AbsPath) }
87 } 104 }
88 105
106 pub fn parent(&self) -> Option<&AbsPath> {
107 self.0.parent().map(AbsPath::assert)
108 }
89 pub fn join(&self, path: impl AsRef<Path>) -> AbsPathBuf { 109 pub fn join(&self, path: impl AsRef<Path>) -> AbsPathBuf {
90 self.as_ref().join(path).try_into().unwrap() 110 self.as_ref().join(path).try_into().unwrap()
91 } 111 }
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index ddf46e6c4..4f4fb4494 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -132,10 +132,17 @@ fn with_files(
132 132
133 let mut file_position = None; 133 let mut file_position = None;
134 134
135 for entry in fixture.iter() { 135 for entry in fixture {
136 let meta = match ParsedMeta::from(entry) { 136 let text = if entry.text.contains(CURSOR_MARKER) {
137 ParsedMeta::File(it) => it, 137 let (range_or_offset, text) = extract_range_or_offset(&entry.text);
138 assert!(file_position.is_none());
139 file_position = Some((file_id, range_or_offset));
140 text.to_string()
141 } else {
142 entry.text.clone()
138 }; 143 };
144
145 let meta = FileMeta::from(entry);
139 assert!(meta.path.starts_with(&source_root_prefix)); 146 assert!(meta.path.starts_with(&source_root_prefix));
140 147
141 if let Some(krate) = meta.krate { 148 if let Some(krate) = meta.krate {
@@ -157,15 +164,6 @@ fn with_files(
157 default_crate_root = Some(file_id); 164 default_crate_root = Some(file_id);
158 } 165 }
159 166
160 let text = if entry.text.contains(CURSOR_MARKER) {
161 let (range_or_offset, text) = extract_range_or_offset(&entry.text);
162 assert!(file_position.is_none());
163 file_position = Some((file_id, range_or_offset));
164 text.to_string()
165 } else {
166 entry.text.to_string()
167 };
168
169 db.set_file_text(file_id, Arc::new(text)); 167 db.set_file_text(file_id, Arc::new(text));
170 db.set_file_source_root(file_id, source_root_id); 168 db.set_file_source_root(file_id, source_root_id);
171 let path = VfsPath::new_virtual_path(meta.path); 169 let path = VfsPath::new_virtual_path(meta.path);
@@ -198,10 +196,6 @@ fn with_files(
198 (file_position, files) 196 (file_position, files)
199} 197}
200 198
201enum ParsedMeta {
202 File(FileMeta),
203}
204
205struct FileMeta { 199struct FileMeta {
206 path: String, 200 path: String,
207 krate: Option<String>, 201 krate: Option<String>,
@@ -211,22 +205,22 @@ struct FileMeta {
211 env: Env, 205 env: Env,
212} 206}
213 207
214impl From<&Fixture> for ParsedMeta { 208impl From<Fixture> for FileMeta {
215 fn from(f: &Fixture) -> Self { 209 fn from(f: Fixture) -> FileMeta {
216 let mut cfg = CfgOptions::default(); 210 let mut cfg = CfgOptions::default();
217 f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into())); 211 f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
218 f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into())); 212 f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
219 213
220 Self::File(FileMeta { 214 FileMeta {
221 path: f.path.to_owned(), 215 path: f.path,
222 krate: f.crate_name.to_owned(), 216 krate: f.krate,
223 deps: f.deps.to_owned(), 217 deps: f.deps,
224 cfg, 218 cfg,
225 edition: f 219 edition: f
226 .edition 220 .edition
227 .as_ref() 221 .as_ref()
228 .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()), 222 .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()),
229 env: Env::from(f.env.iter()), 223 env: Env::from(f.env.iter()),
230 }) 224 }
231 } 225 }
232} 226}
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index 4006f595d..23de2bd6b 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -4,7 +4,7 @@ use std::iter::repeat;
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use hir_def::{ 6use hir_def::{
7 expr::{BindingAnnotation, Pat, PatId, RecordFieldPat}, 7 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat},
8 path::Path, 8 path::Path,
9 type_ref::Mutability, 9 type_ref::Mutability,
10 FieldId, 10 FieldId,
@@ -90,18 +90,7 @@ impl<'a> InferenceContext<'a> {
90 ) -> Ty { 90 ) -> Ty {
91 let body = Arc::clone(&self.body); // avoid borrow checker problem 91 let body = Arc::clone(&self.body); // avoid borrow checker problem
92 92
93 let is_non_ref_pat = match &body[pat] { 93 if is_non_ref_pat(&body, pat) {
94 Pat::Tuple { .. }
95 | Pat::Or(..)
96 | Pat::TupleStruct { .. }
97 | Pat::Record { .. }
98 | Pat::Range { .. }
99 | Pat::Slice { .. } => true,
100 // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented.
101 Pat::Path(..) | Pat::Lit(..) => true,
102 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
103 };
104 if is_non_ref_pat {
105 while let Some((inner, mutability)) = expected.as_reference() { 94 while let Some((inner, mutability)) = expected.as_reference() {
106 expected = inner; 95 expected = inner;
107 default_bm = match default_bm { 96 default_bm = match default_bm {
@@ -227,3 +216,21 @@ impl<'a> InferenceContext<'a> {
227 ty 216 ty
228 } 217 }
229} 218}
219
220fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
221 match &body[pat] {
222 Pat::Tuple { .. }
223 | Pat::TupleStruct { .. }
224 | Pat::Record { .. }
225 | Pat::Range { .. }
226 | Pat::Slice { .. } => true,
227 Pat::Or(pats) => pats.iter().all(|p| is_non_ref_pat(body, *p)),
228 // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented.
229 Pat::Path(..) => true,
230 Pat::Lit(expr) => match body[*expr] {
231 Expr::Literal(Literal::String(..)) => false,
232 _ => true,
233 },
234 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
235 }
236}
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs
index 8fa296137..e5ef241ca 100644
--- a/crates/ra_hir_ty/src/tests/patterns.rs
+++ b/crates/ra_hir_ty/src/tests/patterns.rs
@@ -271,6 +271,63 @@ fn test() {
271} 271}
272 272
273#[test] 273#[test]
274fn infer_pattern_match_string_literal() {
275 assert_snapshot!(
276 infer_with_mismatches(r#"
277fn test() {
278 let s: &str = "hello";
279 match s {
280 "hello" => {}
281 _ => {}
282 }
283}
284"#, true),
285 @r###"
286 10..98 '{ ... } }': ()
287 20..21 's': &str
288 30..37 '"hello"': &str
289 43..96 'match ... }': ()
290 49..50 's': &str
291 61..68 '"hello"': &str
292 61..68 '"hello"': &str
293 72..74 '{}': ()
294 83..84 '_': &str
295 88..90 '{}': ()
296 "###
297 );
298}
299
300#[test]
301fn infer_pattern_match_or() {
302 assert_snapshot!(
303 infer_with_mismatches(r#"
304fn test() {
305 let s: &str = "hello";
306 match s {
307 "hello" | "world" => {}
308 _ => {}
309 }
310}
311"#, true),
312 @r###"
313 10..108 '{ ... } }': ()
314 20..21 's': &str
315 30..37 '"hello"': &str
316 43..106 'match ... }': ()
317 49..50 's': &str
318 61..68 '"hello"': &str
319 61..68 '"hello"': &str
320 61..78 '"hello...world"': &str
321 71..78 '"world"': &str
322 71..78 '"world"': &str
323 82..84 '{}': ()
324 93..94 '_': &str
325 98..100 '{}': ()
326 "###
327 );
328}
329
330#[test]
274fn infer_pattern_match_arr() { 331fn infer_pattern_match_arr() {
275 assert_snapshot!( 332 assert_snapshot!(
276 infer(r#" 333 infer(r#"
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index aa039e6fc..a6bdf1c9d 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -215,7 +215,7 @@ impl CallInfo {
215mod tests { 215mod tests {
216 use test_utils::mark; 216 use test_utils::mark;
217 217
218 use crate::mock_analysis::single_file_with_position; 218 use crate::mock_analysis::analysis_and_position;
219 219
220 use super::*; 220 use super::*;
221 221
@@ -231,7 +231,7 @@ mod tests {
231 } 231 }
232 232
233 fn call_info_helper(text: &str) -> Option<CallInfo> { 233 fn call_info_helper(text: &str) -> Option<CallInfo> {
234 let (analysis, position) = single_file_with_position(text); 234 let (analysis, position) = analysis_and_position(text);
235 analysis.call_info(position).unwrap() 235 analysis.call_info(position).unwrap()
236 } 236 }
237 237
@@ -530,7 +530,7 @@ By default this method stops actor's `Context`."#
530 #[test] 530 #[test]
531 fn call_info_bad_offset() { 531 fn call_info_bad_offset() {
532 mark::check!(call_info_bad_offset); 532 mark::check!(call_info_bad_offset);
533 let (analysis, position) = single_file_with_position( 533 let (analysis, position) = analysis_and_position(
534 r#"fn foo(x: u32, y: u32) -> u32 {x + y} 534 r#"fn foo(x: u32, y: u32) -> u32 {x + y}
535 fn bar() { foo <|> (3, ); }"#, 535 fn bar() { foo <|> (3, ); }"#,
536 ); 536 );
diff --git a/crates/ra_ide/src/completion/complete_attribute.rs b/crates/ra_ide/src/completion/complete_attribute.rs
index ade17a1ff..6beeca457 100644
--- a/crates/ra_ide/src/completion/complete_attribute.rs
+++ b/crates/ra_ide/src/completion/complete_attribute.rs
@@ -333,69 +333,69 @@ mod tests {
333 [ 333 [
334 CompletionItem { 334 CompletionItem {
335 label: "Clone", 335 label: "Clone",
336 source_range: 30..30, 336 source_range: 9..9,
337 delete: 30..30, 337 delete: 9..9,
338 insert: "Clone", 338 insert: "Clone",
339 kind: Attribute, 339 kind: Attribute,
340 }, 340 },
341 CompletionItem { 341 CompletionItem {
342 label: "Copy, Clone", 342 label: "Copy, Clone",
343 source_range: 30..30, 343 source_range: 9..9,
344 delete: 30..30, 344 delete: 9..9,
345 insert: "Copy, Clone", 345 insert: "Copy, Clone",
346 kind: Attribute, 346 kind: Attribute,
347 }, 347 },
348 CompletionItem { 348 CompletionItem {
349 label: "Debug", 349 label: "Debug",
350 source_range: 30..30, 350 source_range: 9..9,
351 delete: 30..30, 351 delete: 9..9,
352 insert: "Debug", 352 insert: "Debug",
353 kind: Attribute, 353 kind: Attribute,
354 }, 354 },
355 CompletionItem { 355 CompletionItem {
356 label: "Default", 356 label: "Default",
357 source_range: 30..30, 357 source_range: 9..9,
358 delete: 30..30, 358 delete: 9..9,
359 insert: "Default", 359 insert: "Default",
360 kind: Attribute, 360 kind: Attribute,
361 }, 361 },
362 CompletionItem { 362 CompletionItem {
363 label: "Eq, PartialEq", 363 label: "Eq, PartialEq",
364 source_range: 30..30, 364 source_range: 9..9,
365 delete: 30..30, 365 delete: 9..9,
366 insert: "Eq, PartialEq", 366 insert: "Eq, PartialEq",
367 kind: Attribute, 367 kind: Attribute,
368 }, 368 },
369 CompletionItem { 369 CompletionItem {
370 label: "Hash", 370 label: "Hash",
371 source_range: 30..30, 371 source_range: 9..9,
372 delete: 30..30, 372 delete: 9..9,
373 insert: "Hash", 373 insert: "Hash",
374 kind: Attribute, 374 kind: Attribute,
375 }, 375 },
376 CompletionItem { 376 CompletionItem {
377 label: "Ord, PartialOrd, Eq, PartialEq", 377 label: "Ord, PartialOrd, Eq, PartialEq",
378 source_range: 30..30, 378 source_range: 9..9,
379 delete: 30..30, 379 delete: 9..9,
380 insert: "Ord, PartialOrd, Eq, PartialEq", 380 insert: "Ord, PartialOrd, Eq, PartialEq",
381 kind: Attribute, 381 kind: Attribute,
382 }, 382 },
383 CompletionItem { 383 CompletionItem {
384 label: "PartialEq", 384 label: "PartialEq",
385 source_range: 30..30, 385 source_range: 9..9,
386 delete: 30..30, 386 delete: 9..9,
387 insert: "PartialEq", 387 insert: "PartialEq",
388 kind: Attribute, 388 kind: Attribute,
389 }, 389 },
390 CompletionItem { 390 CompletionItem {
391 label: "PartialOrd, PartialEq", 391 label: "PartialOrd, PartialEq",
392 source_range: 30..30, 392 source_range: 9..9,
393 delete: 30..30, 393 delete: 9..9,
394 insert: "PartialOrd, PartialEq", 394 insert: "PartialOrd, PartialEq",
395 kind: Attribute, 395 kind: Attribute,
396 }, 396 },
397 ] 397 ]
398 "### 398 "###
399 ); 399 );
400 } 400 }
401 401
@@ -425,62 +425,62 @@ mod tests {
425 [ 425 [
426 CompletionItem { 426 CompletionItem {
427 label: "Clone", 427 label: "Clone",
428 source_range: 59..59, 428 source_range: 38..38,
429 delete: 59..59, 429 delete: 38..38,
430 insert: "Clone", 430 insert: "Clone",
431 kind: Attribute, 431 kind: Attribute,
432 }, 432 },
433 CompletionItem { 433 CompletionItem {
434 label: "Copy, Clone", 434 label: "Copy, Clone",
435 source_range: 59..59, 435 source_range: 38..38,
436 delete: 59..59, 436 delete: 38..38,
437 insert: "Copy, Clone", 437 insert: "Copy, Clone",
438 kind: Attribute, 438 kind: Attribute,
439 }, 439 },
440 CompletionItem { 440 CompletionItem {
441 label: "Debug", 441 label: "Debug",
442 source_range: 59..59, 442 source_range: 38..38,
443 delete: 59..59, 443 delete: 38..38,
444 insert: "Debug", 444 insert: "Debug",
445 kind: Attribute, 445 kind: Attribute,
446 }, 446 },
447 CompletionItem { 447 CompletionItem {
448 label: "Default", 448 label: "Default",
449 source_range: 59..59, 449 source_range: 38..38,
450 delete: 59..59, 450 delete: 38..38,
451 insert: "Default", 451 insert: "Default",
452 kind: Attribute, 452 kind: Attribute,
453 }, 453 },
454 CompletionItem { 454 CompletionItem {
455 label: "Eq", 455 label: "Eq",
456 source_range: 59..59, 456 source_range: 38..38,
457 delete: 59..59, 457 delete: 38..38,
458 insert: "Eq", 458 insert: "Eq",
459 kind: Attribute, 459 kind: Attribute,
460 }, 460 },
461 CompletionItem { 461 CompletionItem {
462 label: "Hash", 462 label: "Hash",
463 source_range: 59..59, 463 source_range: 38..38,
464 delete: 59..59, 464 delete: 38..38,
465 insert: "Hash", 465 insert: "Hash",
466 kind: Attribute, 466 kind: Attribute,
467 }, 467 },
468 CompletionItem { 468 CompletionItem {
469 label: "Ord, PartialOrd, Eq", 469 label: "Ord, PartialOrd, Eq",
470 source_range: 59..59, 470 source_range: 38..38,
471 delete: 59..59, 471 delete: 38..38,
472 insert: "Ord, PartialOrd, Eq", 472 insert: "Ord, PartialOrd, Eq",
473 kind: Attribute, 473 kind: Attribute,
474 }, 474 },
475 CompletionItem { 475 CompletionItem {
476 label: "PartialOrd", 476 label: "PartialOrd",
477 source_range: 59..59, 477 source_range: 38..38,
478 delete: 59..59, 478 delete: 38..38,
479 insert: "PartialOrd", 479 insert: "PartialOrd",
480 kind: Attribute, 480 kind: Attribute,
481 }, 481 },
482 ] 482 ]
483 "### 483 "###
484 ); 484 );
485 } 485 }
486 486
@@ -496,207 +496,207 @@ mod tests {
496 [ 496 [
497 CompletionItem { 497 CompletionItem {
498 label: "allow(…)", 498 label: "allow(…)",
499 source_range: 19..19, 499 source_range: 2..2,
500 delete: 19..19, 500 delete: 2..2,
501 insert: "allow(${0:lint})", 501 insert: "allow(${0:lint})",
502 kind: Attribute, 502 kind: Attribute,
503 lookup: "allow", 503 lookup: "allow",
504 }, 504 },
505 CompletionItem { 505 CompletionItem {
506 label: "cfg(…)", 506 label: "cfg(…)",
507 source_range: 19..19, 507 source_range: 2..2,
508 delete: 19..19, 508 delete: 2..2,
509 insert: "cfg(${0:predicate})", 509 insert: "cfg(${0:predicate})",
510 kind: Attribute, 510 kind: Attribute,
511 lookup: "cfg", 511 lookup: "cfg",
512 }, 512 },
513 CompletionItem { 513 CompletionItem {
514 label: "cfg_attr(…)", 514 label: "cfg_attr(…)",
515 source_range: 19..19, 515 source_range: 2..2,
516 delete: 19..19, 516 delete: 2..2,
517 insert: "cfg_attr(${1:predicate}, ${0:attr})", 517 insert: "cfg_attr(${1:predicate}, ${0:attr})",
518 kind: Attribute, 518 kind: Attribute,
519 lookup: "cfg_attr", 519 lookup: "cfg_attr",
520 }, 520 },
521 CompletionItem { 521 CompletionItem {
522 label: "deny(…)", 522 label: "deny(…)",
523 source_range: 19..19, 523 source_range: 2..2,
524 delete: 19..19, 524 delete: 2..2,
525 insert: "deny(${0:lint})", 525 insert: "deny(${0:lint})",
526 kind: Attribute, 526 kind: Attribute,
527 lookup: "deny", 527 lookup: "deny",
528 }, 528 },
529 CompletionItem { 529 CompletionItem {
530 label: "deprecated = \"…\"", 530 label: "deprecated = \"…\"",
531 source_range: 19..19, 531 source_range: 2..2,
532 delete: 19..19, 532 delete: 2..2,
533 insert: "deprecated = \"${0:reason}\"", 533 insert: "deprecated = \"${0:reason}\"",
534 kind: Attribute, 534 kind: Attribute,
535 lookup: "deprecated", 535 lookup: "deprecated",
536 }, 536 },
537 CompletionItem { 537 CompletionItem {
538 label: "derive(…)", 538 label: "derive(…)",
539 source_range: 19..19, 539 source_range: 2..2,
540 delete: 19..19, 540 delete: 2..2,
541 insert: "derive(${0:Debug})", 541 insert: "derive(${0:Debug})",
542 kind: Attribute, 542 kind: Attribute,
543 lookup: "derive", 543 lookup: "derive",
544 }, 544 },
545 CompletionItem { 545 CompletionItem {
546 label: "doc = \"…\"", 546 label: "doc = \"…\"",
547 source_range: 19..19, 547 source_range: 2..2,
548 delete: 19..19, 548 delete: 2..2,
549 insert: "doc = \"${0:docs}\"", 549 insert: "doc = \"${0:docs}\"",
550 kind: Attribute, 550 kind: Attribute,
551 lookup: "doc", 551 lookup: "doc",
552 }, 552 },
553 CompletionItem { 553 CompletionItem {
554 label: "forbid(…)", 554 label: "forbid(…)",
555 source_range: 19..19, 555 source_range: 2..2,
556 delete: 19..19, 556 delete: 2..2,
557 insert: "forbid(${0:lint})", 557 insert: "forbid(${0:lint})",
558 kind: Attribute, 558 kind: Attribute,
559 lookup: "forbid", 559 lookup: "forbid",
560 }, 560 },
561 CompletionItem { 561 CompletionItem {
562 label: "ignore(…)", 562 label: "ignore(…)",
563 source_range: 19..19, 563 source_range: 2..2,
564 delete: 19..19, 564 delete: 2..2,
565 insert: "ignore(${0:lint})", 565 insert: "ignore(${0:lint})",
566 kind: Attribute, 566 kind: Attribute,
567 lookup: "ignore", 567 lookup: "ignore",
568 }, 568 },
569 CompletionItem { 569 CompletionItem {
570 label: "inline(…)", 570 label: "inline(…)",
571 source_range: 19..19, 571 source_range: 2..2,
572 delete: 19..19, 572 delete: 2..2,
573 insert: "inline(${0:lint})", 573 insert: "inline(${0:lint})",
574 kind: Attribute, 574 kind: Attribute,
575 lookup: "inline", 575 lookup: "inline",
576 }, 576 },
577 CompletionItem { 577 CompletionItem {
578 label: "link", 578 label: "link",
579 source_range: 19..19, 579 source_range: 2..2,
580 delete: 19..19, 580 delete: 2..2,
581 insert: "link", 581 insert: "link",
582 kind: Attribute, 582 kind: Attribute,
583 }, 583 },
584 CompletionItem { 584 CompletionItem {
585 label: "link_name = \"…\"", 585 label: "link_name = \"…\"",
586 source_range: 19..19, 586 source_range: 2..2,
587 delete: 19..19, 587 delete: 2..2,
588 insert: "link_name = \"${0:symbol_name}\"", 588 insert: "link_name = \"${0:symbol_name}\"",
589 kind: Attribute, 589 kind: Attribute,
590 lookup: "link_name", 590 lookup: "link_name",
591 }, 591 },
592 CompletionItem { 592 CompletionItem {
593 label: "macro_export", 593 label: "macro_export",
594 source_range: 19..19, 594 source_range: 2..2,
595 delete: 19..19, 595 delete: 2..2,
596 insert: "macro_export", 596 insert: "macro_export",
597 kind: Attribute, 597 kind: Attribute,
598 }, 598 },
599 CompletionItem { 599 CompletionItem {
600 label: "macro_use", 600 label: "macro_use",
601 source_range: 19..19, 601 source_range: 2..2,
602 delete: 19..19, 602 delete: 2..2,
603 insert: "macro_use", 603 insert: "macro_use",
604 kind: Attribute, 604 kind: Attribute,
605 }, 605 },
606 CompletionItem { 606 CompletionItem {
607 label: "must_use = \"…\"", 607 label: "must_use = \"…\"",
608 source_range: 19..19, 608 source_range: 2..2,
609 delete: 19..19, 609 delete: 2..2,
610 insert: "must_use = \"${0:reason}\"", 610 insert: "must_use = \"${0:reason}\"",
611 kind: Attribute, 611 kind: Attribute,
612 lookup: "must_use", 612 lookup: "must_use",
613 }, 613 },
614 CompletionItem { 614 CompletionItem {
615 label: "no_mangle", 615 label: "no_mangle",
616 source_range: 19..19, 616 source_range: 2..2,
617 delete: 19..19, 617 delete: 2..2,
618 insert: "no_mangle", 618 insert: "no_mangle",
619 kind: Attribute, 619 kind: Attribute,
620 }, 620 },
621 CompletionItem { 621 CompletionItem {
622 label: "non_exhaustive", 622 label: "non_exhaustive",
623 source_range: 19..19, 623 source_range: 2..2,
624 delete: 19..19, 624 delete: 2..2,
625 insert: "non_exhaustive", 625 insert: "non_exhaustive",
626 kind: Attribute, 626 kind: Attribute,
627 }, 627 },
628 CompletionItem { 628 CompletionItem {
629 label: "path = \"…\"", 629 label: "path = \"…\"",
630 source_range: 19..19, 630 source_range: 2..2,
631 delete: 19..19, 631 delete: 2..2,
632 insert: "path =\"${0:path}\"", 632 insert: "path =\"${0:path}\"",
633 kind: Attribute, 633 kind: Attribute,
634 lookup: "path", 634 lookup: "path",
635 }, 635 },
636 CompletionItem { 636 CompletionItem {
637 label: "proc_macro", 637 label: "proc_macro",
638 source_range: 19..19, 638 source_range: 2..2,
639 delete: 19..19, 639 delete: 2..2,
640 insert: "proc_macro", 640 insert: "proc_macro",
641 kind: Attribute, 641 kind: Attribute,
642 }, 642 },
643 CompletionItem { 643 CompletionItem {
644 label: "proc_macro_attribute", 644 label: "proc_macro_attribute",
645 source_range: 19..19, 645 source_range: 2..2,
646 delete: 19..19, 646 delete: 2..2,
647 insert: "proc_macro_attribute", 647 insert: "proc_macro_attribute",
648 kind: Attribute, 648 kind: Attribute,
649 }, 649 },
650 CompletionItem { 650 CompletionItem {
651 label: "proc_macro_derive(…)", 651 label: "proc_macro_derive(…)",
652 source_range: 19..19, 652 source_range: 2..2,
653 delete: 19..19, 653 delete: 2..2,
654 insert: "proc_macro_derive(${0:Trait})", 654 insert: "proc_macro_derive(${0:Trait})",
655 kind: Attribute, 655 kind: Attribute,
656 lookup: "proc_macro_derive", 656 lookup: "proc_macro_derive",
657 }, 657 },
658 CompletionItem { 658 CompletionItem {
659 label: "repr(…)", 659 label: "repr(…)",
660 source_range: 19..19, 660 source_range: 2..2,
661 delete: 19..19, 661 delete: 2..2,
662 insert: "repr(${0:C})", 662 insert: "repr(${0:C})",
663 kind: Attribute, 663 kind: Attribute,
664 lookup: "repr", 664 lookup: "repr",
665 }, 665 },
666 CompletionItem { 666 CompletionItem {
667 label: "should_panic(…)", 667 label: "should_panic(…)",
668 source_range: 19..19, 668 source_range: 2..2,
669 delete: 19..19, 669 delete: 2..2,
670 insert: "should_panic(expected = \"${0:reason}\")", 670 insert: "should_panic(expected = \"${0:reason}\")",
671 kind: Attribute, 671 kind: Attribute,
672 lookup: "should_panic", 672 lookup: "should_panic",
673 }, 673 },
674 CompletionItem { 674 CompletionItem {
675 label: "target_feature = \"…\"", 675 label: "target_feature = \"…\"",
676 source_range: 19..19, 676 source_range: 2..2,
677 delete: 19..19, 677 delete: 2..2,
678 insert: "target_feature = \"${0:feature}\"", 678 insert: "target_feature = \"${0:feature}\"",
679 kind: Attribute, 679 kind: Attribute,
680 lookup: "target_feature", 680 lookup: "target_feature",
681 }, 681 },
682 CompletionItem { 682 CompletionItem {
683 label: "test", 683 label: "test",
684 source_range: 19..19, 684 source_range: 2..2,
685 delete: 19..19, 685 delete: 2..2,
686 insert: "test", 686 insert: "test",
687 kind: Attribute, 687 kind: Attribute,
688 }, 688 },
689 CompletionItem { 689 CompletionItem {
690 label: "used", 690 label: "used",
691 source_range: 19..19, 691 source_range: 2..2,
692 delete: 19..19, 692 delete: 2..2,
693 insert: "used", 693 insert: "used",
694 kind: Attribute, 694 kind: Attribute,
695 }, 695 },
696 CompletionItem { 696 CompletionItem {
697 label: "warn(…)", 697 label: "warn(…)",
698 source_range: 19..19, 698 source_range: 2..2,
699 delete: 19..19, 699 delete: 2..2,
700 insert: "warn(${0:lint})", 700 insert: "warn(${0:lint})",
701 kind: Attribute, 701 kind: Attribute,
702 lookup: "warn", 702 lookup: "warn",
@@ -732,252 +732,252 @@ mod tests {
732 [ 732 [
733 CompletionItem { 733 CompletionItem {
734 label: "allow(…)", 734 label: "allow(…)",
735 source_range: 20..20, 735 source_range: 3..3,
736 delete: 20..20, 736 delete: 3..3,
737 insert: "allow(${0:lint})", 737 insert: "allow(${0:lint})",
738 kind: Attribute, 738 kind: Attribute,
739 lookup: "allow", 739 lookup: "allow",
740 }, 740 },
741 CompletionItem { 741 CompletionItem {
742 label: "cfg(…)", 742 label: "cfg(…)",
743 source_range: 20..20, 743 source_range: 3..3,
744 delete: 20..20, 744 delete: 3..3,
745 insert: "cfg(${0:predicate})", 745 insert: "cfg(${0:predicate})",
746 kind: Attribute, 746 kind: Attribute,
747 lookup: "cfg", 747 lookup: "cfg",
748 }, 748 },
749 CompletionItem { 749 CompletionItem {
750 label: "cfg_attr(…)", 750 label: "cfg_attr(…)",
751 source_range: 20..20, 751 source_range: 3..3,
752 delete: 20..20, 752 delete: 3..3,
753 insert: "cfg_attr(${1:predicate}, ${0:attr})", 753 insert: "cfg_attr(${1:predicate}, ${0:attr})",
754 kind: Attribute, 754 kind: Attribute,
755 lookup: "cfg_attr", 755 lookup: "cfg_attr",
756 }, 756 },
757 CompletionItem { 757 CompletionItem {
758 label: "deny(…)", 758 label: "deny(…)",
759 source_range: 20..20, 759 source_range: 3..3,
760 delete: 20..20, 760 delete: 3..3,
761 insert: "deny(${0:lint})", 761 insert: "deny(${0:lint})",
762 kind: Attribute, 762 kind: Attribute,
763 lookup: "deny", 763 lookup: "deny",
764 }, 764 },
765 CompletionItem { 765 CompletionItem {
766 label: "deprecated = \"…\"", 766 label: "deprecated = \"…\"",
767 source_range: 20..20, 767 source_range: 3..3,
768 delete: 20..20, 768 delete: 3..3,
769 insert: "deprecated = \"${0:reason}\"", 769 insert: "deprecated = \"${0:reason}\"",
770 kind: Attribute, 770 kind: Attribute,
771 lookup: "deprecated", 771 lookup: "deprecated",
772 }, 772 },
773 CompletionItem { 773 CompletionItem {
774 label: "derive(…)", 774 label: "derive(…)",
775 source_range: 20..20, 775 source_range: 3..3,
776 delete: 20..20, 776 delete: 3..3,
777 insert: "derive(${0:Debug})", 777 insert: "derive(${0:Debug})",
778 kind: Attribute, 778 kind: Attribute,
779 lookup: "derive", 779 lookup: "derive",
780 }, 780 },
781 CompletionItem { 781 CompletionItem {
782 label: "doc = \"…\"", 782 label: "doc = \"…\"",
783 source_range: 20..20, 783 source_range: 3..3,
784 delete: 20..20, 784 delete: 3..3,
785 insert: "doc = \"${0:docs}\"", 785 insert: "doc = \"${0:docs}\"",
786 kind: Attribute, 786 kind: Attribute,
787 lookup: "doc", 787 lookup: "doc",
788 }, 788 },
789 CompletionItem { 789 CompletionItem {
790 label: "feature(…)", 790 label: "feature(…)",
791 source_range: 20..20, 791 source_range: 3..3,
792 delete: 20..20, 792 delete: 3..3,
793 insert: "feature(${0:flag})", 793 insert: "feature(${0:flag})",
794 kind: Attribute, 794 kind: Attribute,
795 lookup: "feature", 795 lookup: "feature",
796 }, 796 },
797 CompletionItem { 797 CompletionItem {
798 label: "forbid(…)", 798 label: "forbid(…)",
799 source_range: 20..20, 799 source_range: 3..3,
800 delete: 20..20, 800 delete: 3..3,
801 insert: "forbid(${0:lint})", 801 insert: "forbid(${0:lint})",
802 kind: Attribute, 802 kind: Attribute,
803 lookup: "forbid", 803 lookup: "forbid",
804 }, 804 },
805 CompletionItem { 805 CompletionItem {
806 label: "global_allocator", 806 label: "global_allocator",
807 source_range: 20..20, 807 source_range: 3..3,
808 delete: 20..20, 808 delete: 3..3,
809 insert: "global_allocator", 809 insert: "global_allocator",
810 kind: Attribute, 810 kind: Attribute,
811 }, 811 },
812 CompletionItem { 812 CompletionItem {
813 label: "ignore(…)", 813 label: "ignore(…)",
814 source_range: 20..20, 814 source_range: 3..3,
815 delete: 20..20, 815 delete: 3..3,
816 insert: "ignore(${0:lint})", 816 insert: "ignore(${0:lint})",
817 kind: Attribute, 817 kind: Attribute,
818 lookup: "ignore", 818 lookup: "ignore",
819 }, 819 },
820 CompletionItem { 820 CompletionItem {
821 label: "inline(…)", 821 label: "inline(…)",
822 source_range: 20..20, 822 source_range: 3..3,
823 delete: 20..20, 823 delete: 3..3,
824 insert: "inline(${0:lint})", 824 insert: "inline(${0:lint})",
825 kind: Attribute, 825 kind: Attribute,
826 lookup: "inline", 826 lookup: "inline",
827 }, 827 },
828 CompletionItem { 828 CompletionItem {
829 label: "link", 829 label: "link",
830 source_range: 20..20, 830 source_range: 3..3,
831 delete: 20..20, 831 delete: 3..3,
832 insert: "link", 832 insert: "link",
833 kind: Attribute, 833 kind: Attribute,
834 }, 834 },
835 CompletionItem { 835 CompletionItem {
836 label: "link_name = \"…\"", 836 label: "link_name = \"…\"",
837 source_range: 20..20, 837 source_range: 3..3,
838 delete: 20..20, 838 delete: 3..3,
839 insert: "link_name = \"${0:symbol_name}\"", 839 insert: "link_name = \"${0:symbol_name}\"",
840 kind: Attribute, 840 kind: Attribute,
841 lookup: "link_name", 841 lookup: "link_name",
842 }, 842 },
843 CompletionItem { 843 CompletionItem {
844 label: "macro_export", 844 label: "macro_export",
845 source_range: 20..20, 845 source_range: 3..3,
846 delete: 20..20, 846 delete: 3..3,
847 insert: "macro_export", 847 insert: "macro_export",
848 kind: Attribute, 848 kind: Attribute,
849 }, 849 },
850 CompletionItem { 850 CompletionItem {
851 label: "macro_use", 851 label: "macro_use",
852 source_range: 20..20, 852 source_range: 3..3,
853 delete: 20..20, 853 delete: 3..3,
854 insert: "macro_use", 854 insert: "macro_use",
855 kind: Attribute, 855 kind: Attribute,
856 }, 856 },
857 CompletionItem { 857 CompletionItem {
858 label: "must_use = \"…\"", 858 label: "must_use = \"…\"",
859 source_range: 20..20, 859 source_range: 3..3,
860 delete: 20..20, 860 delete: 3..3,
861 insert: "must_use = \"${0:reason}\"", 861 insert: "must_use = \"${0:reason}\"",
862 kind: Attribute, 862 kind: Attribute,
863 lookup: "must_use", 863 lookup: "must_use",
864 }, 864 },
865 CompletionItem { 865 CompletionItem {
866 label: "no_mangle", 866 label: "no_mangle",
867 source_range: 20..20, 867 source_range: 3..3,
868 delete: 20..20, 868 delete: 3..3,
869 insert: "no_mangle", 869 insert: "no_mangle",
870 kind: Attribute, 870 kind: Attribute,
871 }, 871 },
872 CompletionItem { 872 CompletionItem {
873 label: "no_std", 873 label: "no_std",
874 source_range: 20..20, 874 source_range: 3..3,
875 delete: 20..20, 875 delete: 3..3,
876 insert: "no_std", 876 insert: "no_std",
877 kind: Attribute, 877 kind: Attribute,
878 }, 878 },
879 CompletionItem { 879 CompletionItem {
880 label: "non_exhaustive", 880 label: "non_exhaustive",
881 source_range: 20..20, 881 source_range: 3..3,
882 delete: 20..20, 882 delete: 3..3,
883 insert: "non_exhaustive", 883 insert: "non_exhaustive",
884 kind: Attribute, 884 kind: Attribute,
885 }, 885 },
886 CompletionItem { 886 CompletionItem {
887 label: "panic_handler", 887 label: "panic_handler",
888 source_range: 20..20, 888 source_range: 3..3,
889 delete: 20..20, 889 delete: 3..3,
890 insert: "panic_handler", 890 insert: "panic_handler",
891 kind: Attribute, 891 kind: Attribute,
892 }, 892 },
893 CompletionItem { 893 CompletionItem {
894 label: "path = \"…\"", 894 label: "path = \"…\"",
895 source_range: 20..20, 895 source_range: 3..3,
896 delete: 20..20, 896 delete: 3..3,
897 insert: "path =\"${0:path}\"", 897 insert: "path =\"${0:path}\"",
898 kind: Attribute, 898 kind: Attribute,
899 lookup: "path", 899 lookup: "path",
900 }, 900 },
901 CompletionItem { 901 CompletionItem {
902 label: "proc_macro", 902 label: "proc_macro",
903 source_range: 20..20, 903 source_range: 3..3,
904 delete: 20..20, 904 delete: 3..3,
905 insert: "proc_macro", 905 insert: "proc_macro",
906 kind: Attribute, 906 kind: Attribute,
907 }, 907 },
908 CompletionItem { 908 CompletionItem {
909 label: "proc_macro_attribute", 909 label: "proc_macro_attribute",
910 source_range: 20..20, 910 source_range: 3..3,
911 delete: 20..20, 911 delete: 3..3,
912 insert: "proc_macro_attribute", 912 insert: "proc_macro_attribute",
913 kind: Attribute, 913 kind: Attribute,
914 }, 914 },
915 CompletionItem { 915 CompletionItem {
916 label: "proc_macro_derive(…)", 916 label: "proc_macro_derive(…)",
917 source_range: 20..20, 917 source_range: 3..3,
918 delete: 20..20, 918 delete: 3..3,
919 insert: "proc_macro_derive(${0:Trait})", 919 insert: "proc_macro_derive(${0:Trait})",
920 kind: Attribute, 920 kind: Attribute,
921 lookup: "proc_macro_derive", 921 lookup: "proc_macro_derive",
922 }, 922 },
923 CompletionItem { 923 CompletionItem {
924 label: "recursion_limit = …", 924 label: "recursion_limit = …",
925 source_range: 20..20, 925 source_range: 3..3,
926 delete: 20..20, 926 delete: 3..3,
927 insert: "recursion_limit = ${0:128}", 927 insert: "recursion_limit = ${0:128}",
928 kind: Attribute, 928 kind: Attribute,
929 lookup: "recursion_limit", 929 lookup: "recursion_limit",
930 }, 930 },
931 CompletionItem { 931 CompletionItem {
932 label: "repr(…)", 932 label: "repr(…)",
933 source_range: 20..20, 933 source_range: 3..3,
934 delete: 20..20, 934 delete: 3..3,
935 insert: "repr(${0:C})", 935 insert: "repr(${0:C})",
936 kind: Attribute, 936 kind: Attribute,
937 lookup: "repr", 937 lookup: "repr",
938 }, 938 },
939 CompletionItem { 939 CompletionItem {
940 label: "should_panic(…)", 940 label: "should_panic(…)",
941 source_range: 20..20, 941 source_range: 3..3,
942 delete: 20..20, 942 delete: 3..3,
943 insert: "should_panic(expected = \"${0:reason}\")", 943 insert: "should_panic(expected = \"${0:reason}\")",
944 kind: Attribute, 944 kind: Attribute,
945 lookup: "should_panic", 945 lookup: "should_panic",
946 }, 946 },
947 CompletionItem { 947 CompletionItem {
948 label: "target_feature = \"…\"", 948 label: "target_feature = \"…\"",
949 source_range: 20..20, 949 source_range: 3..3,
950 delete: 20..20, 950 delete: 3..3,
951 insert: "target_feature = \"${0:feature}\"", 951 insert: "target_feature = \"${0:feature}\"",
952 kind: Attribute, 952 kind: Attribute,
953 lookup: "target_feature", 953 lookup: "target_feature",
954 }, 954 },
955 CompletionItem { 955 CompletionItem {
956 label: "test", 956 label: "test",
957 source_range: 20..20, 957 source_range: 3..3,
958 delete: 20..20, 958 delete: 3..3,
959 insert: "test", 959 insert: "test",
960 kind: Attribute, 960 kind: Attribute,
961 }, 961 },
962 CompletionItem { 962 CompletionItem {
963 label: "used", 963 label: "used",
964 source_range: 20..20, 964 source_range: 3..3,
965 delete: 20..20, 965 delete: 3..3,
966 insert: "used", 966 insert: "used",
967 kind: Attribute, 967 kind: Attribute,
968 }, 968 },
969 CompletionItem { 969 CompletionItem {
970 label: "warn(…)", 970 label: "warn(…)",
971 source_range: 20..20, 971 source_range: 3..3,
972 delete: 20..20, 972 delete: 3..3,
973 insert: "warn(${0:lint})", 973 insert: "warn(${0:lint})",
974 kind: Attribute, 974 kind: Attribute,
975 lookup: "warn", 975 lookup: "warn",
976 }, 976 },
977 CompletionItem { 977 CompletionItem {
978 label: "windows_subsystem = \"…\"", 978 label: "windows_subsystem = \"…\"",
979 source_range: 20..20, 979 source_range: 3..3,
980 delete: 20..20, 980 delete: 3..3,
981 insert: "windows_subsystem = \"${0:subsystem}\"", 981 insert: "windows_subsystem = \"${0:subsystem}\"",
982 kind: Attribute, 982 kind: Attribute,
983 lookup: "windows_subsystem", 983 lookup: "windows_subsystem",
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 05f825c6f..ee4e24fca 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -94,8 +94,8 @@ mod tests {
94 [ 94 [
95 CompletionItem { 95 CompletionItem {
96 label: "the_field", 96 label: "the_field",
97 source_range: 94..94, 97 source_range: 45..45,
98 delete: 94..94, 98 delete: 45..45,
99 insert: "the_field", 99 insert: "the_field",
100 kind: Field, 100 kind: Field,
101 detail: "u32", 101 detail: "u32",
@@ -125,8 +125,8 @@ mod tests {
125 [ 125 [
126 CompletionItem { 126 CompletionItem {
127 label: "foo()", 127 label: "foo()",
128 source_range: 187..187, 128 source_range: 102..102,
129 delete: 187..187, 129 delete: 102..102,
130 insert: "foo()$0", 130 insert: "foo()$0",
131 kind: Method, 131 kind: Method,
132 lookup: "foo", 132 lookup: "foo",
@@ -134,8 +134,8 @@ mod tests {
134 }, 134 },
135 CompletionItem { 135 CompletionItem {
136 label: "the_field", 136 label: "the_field",
137 source_range: 187..187, 137 source_range: 102..102,
138 delete: 187..187, 138 delete: 102..102,
139 insert: "the_field", 139 insert: "the_field",
140 kind: Field, 140 kind: Field,
141 detail: "(u32,)", 141 detail: "(u32,)",
@@ -165,8 +165,8 @@ mod tests {
165 [ 165 [
166 CompletionItem { 166 CompletionItem {
167 label: "foo()", 167 label: "foo()",
168 source_range: 126..126, 168 source_range: 77..77,
169 delete: 126..126, 169 delete: 77..77,
170 insert: "foo()$0", 170 insert: "foo()$0",
171 kind: Method, 171 kind: Method,
172 lookup: "foo", 172 lookup: "foo",
@@ -174,8 +174,8 @@ mod tests {
174 }, 174 },
175 CompletionItem { 175 CompletionItem {
176 label: "the_field", 176 label: "the_field",
177 source_range: 126..126, 177 source_range: 77..77,
178 delete: 126..126, 178 delete: 77..77,
179 insert: "the_field", 179 insert: "the_field",
180 kind: Field, 180 kind: Field,
181 detail: "(u32, i32)", 181 detail: "(u32, i32)",
@@ -222,24 +222,24 @@ mod tests {
222 [ 222 [
223 CompletionItem { 223 CompletionItem {
224 label: "crate_field", 224 label: "crate_field",
225 source_range: 313..313, 225 source_range: 192..192,
226 delete: 313..313, 226 delete: 192..192,
227 insert: "crate_field", 227 insert: "crate_field",
228 kind: Field, 228 kind: Field,
229 detail: "u32", 229 detail: "u32",
230 }, 230 },
231 CompletionItem { 231 CompletionItem {
232 label: "pub_field", 232 label: "pub_field",
233 source_range: 313..313, 233 source_range: 192..192,
234 delete: 313..313, 234 delete: 192..192,
235 insert: "pub_field", 235 insert: "pub_field",
236 kind: Field, 236 kind: Field,
237 detail: "u32", 237 detail: "u32",
238 }, 238 },
239 CompletionItem { 239 CompletionItem {
240 label: "super_field", 240 label: "super_field",
241 source_range: 313..313, 241 source_range: 192..192,
242 delete: 313..313, 242 delete: 192..192,
243 insert: "super_field", 243 insert: "super_field",
244 kind: Field, 244 kind: Field,
245 detail: "u32", 245 detail: "u32",
@@ -268,16 +268,16 @@ mod tests {
268 [ 268 [
269 CompletionItem { 269 CompletionItem {
270 label: "field", 270 label: "field",
271 source_range: 140..140, 271 source_range: 67..67,
272 delete: 140..140, 272 delete: 67..67,
273 insert: "field", 273 insert: "field",
274 kind: Field, 274 kind: Field,
275 detail: "u8", 275 detail: "u8",
276 }, 276 },
277 CompletionItem { 277 CompletionItem {
278 label: "other", 278 label: "other",
279 source_range: 140..140, 279 source_range: 67..67,
280 delete: 140..140, 280 delete: 67..67,
281 insert: "other", 281 insert: "other",
282 kind: Field, 282 kind: Field,
283 detail: "u16", 283 detail: "u16",
@@ -305,8 +305,8 @@ mod tests {
305 [ 305 [
306 CompletionItem { 306 CompletionItem {
307 label: "the_method()", 307 label: "the_method()",
308 source_range: 144..144, 308 source_range: 71..71,
309 delete: 144..144, 309 delete: 71..71,
310 insert: "the_method()$0", 310 insert: "the_method()$0",
311 kind: Method, 311 kind: Method,
312 lookup: "the_method", 312 lookup: "the_method",
@@ -338,8 +338,8 @@ mod tests {
338 [ 338 [
339 CompletionItem { 339 CompletionItem {
340 label: "the_method()", 340 label: "the_method()",
341 source_range: 243..243, 341 source_range: 134..134,
342 delete: 243..243, 342 delete: 134..134,
343 insert: "the_method()$0", 343 insert: "the_method()$0",
344 kind: Method, 344 kind: Method,
345 lookup: "the_method", 345 lookup: "the_method",
@@ -371,8 +371,8 @@ mod tests {
371 [ 371 [
372 CompletionItem { 372 CompletionItem {
373 label: "the_method()", 373 label: "the_method()",
374 source_range: 256..256, 374 source_range: 147..147,
375 delete: 256..256, 375 delete: 147..147,
376 insert: "the_method()$0", 376 insert: "the_method()$0",
377 kind: Method, 377 kind: Method,
378 lookup: "the_method", 378 lookup: "the_method",
@@ -400,8 +400,8 @@ mod tests {
400 [ 400 [
401 CompletionItem { 401 CompletionItem {
402 label: "the_method()", 402 label: "the_method()",
403 source_range: 151..151, 403 source_range: 90..90,
404 delete: 151..151, 404 delete: 90..90,
405 insert: "the_method()$0", 405 insert: "the_method()$0",
406 kind: Method, 406 kind: Method,
407 lookup: "the_method", 407 lookup: "the_method",
@@ -429,8 +429,8 @@ mod tests {
429 [ 429 [
430 CompletionItem { 430 CompletionItem {
431 label: "the_method()", 431 label: "the_method()",
432 source_range: 155..155, 432 source_range: 94..94,
433 delete: 155..155, 433 delete: 94..94,
434 insert: "the_method()$0", 434 insert: "the_method()$0",
435 kind: Method, 435 kind: Method,
436 lookup: "the_method", 436 lookup: "the_method",
@@ -461,8 +461,8 @@ mod tests {
461 [ 461 [
462 CompletionItem { 462 CompletionItem {
463 label: "the_method()", 463 label: "the_method()",
464 source_range: 219..219, 464 source_range: 122..122,
465 delete: 219..219, 465 delete: 122..122,
466 insert: "the_method()$0", 466 insert: "the_method()$0",
467 kind: Method, 467 kind: Method,
468 lookup: "the_method", 468 lookup: "the_method",
@@ -513,8 +513,8 @@ mod tests {
513 [ 513 [
514 CompletionItem { 514 CompletionItem {
515 label: "the_method()", 515 label: "the_method()",
516 source_range: 249..249, 516 source_range: 128..128,
517 delete: 249..249, 517 delete: 128..128,
518 insert: "the_method()$0", 518 insert: "the_method()$0",
519 kind: Method, 519 kind: Method,
520 lookup: "the_method", 520 lookup: "the_method",
@@ -540,16 +540,16 @@ mod tests {
540 [ 540 [
541 CompletionItem { 541 CompletionItem {
542 label: "0", 542 label: "0",
543 source_range: 75..75, 543 source_range: 38..38,
544 delete: 75..75, 544 delete: 38..38,
545 insert: "0", 545 insert: "0",
546 kind: Field, 546 kind: Field,
547 detail: "i32", 547 detail: "i32",
548 }, 548 },
549 CompletionItem { 549 CompletionItem {
550 label: "1", 550 label: "1",
551 source_range: 75..75, 551 source_range: 38..38,
552 delete: 75..75, 552 delete: 38..38,
553 insert: "1", 553 insert: "1",
554 kind: Field, 554 kind: Field,
555 detail: "f64", 555 detail: "f64",
@@ -583,8 +583,8 @@ mod tests {
583 [ 583 [
584 CompletionItem { 584 CompletionItem {
585 label: "blah()", 585 label: "blah()",
586 source_range: 299..300, 586 source_range: 190..191,
587 delete: 299..300, 587 delete: 190..191,
588 insert: "blah()$0", 588 insert: "blah()$0",
589 kind: Method, 589 kind: Method,
590 lookup: "blah", 590 lookup: "blah",
@@ -610,8 +610,8 @@ mod tests {
610 [ 610 [
611 CompletionItem { 611 CompletionItem {
612 label: "the_field", 612 label: "the_field",
613 source_range: 106..106, 613 source_range: 69..69,
614 delete: 106..106, 614 delete: 69..69,
615 insert: "the_field", 615 insert: "the_field",
616 kind: Field, 616 kind: Field,
617 detail: "u32", 617 detail: "u32",
@@ -676,15 +676,15 @@ mod tests {
676 [ 676 [
677 CompletionItem { 677 CompletionItem {
678 label: "A", 678 label: "A",
679 source_range: 217..217, 679 source_range: 120..120,
680 delete: 217..217, 680 delete: 120..120,
681 insert: "A", 681 insert: "A",
682 kind: Const, 682 kind: Const,
683 }, 683 },
684 CompletionItem { 684 CompletionItem {
685 label: "b", 685 label: "b",
686 source_range: 217..217, 686 source_range: 120..120,
687 delete: 217..217, 687 delete: 120..120,
688 insert: "b", 688 insert: "b",
689 kind: Module, 689 kind: Module,
690 }, 690 },
@@ -709,8 +709,8 @@ mod tests {
709 [ 709 [
710 CompletionItem { 710 CompletionItem {
711 label: "the_field", 711 label: "the_field",
712 source_range: 156..157, 712 source_range: 91..92,
713 delete: 156..157, 713 delete: 91..92,
714 insert: "the_field", 714 insert: "the_field",
715 kind: Field, 715 kind: Field,
716 detail: "u32", 716 detail: "u32",
@@ -736,8 +736,8 @@ mod tests {
736 [ 736 [
737 CompletionItem { 737 CompletionItem {
738 label: "the_field", 738 label: "the_field",
739 source_range: 156..157, 739 source_range: 91..92,
740 delete: 156..157, 740 delete: 91..92,
741 insert: "the_field", 741 insert: "the_field",
742 kind: Field, 742 kind: Field,
743 detail: "u32", 743 detail: "u32",
@@ -764,8 +764,8 @@ mod tests {
764 [ 764 [
765 CompletionItem { 765 CompletionItem {
766 label: "the_field", 766 label: "the_field",
767 source_range: 156..156, 767 source_range: 91..91,
768 delete: 156..156, 768 delete: 91..91,
769 insert: "the_field", 769 insert: "the_field",
770 kind: Field, 770 kind: Field,
771 detail: "u32", 771 detail: "u32",
@@ -791,8 +791,8 @@ mod tests {
791 [ 791 [
792 CompletionItem { 792 CompletionItem {
793 label: "the_field", 793 label: "the_field",
794 source_range: 162..163, 794 source_range: 97..98,
795 delete: 162..163, 795 delete: 97..98,
796 insert: "the_field", 796 insert: "the_field",
797 kind: Field, 797 kind: Field,
798 detail: "u32", 798 detail: "u32",
@@ -828,8 +828,8 @@ mod tests {
828 [ 828 [
829 CompletionItem { 829 CompletionItem {
830 label: "the_field", 830 label: "the_field",
831 source_range: 552..552, 831 source_range: 327..327,
832 delete: 552..552, 832 delete: 327..327,
833 insert: "the_field", 833 insert: "the_field",
834 kind: Field, 834 kind: Field,
835 detail: "u32", 835 detail: "u32",
@@ -858,8 +858,8 @@ mod tests {
858 [ 858 [
859 CompletionItem { 859 CompletionItem {
860 label: "the_method()", 860 label: "the_method()",
861 source_range: 201..201, 861 source_range: 116..116,
862 delete: 201..201, 862 delete: 116..116,
863 insert: "the_method()$0", 863 insert: "the_method()$0",
864 kind: Method, 864 kind: Method,
865 lookup: "the_method", 865 lookup: "the_method",
diff --git a/crates/ra_ide/src/completion/complete_fn_param.rs b/crates/ra_ide/src/completion/complete_fn_param.rs
index a661932a3..f5573ddf7 100644
--- a/crates/ra_ide/src/completion/complete_fn_param.rs
+++ b/crates/ra_ide/src/completion/complete_fn_param.rs
@@ -75,8 +75,8 @@ mod tests {
75 [ 75 [
76 CompletionItem { 76 CompletionItem {
77 label: "file_id: FileId", 77 label: "file_id: FileId",
78 source_range: 110..114, 78 source_range: 61..65,
79 delete: 110..114, 79 delete: 61..65,
80 insert: "file_id: FileId", 80 insert: "file_id: FileId",
81 lookup: "file_id", 81 lookup: "file_id",
82 }, 82 },
@@ -99,8 +99,8 @@ mod tests {
99 [ 99 [
100 CompletionItem { 100 CompletionItem {
101 label: "file_id: FileId", 101 label: "file_id: FileId",
102 source_range: 110..114, 102 source_range: 61..65,
103 delete: 110..114, 103 delete: 61..65,
104 insert: "file_id: FileId", 104 insert: "file_id: FileId",
105 lookup: "file_id", 105 lookup: "file_id",
106 }, 106 },
@@ -126,8 +126,8 @@ mod tests {
126 [ 126 [
127 CompletionItem { 127 CompletionItem {
128 label: "file_id: FileId", 128 label: "file_id: FileId",
129 source_range: 289..293, 129 source_range: 208..212,
130 delete: 289..293, 130 delete: 208..212,
131 insert: "file_id: FileId", 131 insert: "file_id: FileId",
132 lookup: "file_id", 132 lookup: "file_id",
133 }, 133 },
diff --git a/crates/ra_ide/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs
index fdd9e928b..367e2bbce 100644
--- a/crates/ra_ide/src/completion/complete_pattern.rs
+++ b/crates/ra_ide/src/completion/complete_pattern.rs
@@ -63,37 +63,37 @@ mod tests {
63 [ 63 [
64 CompletionItem { 64 CompletionItem {
65 label: "Bar", 65 label: "Bar",
66 source_range: 246..246, 66 source_range: 137..137,
67 delete: 246..246, 67 delete: 137..137,
68 insert: "Bar", 68 insert: "Bar",
69 kind: Struct, 69 kind: Struct,
70 }, 70 },
71 CompletionItem { 71 CompletionItem {
72 label: "E", 72 label: "E",
73 source_range: 246..246, 73 source_range: 137..137,
74 delete: 246..246, 74 delete: 137..137,
75 insert: "E", 75 insert: "E",
76 kind: Enum, 76 kind: Enum,
77 }, 77 },
78 CompletionItem { 78 CompletionItem {
79 label: "X", 79 label: "X",
80 source_range: 246..246, 80 source_range: 137..137,
81 delete: 246..246, 81 delete: 137..137,
82 insert: "X", 82 insert: "X",
83 kind: EnumVariant, 83 kind: EnumVariant,
84 detail: "()", 84 detail: "()",
85 }, 85 },
86 CompletionItem { 86 CompletionItem {
87 label: "Z", 87 label: "Z",
88 source_range: 246..246, 88 source_range: 137..137,
89 delete: 246..246, 89 delete: 137..137,
90 insert: "Z", 90 insert: "Z",
91 kind: Const, 91 kind: Const,
92 }, 92 },
93 CompletionItem { 93 CompletionItem {
94 label: "m", 94 label: "m",
95 source_range: 246..246, 95 source_range: 137..137,
96 delete: 246..246, 96 delete: 137..137,
97 insert: "m", 97 insert: "m",
98 kind: Module, 98 kind: Module,
99 }, 99 },
@@ -119,15 +119,15 @@ mod tests {
119 [ 119 [
120 CompletionItem { 120 CompletionItem {
121 label: "E", 121 label: "E",
122 source_range: 151..151, 122 source_range: 90..90,
123 delete: 151..151, 123 delete: 90..90,
124 insert: "E", 124 insert: "E",
125 kind: Enum, 125 kind: Enum,
126 }, 126 },
127 CompletionItem { 127 CompletionItem {
128 label: "m!(…)", 128 label: "m!(…)",
129 source_range: 151..151, 129 source_range: 90..90,
130 delete: 151..151, 130 delete: 90..90,
131 insert: "m!($0)", 131 insert: "m!($0)",
132 kind: Macro, 132 kind: Macro,
133 detail: "macro_rules! m", 133 detail: "macro_rules! m",
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs
index b878aeb0a..3bd64804f 100644
--- a/crates/ra_ide/src/completion/complete_postfix.rs
+++ b/crates/ra_ide/src/completion/complete_postfix.rs
@@ -260,64 +260,64 @@ mod tests {
260 [ 260 [
261 CompletionItem { 261 CompletionItem {
262 label: "box", 262 label: "box",
263 source_range: 89..89, 263 source_range: 40..40,
264 delete: 85..89, 264 delete: 36..40,
265 insert: "Box::new(bar)", 265 insert: "Box::new(bar)",
266 detail: "Box::new(expr)", 266 detail: "Box::new(expr)",
267 }, 267 },
268 CompletionItem { 268 CompletionItem {
269 label: "call", 269 label: "call",
270 source_range: 89..89, 270 source_range: 40..40,
271 delete: 85..89, 271 delete: 36..40,
272 insert: "${1}(bar)", 272 insert: "${1}(bar)",
273 detail: "function(expr)", 273 detail: "function(expr)",
274 }, 274 },
275 CompletionItem { 275 CompletionItem {
276 label: "dbg", 276 label: "dbg",
277 source_range: 89..89, 277 source_range: 40..40,
278 delete: 85..89, 278 delete: 36..40,
279 insert: "dbg!(bar)", 279 insert: "dbg!(bar)",
280 detail: "dbg!(expr)", 280 detail: "dbg!(expr)",
281 }, 281 },
282 CompletionItem { 282 CompletionItem {
283 label: "if", 283 label: "if",
284 source_range: 89..89, 284 source_range: 40..40,
285 delete: 85..89, 285 delete: 36..40,
286 insert: "if bar {\n $0\n}", 286 insert: "if bar {\n $0\n}",
287 detail: "if expr {}", 287 detail: "if expr {}",
288 }, 288 },
289 CompletionItem { 289 CompletionItem {
290 label: "match", 290 label: "match",
291 source_range: 89..89, 291 source_range: 40..40,
292 delete: 85..89, 292 delete: 36..40,
293 insert: "match bar {\n ${1:_} => {$0\\},\n}", 293 insert: "match bar {\n ${1:_} => {$0\\},\n}",
294 detail: "match expr {}", 294 detail: "match expr {}",
295 }, 295 },
296 CompletionItem { 296 CompletionItem {
297 label: "not", 297 label: "not",
298 source_range: 89..89, 298 source_range: 40..40,
299 delete: 85..89, 299 delete: 36..40,
300 insert: "!bar", 300 insert: "!bar",
301 detail: "!expr", 301 detail: "!expr",
302 }, 302 },
303 CompletionItem { 303 CompletionItem {
304 label: "ref", 304 label: "ref",
305 source_range: 89..89, 305 source_range: 40..40,
306 delete: 85..89, 306 delete: 36..40,
307 insert: "&bar", 307 insert: "&bar",
308 detail: "&expr", 308 detail: "&expr",
309 }, 309 },
310 CompletionItem { 310 CompletionItem {
311 label: "refm", 311 label: "refm",
312 source_range: 89..89, 312 source_range: 40..40,
313 delete: 85..89, 313 delete: 36..40,
314 insert: "&mut bar", 314 insert: "&mut bar",
315 detail: "&mut expr", 315 detail: "&mut expr",
316 }, 316 },
317 CompletionItem { 317 CompletionItem {
318 label: "while", 318 label: "while",
319 source_range: 89..89, 319 source_range: 40..40,
320 delete: 85..89, 320 delete: 36..40,
321 insert: "while bar {\n $0\n}", 321 insert: "while bar {\n $0\n}",
322 detail: "while expr {}", 322 detail: "while expr {}",
323 }, 323 },
@@ -346,64 +346,64 @@ mod tests {
346 [ 346 [
347 CompletionItem { 347 CompletionItem {
348 label: "box", 348 label: "box",
349 source_range: 210..210, 349 source_range: 97..97,
350 delete: 206..210, 350 delete: 93..97,
351 insert: "Box::new(bar)", 351 insert: "Box::new(bar)",
352 detail: "Box::new(expr)", 352 detail: "Box::new(expr)",
353 }, 353 },
354 CompletionItem { 354 CompletionItem {
355 label: "call", 355 label: "call",
356 source_range: 210..210, 356 source_range: 97..97,
357 delete: 206..210, 357 delete: 93..97,
358 insert: "${1}(bar)", 358 insert: "${1}(bar)",
359 detail: "function(expr)", 359 detail: "function(expr)",
360 }, 360 },
361 CompletionItem { 361 CompletionItem {
362 label: "dbg", 362 label: "dbg",
363 source_range: 210..210, 363 source_range: 97..97,
364 delete: 206..210, 364 delete: 93..97,
365 insert: "dbg!(bar)", 365 insert: "dbg!(bar)",
366 detail: "dbg!(expr)", 366 detail: "dbg!(expr)",
367 }, 367 },
368 CompletionItem { 368 CompletionItem {
369 label: "ifl", 369 label: "ifl",
370 source_range: 210..210, 370 source_range: 97..97,
371 delete: 206..210, 371 delete: 93..97,
372 insert: "if let Some($1) = bar {\n $0\n}", 372 insert: "if let Some($1) = bar {\n $0\n}",
373 detail: "if let Some {}", 373 detail: "if let Some {}",
374 }, 374 },
375 CompletionItem { 375 CompletionItem {
376 label: "match", 376 label: "match",
377 source_range: 210..210, 377 source_range: 97..97,
378 delete: 206..210, 378 delete: 93..97,
379 insert: "match bar {\n Some(${1:_}) => {$2\\},\n None => {$0\\},\n}", 379 insert: "match bar {\n Some(${1:_}) => {$2\\},\n None => {$0\\},\n}",
380 detail: "match expr {}", 380 detail: "match expr {}",
381 }, 381 },
382 CompletionItem { 382 CompletionItem {
383 label: "not", 383 label: "not",
384 source_range: 210..210, 384 source_range: 97..97,
385 delete: 206..210, 385 delete: 93..97,
386 insert: "!bar", 386 insert: "!bar",
387 detail: "!expr", 387 detail: "!expr",
388 }, 388 },
389 CompletionItem { 389 CompletionItem {
390 label: "ref", 390 label: "ref",
391 source_range: 210..210, 391 source_range: 97..97,
392 delete: 206..210, 392 delete: 93..97,
393 insert: "&bar", 393 insert: "&bar",
394 detail: "&expr", 394 detail: "&expr",
395 }, 395 },
396 CompletionItem { 396 CompletionItem {
397 label: "refm", 397 label: "refm",
398 source_range: 210..210, 398 source_range: 97..97,
399 delete: 206..210, 399 delete: 93..97,
400 insert: "&mut bar", 400 insert: "&mut bar",
401 detail: "&mut expr", 401 detail: "&mut expr",
402 }, 402 },
403 CompletionItem { 403 CompletionItem {
404 label: "while", 404 label: "while",
405 source_range: 210..210, 405 source_range: 97..97,
406 delete: 206..210, 406 delete: 93..97,
407 insert: "while let Some($1) = bar {\n $0\n}", 407 insert: "while let Some($1) = bar {\n $0\n}",
408 detail: "while let Some {}", 408 detail: "while let Some {}",
409 }, 409 },
@@ -432,64 +432,64 @@ mod tests {
432 [ 432 [
433 CompletionItem { 433 CompletionItem {
434 label: "box", 434 label: "box",
435 source_range: 211..211, 435 source_range: 98..98,
436 delete: 207..211, 436 delete: 94..98,
437 insert: "Box::new(bar)", 437 insert: "Box::new(bar)",
438 detail: "Box::new(expr)", 438 detail: "Box::new(expr)",
439 }, 439 },
440 CompletionItem { 440 CompletionItem {
441 label: "call", 441 label: "call",
442 source_range: 211..211, 442 source_range: 98..98,
443 delete: 207..211, 443 delete: 94..98,
444 insert: "${1}(bar)", 444 insert: "${1}(bar)",
445 detail: "function(expr)", 445 detail: "function(expr)",
446 }, 446 },
447 CompletionItem { 447 CompletionItem {
448 label: "dbg", 448 label: "dbg",
449 source_range: 211..211, 449 source_range: 98..98,
450 delete: 207..211, 450 delete: 94..98,
451 insert: "dbg!(bar)", 451 insert: "dbg!(bar)",
452 detail: "dbg!(expr)", 452 detail: "dbg!(expr)",
453 }, 453 },
454 CompletionItem { 454 CompletionItem {
455 label: "ifl", 455 label: "ifl",
456 source_range: 211..211, 456 source_range: 98..98,
457 delete: 207..211, 457 delete: 94..98,
458 insert: "if let Ok($1) = bar {\n $0\n}", 458 insert: "if let Ok($1) = bar {\n $0\n}",
459 detail: "if let Ok {}", 459 detail: "if let Ok {}",
460 }, 460 },
461 CompletionItem { 461 CompletionItem {
462 label: "match", 462 label: "match",
463 source_range: 211..211, 463 source_range: 98..98,
464 delete: 207..211, 464 delete: 94..98,
465 insert: "match bar {\n Ok(${1:_}) => {$2\\},\n Err(${3:_}) => {$0\\},\n}", 465 insert: "match bar {\n Ok(${1:_}) => {$2\\},\n Err(${3:_}) => {$0\\},\n}",
466 detail: "match expr {}", 466 detail: "match expr {}",
467 }, 467 },
468 CompletionItem { 468 CompletionItem {
469 label: "not", 469 label: "not",
470 source_range: 211..211, 470 source_range: 98..98,
471 delete: 207..211, 471 delete: 94..98,
472 insert: "!bar", 472 insert: "!bar",
473 detail: "!expr", 473 detail: "!expr",
474 }, 474 },
475 CompletionItem { 475 CompletionItem {
476 label: "ref", 476 label: "ref",
477 source_range: 211..211, 477 source_range: 98..98,
478 delete: 207..211, 478 delete: 94..98,
479 insert: "&bar", 479 insert: "&bar",
480 detail: "&expr", 480 detail: "&expr",
481 }, 481 },
482 CompletionItem { 482 CompletionItem {
483 label: "refm", 483 label: "refm",
484 source_range: 211..211, 484 source_range: 98..98,
485 delete: 207..211, 485 delete: 94..98,
486 insert: "&mut bar", 486 insert: "&mut bar",
487 detail: "&mut expr", 487 detail: "&mut expr",
488 }, 488 },
489 CompletionItem { 489 CompletionItem {
490 label: "while", 490 label: "while",
491 source_range: 211..211, 491 source_range: 98..98,
492 delete: 207..211, 492 delete: 94..98,
493 insert: "while let Ok($1) = bar {\n $0\n}", 493 insert: "while let Ok($1) = bar {\n $0\n}",
494 detail: "while let Ok {}", 494 detail: "while let Ok {}",
495 }, 495 },
@@ -513,50 +513,50 @@ mod tests {
513 [ 513 [
514 CompletionItem { 514 CompletionItem {
515 label: "box", 515 label: "box",
516 source_range: 91..91, 516 source_range: 42..42,
517 delete: 87..91, 517 delete: 38..42,
518 insert: "Box::new(bar)", 518 insert: "Box::new(bar)",
519 detail: "Box::new(expr)", 519 detail: "Box::new(expr)",
520 }, 520 },
521 CompletionItem { 521 CompletionItem {
522 label: "call", 522 label: "call",
523 source_range: 91..91, 523 source_range: 42..42,
524 delete: 87..91, 524 delete: 38..42,
525 insert: "${1}(bar)", 525 insert: "${1}(bar)",
526 detail: "function(expr)", 526 detail: "function(expr)",
527 }, 527 },
528 CompletionItem { 528 CompletionItem {
529 label: "dbg", 529 label: "dbg",
530 source_range: 91..91, 530 source_range: 42..42,
531 delete: 87..91, 531 delete: 38..42,
532 insert: "dbg!(bar)", 532 insert: "dbg!(bar)",
533 detail: "dbg!(expr)", 533 detail: "dbg!(expr)",
534 }, 534 },
535 CompletionItem { 535 CompletionItem {
536 label: "match", 536 label: "match",
537 source_range: 91..91, 537 source_range: 42..42,
538 delete: 87..91, 538 delete: 38..42,
539 insert: "match bar {\n ${1:_} => {$0\\},\n}", 539 insert: "match bar {\n ${1:_} => {$0\\},\n}",
540 detail: "match expr {}", 540 detail: "match expr {}",
541 }, 541 },
542 CompletionItem { 542 CompletionItem {
543 label: "not", 543 label: "not",
544 source_range: 91..91, 544 source_range: 42..42,
545 delete: 87..91, 545 delete: 38..42,
546 insert: "!bar", 546 insert: "!bar",
547 detail: "!expr", 547 detail: "!expr",
548 }, 548 },
549 CompletionItem { 549 CompletionItem {
550 label: "ref", 550 label: "ref",
551 source_range: 91..91, 551 source_range: 42..42,
552 delete: 87..91, 552 delete: 38..42,
553 insert: "&bar", 553 insert: "&bar",
554 detail: "&expr", 554 detail: "&expr",
555 }, 555 },
556 CompletionItem { 556 CompletionItem {
557 label: "refm", 557 label: "refm",
558 source_range: 91..91, 558 source_range: 42..42,
559 delete: 87..91, 559 delete: 38..42,
560 insert: "&mut bar", 560 insert: "&mut bar",
561 detail: "&mut expr", 561 detail: "&mut expr",
562 }, 562 },
@@ -579,50 +579,50 @@ mod tests {
579 [ 579 [
580 CompletionItem { 580 CompletionItem {
581 label: "box", 581 label: "box",
582 source_range: 52..52, 582 source_range: 19..19,
583 delete: 49..52, 583 delete: 16..19,
584 insert: "Box::new(42)", 584 insert: "Box::new(42)",
585 detail: "Box::new(expr)", 585 detail: "Box::new(expr)",
586 }, 586 },
587 CompletionItem { 587 CompletionItem {
588 label: "call", 588 label: "call",
589 source_range: 52..52, 589 source_range: 19..19,
590 delete: 49..52, 590 delete: 16..19,
591 insert: "${1}(42)", 591 insert: "${1}(42)",
592 detail: "function(expr)", 592 detail: "function(expr)",
593 }, 593 },
594 CompletionItem { 594 CompletionItem {
595 label: "dbg", 595 label: "dbg",
596 source_range: 52..52, 596 source_range: 19..19,
597 delete: 49..52, 597 delete: 16..19,
598 insert: "dbg!(42)", 598 insert: "dbg!(42)",
599 detail: "dbg!(expr)", 599 detail: "dbg!(expr)",
600 }, 600 },
601 CompletionItem { 601 CompletionItem {
602 label: "match", 602 label: "match",
603 source_range: 52..52, 603 source_range: 19..19,
604 delete: 49..52, 604 delete: 16..19,
605 insert: "match 42 {\n ${1:_} => {$0\\},\n}", 605 insert: "match 42 {\n ${1:_} => {$0\\},\n}",
606 detail: "match expr {}", 606 detail: "match expr {}",
607 }, 607 },
608 CompletionItem { 608 CompletionItem {
609 label: "not", 609 label: "not",
610 source_range: 52..52, 610 source_range: 19..19,
611 delete: 49..52, 611 delete: 16..19,
612 insert: "!42", 612 insert: "!42",
613 detail: "!expr", 613 detail: "!expr",
614 }, 614 },
615 CompletionItem { 615 CompletionItem {
616 label: "ref", 616 label: "ref",
617 source_range: 52..52, 617 source_range: 19..19,
618 delete: 49..52, 618 delete: 16..19,
619 insert: "&42", 619 insert: "&42",
620 detail: "&expr", 620 detail: "&expr",
621 }, 621 },
622 CompletionItem { 622 CompletionItem {
623 label: "refm", 623 label: "refm",
624 source_range: 52..52, 624 source_range: 19..19,
625 delete: 49..52, 625 delete: 16..19,
626 insert: "&mut 42", 626 insert: "&mut 42",
627 detail: "&mut expr", 627 detail: "&mut expr",
628 }, 628 },
@@ -647,50 +647,50 @@ mod tests {
647 [ 647 [
648 CompletionItem { 648 CompletionItem {
649 label: "box", 649 label: "box",
650 source_range: 149..150, 650 source_range: 84..85,
651 delete: 145..150, 651 delete: 80..85,
652 insert: "Box::new(bar)", 652 insert: "Box::new(bar)",
653 detail: "Box::new(expr)", 653 detail: "Box::new(expr)",
654 }, 654 },
655 CompletionItem { 655 CompletionItem {
656 label: "call", 656 label: "call",
657 source_range: 149..150, 657 source_range: 84..85,
658 delete: 145..150, 658 delete: 80..85,
659 insert: "${1}(bar)", 659 insert: "${1}(bar)",
660 detail: "function(expr)", 660 detail: "function(expr)",
661 }, 661 },
662 CompletionItem { 662 CompletionItem {
663 label: "dbg", 663 label: "dbg",
664 source_range: 149..150, 664 source_range: 84..85,
665 delete: 145..150, 665 delete: 80..85,
666 insert: "dbg!(bar)", 666 insert: "dbg!(bar)",
667 detail: "dbg!(expr)", 667 detail: "dbg!(expr)",
668 }, 668 },
669 CompletionItem { 669 CompletionItem {
670 label: "match", 670 label: "match",
671 source_range: 149..150, 671 source_range: 84..85,
672 delete: 145..150, 672 delete: 80..85,
673 insert: "match bar {\n ${1:_} => {$0\\},\n}", 673 insert: "match bar {\n ${1:_} => {$0\\},\n}",
674 detail: "match expr {}", 674 detail: "match expr {}",
675 }, 675 },
676 CompletionItem { 676 CompletionItem {
677 label: "not", 677 label: "not",
678 source_range: 149..150, 678 source_range: 84..85,
679 delete: 145..150, 679 delete: 80..85,
680 insert: "!bar", 680 insert: "!bar",
681 detail: "!expr", 681 detail: "!expr",
682 }, 682 },
683 CompletionItem { 683 CompletionItem {
684 label: "ref", 684 label: "ref",
685 source_range: 149..150, 685 source_range: 84..85,
686 delete: 145..150, 686 delete: 80..85,
687 insert: "&bar", 687 insert: "&bar",
688 detail: "&expr", 688 detail: "&expr",
689 }, 689 },
690 CompletionItem { 690 CompletionItem {
691 label: "refm", 691 label: "refm",
692 source_range: 149..150, 692 source_range: 84..85,
693 delete: 145..150, 693 delete: 80..85,
694 insert: "&mut bar", 694 insert: "&mut bar",
695 detail: "&mut expr", 695 detail: "&mut expr",
696 }, 696 },
@@ -713,50 +713,50 @@ mod tests {
713 [ 713 [
714 CompletionItem { 714 CompletionItem {
715 label: "box", 715 label: "box",
716 source_range: 56..56, 716 source_range: 23..23,
717 delete: 49..56, 717 delete: 16..23,
718 insert: "Box::new(&&&&42)", 718 insert: "Box::new(&&&&42)",
719 detail: "Box::new(expr)", 719 detail: "Box::new(expr)",
720 }, 720 },
721 CompletionItem { 721 CompletionItem {
722 label: "call", 722 label: "call",
723 source_range: 56..56, 723 source_range: 23..23,
724 delete: 49..56, 724 delete: 16..23,
725 insert: "${1}(&&&&42)", 725 insert: "${1}(&&&&42)",
726 detail: "function(expr)", 726 detail: "function(expr)",
727 }, 727 },
728 CompletionItem { 728 CompletionItem {
729 label: "dbg", 729 label: "dbg",
730 source_range: 56..56, 730 source_range: 23..23,
731 delete: 49..56, 731 delete: 16..23,
732 insert: "dbg!(&&&&42)", 732 insert: "dbg!(&&&&42)",
733 detail: "dbg!(expr)", 733 detail: "dbg!(expr)",
734 }, 734 },
735 CompletionItem { 735 CompletionItem {
736 label: "match", 736 label: "match",
737 source_range: 56..56, 737 source_range: 23..23,
738 delete: 49..56, 738 delete: 16..23,
739 insert: "match &&&&42 {\n ${1:_} => {$0\\},\n}", 739 insert: "match &&&&42 {\n ${1:_} => {$0\\},\n}",
740 detail: "match expr {}", 740 detail: "match expr {}",
741 }, 741 },
742 CompletionItem { 742 CompletionItem {
743 label: "not", 743 label: "not",
744 source_range: 56..56, 744 source_range: 23..23,
745 delete: 53..56, 745 delete: 20..23,
746 insert: "!42", 746 insert: "!42",
747 detail: "!expr", 747 detail: "!expr",
748 }, 748 },
749 CompletionItem { 749 CompletionItem {
750 label: "ref", 750 label: "ref",
751 source_range: 56..56, 751 source_range: 23..23,
752 delete: 53..56, 752 delete: 20..23,
753 insert: "&42", 753 insert: "&42",
754 detail: "&expr", 754 detail: "&expr",
755 }, 755 },
756 CompletionItem { 756 CompletionItem {
757 label: "refm", 757 label: "refm",
758 source_range: 56..56, 758 source_range: 23..23,
759 delete: 53..56, 759 delete: 20..23,
760 insert: "&mut 42", 760 insert: "&mut 42",
761 detail: "&mut expr", 761 detail: "&mut expr",
762 }, 762 },
diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs
index d3a1cbc1d..f133ce3ce 100644
--- a/crates/ra_ide/src/completion/complete_qualified_path.rs
+++ b/crates/ra_ide/src/completion/complete_qualified_path.rs
@@ -212,8 +212,8 @@ mod tests {
212 [ 212 [
213 CompletionItem { 213 CompletionItem {
214 label: "my", 214 label: "my",
215 source_range: 27..29, 215 source_range: 10..12,
216 delete: 27..29, 216 delete: 10..12,
217 insert: "my", 217 insert: "my",
218 kind: Module, 218 kind: Module,
219 documentation: Documentation( 219 documentation: Documentation(
@@ -243,8 +243,8 @@ mod tests {
243 [ 243 [
244 CompletionItem { 244 CompletionItem {
245 label: "Bar", 245 label: "Bar",
246 source_range: 31..31, 246 source_range: 14..14,
247 delete: 31..31, 247 delete: 14..14,
248 insert: "Bar", 248 insert: "Bar",
249 kind: Struct, 249 kind: Struct,
250 }, 250 },
@@ -271,15 +271,15 @@ mod tests {
271 [ 271 [
272 CompletionItem { 272 CompletionItem {
273 label: "Foo", 273 label: "Foo",
274 source_range: 31..31, 274 source_range: 14..14,
275 delete: 31..31, 275 delete: 14..14,
276 insert: "Foo", 276 insert: "Foo",
277 kind: Struct, 277 kind: Struct,
278 }, 278 },
279 CompletionItem { 279 CompletionItem {
280 label: "PublicBar", 280 label: "PublicBar",
281 source_range: 31..31, 281 source_range: 14..14,
282 delete: 31..31, 282 delete: 14..14,
283 insert: "PublicBar", 283 insert: "PublicBar",
284 kind: Struct, 284 kind: Struct,
285 }, 285 },
@@ -304,8 +304,8 @@ mod tests {
304 [ 304 [
305 CompletionItem { 305 CompletionItem {
306 label: "Bar", 306 label: "Bar",
307 source_range: 30..30, 307 source_range: 13..13,
308 delete: 30..30, 308 delete: 13..13,
309 insert: "Bar", 309 insert: "Bar",
310 kind: Struct, 310 kind: Struct,
311 }, 311 },
@@ -1145,8 +1145,8 @@ mod tests {
1145 [ 1145 [
1146 CompletionItem { 1146 CompletionItem {
1147 label: "bar()", 1147 label: "bar()",
1148 source_range: 185..185, 1148 source_range: 88..88,
1149 delete: 185..185, 1149 delete: 88..88,
1150 insert: "bar()$0", 1150 insert: "bar()$0",
1151 kind: Function, 1151 kind: Function,
1152 lookup: "bar", 1152 lookup: "bar",
@@ -1154,8 +1154,8 @@ mod tests {
1154 }, 1154 },
1155 CompletionItem { 1155 CompletionItem {
1156 label: "foo()", 1156 label: "foo()",
1157 source_range: 185..185, 1157 source_range: 88..88,
1158 delete: 185..185, 1158 delete: 88..88,
1159 insert: "foo()$0", 1159 insert: "foo()$0",
1160 kind: Function, 1160 kind: Function,
1161 lookup: "foo", 1161 lookup: "foo",
@@ -1185,16 +1185,16 @@ mod tests {
1185 [ 1185 [
1186 CompletionItem { 1186 CompletionItem {
1187 label: "foo!(…)", 1187 label: "foo!(…)",
1188 source_range: 179..179, 1188 source_range: 82..82,
1189 delete: 179..179, 1189 delete: 82..82,
1190 insert: "foo!($0)", 1190 insert: "foo!($0)",
1191 kind: Macro, 1191 kind: Macro,
1192 detail: "#[macro_export]\nmacro_rules! foo", 1192 detail: "#[macro_export]\nmacro_rules! foo",
1193 }, 1193 },
1194 CompletionItem { 1194 CompletionItem {
1195 label: "main()", 1195 label: "main()",
1196 source_range: 179..179, 1196 source_range: 82..82,
1197 delete: 179..179, 1197 delete: 82..82,
1198 insert: "main()$0", 1198 insert: "main()$0",
1199 kind: Function, 1199 kind: Function,
1200 lookup: "main", 1200 lookup: "main",
@@ -1230,22 +1230,22 @@ mod tests {
1230 [ 1230 [
1231 CompletionItem { 1231 CompletionItem {
1232 label: "RIGHT_CONST", 1232 label: "RIGHT_CONST",
1233 source_range: 57..57, 1233 source_range: 24..24,
1234 delete: 57..57, 1234 delete: 24..24,
1235 insert: "RIGHT_CONST", 1235 insert: "RIGHT_CONST",
1236 kind: Const, 1236 kind: Const,
1237 }, 1237 },
1238 CompletionItem { 1238 CompletionItem {
1239 label: "RightType", 1239 label: "RightType",
1240 source_range: 57..57, 1240 source_range: 24..24,
1241 delete: 57..57, 1241 delete: 24..24,
1242 insert: "RightType", 1242 insert: "RightType",
1243 kind: Struct, 1243 kind: Struct,
1244 }, 1244 },
1245 CompletionItem { 1245 CompletionItem {
1246 label: "right_fn()", 1246 label: "right_fn()",
1247 source_range: 57..57, 1247 source_range: 24..24,
1248 delete: 57..57, 1248 delete: 24..24,
1249 insert: "right_fn()$0", 1249 insert: "right_fn()$0",
1250 kind: Function, 1250 kind: Function,
1251 lookup: "right_fn", 1251 lookup: "right_fn",
@@ -1269,8 +1269,8 @@ mod tests {
1269 [ 1269 [
1270 CompletionItem { 1270 CompletionItem {
1271 label: "foo()", 1271 label: "foo()",
1272 source_range: 93..94, 1272 source_range: 60..61,
1273 delete: 93..94, 1273 delete: 60..61,
1274 insert: "foo()$0", 1274 insert: "foo()$0",
1275 kind: Function, 1275 kind: Function,
1276 lookup: "foo", 1276 lookup: "foo",
@@ -1278,8 +1278,8 @@ mod tests {
1278 }, 1278 },
1279 CompletionItem { 1279 CompletionItem {
1280 label: "main()", 1280 label: "main()",
1281 source_range: 93..94, 1281 source_range: 60..61,
1282 delete: 93..94, 1282 delete: 60..61,
1283 insert: "main()$0", 1283 insert: "main()$0",
1284 kind: Function, 1284 kind: Function,
1285 lookup: "main", 1285 lookup: "main",
@@ -1308,15 +1308,15 @@ mod tests {
1308 [ 1308 [
1309 CompletionItem { 1309 CompletionItem {
1310 label: "z", 1310 label: "z",
1311 source_range: 57..57, 1311 source_range: 24..24,
1312 delete: 57..57, 1312 delete: 24..24,
1313 insert: "z", 1313 insert: "z",
1314 kind: Module, 1314 kind: Module,
1315 }, 1315 },
1316 CompletionItem { 1316 CompletionItem {
1317 label: "z()", 1317 label: "z()",
1318 source_range: 57..57, 1318 source_range: 24..24,
1319 delete: 57..57, 1319 delete: 24..24,
1320 insert: "z()$0", 1320 insert: "z()$0",
1321 kind: Function, 1321 kind: Function,
1322 lookup: "z", 1322 lookup: "z",
@@ -1347,8 +1347,8 @@ mod tests {
1347 [ 1347 [
1348 CompletionItem { 1348 CompletionItem {
1349 label: "new()", 1349 label: "new()",
1350 source_range: 292..292, 1350 source_range: 179..179,
1351 delete: 292..292, 1351 delete: 179..179,
1352 insert: "new()$0", 1352 insert: "new()$0",
1353 kind: Function, 1353 kind: Function,
1354 lookup: "new", 1354 lookup: "new",
diff --git a/crates/ra_ide/src/completion/complete_record.rs b/crates/ra_ide/src/completion/complete_record.rs
index b7ab654c5..13eb2f79f 100644
--- a/crates/ra_ide/src/completion/complete_record.rs
+++ b/crates/ra_ide/src/completion/complete_record.rs
@@ -41,17 +41,17 @@ mod tests {
41 ", 41 ",
42 ); 42 );
43 assert_debug_snapshot!(completions, @r###" 43 assert_debug_snapshot!(completions, @r###"
44 [ 44 [
45 CompletionItem { 45 CompletionItem {
46 label: "foo", 46 label: "foo",
47 source_range: 117..118, 47 source_range: 68..69,
48 delete: 117..118, 48 delete: 68..69,
49 insert: "foo", 49 insert: "foo",
50 kind: Field, 50 kind: Field,
51 detail: "u32", 51 detail: "u32",
52 }, 52 },
53 ] 53 ]
54 "###); 54 "###);
55 } 55 }
56 56
57 #[test] 57 #[test]
@@ -70,25 +70,25 @@ mod tests {
70 ", 70 ",
71 ); 71 );
72 assert_debug_snapshot!(completions, @r###" 72 assert_debug_snapshot!(completions, @r###"
73 [ 73 [
74 CompletionItem { 74 CompletionItem {
75 label: "bar", 75 label: "bar",
76 source_range: 161..161, 76 source_range: 88..88,
77 delete: 161..161, 77 delete: 88..88,
78 insert: "bar", 78 insert: "bar",
79 kind: Field, 79 kind: Field,
80 detail: "()", 80 detail: "()",
81 }, 81 },
82 CompletionItem { 82 CompletionItem {
83 label: "foo", 83 label: "foo",
84 source_range: 161..161, 84 source_range: 88..88,
85 delete: 161..161, 85 delete: 88..88,
86 insert: "foo", 86 insert: "foo",
87 kind: Field, 87 kind: Field,
88 detail: "u32", 88 detail: "u32",
89 }, 89 },
90 ] 90 ]
91 "###); 91 "###);
92 } 92 }
93 93
94 #[test] 94 #[test]
@@ -106,17 +106,17 @@ mod tests {
106 ", 106 ",
107 ); 107 );
108 assert_debug_snapshot!(completions, @r###" 108 assert_debug_snapshot!(completions, @r###"
109 [ 109 [
110 CompletionItem { 110 CompletionItem {
111 label: "foo", 111 label: "foo",
112 source_range: 171..172, 112 source_range: 110..111,
113 delete: 171..172, 113 delete: 110..111,
114 insert: "foo", 114 insert: "foo",
115 kind: Field, 115 kind: Field,
116 detail: "u32", 116 detail: "u32",
117 }, 117 },
118 ] 118 ]
119 "###); 119 "###);
120 } 120 }
121 121
122 #[test] 122 #[test]
@@ -142,25 +142,25 @@ mod tests {
142 ", 142 ",
143 ); 143 );
144 assert_debug_snapshot!(completions, @r###" 144 assert_debug_snapshot!(completions, @r###"
145 [ 145 [
146 CompletionItem { 146 CompletionItem {
147 label: "bar", 147 label: "bar",
148 source_range: 372..372, 148 source_range: 203..203,
149 delete: 372..372, 149 delete: 203..203,
150 insert: "bar", 150 insert: "bar",
151 kind: Field, 151 kind: Field,
152 detail: "u32", 152 detail: "u32",
153 }, 153 },
154 CompletionItem { 154 CompletionItem {
155 label: "baz", 155 label: "baz",
156 source_range: 372..372, 156 source_range: 203..203,
157 delete: 372..372, 157 delete: 203..203,
158 insert: "baz", 158 insert: "baz",
159 kind: Field, 159 kind: Field,
160 detail: "u32", 160 detail: "u32",
161 }, 161 },
162 ] 162 ]
163 "###); 163 "###);
164 } 164 }
165 } 165 }
166 166
@@ -187,18 +187,18 @@ mod tests {
187 ", 187 ",
188 ); 188 );
189 assert_debug_snapshot!(completions, @r###" 189 assert_debug_snapshot!(completions, @r###"
190 [ 190 [
191 CompletionItem { 191 CompletionItem {
192 label: "the_field", 192 label: "the_field",
193 source_range: 142..145, 193 source_range: 69..72,
194 delete: 142..145, 194 delete: 69..72,
195 insert: "the_field", 195 insert: "the_field",
196 kind: Field, 196 kind: Field,
197 detail: "u32", 197 detail: "u32",
198 deprecated: true, 198 deprecated: true,
199 }, 199 },
200 ] 200 ]
201 "###); 201 "###);
202 } 202 }
203 203
204 #[test] 204 #[test]
@@ -212,17 +212,17 @@ mod tests {
212 ", 212 ",
213 ); 213 );
214 assert_debug_snapshot!(completions, @r###" 214 assert_debug_snapshot!(completions, @r###"
215 [ 215 [
216 CompletionItem { 216 CompletionItem {
217 label: "the_field", 217 label: "the_field",
218 source_range: 83..86, 218 source_range: 46..49,
219 delete: 83..86, 219 delete: 46..49,
220 insert: "the_field", 220 insert: "the_field",
221 kind: Field, 221 kind: Field,
222 detail: "u32", 222 detail: "u32",
223 }, 223 },
224 ] 224 ]
225 "###); 225 "###);
226 } 226 }
227 227
228 #[test] 228 #[test]
@@ -238,17 +238,17 @@ mod tests {
238 ", 238 ",
239 ); 239 );
240 assert_debug_snapshot!(completions, @r###" 240 assert_debug_snapshot!(completions, @r###"
241 [ 241 [
242 CompletionItem { 242 CompletionItem {
243 label: "a", 243 label: "a",
244 source_range: 119..119, 244 source_range: 58..58,
245 delete: 119..119, 245 delete: 58..58,
246 insert: "a", 246 insert: "a",
247 kind: Field, 247 kind: Field,
248 detail: "u32", 248 detail: "u32",
249 }, 249 },
250 ] 250 ]
251 "###); 251 "###);
252 } 252 }
253 253
254 #[test] 254 #[test]
@@ -264,17 +264,17 @@ mod tests {
264 ", 264 ",
265 ); 265 );
266 assert_debug_snapshot!(completions, @r###" 266 assert_debug_snapshot!(completions, @r###"
267 [ 267 [
268 CompletionItem { 268 CompletionItem {
269 label: "b", 269 label: "b",
270 source_range: 119..119, 270 source_range: 70..70,
271 delete: 119..119, 271 delete: 70..70,
272 insert: "b", 272 insert: "b",
273 kind: Field, 273 kind: Field,
274 detail: "u32", 274 detail: "u32",
275 }, 275 },
276 ] 276 ]
277 "###); 277 "###);
278 } 278 }
279 279
280 #[test] 280 #[test]
@@ -289,17 +289,17 @@ mod tests {
289 ", 289 ",
290 ); 290 );
291 assert_debug_snapshot!(completions, @r###" 291 assert_debug_snapshot!(completions, @r###"
292 [ 292 [
293 CompletionItem { 293 CompletionItem {
294 label: "a", 294 label: "a",
295 source_range: 93..93, 295 source_range: 56..56,
296 delete: 93..93, 296 delete: 56..56,
297 insert: "a", 297 insert: "a",
298 kind: Field, 298 kind: Field,
299 detail: "u32", 299 detail: "u32",
300 }, 300 },
301 ] 301 ]
302 "###); 302 "###);
303 } 303 }
304 304
305 #[test] 305 #[test]
@@ -314,17 +314,17 @@ mod tests {
314 ", 314 ",
315 ); 315 );
316 assert_debug_snapshot!(completions, @r###" 316 assert_debug_snapshot!(completions, @r###"
317 [ 317 [
318 CompletionItem { 318 CompletionItem {
319 label: "the_field", 319 label: "the_field",
320 source_range: 137..140, 320 source_range: 88..91,
321 delete: 137..140, 321 delete: 88..91,
322 insert: "the_field", 322 insert: "the_field",
323 kind: Field, 323 kind: Field,
324 detail: "u32", 324 detail: "u32",
325 }, 325 },
326 ] 326 ]
327 "###); 327 "###);
328 } 328 }
329 329
330 #[test] 330 #[test]
@@ -349,25 +349,25 @@ mod tests {
349 ", 349 ",
350 ); 350 );
351 assert_debug_snapshot!(completions, @r###" 351 assert_debug_snapshot!(completions, @r###"
352 [ 352 [
353 CompletionItem { 353 CompletionItem {
354 label: "bar", 354 label: "bar",
355 source_range: 302..302, 355 source_range: 157..157,
356 delete: 302..302, 356 delete: 157..157,
357 insert: "bar", 357 insert: "bar",
358 kind: Field, 358 kind: Field,
359 detail: "u32", 359 detail: "u32",
360 }, 360 },
361 CompletionItem { 361 CompletionItem {
362 label: "baz", 362 label: "baz",
363 source_range: 302..302, 363 source_range: 157..157,
364 delete: 302..302, 364 delete: 157..157,
365 insert: "baz", 365 insert: "baz",
366 kind: Field, 366 kind: Field,
367 detail: "u32", 367 detail: "u32",
368 }, 368 },
369 ] 369 ]
370 "###); 370 "###);
371 } 371 }
372 372
373 #[test] 373 #[test]
@@ -390,17 +390,17 @@ mod tests {
390 ", 390 ",
391 ); 391 );
392 assert_debug_snapshot!(completions, @r###" 392 assert_debug_snapshot!(completions, @r###"
393 [ 393 [
394 CompletionItem { 394 CompletionItem {
395 label: "foo2", 395 label: "foo2",
396 source_range: 221..221, 396 source_range: 112..112,
397 delete: 221..221, 397 delete: 112..112,
398 insert: "foo2", 398 insert: "foo2",
399 kind: Field, 399 kind: Field,
400 detail: "u32", 400 detail: "u32",
401 }, 401 },
402 ] 402 ]
403 "###); 403 "###);
404 } 404 }
405 } 405 }
406} 406}
diff --git a/crates/ra_ide/src/completion/complete_snippet.rs b/crates/ra_ide/src/completion/complete_snippet.rs
index 0568d9ccf..52aaa70f0 100644
--- a/crates/ra_ide/src/completion/complete_snippet.rs
+++ b/crates/ra_ide/src/completion/complete_snippet.rs
@@ -129,31 +129,31 @@ mod tests {
129 [ 129 [
130 CompletionItem { 130 CompletionItem {
131 label: "Test function", 131 label: "Test function",
132 source_range: 78..78, 132 source_range: 29..29,
133 delete: 78..78, 133 delete: 29..29,
134 insert: "#[test]\nfn ${1:feature}() {\n $0\n}", 134 insert: "#[test]\nfn ${1:feature}() {\n $0\n}",
135 kind: Snippet, 135 kind: Snippet,
136 lookup: "tfn", 136 lookup: "tfn",
137 }, 137 },
138 CompletionItem { 138 CompletionItem {
139 label: "Test module", 139 label: "Test module",
140 source_range: 78..78, 140 source_range: 29..29,
141 delete: 78..78, 141 delete: 29..29,
142 insert: "#[cfg(test)]\nmod tests {\n use super::*;\n\n #[test]\n fn ${1:test_name}() {\n $0\n }\n}", 142 insert: "#[cfg(test)]\nmod tests {\n use super::*;\n\n #[test]\n fn ${1:test_name}() {\n $0\n }\n}",
143 kind: Snippet, 143 kind: Snippet,
144 lookup: "tmod", 144 lookup: "tmod",
145 }, 145 },
146 CompletionItem { 146 CompletionItem {
147 label: "macro_rules", 147 label: "macro_rules",
148 source_range: 78..78, 148 source_range: 29..29,
149 delete: 78..78, 149 delete: 29..29,
150 insert: "macro_rules! $1 {\n\t($2) => {\n\t\t$0\n\t};\n}", 150 insert: "macro_rules! $1 {\n\t($2) => {\n\t\t$0\n\t};\n}",
151 kind: Snippet, 151 kind: Snippet,
152 }, 152 },
153 CompletionItem { 153 CompletionItem {
154 label: "pub(crate)", 154 label: "pub(crate)",
155 source_range: 78..78, 155 source_range: 29..29,
156 delete: 78..78, 156 delete: 29..29,
157 insert: "pub(crate) $0", 157 insert: "pub(crate) $0",
158 kind: Snippet, 158 kind: Snippet,
159 }, 159 },
diff --git a/crates/ra_ide/src/completion/complete_trait_impl.rs b/crates/ra_ide/src/completion/complete_trait_impl.rs
index 21c9316e6..23e42928d 100644
--- a/crates/ra_ide/src/completion/complete_trait_impl.rs
+++ b/crates/ra_ide/src/completion/complete_trait_impl.rs
@@ -256,24 +256,24 @@ mod tests {
256 [ 256 [
257 CompletionItem { 257 CompletionItem {
258 label: "const TEST_CONST: u16 = ", 258 label: "const TEST_CONST: u16 = ",
259 source_range: 209..210, 259 source_range: 112..113,
260 delete: 209..210, 260 delete: 112..113,
261 insert: "const TEST_CONST: u16 = ", 261 insert: "const TEST_CONST: u16 = ",
262 kind: Const, 262 kind: Const,
263 lookup: "TEST_CONST", 263 lookup: "TEST_CONST",
264 }, 264 },
265 CompletionItem { 265 CompletionItem {
266 label: "fn test()", 266 label: "fn test()",
267 source_range: 209..210, 267 source_range: 112..113,
268 delete: 209..210, 268 delete: 112..113,
269 insert: "fn test() {\n $0\n}", 269 insert: "fn test() {\n $0\n}",
270 kind: Function, 270 kind: Function,
271 lookup: "test", 271 lookup: "test",
272 }, 272 },
273 CompletionItem { 273 CompletionItem {
274 label: "type TestType = ", 274 label: "type TestType = ",
275 source_range: 209..210, 275 source_range: 112..113,
276 delete: 209..210, 276 delete: 112..113,
277 insert: "type TestType = ", 277 insert: "type TestType = ",
278 kind: TypeAlias, 278 kind: TypeAlias,
279 lookup: "TestType", 279 lookup: "TestType",
@@ -322,8 +322,8 @@ mod tests {
322 [ 322 [
323 CompletionItem { 323 CompletionItem {
324 label: "fn test()", 324 label: "fn test()",
325 source_range: 139..140, 325 source_range: 66..67,
326 delete: 139..140, 326 delete: 66..67,
327 insert: "fn test() {\n $0\n}", 327 insert: "fn test() {\n $0\n}",
328 kind: Function, 328 kind: Function,
329 lookup: "test", 329 lookup: "test",
@@ -351,8 +351,8 @@ mod tests {
351 [ 351 [
352 CompletionItem { 352 CompletionItem {
353 label: "fn foo()", 353 label: "fn foo()",
354 source_range: 141..142, 354 source_range: 68..69,
355 delete: 138..142, 355 delete: 65..69,
356 insert: "fn foo() {\n $0\n}", 356 insert: "fn foo() {\n $0\n}",
357 kind: Function, 357 kind: Function,
358 lookup: "foo", 358 lookup: "foo",
@@ -383,8 +383,8 @@ mod tests {
383 [ 383 [
384 CompletionItem { 384 CompletionItem {
385 label: "fn foo_bar()", 385 label: "fn foo_bar()",
386 source_range: 200..201, 386 source_range: 103..104,
387 delete: 197..201, 387 delete: 100..104,
388 insert: "fn foo_bar() {\n $0\n}", 388 insert: "fn foo_bar() {\n $0\n}",
389 kind: Function, 389 kind: Function,
390 lookup: "foo_bar", 390 lookup: "foo_bar",
@@ -434,8 +434,8 @@ mod tests {
434 [ 434 [
435 CompletionItem { 435 CompletionItem {
436 label: "fn foo()", 436 label: "fn foo()",
437 source_range: 144..145, 437 source_range: 71..72,
438 delete: 141..145, 438 delete: 68..72,
439 insert: "fn foo<T>() {\n $0\n}", 439 insert: "fn foo<T>() {\n $0\n}",
440 kind: Function, 440 kind: Function,
441 lookup: "foo", 441 lookup: "foo",
@@ -463,8 +463,8 @@ mod tests {
463 [ 463 [
464 CompletionItem { 464 CompletionItem {
465 label: "fn foo()", 465 label: "fn foo()",
466 source_range: 166..167, 466 source_range: 93..94,
467 delete: 163..167, 467 delete: 90..94,
468 insert: "fn foo<T>()\nwhere T: Into<String> {\n $0\n}", 468 insert: "fn foo<T>()\nwhere T: Into<String> {\n $0\n}",
469 kind: Function, 469 kind: Function,
470 lookup: "foo", 470 lookup: "foo",
@@ -490,8 +490,8 @@ mod tests {
490 [ 490 [
491 CompletionItem { 491 CompletionItem {
492 label: "type SomeType = ", 492 label: "type SomeType = ",
493 source_range: 124..125, 493 source_range: 63..64,
494 delete: 119..125, 494 delete: 58..64,
495 insert: "type SomeType = ", 495 insert: "type SomeType = ",
496 kind: TypeAlias, 496 kind: TypeAlias,
497 lookup: "SomeType", 497 lookup: "SomeType",
@@ -517,8 +517,8 @@ mod tests {
517 [ 517 [
518 CompletionItem { 518 CompletionItem {
519 label: "const SOME_CONST: u16 = ", 519 label: "const SOME_CONST: u16 = ",
520 source_range: 133..134, 520 source_range: 72..73,
521 delete: 127..134, 521 delete: 66..73,
522 insert: "const SOME_CONST: u16 = ", 522 insert: "const SOME_CONST: u16 = ",
523 kind: Const, 523 kind: Const,
524 lookup: "SOME_CONST", 524 lookup: "SOME_CONST",
@@ -544,8 +544,8 @@ mod tests {
544 [ 544 [
545 CompletionItem { 545 CompletionItem {
546 label: "const SOME_CONST: u16 = ", 546 label: "const SOME_CONST: u16 = ",
547 source_range: 138..139, 547 source_range: 77..78,
548 delete: 132..139, 548 delete: 71..78,
549 insert: "const SOME_CONST: u16 = ", 549 insert: "const SOME_CONST: u16 = ",
550 kind: Const, 550 kind: Const,
551 lookup: "SOME_CONST", 551 lookup: "SOME_CONST",
diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs
index aa2b07a2f..a0a04bb58 100644
--- a/crates/ra_ide/src/completion/complete_unqualified_path.rs
+++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs
@@ -85,15 +85,15 @@ mod tests {
85 "#, 85 "#,
86 ), 86 ),
87 @r###" 87 @r###"
88 [ 88 [
89 CompletionItem { 89 CompletionItem {
90 label: "collections", 90 label: "collections",
91 source_range: 21..24, 91 source_range: 4..7,
92 delete: 21..24, 92 delete: 4..7,
93 insert: "collections", 93 insert: "collections",
94 }, 94 },
95 ] 95 ]
96 "### 96 "###
97 ); 97 );
98 } 98 }
99 99
@@ -157,16 +157,16 @@ mod tests {
157 " 157 "
158 ), 158 ),
159 @r###" 159 @r###"
160 [ 160 [
161 CompletionItem { 161 CompletionItem {
162 label: "Enum", 162 label: "Enum",
163 source_range: 231..233, 163 source_range: 102..104,
164 delete: 231..233, 164 delete: 102..104,
165 insert: "Enum", 165 insert: "Enum",
166 kind: Enum, 166 kind: Enum,
167 }, 167 },
168 ] 168 ]
169 "### 169 "###
170 ); 170 );
171 } 171 }
172 172
@@ -186,8 +186,8 @@ mod tests {
186 [ 186 [
187 CompletionItem { 187 CompletionItem {
188 label: "quux(…)", 188 label: "quux(…)",
189 source_range: 91..91, 189 source_range: 42..42,
190 delete: 91..91, 190 delete: 42..42,
191 insert: "quux(${1:x})$0", 191 insert: "quux(${1:x})$0",
192 kind: Function, 192 kind: Function,
193 lookup: "quux", 193 lookup: "quux",
@@ -196,16 +196,16 @@ mod tests {
196 }, 196 },
197 CompletionItem { 197 CompletionItem {
198 label: "x", 198 label: "x",
199 source_range: 91..91, 199 source_range: 42..42,
200 delete: 91..91, 200 delete: 42..42,
201 insert: "x", 201 insert: "x",
202 kind: Binding, 202 kind: Binding,
203 detail: "i32", 203 detail: "i32",
204 }, 204 },
205 CompletionItem { 205 CompletionItem {
206 label: "y", 206 label: "y",
207 source_range: 91..91, 207 source_range: 42..42,
208 delete: 91..91, 208 delete: 42..42,
209 insert: "y", 209 insert: "y",
210 kind: Binding, 210 kind: Binding,
211 detail: "i32", 211 detail: "i32",
@@ -235,23 +235,23 @@ mod tests {
235 [ 235 [
236 CompletionItem { 236 CompletionItem {
237 label: "a", 237 label: "a",
238 source_range: 242..242, 238 source_range: 129..129,
239 delete: 242..242, 239 delete: 129..129,
240 insert: "a", 240 insert: "a",
241 kind: Binding, 241 kind: Binding,
242 }, 242 },
243 CompletionItem { 243 CompletionItem {
244 label: "b", 244 label: "b",
245 source_range: 242..242, 245 source_range: 129..129,
246 delete: 242..242, 246 delete: 129..129,
247 insert: "b", 247 insert: "b",
248 kind: Binding, 248 kind: Binding,
249 detail: "i32", 249 detail: "i32",
250 }, 250 },
251 CompletionItem { 251 CompletionItem {
252 label: "quux()", 252 label: "quux()",
253 source_range: 242..242, 253 source_range: 129..129,
254 delete: 242..242, 254 delete: 129..129,
255 insert: "quux()$0", 255 insert: "quux()$0",
256 kind: Function, 256 kind: Function,
257 lookup: "quux", 257 lookup: "quux",
@@ -278,8 +278,8 @@ mod tests {
278 [ 278 [
279 CompletionItem { 279 CompletionItem {
280 label: "quux()", 280 label: "quux()",
281 source_range: 95..95, 281 source_range: 46..46,
282 delete: 95..95, 282 delete: 46..46,
283 insert: "quux()$0", 283 insert: "quux()$0",
284 kind: Function, 284 kind: Function,
285 lookup: "quux", 285 lookup: "quux",
@@ -287,8 +287,8 @@ mod tests {
287 }, 287 },
288 CompletionItem { 288 CompletionItem {
289 label: "x", 289 label: "x",
290 source_range: 95..95, 290 source_range: 46..46,
291 delete: 95..95, 291 delete: 46..46,
292 insert: "x", 292 insert: "x",
293 kind: Binding, 293 kind: Binding,
294 }, 294 },
@@ -314,15 +314,15 @@ mod tests {
314 [ 314 [
315 CompletionItem { 315 CompletionItem {
316 label: "index", 316 label: "index",
317 source_range: 107..107, 317 source_range: 58..58,
318 delete: 107..107, 318 delete: 58..58,
319 insert: "index", 319 insert: "index",
320 kind: Binding, 320 kind: Binding,
321 }, 321 },
322 CompletionItem { 322 CompletionItem {
323 label: "test()", 323 label: "test()",
324 source_range: 107..107, 324 source_range: 58..58,
325 delete: 107..107, 325 delete: 58..58,
326 insert: "test()$0", 326 insert: "test()$0",
327 kind: Function, 327 kind: Function,
328 lookup: "test", 328 lookup: "test",
@@ -347,15 +347,15 @@ mod tests {
347 [ 347 [
348 CompletionItem { 348 CompletionItem {
349 label: "T", 349 label: "T",
350 source_range: 52..52, 350 source_range: 19..19,
351 delete: 52..52, 351 delete: 19..19,
352 insert: "T", 352 insert: "T",
353 kind: TypeParam, 353 kind: TypeParam,
354 }, 354 },
355 CompletionItem { 355 CompletionItem {
356 label: "quux()", 356 label: "quux()",
357 source_range: 52..52, 357 source_range: 19..19,
358 delete: 52..52, 358 delete: 19..19,
359 insert: "quux()$0", 359 insert: "quux()$0",
360 kind: Function, 360 kind: Function,
361 lookup: "quux", 361 lookup: "quux",
@@ -380,22 +380,22 @@ mod tests {
380 [ 380 [
381 CompletionItem { 381 CompletionItem {
382 label: "Self", 382 label: "Self",
383 source_range: 54..54, 383 source_range: 21..21,
384 delete: 54..54, 384 delete: 21..21,
385 insert: "Self", 385 insert: "Self",
386 kind: TypeParam, 386 kind: TypeParam,
387 }, 387 },
388 CompletionItem { 388 CompletionItem {
389 label: "T", 389 label: "T",
390 source_range: 54..54, 390 source_range: 21..21,
391 delete: 54..54, 391 delete: 21..21,
392 insert: "T", 392 insert: "T",
393 kind: TypeParam, 393 kind: TypeParam,
394 }, 394 },
395 CompletionItem { 395 CompletionItem {
396 label: "X<…>", 396 label: "X<…>",
397 source_range: 54..54, 397 source_range: 21..21,
398 delete: 54..54, 398 delete: 21..21,
399 insert: "X<$0>", 399 insert: "X<$0>",
400 kind: Struct, 400 kind: Struct,
401 lookup: "X", 401 lookup: "X",
@@ -419,15 +419,15 @@ mod tests {
419 [ 419 [
420 CompletionItem { 420 CompletionItem {
421 label: "Self", 421 label: "Self",
422 source_range: 48..48, 422 source_range: 15..15,
423 delete: 48..48, 423 delete: 15..15,
424 insert: "Self", 424 insert: "Self",
425 kind: TypeParam, 425 kind: TypeParam,
426 }, 426 },
427 CompletionItem { 427 CompletionItem {
428 label: "X", 428 label: "X",
429 source_range: 48..48, 429 source_range: 15..15,
430 delete: 48..48, 430 delete: 15..15,
431 insert: "X", 431 insert: "X",
432 kind: Enum, 432 kind: Enum,
433 }, 433 },
@@ -452,22 +452,22 @@ mod tests {
452 [ 452 [
453 CompletionItem { 453 CompletionItem {
454 label: "Baz", 454 label: "Baz",
455 source_range: 105..105, 455 source_range: 40..40,
456 delete: 105..105, 456 delete: 40..40,
457 insert: "Baz", 457 insert: "Baz",
458 kind: Enum, 458 kind: Enum,
459 }, 459 },
460 CompletionItem { 460 CompletionItem {
461 label: "Foo", 461 label: "Foo",
462 source_range: 105..105, 462 source_range: 40..40,
463 delete: 105..105, 463 delete: 40..40,
464 insert: "Foo", 464 insert: "Foo",
465 kind: Struct, 465 kind: Struct,
466 }, 466 },
467 CompletionItem { 467 CompletionItem {
468 label: "quux()", 468 label: "quux()",
469 source_range: 105..105, 469 source_range: 40..40,
470 delete: 105..105, 470 delete: 40..40,
471 insert: "quux()$0", 471 insert: "quux()$0",
472 kind: Function, 472 kind: Function,
473 lookup: "quux", 473 lookup: "quux",
@@ -520,15 +520,15 @@ mod tests {
520 [ 520 [
521 CompletionItem { 521 CompletionItem {
522 label: "Bar", 522 label: "Bar",
523 source_range: 117..117, 523 source_range: 52..52,
524 delete: 117..117, 524 delete: 52..52,
525 insert: "Bar", 525 insert: "Bar",
526 kind: Struct, 526 kind: Struct,
527 }, 527 },
528 CompletionItem { 528 CompletionItem {
529 label: "quux()", 529 label: "quux()",
530 source_range: 117..117, 530 source_range: 52..52,
531 delete: 117..117, 531 delete: 52..52,
532 insert: "quux()$0", 532 insert: "quux()$0",
533 kind: Function, 533 kind: Function,
534 lookup: "quux", 534 lookup: "quux",
@@ -552,15 +552,15 @@ mod tests {
552 [ 552 [
553 CompletionItem { 553 CompletionItem {
554 label: "Foo", 554 label: "Foo",
555 source_range: 55..55, 555 source_range: 22..22,
556 delete: 55..55, 556 delete: 22..22,
557 insert: "Foo", 557 insert: "Foo",
558 kind: Struct, 558 kind: Struct,
559 }, 559 },
560 CompletionItem { 560 CompletionItem {
561 label: "x()", 561 label: "x()",
562 source_range: 55..55, 562 source_range: 22..22,
563 delete: 55..55, 563 delete: 22..22,
564 insert: "x()$0", 564 insert: "x()$0",
565 kind: Function, 565 kind: Function,
566 lookup: "x", 566 lookup: "x",
@@ -589,16 +589,16 @@ mod tests {
589 [ 589 [
590 CompletionItem { 590 CompletionItem {
591 label: "bar", 591 label: "bar",
592 source_range: 146..146, 592 source_range: 65..65,
593 delete: 146..146, 593 delete: 65..65,
594 insert: "bar", 594 insert: "bar",
595 kind: Binding, 595 kind: Binding,
596 detail: "i32", 596 detail: "i32",
597 }, 597 },
598 CompletionItem { 598 CompletionItem {
599 label: "foo()", 599 label: "foo()",
600 source_range: 146..146, 600 source_range: 65..65,
601 delete: 146..146, 601 delete: 65..65,
602 insert: "foo()$0", 602 insert: "foo()$0",
603 kind: Function, 603 kind: Function,
604 lookup: "foo", 604 lookup: "foo",
@@ -1001,16 +1001,16 @@ mod tests {
1001 [ 1001 [
1002 CompletionItem { 1002 CompletionItem {
1003 label: "m!(…)", 1003 label: "m!(…)",
1004 source_range: 145..145, 1004 source_range: 80..80,
1005 delete: 145..145, 1005 delete: 80..80,
1006 insert: "m!($0)", 1006 insert: "m!($0)",
1007 kind: Macro, 1007 kind: Macro,
1008 detail: "macro_rules! m", 1008 detail: "macro_rules! m",
1009 }, 1009 },
1010 CompletionItem { 1010 CompletionItem {
1011 label: "quux(…)", 1011 label: "quux(…)",
1012 source_range: 145..145, 1012 source_range: 80..80,
1013 delete: 145..145, 1013 delete: 80..80,
1014 insert: "quux(${1:x})$0", 1014 insert: "quux(${1:x})$0",
1015 kind: Function, 1015 kind: Function,
1016 lookup: "quux", 1016 lookup: "quux",
@@ -1019,16 +1019,16 @@ mod tests {
1019 }, 1019 },
1020 CompletionItem { 1020 CompletionItem {
1021 label: "x", 1021 label: "x",
1022 source_range: 145..145, 1022 source_range: 80..80,
1023 delete: 145..145, 1023 delete: 80..80,
1024 insert: "x", 1024 insert: "x",
1025 kind: Binding, 1025 kind: Binding,
1026 detail: "i32", 1026 detail: "i32",
1027 }, 1027 },
1028 CompletionItem { 1028 CompletionItem {
1029 label: "y", 1029 label: "y",
1030 source_range: 145..145, 1030 source_range: 80..80,
1031 delete: 145..145, 1031 delete: 80..80,
1032 insert: "y", 1032 insert: "y",
1033 kind: Binding, 1033 kind: Binding,
1034 detail: "i32", 1034 detail: "i32",
@@ -1054,16 +1054,16 @@ mod tests {
1054 [ 1054 [
1055 CompletionItem { 1055 CompletionItem {
1056 label: "m!(…)", 1056 label: "m!(…)",
1057 source_range: 145..146, 1057 source_range: 80..81,
1058 delete: 145..146, 1058 delete: 80..81,
1059 insert: "m!($0)", 1059 insert: "m!($0)",
1060 kind: Macro, 1060 kind: Macro,
1061 detail: "macro_rules! m", 1061 detail: "macro_rules! m",
1062 }, 1062 },
1063 CompletionItem { 1063 CompletionItem {
1064 label: "quux(…)", 1064 label: "quux(…)",
1065 source_range: 145..146, 1065 source_range: 80..81,
1066 delete: 145..146, 1066 delete: 80..81,
1067 insert: "quux(${1:x})$0", 1067 insert: "quux(${1:x})$0",
1068 kind: Function, 1068 kind: Function,
1069 lookup: "quux", 1069 lookup: "quux",
@@ -1072,16 +1072,16 @@ mod tests {
1072 }, 1072 },
1073 CompletionItem { 1073 CompletionItem {
1074 label: "x", 1074 label: "x",
1075 source_range: 145..146, 1075 source_range: 80..81,
1076 delete: 145..146, 1076 delete: 80..81,
1077 insert: "x", 1077 insert: "x",
1078 kind: Binding, 1078 kind: Binding,
1079 detail: "i32", 1079 detail: "i32",
1080 }, 1080 },
1081 CompletionItem { 1081 CompletionItem {
1082 label: "y", 1082 label: "y",
1083 source_range: 145..146, 1083 source_range: 80..81,
1084 delete: 145..146, 1084 delete: 80..81,
1085 insert: "y", 1085 insert: "y",
1086 kind: Binding, 1086 kind: Binding,
1087 detail: "i32", 1087 detail: "i32",
@@ -1107,16 +1107,16 @@ mod tests {
1107 [ 1107 [
1108 CompletionItem { 1108 CompletionItem {
1109 label: "m!(…)", 1109 label: "m!(…)",
1110 source_range: 145..146, 1110 source_range: 80..81,
1111 delete: 145..146, 1111 delete: 80..81,
1112 insert: "m!($0)", 1112 insert: "m!($0)",
1113 kind: Macro, 1113 kind: Macro,
1114 detail: "macro_rules! m", 1114 detail: "macro_rules! m",
1115 }, 1115 },
1116 CompletionItem { 1116 CompletionItem {
1117 label: "quux(…)", 1117 label: "quux(…)",
1118 source_range: 145..146, 1118 source_range: 80..81,
1119 delete: 145..146, 1119 delete: 80..81,
1120 insert: "quux(${1:x})$0", 1120 insert: "quux(${1:x})$0",
1121 kind: Function, 1121 kind: Function,
1122 lookup: "quux", 1122 lookup: "quux",
@@ -1125,16 +1125,16 @@ mod tests {
1125 }, 1125 },
1126 CompletionItem { 1126 CompletionItem {
1127 label: "x", 1127 label: "x",
1128 source_range: 145..146, 1128 source_range: 80..81,
1129 delete: 145..146, 1129 delete: 80..81,
1130 insert: "x", 1130 insert: "x",
1131 kind: Binding, 1131 kind: Binding,
1132 detail: "i32", 1132 detail: "i32",
1133 }, 1133 },
1134 CompletionItem { 1134 CompletionItem {
1135 label: "y", 1135 label: "y",
1136 source_range: 145..146, 1136 source_range: 80..81,
1137 delete: 145..146, 1137 delete: 80..81,
1138 insert: "y", 1138 insert: "y",
1139 kind: Binding, 1139 kind: Binding,
1140 detail: "i32", 1140 detail: "i32",
@@ -1160,14 +1160,14 @@ mod tests {
1160 [ 1160 [
1161 CompletionItem { 1161 CompletionItem {
1162 label: "Quux", 1162 label: "Quux",
1163 source_range: 82..82, 1163 source_range: 33..33,
1164 delete: 82..82, 1164 delete: 33..33,
1165 insert: "Quux", 1165 insert: "Quux",
1166 }, 1166 },
1167 CompletionItem { 1167 CompletionItem {
1168 label: "main()", 1168 label: "main()",
1169 source_range: 82..82, 1169 source_range: 33..33,
1170 delete: 82..82, 1170 delete: 33..33,
1171 insert: "main()$0", 1171 insert: "main()$0",
1172 kind: Function, 1172 kind: Function,
1173 lookup: "main", 1173 lookup: "main",
@@ -1201,15 +1201,15 @@ mod tests {
1201 [ 1201 [
1202 CompletionItem { 1202 CompletionItem {
1203 label: "Foo", 1203 label: "Foo",
1204 source_range: 248..250, 1204 source_range: 103..105,
1205 delete: 248..250, 1205 delete: 103..105,
1206 insert: "Foo", 1206 insert: "Foo",
1207 kind: Enum, 1207 kind: Enum,
1208 }, 1208 },
1209 CompletionItem { 1209 CompletionItem {
1210 label: "Foo::Bar", 1210 label: "Foo::Bar",
1211 source_range: 248..250, 1211 source_range: 103..105,
1212 delete: 248..250, 1212 delete: 103..105,
1213 insert: "Foo::Bar", 1213 insert: "Foo::Bar",
1214 kind: EnumVariant, 1214 kind: EnumVariant,
1215 lookup: "Bar", 1215 lookup: "Bar",
@@ -1217,8 +1217,8 @@ mod tests {
1217 }, 1217 },
1218 CompletionItem { 1218 CompletionItem {
1219 label: "Foo::Baz", 1219 label: "Foo::Baz",
1220 source_range: 248..250, 1220 source_range: 103..105,
1221 delete: 248..250, 1221 delete: 103..105,
1222 insert: "Foo::Baz", 1222 insert: "Foo::Baz",
1223 kind: EnumVariant, 1223 kind: EnumVariant,
1224 lookup: "Baz", 1224 lookup: "Baz",
@@ -1226,8 +1226,8 @@ mod tests {
1226 }, 1226 },
1227 CompletionItem { 1227 CompletionItem {
1228 label: "Foo::Quux", 1228 label: "Foo::Quux",
1229 source_range: 248..250, 1229 source_range: 103..105,
1230 delete: 248..250, 1230 delete: 103..105,
1231 insert: "Foo::Quux", 1231 insert: "Foo::Quux",
1232 kind: EnumVariant, 1232 kind: EnumVariant,
1233 lookup: "Quux", 1233 lookup: "Quux",
@@ -1262,15 +1262,15 @@ mod tests {
1262 [ 1262 [
1263 CompletionItem { 1263 CompletionItem {
1264 label: "Foo", 1264 label: "Foo",
1265 source_range: 219..221, 1265 source_range: 90..92,
1266 delete: 219..221, 1266 delete: 90..92,
1267 insert: "Foo", 1267 insert: "Foo",
1268 kind: Enum, 1268 kind: Enum,
1269 }, 1269 },
1270 CompletionItem { 1270 CompletionItem {
1271 label: "Foo::Bar", 1271 label: "Foo::Bar",
1272 source_range: 219..221, 1272 source_range: 90..92,
1273 delete: 219..221, 1273 delete: 90..92,
1274 insert: "Foo::Bar", 1274 insert: "Foo::Bar",
1275 kind: EnumVariant, 1275 kind: EnumVariant,
1276 lookup: "Bar", 1276 lookup: "Bar",
@@ -1278,8 +1278,8 @@ mod tests {
1278 }, 1278 },
1279 CompletionItem { 1279 CompletionItem {
1280 label: "Foo::Baz", 1280 label: "Foo::Baz",
1281 source_range: 219..221, 1281 source_range: 90..92,
1282 delete: 219..221, 1282 delete: 90..92,
1283 insert: "Foo::Baz", 1283 insert: "Foo::Baz",
1284 kind: EnumVariant, 1284 kind: EnumVariant,
1285 lookup: "Baz", 1285 lookup: "Baz",
@@ -1287,8 +1287,8 @@ mod tests {
1287 }, 1287 },
1288 CompletionItem { 1288 CompletionItem {
1289 label: "Foo::Quux", 1289 label: "Foo::Quux",
1290 source_range: 219..221, 1290 source_range: 90..92,
1291 delete: 219..221, 1291 delete: 90..92,
1292 insert: "Foo::Quux", 1292 insert: "Foo::Quux",
1293 kind: EnumVariant, 1293 kind: EnumVariant,
1294 lookup: "Quux", 1294 lookup: "Quux",
@@ -1319,15 +1319,15 @@ mod tests {
1319 [ 1319 [
1320 CompletionItem { 1320 CompletionItem {
1321 label: "Foo", 1321 label: "Foo",
1322 source_range: 185..186, 1322 source_range: 72..73,
1323 delete: 185..186, 1323 delete: 72..73,
1324 insert: "Foo", 1324 insert: "Foo",
1325 kind: Enum, 1325 kind: Enum,
1326 }, 1326 },
1327 CompletionItem { 1327 CompletionItem {
1328 label: "Foo::Bar", 1328 label: "Foo::Bar",
1329 source_range: 185..186, 1329 source_range: 72..73,
1330 delete: 185..186, 1330 delete: 72..73,
1331 insert: "Foo::Bar", 1331 insert: "Foo::Bar",
1332 kind: EnumVariant, 1332 kind: EnumVariant,
1333 lookup: "Bar", 1333 lookup: "Bar",
@@ -1335,8 +1335,8 @@ mod tests {
1335 }, 1335 },
1336 CompletionItem { 1336 CompletionItem {
1337 label: "Foo::Baz", 1337 label: "Foo::Baz",
1338 source_range: 185..186, 1338 source_range: 72..73,
1339 delete: 185..186, 1339 delete: 72..73,
1340 insert: "Foo::Baz", 1340 insert: "Foo::Baz",
1341 kind: EnumVariant, 1341 kind: EnumVariant,
1342 lookup: "Baz", 1342 lookup: "Baz",
@@ -1344,8 +1344,8 @@ mod tests {
1344 }, 1344 },
1345 CompletionItem { 1345 CompletionItem {
1346 label: "Foo::Quux", 1346 label: "Foo::Quux",
1347 source_range: 185..186, 1347 source_range: 72..73,
1348 delete: 185..186, 1348 delete: 72..73,
1349 insert: "Foo::Quux", 1349 insert: "Foo::Quux",
1350 kind: EnumVariant, 1350 kind: EnumVariant,
1351 lookup: "Quux", 1351 lookup: "Quux",
@@ -1353,8 +1353,8 @@ mod tests {
1353 }, 1353 },
1354 CompletionItem { 1354 CompletionItem {
1355 label: "main()", 1355 label: "main()",
1356 source_range: 185..186, 1356 source_range: 72..73,
1357 delete: 185..186, 1357 delete: 72..73,
1358 insert: "main()$0", 1358 insert: "main()$0",
1359 kind: Function, 1359 kind: Function,
1360 lookup: "main", 1360 lookup: "main",
@@ -1381,8 +1381,8 @@ mod tests {
1381 [ 1381 [
1382 CompletionItem { 1382 CompletionItem {
1383 label: "f()", 1383 label: "f()",
1384 source_range: 98..99, 1384 source_range: 49..50,
1385 delete: 98..99, 1385 delete: 49..50,
1386 insert: "f()$0", 1386 insert: "f()$0",
1387 kind: Function, 1387 kind: Function,
1388 lookup: "f", 1388 lookup: "f",
@@ -1390,15 +1390,15 @@ mod tests {
1390 }, 1390 },
1391 CompletionItem { 1391 CompletionItem {
1392 label: "m", 1392 label: "m",
1393 source_range: 98..99, 1393 source_range: 49..50,
1394 delete: 98..99, 1394 delete: 49..50,
1395 insert: "m", 1395 insert: "m",
1396 kind: Module, 1396 kind: Module,
1397 }, 1397 },
1398 CompletionItem { 1398 CompletionItem {
1399 label: "m::E::V", 1399 label: "m::E::V",
1400 source_range: 98..99, 1400 source_range: 49..50,
1401 delete: 98..99, 1401 delete: 49..50,
1402 insert: "m::E::V", 1402 insert: "m::E::V",
1403 kind: EnumVariant, 1403 kind: EnumVariant,
1404 lookup: "V", 1404 lookup: "V",
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index 61565c84f..4fdc2f0bb 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -491,13 +491,14 @@ mod tests {
491 [ 491 [
492 CompletionItem { 492 CompletionItem {
493 label: "Foo", 493 label: "Foo",
494 source_range: 121..123, 494 source_range: 56..58,
495 delete: 121..123, 495 delete: 56..58,
496 insert: "Foo", 496 insert: "Foo",
497 kind: EnumVariant, 497 kind: EnumVariant,
498 detail: "{ x: i32, y: i32 }", 498 detail: "{ x: i32, y: i32 }",
499 }, 499 },
500 ]"### 500 ]
501 "###
501 ); 502 );
502 } 503 }
503 504
@@ -517,15 +518,16 @@ mod tests {
517 [ 518 [
518 CompletionItem { 519 CompletionItem {
519 label: "Foo(…)", 520 label: "Foo(…)",
520 source_range: 115..117, 521 source_range: 50..52,
521 delete: 115..117, 522 delete: 50..52,
522 insert: "Foo($0)", 523 insert: "Foo($0)",
523 kind: EnumVariant, 524 kind: EnumVariant,
524 lookup: "Foo", 525 lookup: "Foo",
525 detail: "(i32, i32)", 526 detail: "(i32, i32)",
526 trigger_call_info: true, 527 trigger_call_info: true,
527 }, 528 },
528 ]"### 529 ]
530 "###
529 ); 531 );
530 } 532 }
531 533
@@ -545,13 +547,14 @@ mod tests {
545 [ 547 [
546 CompletionItem { 548 CompletionItem {
547 label: "Foo", 549 label: "Foo",
548 source_range: 104..106, 550 source_range: 39..41,
549 delete: 104..106, 551 delete: 39..41,
550 insert: "Foo", 552 insert: "Foo",
551 kind: EnumVariant, 553 kind: EnumVariant,
552 detail: "()", 554 detail: "()",
553 }, 555 },
554 ]"### 556 ]
557 "###
555 ); 558 );
556 } 559 }
557 560
@@ -573,8 +576,8 @@ mod tests {
573 [ 576 [
574 CompletionItem { 577 CompletionItem {
575 label: "main()", 578 label: "main()",
576 source_range: 203..206, 579 source_range: 122..125,
577 delete: 203..206, 580 delete: 122..125,
578 insert: "main()$0", 581 insert: "main()$0",
579 kind: Function, 582 kind: Function,
580 lookup: "main", 583 lookup: "main",
@@ -582,8 +585,8 @@ mod tests {
582 }, 585 },
583 CompletionItem { 586 CompletionItem {
584 label: "something_deprecated()", 587 label: "something_deprecated()",
585 source_range: 203..206, 588 source_range: 122..125,
586 delete: 203..206, 589 delete: 122..125,
587 insert: "something_deprecated()$0", 590 insert: "something_deprecated()$0",
588 kind: Function, 591 kind: Function,
589 lookup: "something_deprecated", 592 lookup: "something_deprecated",
@@ -592,8 +595,8 @@ mod tests {
592 }, 595 },
593 CompletionItem { 596 CompletionItem {
594 label: "something_else_deprecated()", 597 label: "something_else_deprecated()",
595 source_range: 203..206, 598 source_range: 122..125,
596 delete: 203..206, 599 delete: 122..125,
597 insert: "something_else_deprecated()$0", 600 insert: "something_else_deprecated()$0",
598 kind: Function, 601 kind: Function,
599 lookup: "something_else_deprecated", 602 lookup: "something_else_deprecated",
@@ -619,8 +622,8 @@ mod tests {
619 [ 622 [
620 CompletionItem { 623 CompletionItem {
621 label: "main()", 624 label: "main()",
622 source_range: 61..64, 625 source_range: 28..31,
623 delete: 61..64, 626 delete: 28..31,
624 insert: "main()$0", 627 insert: "main()$0",
625 kind: Function, 628 kind: Function,
626 lookup: "main", 629 lookup: "main",
@@ -628,8 +631,8 @@ mod tests {
628 }, 631 },
629 CompletionItem { 632 CompletionItem {
630 label: "no_args()", 633 label: "no_args()",
631 source_range: 61..64, 634 source_range: 28..31,
632 delete: 61..64, 635 delete: 28..31,
633 insert: "no_args()$0", 636 insert: "no_args()$0",
634 kind: Function, 637 kind: Function,
635 lookup: "no_args", 638 lookup: "no_args",
@@ -649,8 +652,8 @@ mod tests {
649 [ 652 [
650 CompletionItem { 653 CompletionItem {
651 label: "main()", 654 label: "main()",
652 source_range: 80..85, 655 source_range: 47..52,
653 delete: 80..85, 656 delete: 47..52,
654 insert: "main()$0", 657 insert: "main()$0",
655 kind: Function, 658 kind: Function,
656 lookup: "main", 659 lookup: "main",
@@ -658,8 +661,8 @@ mod tests {
658 }, 661 },
659 CompletionItem { 662 CompletionItem {
660 label: "with_args(…)", 663 label: "with_args(…)",
661 source_range: 80..85, 664 source_range: 47..52,
662 delete: 80..85, 665 delete: 47..52,
663 insert: "with_args(${1:x}, ${2:y})$0", 666 insert: "with_args(${1:x}, ${2:y})$0",
664 kind: Function, 667 kind: Function,
665 lookup: "with_args", 668 lookup: "with_args",
@@ -680,8 +683,8 @@ mod tests {
680 [ 683 [
681 CompletionItem { 684 CompletionItem {
682 label: "main()", 685 label: "main()",
683 source_range: 110..115, 686 source_range: 77..82,
684 delete: 110..115, 687 delete: 77..82,
685 insert: "main()$0", 688 insert: "main()$0",
686 kind: Function, 689 kind: Function,
687 lookup: "main", 690 lookup: "main",
@@ -689,8 +692,8 @@ mod tests {
689 }, 692 },
690 CompletionItem { 693 CompletionItem {
691 label: "with_ignored_args(…)", 694 label: "with_ignored_args(…)",
692 source_range: 110..115, 695 source_range: 77..82,
693 delete: 110..115, 696 delete: 77..82,
694 insert: "with_ignored_args(${1:foo}, ${2:bar}, ${3:ho_ge_})$0", 697 insert: "with_ignored_args(${1:foo}, ${2:bar}, ${3:ho_ge_})$0",
695 kind: Function, 698 kind: Function,
696 lookup: "with_ignored_args", 699 lookup: "with_ignored_args",
@@ -716,8 +719,8 @@ mod tests {
716 [ 719 [
717 CompletionItem { 720 CompletionItem {
718 label: "foo()", 721 label: "foo()",
719 source_range: 163..164, 722 source_range: 66..67,
720 delete: 163..164, 723 delete: 66..67,
721 insert: "foo()$0", 724 insert: "foo()$0",
722 kind: Method, 725 kind: Method,
723 lookup: "foo", 726 lookup: "foo",
@@ -742,8 +745,8 @@ mod tests {
742 [ 745 [
743 CompletionItem { 746 CompletionItem {
744 label: "foo_ignored_args(…)", 747 label: "foo_ignored_args(…)",
745 source_range: 194..195, 748 source_range: 97..98,
746 delete: 194..195, 749 delete: 97..98,
747 insert: "foo_ignored_args(${1:a}, ${2:b})$0", 750 insert: "foo_ignored_args(${1:a}, ${2:b})$0",
748 kind: Method, 751 kind: Method,
749 lookup: "foo_ignored_args", 752 lookup: "foo_ignored_args",
@@ -771,23 +774,23 @@ mod tests {
771 [ 774 [
772 CompletionItem { 775 CompletionItem {
773 label: "None", 776 label: "None",
774 source_range: 144..147, 777 source_range: 79..82,
775 delete: 144..147, 778 delete: 79..82,
776 insert: "None", 779 insert: "None",
777 kind: EnumVariant, 780 kind: EnumVariant,
778 detail: "()", 781 detail: "()",
779 }, 782 },
780 CompletionItem { 783 CompletionItem {
781 label: "Option", 784 label: "Option",
782 source_range: 144..147, 785 source_range: 79..82,
783 delete: 144..147, 786 delete: 79..82,
784 insert: "Option", 787 insert: "Option",
785 kind: Enum, 788 kind: Enum,
786 }, 789 },
787 CompletionItem { 790 CompletionItem {
788 label: "Some(…)", 791 label: "Some(…)",
789 source_range: 144..147, 792 source_range: 79..82,
790 delete: 144..147, 793 delete: 79..82,
791 insert: "Some($0)", 794 insert: "Some($0)",
792 kind: EnumVariant, 795 kind: EnumVariant,
793 lookup: "Some", 796 lookup: "Some",
@@ -796,8 +799,8 @@ mod tests {
796 }, 799 },
797 CompletionItem { 800 CompletionItem {
798 label: "main()", 801 label: "main()",
799 source_range: 144..147, 802 source_range: 79..82,
800 delete: 144..147, 803 delete: 79..82,
801 insert: "main()$0", 804 insert: "main()$0",
802 kind: Function, 805 kind: Function,
803 lookup: "main", 806 lookup: "main",
@@ -822,23 +825,23 @@ mod tests {
822 [ 825 [
823 CompletionItem { 826 CompletionItem {
824 label: "None", 827 label: "None",
825 source_range: 185..188, 828 source_range: 104..107,
826 delete: 185..188, 829 delete: 104..107,
827 insert: "None", 830 insert: "None",
828 kind: EnumVariant, 831 kind: EnumVariant,
829 detail: "()", 832 detail: "()",
830 }, 833 },
831 CompletionItem { 834 CompletionItem {
832 label: "Option", 835 label: "Option",
833 source_range: 185..188, 836 source_range: 104..107,
834 delete: 185..188, 837 delete: 104..107,
835 insert: "Option", 838 insert: "Option",
836 kind: Enum, 839 kind: Enum,
837 }, 840 },
838 CompletionItem { 841 CompletionItem {
839 label: "Some(…)", 842 label: "Some(…)",
840 source_range: 185..188, 843 source_range: 104..107,
841 delete: 185..188, 844 delete: 104..107,
842 insert: "Some($0)", 845 insert: "Some($0)",
843 kind: EnumVariant, 846 kind: EnumVariant,
844 lookup: "Some", 847 lookup: "Some",
@@ -872,23 +875,23 @@ mod tests {
872 [ 875 [
873 CompletionItem { 876 CompletionItem {
874 label: "ManualVtable", 877 label: "ManualVtable",
875 source_range: 295..299, 878 source_range: 182..186,
876 delete: 295..299, 879 delete: 182..186,
877 insert: "ManualVtable", 880 insert: "ManualVtable",
878 kind: Struct, 881 kind: Struct,
879 }, 882 },
880 CompletionItem { 883 CompletionItem {
881 label: "main", 884 label: "main",
882 source_range: 295..299, 885 source_range: 182..186,
883 delete: 295..299, 886 delete: 182..186,
884 insert: "main", 887 insert: "main",
885 kind: Function, 888 kind: Function,
886 detail: "fn main() -> ManualVtable", 889 detail: "fn main() -> ManualVtable",
887 }, 890 },
888 CompletionItem { 891 CompletionItem {
889 label: "somefn", 892 label: "somefn",
890 source_range: 295..299, 893 source_range: 182..186,
891 delete: 295..299, 894 delete: 182..186,
892 insert: "somefn", 895 insert: "somefn",
893 kind: Function, 896 kind: Function,
894 detail: "fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8)", 897 detail: "fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8)",
@@ -916,8 +919,8 @@ mod tests {
916 [ 919 [
917 CompletionItem { 920 CompletionItem {
918 label: "foo(…)", 921 label: "foo(…)",
919 source_range: 171..172, 922 source_range: 74..75,
920 delete: 171..172, 923 delete: 74..75,
921 insert: "foo(${1:x})$0", 924 insert: "foo(${1:x})$0",
922 kind: Method, 925 kind: Method,
923 lookup: "foo", 926 lookup: "foo",
@@ -951,8 +954,8 @@ mod tests {
951 [ 954 [
952 CompletionItem { 955 CompletionItem {
953 label: "foo(…)", 956 label: "foo(…)",
954 source_range: 171..172, 957 source_range: 74..75,
955 delete: 171..172, 958 delete: 74..75,
956 insert: "foo($0)", 959 insert: "foo($0)",
957 kind: Method, 960 kind: Method,
958 lookup: "foo", 961 lookup: "foo",
@@ -1062,16 +1065,16 @@ mod tests {
1062 [ 1065 [
1063 CompletionItem { 1066 CompletionItem {
1064 label: "Vec<…>", 1067 label: "Vec<…>",
1065 source_range: 61..63, 1068 source_range: 28..30,
1066 delete: 61..63, 1069 delete: 28..30,
1067 insert: "Vec<$0>", 1070 insert: "Vec<$0>",
1068 kind: Struct, 1071 kind: Struct,
1069 lookup: "Vec", 1072 lookup: "Vec",
1070 }, 1073 },
1071 CompletionItem { 1074 CompletionItem {
1072 label: "foo(…)", 1075 label: "foo(…)",
1073 source_range: 61..63, 1076 source_range: 28..30,
1074 delete: 61..63, 1077 delete: 28..30,
1075 insert: "foo(${1:xs})$0", 1078 insert: "foo(${1:xs})$0",
1076 kind: Function, 1079 kind: Function,
1077 lookup: "foo", 1080 lookup: "foo",
@@ -1092,16 +1095,16 @@ mod tests {
1092 [ 1095 [
1093 CompletionItem { 1096 CompletionItem {
1094 label: "Vec<…>", 1097 label: "Vec<…>",
1095 source_range: 64..66, 1098 source_range: 31..33,
1096 delete: 64..66, 1099 delete: 31..33,
1097 insert: "Vec<$0>", 1100 insert: "Vec<$0>",
1098 kind: TypeAlias, 1101 kind: TypeAlias,
1099 lookup: "Vec", 1102 lookup: "Vec",
1100 }, 1103 },
1101 CompletionItem { 1104 CompletionItem {
1102 label: "foo(…)", 1105 label: "foo(…)",
1103 source_range: 64..66, 1106 source_range: 31..33,
1104 delete: 64..66, 1107 delete: 31..33,
1105 insert: "foo(${1:xs})$0", 1108 insert: "foo(${1:xs})$0",
1106 kind: Function, 1109 kind: Function,
1107 lookup: "foo", 1110 lookup: "foo",
@@ -1122,15 +1125,15 @@ mod tests {
1122 [ 1125 [
1123 CompletionItem { 1126 CompletionItem {
1124 label: "Vec", 1127 label: "Vec",
1125 source_range: 68..70, 1128 source_range: 35..37,
1126 delete: 68..70, 1129 delete: 35..37,
1127 insert: "Vec", 1130 insert: "Vec",
1128 kind: Struct, 1131 kind: Struct,
1129 }, 1132 },
1130 CompletionItem { 1133 CompletionItem {
1131 label: "foo(…)", 1134 label: "foo(…)",
1132 source_range: 68..70, 1135 source_range: 35..37,
1133 delete: 68..70, 1136 delete: 35..37,
1134 insert: "foo(${1:xs})$0", 1137 insert: "foo(${1:xs})$0",
1135 kind: Function, 1138 kind: Function,
1136 lookup: "foo", 1139 lookup: "foo",
@@ -1151,15 +1154,15 @@ mod tests {
1151 [ 1154 [
1152 CompletionItem { 1155 CompletionItem {
1153 label: "Vec", 1156 label: "Vec",
1154 source_range: 61..63, 1157 source_range: 28..30,
1155 delete: 61..63, 1158 delete: 28..30,
1156 insert: "Vec", 1159 insert: "Vec",
1157 kind: Struct, 1160 kind: Struct,
1158 }, 1161 },
1159 CompletionItem { 1162 CompletionItem {
1160 label: "foo(…)", 1163 label: "foo(…)",
1161 source_range: 61..63, 1164 source_range: 28..30,
1162 delete: 61..63, 1165 delete: 28..30,
1163 insert: "foo(${1:xs})$0", 1166 insert: "foo(${1:xs})$0",
1164 kind: Function, 1167 kind: Function,
1165 lookup: "foo", 1168 lookup: "foo",
@@ -1254,24 +1257,24 @@ mod tests {
1254 [ 1257 [
1255 CompletionItem { 1258 CompletionItem {
1256 label: "another_field", 1259 label: "another_field",
1257 source_range: 201..201, 1260 source_range: 136..136,
1258 delete: 201..201, 1261 delete: 136..136,
1259 insert: "another_field", 1262 insert: "another_field",
1260 kind: Field, 1263 kind: Field,
1261 detail: "i64", 1264 detail: "i64",
1262 }, 1265 },
1263 CompletionItem { 1266 CompletionItem {
1264 label: "my_string", 1267 label: "my_string",
1265 source_range: 201..201, 1268 source_range: 136..136,
1266 delete: 201..201, 1269 delete: 136..136,
1267 insert: "my_string", 1270 insert: "my_string",
1268 kind: Field, 1271 kind: Field,
1269 detail: "{unknown}", 1272 detail: "{unknown}",
1270 }, 1273 },
1271 CompletionItem { 1274 CompletionItem {
1272 label: "the_field", 1275 label: "the_field",
1273 source_range: 201..201, 1276 source_range: 136..136,
1274 delete: 201..201, 1277 delete: 136..136,
1275 insert: "the_field", 1278 insert: "the_field",
1276 kind: Field, 1279 kind: Field,
1277 detail: "u32", 1280 detail: "u32",
@@ -1298,16 +1301,16 @@ mod tests {
1298 [ 1301 [
1299 CompletionItem { 1302 CompletionItem {
1300 label: "another_field", 1303 label: "another_field",
1301 source_range: 208..208, 1304 source_range: 143..143,
1302 delete: 208..208, 1305 delete: 143..143,
1303 insert: "another_field", 1306 insert: "another_field",
1304 kind: Field, 1307 kind: Field,
1305 detail: "i64", 1308 detail: "i64",
1306 }, 1309 },
1307 CompletionItem { 1310 CompletionItem {
1308 label: "another_good_type", 1311 label: "another_good_type",
1309 source_range: 208..208, 1312 source_range: 143..143,
1310 delete: 208..208, 1313 delete: 143..143,
1311 insert: "another_good_type", 1314 insert: "another_good_type",
1312 kind: Field, 1315 kind: Field,
1313 detail: "u32", 1316 detail: "u32",
@@ -1315,8 +1318,8 @@ mod tests {
1315 }, 1318 },
1316 CompletionItem { 1319 CompletionItem {
1317 label: "the_field", 1320 label: "the_field",
1318 source_range: 208..208, 1321 source_range: 143..143,
1319 delete: 208..208, 1322 delete: 143..143,
1320 insert: "the_field", 1323 insert: "the_field",
1321 kind: Field, 1324 kind: Field,
1322 detail: "u32", 1325 detail: "u32",
@@ -1346,16 +1349,16 @@ mod tests {
1346 [ 1349 [
1347 CompletionItem { 1350 CompletionItem {
1348 label: "another_field", 1351 label: "another_field",
1349 source_range: 270..270, 1352 source_range: 189..189,
1350 delete: 270..270, 1353 delete: 189..189,
1351 insert: "another_field", 1354 insert: "another_field",
1352 kind: Field, 1355 kind: Field,
1353 detail: "i64", 1356 detail: "i64",
1354 }, 1357 },
1355 CompletionItem { 1358 CompletionItem {
1356 label: "another_good_type", 1359 label: "another_good_type",
1357 source_range: 270..270, 1360 source_range: 189..189,
1358 delete: 270..270, 1361 delete: 189..189,
1359 insert: "another_good_type", 1362 insert: "another_good_type",
1360 kind: Field, 1363 kind: Field,
1361 detail: "u32", 1364 detail: "u32",
@@ -1363,8 +1366,8 @@ mod tests {
1363 }, 1366 },
1364 CompletionItem { 1367 CompletionItem {
1365 label: "the_field", 1368 label: "the_field",
1366 source_range: 270..270, 1369 source_range: 189..189,
1367 delete: 270..270, 1370 delete: 189..189,
1368 insert: "the_field", 1371 insert: "the_field",
1369 kind: Field, 1372 kind: Field,
1370 detail: "u32", 1373 detail: "u32",
@@ -1394,8 +1397,8 @@ mod tests {
1394 [ 1397 [
1395 CompletionItem { 1398 CompletionItem {
1396 label: "another_field", 1399 label: "another_field",
1397 source_range: 336..336, 1400 source_range: 239..239,
1398 delete: 336..336, 1401 delete: 239..239,
1399 insert: "another_field", 1402 insert: "another_field",
1400 kind: Field, 1403 kind: Field,
1401 detail: "i64", 1404 detail: "i64",
@@ -1403,16 +1406,16 @@ mod tests {
1403 }, 1406 },
1404 CompletionItem { 1407 CompletionItem {
1405 label: "another_good_type", 1408 label: "another_good_type",
1406 source_range: 336..336, 1409 source_range: 239..239,
1407 delete: 336..336, 1410 delete: 239..239,
1408 insert: "another_good_type", 1411 insert: "another_good_type",
1409 kind: Field, 1412 kind: Field,
1410 detail: "u32", 1413 detail: "u32",
1411 }, 1414 },
1412 CompletionItem { 1415 CompletionItem {
1413 label: "the_field", 1416 label: "the_field",
1414 source_range: 336..336, 1417 source_range: 239..239,
1415 delete: 336..336, 1418 delete: 239..239,
1416 insert: "the_field", 1419 insert: "the_field",
1417 kind: Field, 1420 kind: Field,
1418 detail: "u32", 1421 detail: "u32",
@@ -1441,16 +1444,16 @@ mod tests {
1441 [ 1444 [
1442 CompletionItem { 1445 CompletionItem {
1443 label: "another_field", 1446 label: "another_field",
1444 source_range: 328..328, 1447 source_range: 231..231,
1445 delete: 328..328, 1448 delete: 231..231,
1446 insert: "another_field", 1449 insert: "another_field",
1447 kind: Field, 1450 kind: Field,
1448 detail: "i64", 1451 detail: "i64",
1449 }, 1452 },
1450 CompletionItem { 1453 CompletionItem {
1451 label: "another_good_type", 1454 label: "another_good_type",
1452 source_range: 328..328, 1455 source_range: 231..231,
1453 delete: 328..328, 1456 delete: 231..231,
1454 insert: "another_good_type", 1457 insert: "another_good_type",
1455 kind: Field, 1458 kind: Field,
1456 detail: "u32", 1459 detail: "u32",
@@ -1458,8 +1461,8 @@ mod tests {
1458 }, 1461 },
1459 CompletionItem { 1462 CompletionItem {
1460 label: "the_field", 1463 label: "the_field",
1461 source_range: 328..328, 1464 source_range: 231..231,
1462 delete: 328..328, 1465 delete: 231..231,
1463 insert: "the_field", 1466 insert: "the_field",
1464 kind: Field, 1467 kind: Field,
1465 detail: "u32", 1468 detail: "u32",
@@ -1485,15 +1488,15 @@ mod tests {
1485 [ 1488 [
1486 CompletionItem { 1489 CompletionItem {
1487 label: "WorldSnapshot", 1490 label: "WorldSnapshot",
1488 source_range: 132..133, 1491 source_range: 71..72,
1489 delete: 132..133, 1492 delete: 71..72,
1490 insert: "WorldSnapshot", 1493 insert: "WorldSnapshot",
1491 kind: Struct, 1494 kind: Struct,
1492 }, 1495 },
1493 CompletionItem { 1496 CompletionItem {
1494 label: "go(…)", 1497 label: "go(…)",
1495 source_range: 132..133, 1498 source_range: 71..72,
1496 delete: 132..133, 1499 delete: 71..72,
1497 insert: "go(${1:world})$0", 1500 insert: "go(${1:world})$0",
1498 kind: Function, 1501 kind: Function,
1499 lookup: "go", 1502 lookup: "go",
@@ -1502,8 +1505,8 @@ mod tests {
1502 }, 1505 },
1503 CompletionItem { 1506 CompletionItem {
1504 label: "world", 1507 label: "world",
1505 source_range: 132..133, 1508 source_range: 71..72,
1506 delete: 132..133, 1509 delete: 71..72,
1507 insert: "world", 1510 insert: "world",
1508 kind: Binding, 1511 kind: Binding,
1509 detail: "&WorldSnapshot", 1512 detail: "&WorldSnapshot",
diff --git a/crates/ra_ide/src/completion/test_utils.rs b/crates/ra_ide/src/completion/test_utils.rs
index 1e16a43ca..a1b7c1193 100644
--- a/crates/ra_ide/src/completion/test_utils.rs
+++ b/crates/ra_ide/src/completion/test_utils.rs
@@ -2,7 +2,7 @@
2 2
3use crate::{ 3use crate::{
4 completion::{completion_item::CompletionKind, CompletionConfig}, 4 completion::{completion_item::CompletionKind, CompletionConfig},
5 mock_analysis::{analysis_and_position, single_file_with_position}, 5 mock_analysis::analysis_and_position,
6 CompletionItem, 6 CompletionItem,
7}; 7};
8use hir::Semantics; 8use hir::Semantics;
@@ -33,7 +33,7 @@ fn get_all_completion_items(code: &str, options: &CompletionConfig) -> Vec<Compl
33 let (analysis, position) = if code.contains("//-") { 33 let (analysis, position) = if code.contains("//-") {
34 analysis_and_position(code) 34 analysis_and_position(code)
35 } else { 35 } else {
36 single_file_with_position(code) 36 analysis_and_position(code)
37 }; 37 };
38 analysis.completions(options, position).unwrap().unwrap().into() 38 analysis.completions(options, position).unwrap().unwrap().into()
39} 39}
@@ -55,7 +55,7 @@ pub(crate) fn completion_list_with_options(
55} 55}
56 56
57pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) { 57pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
58 let (analysis, pos) = single_file_with_position(code); 58 let (analysis, pos) = analysis_and_position(code);
59 analysis 59 analysis
60 .with_db(|db| { 60 .with_db(|db| {
61 let sema = Semantics::new(db); 61 let sema = Semantics::new(db);
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index 8cb0700b9..05fb799d6 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -348,8 +348,10 @@ mod tests {
348 ); 348 );
349 } 349 }
350 350
351 fn check_apply_diagnostic_fix(before: &str, after: &str) { 351 fn check_apply_diagnostic_fix(ra_fixture_before: &str, ra_fixture_after: &str) {
352 let (analysis, file_id) = single_file(before); 352 let ra_fixture_after = &trim_indent(ra_fixture_after);
353 let (analysis, file_id) = single_file(ra_fixture_before);
354 let before = analysis.file_text(file_id).unwrap();
353 let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap(); 355 let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap();
354 let mut fix = diagnostic.fix.unwrap(); 356 let mut fix = diagnostic.fix.unwrap();
355 let edit = fix.source_change.source_file_edits.pop().unwrap().edit; 357 let edit = fix.source_change.source_file_edits.pop().unwrap().edit;
@@ -358,7 +360,7 @@ mod tests {
358 edit.apply(&mut actual); 360 edit.apply(&mut actual);
359 actual 361 actual
360 }; 362 };
361 assert_eq_text!(after, &actual); 363 assert_eq_text!(ra_fixture_after, &actual);
362 } 364 }
363 365
364 /// Takes a multi-file input fixture with annotated cursor position and checks that no diagnostics 366 /// Takes a multi-file input fixture with annotated cursor position and checks that no diagnostics
@@ -571,10 +573,9 @@ mod tests {
571 573
572 impl Expr { 574 impl Expr {
573 fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr { 575 fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr {
574 Expr::Bin { <|> } 576 Expr::Bin { }
575 } 577 }
576 } 578 }
577
578 "; 579 ";
579 let after = r" 580 let after = r"
580 enum Expr { 581 enum Expr {
@@ -583,10 +584,9 @@ mod tests {
583 584
584 impl Expr { 585 impl Expr {
585 fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr { 586 fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr {
586 Expr::Bin { lhs: (), rhs: () <|> } 587 Expr::Bin { lhs: (), rhs: () }
587 } 588 }
588 } 589 }
589
590 "; 590 ";
591 check_apply_diagnostic_fix(before, after); 591 check_apply_diagnostic_fix(before, after);
592 } 592 }
@@ -709,7 +709,7 @@ mod tests {
709 [ 709 [
710 Diagnostic { 710 Diagnostic {
711 message: "Missing structure fields:\n- b\n", 711 message: "Missing structure fields:\n- b\n",
712 range: 224..233, 712 range: 127..136,
713 severity: Error, 713 severity: Error,
714 fix: Some( 714 fix: Some(
715 Fix { 715 Fix {
@@ -855,22 +855,22 @@ fn main() {
855 fn test_add_field_from_usage() { 855 fn test_add_field_from_usage() {
856 check_apply_diagnostic_fix( 856 check_apply_diagnostic_fix(
857 r" 857 r"
858 fn main() { 858fn main() {
859 Foo { bar: 3, baz: false}; 859 Foo { bar: 3, baz: false};
860 } 860}
861 struct Foo { 861struct Foo {
862 bar: i32 862 bar: i32
863 } 863}
864 ", 864",
865 r" 865 r"
866 fn main() { 866fn main() {
867 Foo { bar: 3, baz: false}; 867 Foo { bar: 3, baz: false};
868 } 868}
869 struct Foo { 869struct Foo {
870 bar: i32, 870 bar: i32,
871 baz: bool 871 baz: bool
872 } 872}
873 ", 873",
874 ) 874 )
875 } 875 }
876} 876}
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs
index a4bc93cdb..8a6b3ea99 100644
--- a/crates/ra_ide/src/extend_selection.rs
+++ b/crates/ra_ide/src/extend_selection.rs
@@ -315,17 +315,15 @@ fn adj_comments(comment: &ast::Comment, dir: Direction) -> ast::Comment {
315 315
316#[cfg(test)] 316#[cfg(test)]
317mod tests { 317mod tests {
318 use test_utils::extract_offset; 318 use crate::mock_analysis::analysis_and_position;
319
320 use crate::mock_analysis::single_file;
321 319
322 use super::*; 320 use super::*;
323 321
324 fn do_check(before: &str, afters: &[&str]) { 322 fn do_check(before: &str, afters: &[&str]) {
325 let (cursor, before) = extract_offset(before); 323 let (analysis, position) = analysis_and_position(&before);
326 let (analysis, file_id) = single_file(&before); 324 let before = analysis.file_text(position.file_id).unwrap();
327 let range = TextRange::empty(cursor); 325 let range = TextRange::empty(position.offset);
328 let mut frange = FileRange { file_id, range }; 326 let mut frange = FileRange { file_id: position.file_id, range };
329 327
330 for &after in afters { 328 for &after in afters {
331 frange.range = analysis.extend_selection(frange).unwrap(); 329 frange.range = analysis.extend_selection(frange).unwrap();
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index a898f2e4a..c3e36a387 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -399,7 +399,7 @@ mod tests {
399 use ra_db::FileLoader; 399 use ra_db::FileLoader;
400 use ra_syntax::TextRange; 400 use ra_syntax::TextRange;
401 401
402 use crate::mock_analysis::{analysis_and_position, single_file_with_position}; 402 use crate::mock_analysis::analysis_and_position;
403 403
404 fn trim_markup(s: &str) -> &str { 404 fn trim_markup(s: &str) -> &str {
405 s.trim_start_matches("```rust\n").trim_end_matches("\n```") 405 s.trim_start_matches("```rust\n").trim_end_matches("\n```")
@@ -442,17 +442,17 @@ mod tests {
442 442
443 #[test] 443 #[test]
444 fn hover_shows_type_of_an_expression() { 444 fn hover_shows_type_of_an_expression() {
445 let (analysis, position) = single_file_with_position( 445 let (analysis, position) = analysis_and_position(
446 " 446 r#"
447 pub fn foo() -> u32 { 1 } 447pub fn foo() -> u32 { 1 }
448 448
449 fn main() { 449fn main() {
450 let foo_test = foo()<|>; 450 let foo_test = foo()<|>;
451 } 451}
452 ", 452"#,
453 ); 453 );
454 let hover = analysis.hover(position).unwrap().unwrap(); 454 let hover = analysis.hover(position).unwrap().unwrap();
455 assert_eq!(hover.range, TextRange::new(95.into(), 100.into())); 455 assert_eq!(hover.range, TextRange::new(58.into(), 63.into()));
456 assert_eq!(trim_markup_opt(hover.info.first()), Some("u32")); 456 assert_eq!(trim_markup_opt(hover.info.first()), Some("u32"));
457 } 457 }
458 458
@@ -641,7 +641,7 @@ fn main() {
641 641
642 #[test] 642 #[test]
643 fn hover_some() { 643 fn hover_some() {
644 let (analysis, position) = single_file_with_position( 644 let (analysis, position) = analysis_and_position(
645 " 645 "
646 enum Option<T> { Some(T) } 646 enum Option<T> { Some(T) }
647 use Option::Some; 647 use Option::Some;
@@ -654,7 +654,7 @@ fn main() {
654 let hover = analysis.hover(position).unwrap().unwrap(); 654 let hover = analysis.hover(position).unwrap().unwrap();
655 assert_eq!(trim_markup_opt(hover.info.first()), Some("Option\n```\n\n```rust\nSome")); 655 assert_eq!(trim_markup_opt(hover.info.first()), Some("Option\n```\n\n```rust\nSome"));
656 656
657 let (analysis, position) = single_file_with_position( 657 let (analysis, position) = analysis_and_position(
658 " 658 "
659 enum Option<T> { Some(T) } 659 enum Option<T> { Some(T) }
660 use Option::Some; 660 use Option::Some;
@@ -720,21 +720,21 @@ The Some variant
720 720
721 #[test] 721 #[test]
722 fn hover_for_local_variable() { 722 fn hover_for_local_variable() {
723 let (analysis, position) = single_file_with_position("fn func(foo: i32) { fo<|>o; }"); 723 let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }");
724 let hover = analysis.hover(position).unwrap().unwrap(); 724 let hover = analysis.hover(position).unwrap().unwrap();
725 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 725 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
726 } 726 }
727 727
728 #[test] 728 #[test]
729 fn hover_for_local_variable_pat() { 729 fn hover_for_local_variable_pat() {
730 let (analysis, position) = single_file_with_position("fn func(fo<|>o: i32) {}"); 730 let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}");
731 let hover = analysis.hover(position).unwrap().unwrap(); 731 let hover = analysis.hover(position).unwrap().unwrap();
732 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 732 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
733 } 733 }
734 734
735 #[test] 735 #[test]
736 fn hover_local_var_edge() { 736 fn hover_local_var_edge() {
737 let (analysis, position) = single_file_with_position( 737 let (analysis, position) = analysis_and_position(
738 " 738 "
739fn func(foo: i32) { if true { <|>foo; }; } 739fn func(foo: i32) { if true { <|>foo; }; }
740", 740",
@@ -745,14 +745,14 @@ fn func(foo: i32) { if true { <|>foo; }; }
745 745
746 #[test] 746 #[test]
747 fn hover_for_param_edge() { 747 fn hover_for_param_edge() {
748 let (analysis, position) = single_file_with_position("fn func(<|>foo: i32) {}"); 748 let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}");
749 let hover = analysis.hover(position).unwrap().unwrap(); 749 let hover = analysis.hover(position).unwrap().unwrap();
750 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 750 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
751 } 751 }
752 752
753 #[test] 753 #[test]
754 fn test_hover_infer_associated_method_result() { 754 fn test_hover_infer_associated_method_result() {
755 let (analysis, position) = single_file_with_position( 755 let (analysis, position) = analysis_and_position(
756 " 756 "
757 struct Thing { x: u32 } 757 struct Thing { x: u32 }
758 758
@@ -773,7 +773,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
773 773
774 #[test] 774 #[test]
775 fn test_hover_infer_associated_method_exact() { 775 fn test_hover_infer_associated_method_exact() {
776 let (analysis, position) = single_file_with_position( 776 let (analysis, position) = analysis_and_position(
777 " 777 "
778 mod wrapper { 778 mod wrapper {
779 struct Thing { x: u32 } 779 struct Thing { x: u32 }
@@ -799,7 +799,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
799 799
800 #[test] 800 #[test]
801 fn test_hover_infer_associated_const_in_pattern() { 801 fn test_hover_infer_associated_const_in_pattern() {
802 let (analysis, position) = single_file_with_position( 802 let (analysis, position) = analysis_and_position(
803 " 803 "
804 struct X; 804 struct X;
805 impl X { 805 impl X {
@@ -821,7 +821,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
821 821
822 #[test] 822 #[test]
823 fn test_hover_self() { 823 fn test_hover_self() {
824 let (analysis, position) = single_file_with_position( 824 let (analysis, position) = analysis_and_position(
825 " 825 "
826 struct Thing { x: u32 } 826 struct Thing { x: u32 }
827 impl Thing { 827 impl Thing {
@@ -835,7 +835,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
835 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); 835 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
836 836
837 /* FIXME: revive these tests 837 /* FIXME: revive these tests
838 let (analysis, position) = single_file_with_position( 838 let (analysis, position) = analysis_and_position(
839 " 839 "
840 struct Thing { x: u32 } 840 struct Thing { x: u32 }
841 impl Thing { 841 impl Thing {
@@ -849,7 +849,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
849 let hover = analysis.hover(position).unwrap().unwrap(); 849 let hover = analysis.hover(position).unwrap().unwrap();
850 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); 850 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
851 851
852 let (analysis, position) = single_file_with_position( 852 let (analysis, position) = analysis_and_position(
853 " 853 "
854 enum Thing { A } 854 enum Thing { A }
855 impl Thing { 855 impl Thing {
@@ -862,7 +862,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
862 let hover = analysis.hover(position).unwrap().unwrap(); 862 let hover = analysis.hover(position).unwrap().unwrap();
863 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); 863 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing"));
864 864
865 let (analysis, position) = single_file_with_position( 865 let (analysis, position) = analysis_and_position(
866 " 866 "
867 enum Thing { A } 867 enum Thing { A }
868 impl Thing { 868 impl Thing {
@@ -878,7 +878,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
878 878
879 #[test] 879 #[test]
880 fn test_hover_shadowing_pat() { 880 fn test_hover_shadowing_pat() {
881 let (analysis, position) = single_file_with_position( 881 let (analysis, position) = analysis_and_position(
882 " 882 "
883 fn x() {} 883 fn x() {}
884 884
@@ -894,7 +894,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
894 894
895 #[test] 895 #[test]
896 fn test_hover_macro_invocation() { 896 fn test_hover_macro_invocation() {
897 let (analysis, position) = single_file_with_position( 897 let (analysis, position) = analysis_and_position(
898 " 898 "
899 macro_rules! foo { 899 macro_rules! foo {
900 () => {} 900 () => {}
@@ -911,7 +911,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
911 911
912 #[test] 912 #[test]
913 fn test_hover_tuple_field() { 913 fn test_hover_tuple_field() {
914 let (analysis, position) = single_file_with_position( 914 let (analysis, position) = analysis_and_position(
915 " 915 "
916 struct TS(String, i32<|>); 916 struct TS(String, i32<|>);
917 ", 917 ",
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index 7eb2cef73..3fd08b1e8 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -363,16 +363,17 @@ mod tests {
363 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: true, type_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###" 363 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: true, type_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
364 [ 364 [
365 InlayHint { 365 InlayHint {
366 range: 106..107, 366 range: 69..70,
367 kind: ParameterHint, 367 kind: ParameterHint,
368 label: "a", 368 label: "a",
369 }, 369 },
370 InlayHint { 370 InlayHint {
371 range: 109..110, 371 range: 72..73,
372 kind: ParameterHint, 372 kind: ParameterHint,
373 label: "b", 373 label: "b",
374 }, 374 },
375 ]"###); 375 ]
376 "###);
376 } 377 }
377 378
378 #[test] 379 #[test]
@@ -399,11 +400,12 @@ mod tests {
399 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ type_hints: true, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###" 400 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ type_hints: true, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
400 [ 401 [
401 InlayHint { 402 InlayHint {
402 range: 97..99, 403 range: 60..62,
403 kind: TypeHint, 404 kind: TypeHint,
404 label: "i32", 405 label: "i32",
405 }, 406 },
406 ]"###); 407 ]
408 "###);
407 } 409 }
408 #[test] 410 #[test]
409 fn default_generic_types_should_not_be_displayed() { 411 fn default_generic_types_should_not_be_displayed() {
@@ -423,12 +425,12 @@ fn main() {
423 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 425 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
424 [ 426 [
425 InlayHint { 427 InlayHint {
426 range: 69..71, 428 range: 68..70,
427 kind: TypeHint, 429 kind: TypeHint,
428 label: "Test<i32>", 430 label: "Test<i32>",
429 }, 431 },
430 InlayHint { 432 InlayHint {
431 range: 107..113, 433 range: 106..112,
432 kind: TypeHint, 434 kind: TypeHint,
433 label: "&Test<i32>", 435 label: "&Test<i32>",
434 }, 436 },
@@ -480,57 +482,57 @@ fn main() {
480 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 482 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
481 [ 483 [
482 InlayHint { 484 InlayHint {
483 range: 193..197, 485 range: 192..196,
484 kind: TypeHint, 486 kind: TypeHint,
485 label: "i32", 487 label: "i32",
486 }, 488 },
487 InlayHint { 489 InlayHint {
488 range: 236..244, 490 range: 235..243,
489 kind: TypeHint, 491 kind: TypeHint,
490 label: "i32", 492 label: "i32",
491 }, 493 },
492 InlayHint { 494 InlayHint {
493 range: 275..279, 495 range: 274..278,
494 kind: TypeHint, 496 kind: TypeHint,
495 label: "&str", 497 label: "&str",
496 }, 498 },
497 InlayHint { 499 InlayHint {
498 range: 539..543, 500 range: 538..542,
499 kind: TypeHint, 501 kind: TypeHint,
500 label: "(i32, char)", 502 label: "(i32, char)",
501 }, 503 },
502 InlayHint { 504 InlayHint {
503 range: 566..567, 505 range: 565..566,
504 kind: TypeHint, 506 kind: TypeHint,
505 label: "i32", 507 label: "i32",
506 }, 508 },
507 InlayHint { 509 InlayHint {
508 range: 570..571, 510 range: 569..570,
509 kind: TypeHint, 511 kind: TypeHint,
510 label: "i32", 512 label: "i32",
511 }, 513 },
512 InlayHint { 514 InlayHint {
513 range: 573..574, 515 range: 572..573,
514 kind: TypeHint, 516 kind: TypeHint,
515 label: "i32", 517 label: "i32",
516 }, 518 },
517 InlayHint { 519 InlayHint {
518 range: 577..578, 520 range: 576..577,
519 kind: TypeHint, 521 kind: TypeHint,
520 label: "f64", 522 label: "f64",
521 }, 523 },
522 InlayHint { 524 InlayHint {
523 range: 580..581, 525 range: 579..580,
524 kind: TypeHint, 526 kind: TypeHint,
525 label: "f64", 527 label: "f64",
526 }, 528 },
527 InlayHint { 529 InlayHint {
528 range: 584..585, 530 range: 583..584,
529 kind: TypeHint, 531 kind: TypeHint,
530 label: "i32", 532 label: "i32",
531 }, 533 },
532 InlayHint { 534 InlayHint {
533 range: 627..628, 535 range: 626..627,
534 kind: TypeHint, 536 kind: TypeHint,
535 label: "i32", 537 label: "i32",
536 }, 538 },
@@ -560,47 +562,47 @@ fn main() {
560 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 562 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
561 [ 563 [
562 InlayHint { 564 InlayHint {
563 range: 21..30, 565 range: 20..29,
564 kind: TypeHint, 566 kind: TypeHint,
565 label: "i32", 567 label: "i32",
566 }, 568 },
567 InlayHint { 569 InlayHint {
568 range: 57..66, 570 range: 56..65,
569 kind: TypeHint, 571 kind: TypeHint,
570 label: "i32", 572 label: "i32",
571 }, 573 },
572 InlayHint { 574 InlayHint {
573 range: 115..123, 575 range: 114..122,
574 kind: TypeHint, 576 kind: TypeHint,
575 label: "|…| -> i32", 577 label: "|…| -> i32",
576 }, 578 },
577 InlayHint { 579 InlayHint {
578 range: 127..128, 580 range: 126..127,
579 kind: TypeHint, 581 kind: TypeHint,
580 label: "i32", 582 label: "i32",
581 }, 583 },
582 InlayHint { 584 InlayHint {
583 range: 130..131, 585 range: 129..130,
584 kind: TypeHint, 586 kind: TypeHint,
585 label: "i32", 587 label: "i32",
586 }, 588 },
587 InlayHint { 589 InlayHint {
588 range: 133..134, 590 range: 132..133,
589 kind: TypeHint, 591 kind: TypeHint,
590 label: "i32", 592 label: "i32",
591 }, 593 },
592 InlayHint { 594 InlayHint {
593 range: 136..137, 595 range: 135..136,
594 kind: TypeHint, 596 kind: TypeHint,
595 label: "i32", 597 label: "i32",
596 }, 598 },
597 InlayHint { 599 InlayHint {
598 range: 201..213, 600 range: 200..212,
599 kind: TypeHint, 601 kind: TypeHint,
600 label: "&|…| -> i32", 602 label: "&|…| -> i32",
601 }, 603 },
602 InlayHint { 604 InlayHint {
603 range: 236..245, 605 range: 235..244,
604 kind: TypeHint, 606 kind: TypeHint,
605 label: "|| -> i32", 607 label: "|| -> i32",
606 }, 608 },
@@ -624,12 +626,12 @@ fn main() {
624 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 626 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
625 [ 627 [
626 InlayHint { 628 InlayHint {
627 range: 21..30, 629 range: 20..29,
628 kind: TypeHint, 630 kind: TypeHint,
629 label: "i32", 631 label: "i32",
630 }, 632 },
631 InlayHint { 633 InlayHint {
632 range: 44..53, 634 range: 43..52,
633 kind: TypeHint, 635 kind: TypeHint,
634 label: "i32", 636 label: "i32",
635 }, 637 },
@@ -674,57 +676,57 @@ fn main() {
674 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 676 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
675 [ 677 [
676 InlayHint { 678 InlayHint {
677 range: 188..192, 679 range: 187..191,
678 kind: TypeHint, 680 kind: TypeHint,
679 label: "CustomOption<Test>", 681 label: "CustomOption<Test>",
680 }, 682 },
681 InlayHint { 683 InlayHint {
682 range: 267..271, 684 range: 266..270,
683 kind: TypeHint, 685 kind: TypeHint,
684 label: "&CustomOption<Test>", 686 label: "&CustomOption<Test>",
685 }, 687 },
686 InlayHint { 688 InlayHint {
687 range: 300..304, 689 range: 299..303,
688 kind: TypeHint, 690 kind: TypeHint,
689 label: "&Test", 691 label: "&Test",
690 }, 692 },
691 InlayHint { 693 InlayHint {
692 range: 341..342, 694 range: 340..341,
693 kind: TypeHint, 695 kind: TypeHint,
694 label: "&CustomOption<u32>", 696 label: "&CustomOption<u32>",
695 }, 697 },
696 InlayHint { 698 InlayHint {
697 range: 344..345, 699 range: 343..344,
698 kind: TypeHint, 700 kind: TypeHint,
699 label: "&u8", 701 label: "&u8",
700 }, 702 },
701 InlayHint { 703 InlayHint {
702 range: 387..388, 704 range: 386..387,
703 kind: TypeHint, 705 kind: TypeHint,
704 label: "&CustomOption<u32>", 706 label: "&CustomOption<u32>",
705 }, 707 },
706 InlayHint { 708 InlayHint {
707 range: 393..394, 709 range: 392..393,
708 kind: TypeHint, 710 kind: TypeHint,
709 label: "&u8", 711 label: "&u8",
710 }, 712 },
711 InlayHint { 713 InlayHint {
712 range: 441..442, 714 range: 440..441,
713 kind: TypeHint, 715 kind: TypeHint,
714 label: "&u32", 716 label: "&u32",
715 }, 717 },
716 InlayHint { 718 InlayHint {
717 range: 448..449, 719 range: 447..448,
718 kind: TypeHint, 720 kind: TypeHint,
719 label: "&u8", 721 label: "&u8",
720 }, 722 },
721 InlayHint { 723 InlayHint {
722 range: 500..501, 724 range: 499..500,
723 kind: TypeHint, 725 kind: TypeHint,
724 label: "&u8", 726 label: "&u8",
725 }, 727 },
726 InlayHint { 728 InlayHint {
727 range: 543..544, 729 range: 542..543,
728 kind: TypeHint, 730 kind: TypeHint,
729 label: "&u8", 731 label: "&u8",
730 }, 732 },
@@ -769,57 +771,57 @@ fn main() {
769 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 771 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
770 [ 772 [
771 InlayHint { 773 InlayHint {
772 range: 188..192, 774 range: 187..191,
773 kind: TypeHint, 775 kind: TypeHint,
774 label: "CustomOption<Test>", 776 label: "CustomOption<Test>",
775 }, 777 },
776 InlayHint { 778 InlayHint {
777 range: 273..277, 779 range: 272..276,
778 kind: TypeHint, 780 kind: TypeHint,
779 label: "&CustomOption<Test>", 781 label: "&CustomOption<Test>",
780 }, 782 },
781 InlayHint { 783 InlayHint {
782 range: 309..313, 784 range: 308..312,
783 kind: TypeHint, 785 kind: TypeHint,
784 label: "&Test", 786 label: "&Test",
785 }, 787 },
786 InlayHint { 788 InlayHint {
787 range: 353..354, 789 range: 352..353,
788 kind: TypeHint, 790 kind: TypeHint,
789 label: "&CustomOption<u32>", 791 label: "&CustomOption<u32>",
790 }, 792 },
791 InlayHint { 793 InlayHint {
792 range: 356..357, 794 range: 355..356,
793 kind: TypeHint, 795 kind: TypeHint,
794 label: "&u8", 796 label: "&u8",
795 }, 797 },
796 InlayHint { 798 InlayHint {
797 range: 402..403, 799 range: 401..402,
798 kind: TypeHint, 800 kind: TypeHint,
799 label: "&CustomOption<u32>", 801 label: "&CustomOption<u32>",
800 }, 802 },
801 InlayHint { 803 InlayHint {
802 range: 408..409, 804 range: 407..408,
803 kind: TypeHint, 805 kind: TypeHint,
804 label: "&u8", 806 label: "&u8",
805 }, 807 },
806 InlayHint { 808 InlayHint {
807 range: 459..460, 809 range: 458..459,
808 kind: TypeHint, 810 kind: TypeHint,
809 label: "&u32", 811 label: "&u32",
810 }, 812 },
811 InlayHint { 813 InlayHint {
812 range: 466..467, 814 range: 465..466,
813 kind: TypeHint, 815 kind: TypeHint,
814 label: "&u8", 816 label: "&u8",
815 }, 817 },
816 InlayHint { 818 InlayHint {
817 range: 521..522, 819 range: 520..521,
818 kind: TypeHint, 820 kind: TypeHint,
819 label: "&u8", 821 label: "&u8",
820 }, 822 },
821 InlayHint { 823 InlayHint {
822 range: 567..568, 824 range: 566..567,
823 kind: TypeHint, 825 kind: TypeHint,
824 label: "&u8", 826 label: "&u8",
825 }, 827 },
@@ -864,52 +866,52 @@ fn main() {
864 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 866 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
865 [ 867 [
866 InlayHint { 868 InlayHint {
867 range: 252..256, 869 range: 251..255,
868 kind: TypeHint, 870 kind: TypeHint,
869 label: "CustomOption<Test>", 871 label: "CustomOption<Test>",
870 }, 872 },
871 InlayHint { 873 InlayHint {
872 range: 277..281, 874 range: 276..280,
873 kind: TypeHint, 875 kind: TypeHint,
874 label: "Test", 876 label: "Test",
875 }, 877 },
876 InlayHint { 878 InlayHint {
877 range: 310..311, 879 range: 309..310,
878 kind: TypeHint, 880 kind: TypeHint,
879 label: "CustomOption<u32>", 881 label: "CustomOption<u32>",
880 }, 882 },
881 InlayHint { 883 InlayHint {
882 range: 313..314, 884 range: 312..313,
883 kind: TypeHint, 885 kind: TypeHint,
884 label: "u8", 886 label: "u8",
885 }, 887 },
886 InlayHint { 888 InlayHint {
887 range: 348..349, 889 range: 347..348,
888 kind: TypeHint, 890 kind: TypeHint,
889 label: "CustomOption<u32>", 891 label: "CustomOption<u32>",
890 }, 892 },
891 InlayHint { 893 InlayHint {
892 range: 354..355, 894 range: 353..354,
893 kind: TypeHint, 895 kind: TypeHint,
894 label: "u8", 896 label: "u8",
895 }, 897 },
896 InlayHint { 898 InlayHint {
897 range: 394..395, 899 range: 393..394,
898 kind: TypeHint, 900 kind: TypeHint,
899 label: "u32", 901 label: "u32",
900 }, 902 },
901 InlayHint { 903 InlayHint {
902 range: 401..402, 904 range: 400..401,
903 kind: TypeHint, 905 kind: TypeHint,
904 label: "u8", 906 label: "u8",
905 }, 907 },
906 InlayHint { 908 InlayHint {
907 range: 445..446, 909 range: 444..445,
908 kind: TypeHint, 910 kind: TypeHint,
909 label: "u8", 911 label: "u8",
910 }, 912 },
911 InlayHint { 913 InlayHint {
912 range: 480..481, 914 range: 479..480,
913 kind: TypeHint, 915 kind: TypeHint,
914 label: "u8", 916 label: "u8",
915 }, 917 },
@@ -936,17 +938,17 @@ fn main() {
936 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###" 938 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
937 [ 939 [
938 InlayHint { 940 InlayHint {
939 range: 74..75, 941 range: 73..74,
940 kind: TypeHint, 942 kind: TypeHint,
941 label: "Smol<u32>", 943 label: "Smol<u32>",
942 }, 944 },
943 InlayHint { 945 InlayHint {
944 range: 98..99, 946 range: 97..98,
945 kind: TypeHint, 947 kind: TypeHint,
946 label: "VeryLongOuterName<…>", 948 label: "VeryLongOuterName<…>",
947 }, 949 },
948 InlayHint { 950 InlayHint {
949 range: 137..138, 951 range: 136..137,
950 kind: TypeHint, 952 kind: TypeHint,
951 label: "Smol<Smol<…>>", 953 label: "Smol<Smol<…>>",
952 }, 954 },
@@ -1024,77 +1026,77 @@ fn main() {
1024 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###" 1026 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
1025 [ 1027 [
1026 InlayHint { 1028 InlayHint {
1027 range: 798..809, 1029 range: 797..808,
1028 kind: TypeHint, 1030 kind: TypeHint,
1029 label: "i32", 1031 label: "i32",
1030 }, 1032 },
1031 InlayHint { 1033 InlayHint {
1032 range: 842..843, 1034 range: 841..842,
1033 kind: ParameterHint, 1035 kind: ParameterHint,
1034 label: "foo", 1036 label: "foo",
1035 }, 1037 },
1036 InlayHint { 1038 InlayHint {
1037 range: 845..846, 1039 range: 844..845,
1038 kind: ParameterHint, 1040 kind: ParameterHint,
1039 label: "bar", 1041 label: "bar",
1040 }, 1042 },
1041 InlayHint { 1043 InlayHint {
1042 range: 848..855, 1044 range: 847..854,
1043 kind: ParameterHint, 1045 kind: ParameterHint,
1044 label: "msg", 1046 label: "msg",
1045 }, 1047 },
1046 InlayHint { 1048 InlayHint {
1047 range: 860..871, 1049 range: 859..870,
1048 kind: ParameterHint, 1050 kind: ParameterHint,
1049 label: "last", 1051 label: "last",
1050 }, 1052 },
1051 InlayHint { 1053 InlayHint {
1052 range: 914..917, 1054 range: 913..916,
1053 kind: ParameterHint, 1055 kind: ParameterHint,
1054 label: "param", 1056 label: "param",
1055 }, 1057 },
1056 InlayHint { 1058 InlayHint {
1057 range: 937..939, 1059 range: 936..938,
1058 kind: ParameterHint, 1060 kind: ParameterHint,
1059 label: "&self", 1061 label: "&self",
1060 }, 1062 },
1061 InlayHint { 1063 InlayHint {
1062 range: 941..945, 1064 range: 940..944,
1063 kind: ParameterHint, 1065 kind: ParameterHint,
1064 label: "param", 1066 label: "param",
1065 }, 1067 },
1066 InlayHint { 1068 InlayHint {
1067 range: 980..989, 1069 range: 979..988,
1068 kind: ParameterHint, 1070 kind: ParameterHint,
1069 label: "file_id", 1071 label: "file_id",
1070 }, 1072 },
1071 InlayHint { 1073 InlayHint {
1072 range: 999..1012, 1074 range: 998..1011,
1073 kind: ParameterHint, 1075 kind: ParameterHint,
1074 label: "name", 1076 label: "name",
1075 }, 1077 },
1076 InlayHint { 1078 InlayHint {
1077 range: 1022..1026, 1079 range: 1021..1025,
1078 kind: ParameterHint, 1080 kind: ParameterHint,
1079 label: "focus_range", 1081 label: "focus_range",
1080 }, 1082 },
1081 InlayHint { 1083 InlayHint {
1082 range: 1036..1048, 1084 range: 1035..1047,
1083 kind: ParameterHint, 1085 kind: ParameterHint,
1084 label: "full_range", 1086 label: "full_range",
1085 }, 1087 },
1086 InlayHint { 1088 InlayHint {
1087 range: 1058..1071, 1089 range: 1057..1070,
1088 kind: ParameterHint, 1090 kind: ParameterHint,
1089 label: "kind", 1091 label: "kind",
1090 }, 1092 },
1091 InlayHint { 1093 InlayHint {
1092 range: 1081..1085, 1094 range: 1080..1084,
1093 kind: ParameterHint, 1095 kind: ParameterHint,
1094 label: "docs", 1096 label: "docs",
1095 }, 1097 },
1096 InlayHint { 1098 InlayHint {
1097 range: 1095..1099, 1099 range: 1094..1098,
1098 kind: ParameterHint, 1100 kind: ParameterHint,
1099 label: "description", 1101 label: "description",
1100 }, 1102 },
@@ -1239,16 +1241,17 @@ fn main() {
1239 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###" 1241 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
1240 [ 1242 [
1241 InlayHint { 1243 InlayHint {
1242 range: 232..269, 1244 range: 147..172,
1243 kind: ChainingHint, 1245 kind: ChainingHint,
1244 label: "B", 1246 label: "B",
1245 }, 1247 },
1246 InlayHint { 1248 InlayHint {
1247 range: 232..239, 1249 range: 147..154,
1248 kind: ChainingHint, 1250 kind: ChainingHint,
1249 label: "A", 1251 label: "A",
1250 }, 1252 },
1251 ]"###); 1253 ]
1254 "###);
1252 } 1255 }
1253 1256
1254 #[test] 1257 #[test]
@@ -1293,12 +1296,12 @@ fn main() {
1293 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###" 1296 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
1294 [ 1297 [
1295 InlayHint { 1298 InlayHint {
1296 range: 252..323, 1299 range: 143..190,
1297 kind: ChainingHint, 1300 kind: ChainingHint,
1298 label: "C", 1301 label: "C",
1299 }, 1302 },
1300 InlayHint { 1303 InlayHint {
1301 range: 252..300, 1304 range: 143..179,
1302 kind: ChainingHint, 1305 kind: ChainingHint,
1303 label: "B", 1306 label: "B",
1304 }, 1307 },
@@ -1331,15 +1334,16 @@ fn main() {
1331 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###" 1334 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
1332 [ 1335 [
1333 InlayHint { 1336 InlayHint {
1334 range: 403..452, 1337 range: 246..283,
1335 kind: ChainingHint, 1338 kind: ChainingHint,
1336 label: "B<X<i32, bool>>", 1339 label: "B<X<i32, bool>>",
1337 }, 1340 },
1338 InlayHint { 1341 InlayHint {
1339 range: 403..422, 1342 range: 246..265,
1340 kind: ChainingHint, 1343 kind: ChainingHint,
1341 label: "A<X<i32, bool>>", 1344 label: "A<X<i32, bool>>",
1342 }, 1345 },
1343 ]"###); 1346 ]
1347 "###);
1344 } 1348 }
1345} 1349}
diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs
index 981bdf924..889b84c59 100644
--- a/crates/ra_ide/src/mock_analysis.rs
+++ b/crates/ra_ide/src/mock_analysis.rs
@@ -1,87 +1,22 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use std::{str::FromStr, sync::Arc}; 2use std::sync::Arc;
3 3
4use ra_cfg::CfgOptions; 4use ra_cfg::CfgOptions;
5use ra_db::{CrateName, Env, FileSet, SourceRoot, VfsPath}; 5use ra_db::{CrateName, Env, FileSet, SourceRoot, VfsPath};
6use test_utils::{extract_offset, extract_range, Fixture, CURSOR_MARKER}; 6use test_utils::{extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER};
7 7
8use crate::{ 8use crate::{
9 Analysis, AnalysisChange, AnalysisHost, CrateGraph, Edition, FileId, FilePosition, FileRange, 9 Analysis, AnalysisChange, AnalysisHost, CrateGraph, Edition, FileId, FilePosition, FileRange,
10}; 10};
11 11
12#[derive(Debug)]
13enum MockFileData {
14 Plain { path: String, content: String },
15 Fixture(Fixture),
16}
17
18impl MockFileData {
19 fn new(path: String, content: String) -> Self {
20 // `Self::Plain` causes a false warning: 'variant is never constructed: `Plain` '
21 // see https://github.com/rust-lang/rust/issues/69018
22 MockFileData::Plain { path, content }
23 }
24
25 fn path(&self) -> &str {
26 match self {
27 MockFileData::Plain { path, .. } => path.as_str(),
28 MockFileData::Fixture(f) => f.path.as_str(),
29 }
30 }
31
32 fn content(&self) -> &str {
33 match self {
34 MockFileData::Plain { content, .. } => content,
35 MockFileData::Fixture(f) => f.text.as_str(),
36 }
37 }
38
39 fn cfg_options(&self) -> CfgOptions {
40 match self {
41 MockFileData::Fixture(f) => {
42 let mut cfg = CfgOptions::default();
43 f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
44 f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
45 cfg
46 }
47 _ => CfgOptions::default(),
48 }
49 }
50
51 fn edition(&self) -> Edition {
52 match self {
53 MockFileData::Fixture(f) => {
54 f.edition.as_ref().map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap())
55 }
56 _ => Edition::Edition2018,
57 }
58 }
59
60 fn env(&self) -> Env {
61 match self {
62 MockFileData::Fixture(f) => Env::from(f.env.iter()),
63 _ => Env::default(),
64 }
65 }
66}
67
68impl From<Fixture> for MockFileData {
69 fn from(fixture: Fixture) -> Self {
70 Self::Fixture(fixture)
71 }
72}
73
74/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis 12/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis
75/// from a set of in-memory files. 13/// from a set of in-memory files.
76#[derive(Debug, Default)] 14#[derive(Debug, Default)]
77pub struct MockAnalysis { 15pub struct MockAnalysis {
78 files: Vec<MockFileData>, 16 files: Vec<Fixture>,
79} 17}
80 18
81impl MockAnalysis { 19impl MockAnalysis {
82 pub fn new() -> MockAnalysis {
83 MockAnalysis::default()
84 }
85 /// Creates `MockAnalysis` using a fixture data in the following format: 20 /// Creates `MockAnalysis` using a fixture data in the following format:
86 /// 21 ///
87 /// ```not_rust 22 /// ```not_rust
@@ -92,68 +27,53 @@ impl MockAnalysis {
92 /// //- /foo.rs 27 /// //- /foo.rs
93 /// struct Baz; 28 /// struct Baz;
94 /// ``` 29 /// ```
95 pub fn with_files(fixture: &str) -> MockAnalysis { 30 pub fn with_files(ra_fixture: &str) -> MockAnalysis {
96 let mut res = MockAnalysis::new(); 31 let (res, pos) = MockAnalysis::with_fixture(ra_fixture);
97 for entry in Fixture::parse(fixture) { 32 assert!(pos.is_none());
98 res.add_file_fixture(entry);
99 }
100 res 33 res
101 } 34 }
102 35
103 /// Same as `with_files`, but requires that a single file contains a `<|>` marker, 36 /// Same as `with_files`, but requires that a single file contains a `<|>` marker,
104 /// whose position is also returned. 37 /// whose position is also returned.
105 pub fn with_files_and_position(fixture: &str) -> (MockAnalysis, FilePosition) { 38 pub fn with_files_and_position(fixture: &str) -> (MockAnalysis, FilePosition) {
39 let (res, position) = MockAnalysis::with_fixture(fixture);
40 let (file_id, range_or_offset) = position.expect("expected a marker (<|>)");
41 let offset = match range_or_offset {
42 RangeOrOffset::Range(_) => panic!(),
43 RangeOrOffset::Offset(it) => it,
44 };
45 (res, FilePosition { file_id, offset })
46 }
47
48 fn with_fixture(fixture: &str) -> (MockAnalysis, Option<(FileId, RangeOrOffset)>) {
106 let mut position = None; 49 let mut position = None;
107 let mut res = MockAnalysis::new(); 50 let mut res = MockAnalysis::default();
108 for entry in Fixture::parse(fixture) { 51 for mut entry in Fixture::parse(fixture) {
109 if entry.text.contains(CURSOR_MARKER) { 52 if entry.text.contains(CURSOR_MARKER) {
110 assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); 53 assert!(position.is_none(), "only one marker (<|>) per fixture is allowed");
111 position = Some(res.add_file_fixture_with_position(entry)); 54 let (range_or_offset, text) = extract_range_or_offset(&entry.text);
55 entry.text = text;
56 let file_id = res.add_file_fixture(entry);
57 position = Some((file_id, range_or_offset));
112 } else { 58 } else {
113 res.add_file_fixture(entry); 59 res.add_file_fixture(entry);
114 } 60 }
115 } 61 }
116 let position = position.expect("expected a marker (<|>)");
117 (res, position) 62 (res, position)
118 } 63 }
119 64
120 pub fn add_file_fixture(&mut self, fixture: Fixture) -> FileId { 65 fn add_file_fixture(&mut self, fixture: Fixture) -> FileId {
121 let file_id = self.next_id(); 66 let file_id = FileId((self.files.len() + 1) as u32);
122 self.files.push(MockFileData::from(fixture)); 67 self.files.push(fixture);
123 file_id 68 file_id
124 } 69 }
125 70
126 pub fn add_file_fixture_with_position(&mut self, mut fixture: Fixture) -> FilePosition {
127 let (offset, text) = extract_offset(&fixture.text);
128 fixture.text = text;
129 let file_id = self.next_id();
130 self.files.push(MockFileData::from(fixture));
131 FilePosition { file_id, offset }
132 }
133
134 pub fn add_file(&mut self, path: &str, text: &str) -> FileId {
135 let file_id = self.next_id();
136 self.files.push(MockFileData::new(path.to_string(), text.to_string()));
137 file_id
138 }
139 pub fn add_file_with_position(&mut self, path: &str, text: &str) -> FilePosition {
140 let (offset, text) = extract_offset(text);
141 let file_id = self.next_id();
142 self.files.push(MockFileData::new(path.to_string(), text));
143 FilePosition { file_id, offset }
144 }
145 pub fn add_file_with_range(&mut self, path: &str, text: &str) -> FileRange {
146 let (range, text) = extract_range(text);
147 let file_id = self.next_id();
148 self.files.push(MockFileData::new(path.to_string(), text));
149 FileRange { file_id, range }
150 }
151 pub fn id_of(&self, path: &str) -> FileId { 71 pub fn id_of(&self, path: &str) -> FileId {
152 let (idx, _) = self 72 let (idx, _) = self
153 .files 73 .files
154 .iter() 74 .iter()
155 .enumerate() 75 .enumerate()
156 .find(|(_, data)| path == data.path()) 76 .find(|(_, data)| path == data.path)
157 .expect("no file in this mock"); 77 .expect("no file in this mock");
158 FileId(idx as u32 + 1) 78 FileId(idx as u32 + 1)
159 } 79 }
@@ -164,18 +84,23 @@ impl MockAnalysis {
164 let mut crate_graph = CrateGraph::default(); 84 let mut crate_graph = CrateGraph::default();
165 let mut root_crate = None; 85 let mut root_crate = None;
166 for (i, data) in self.files.into_iter().enumerate() { 86 for (i, data) in self.files.into_iter().enumerate() {
167 let path = data.path(); 87 let path = data.path;
168 assert!(path.starts_with('/')); 88 assert!(path.starts_with('/'));
169 let cfg_options = data.cfg_options(); 89
90 let mut cfg = CfgOptions::default();
91 data.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
92 data.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
93 let edition: Edition =
94 data.edition.and_then(|it| it.parse().ok()).unwrap_or(Edition::Edition2018);
95
170 let file_id = FileId(i as u32 + 1); 96 let file_id = FileId(i as u32 + 1);
171 let edition = data.edition(); 97 let env = Env::from(data.env.iter());
172 let env = data.env();
173 if path == "/lib.rs" || path == "/main.rs" { 98 if path == "/lib.rs" || path == "/main.rs" {
174 root_crate = Some(crate_graph.add_crate_root( 99 root_crate = Some(crate_graph.add_crate_root(
175 file_id, 100 file_id,
176 edition, 101 edition,
177 None, 102 None,
178 cfg_options, 103 cfg,
179 env, 104 env,
180 Default::default(), 105 Default::default(),
181 )); 106 ));
@@ -186,7 +111,7 @@ impl MockAnalysis {
186 file_id, 111 file_id,
187 edition, 112 edition,
188 Some(CrateName::new(crate_name).unwrap()), 113 Some(CrateName::new(crate_name).unwrap()),
189 cfg_options, 114 cfg,
190 env, 115 env,
191 Default::default(), 116 Default::default(),
192 ); 117 );
@@ -198,7 +123,7 @@ impl MockAnalysis {
198 } 123 }
199 let path = VfsPath::new_virtual_path(path.to_string()); 124 let path = VfsPath::new_virtual_path(path.to_string());
200 file_set.insert(file_id, path); 125 file_set.insert(file_id, path);
201 change.change_file(file_id, Some(Arc::new(data.content().to_owned()))); 126 change.change_file(file_id, Some(Arc::new(data.text).to_owned()));
202 } 127 }
203 change.set_crate_graph(crate_graph); 128 change.set_crate_graph(crate_graph);
204 change.set_roots(vec![SourceRoot::new_local(file_set)]); 129 change.set_roots(vec![SourceRoot::new_local(file_set)]);
@@ -208,10 +133,6 @@ impl MockAnalysis {
208 pub fn analysis(self) -> Analysis { 133 pub fn analysis(self) -> Analysis {
209 self.analysis_host().analysis() 134 self.analysis_host().analysis()
210 } 135 }
211
212 fn next_id(&self) -> FileId {
213 FileId((self.files.len() + 1) as u32)
214 }
215} 136}
216 137
217/// Creates analysis from a multi-file fixture, returns positions marked with <|>. 138/// Creates analysis from a multi-file fixture, returns positions marked with <|>.
@@ -222,21 +143,18 @@ pub fn analysis_and_position(ra_fixture: &str) -> (Analysis, FilePosition) {
222 143
223/// Creates analysis for a single file. 144/// Creates analysis for a single file.
224pub fn single_file(ra_fixture: &str) -> (Analysis, FileId) { 145pub fn single_file(ra_fixture: &str) -> (Analysis, FileId) {
225 let mut mock = MockAnalysis::new(); 146 let mock = MockAnalysis::with_files(ra_fixture);
226 let file_id = mock.add_file("/main.rs", ra_fixture); 147 let file_id = mock.id_of("/main.rs");
227 (mock.analysis(), file_id) 148 (mock.analysis(), file_id)
228} 149}
229 150
230/// Creates analysis for a single file, returns position marked with <|>.
231pub fn single_file_with_position(ra_fixture: &str) -> (Analysis, FilePosition) {
232 let mut mock = MockAnalysis::new();
233 let pos = mock.add_file_with_position("/main.rs", ra_fixture);
234 (mock.analysis(), pos)
235}
236
237/// Creates analysis for a single file, returns range marked with a pair of <|>. 151/// Creates analysis for a single file, returns range marked with a pair of <|>.
238pub fn single_file_with_range(ra_fixture: &str) -> (Analysis, FileRange) { 152pub fn analysis_and_range(ra_fixture: &str) -> (Analysis, FileRange) {
239 let mut mock = MockAnalysis::new(); 153 let (res, position) = MockAnalysis::with_fixture(ra_fixture);
240 let pos = mock.add_file_with_range("/main.rs", ra_fixture); 154 let (file_id, range_or_offset) = position.expect("expected a marker (<|>)");
241 (mock.analysis(), pos) 155 let range = match range_or_offset {
156 RangeOrOffset::Range(it) => it,
157 RangeOrOffset::Offset(_) => panic!(),
158 };
159 (res.analysis(), FileRange { file_id, range })
242} 160}
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs
index bc7f65470..e3e0c7639 100644
--- a/crates/ra_ide/src/parent_module.rs
+++ b/crates/ra_ide/src/parent_module.rs
@@ -125,12 +125,12 @@ mod tests {
125 #[test] 125 #[test]
126 fn test_resolve_crate_root() { 126 fn test_resolve_crate_root() {
127 let mock = MockAnalysis::with_files( 127 let mock = MockAnalysis::with_files(
128 " 128 r#"
129 //- /bar.rs 129//- /bar.rs
130 mod foo; 130mod foo;
131 //- /foo.rs 131//- /foo.rs
132 // empty <|> 132// empty
133 ", 133"#,
134 ); 134 );
135 let root_file = mock.id_of("/bar.rs"); 135 let root_file = mock.id_of("/bar.rs");
136 let mod_file = mock.id_of("/foo.rs"); 136 let mod_file = mock.id_of("/foo.rs");
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index 4a96d6505..3433fdae3 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -191,239 +191,244 @@ fn get_struct_def_name_for_struct_literal_search(
191#[cfg(test)] 191#[cfg(test)]
192mod tests { 192mod tests {
193 use crate::{ 193 use crate::{
194 mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis}, 194 mock_analysis::{analysis_and_position, MockAnalysis},
195 Declaration, Reference, ReferenceSearchResult, SearchScope, 195 Declaration, Reference, ReferenceSearchResult, SearchScope,
196 }; 196 };
197 197
198 #[test] 198 #[test]
199 fn test_struct_literal_after_space() { 199 fn test_struct_literal_after_space() {
200 let code = r#" 200 let refs = get_all_refs(
201 struct Foo <|>{ 201 r#"
202 a: i32, 202struct Foo <|>{
203 } 203 a: i32,
204 impl Foo { 204}
205 fn f() -> i32 { 42 } 205impl Foo {
206 } 206 fn f() -> i32 { 42 }
207 fn main() { 207}
208 let f: Foo; 208fn main() {
209 f = Foo {a: Foo::f()}; 209 let f: Foo;
210 }"#; 210 f = Foo {a: Foo::f()};
211 211}
212 let refs = get_all_refs(code); 212"#,
213 );
213 check_result( 214 check_result(
214 refs, 215 refs,
215 "Foo STRUCT_DEF FileId(1) 5..39 12..15 Other", 216 "Foo STRUCT_DEF FileId(1) 0..26 7..10 Other",
216 &["FileId(1) 138..141 StructLiteral"], 217 &["FileId(1) 101..104 StructLiteral"],
217 ); 218 );
218 } 219 }
219 220
220 #[test] 221 #[test]
221 fn test_struct_literal_befor_space() { 222 fn test_struct_literal_before_space() {
222 let code = r#" 223 let refs = get_all_refs(
223 struct Foo<|> {} 224 r#"
224 fn main() { 225struct Foo<|> {}
225 let f: Foo; 226 fn main() {
226 f = Foo {}; 227 let f: Foo;
227 }"#; 228 f = Foo {};
228 229}
229 let refs = get_all_refs(code); 230"#,
231 );
230 check_result( 232 check_result(
231 refs, 233 refs,
232 "Foo STRUCT_DEF FileId(1) 5..18 12..15 Other", 234 "Foo STRUCT_DEF FileId(1) 0..13 7..10 Other",
233 &["FileId(1) 54..57 Other", "FileId(1) 71..74 StructLiteral"], 235 &["FileId(1) 41..44 Other", "FileId(1) 54..57 StructLiteral"],
234 ); 236 );
235 } 237 }
236 238
237 #[test] 239 #[test]
238 fn test_struct_literal_with_generic_type() { 240 fn test_struct_literal_with_generic_type() {
239 let code = r#" 241 let refs = get_all_refs(
240 struct Foo<T> <|>{} 242 r#"
241 fn main() { 243struct Foo<T> <|>{}
242 let f: Foo::<i32>; 244 fn main() {
243 f = Foo {}; 245 let f: Foo::<i32>;
244 }"#; 246 f = Foo {};
245 247}
246 let refs = get_all_refs(code); 248"#,
249 );
247 check_result( 250 check_result(
248 refs, 251 refs,
249 "Foo STRUCT_DEF FileId(1) 5..21 12..15 Other", 252 "Foo STRUCT_DEF FileId(1) 0..16 7..10 Other",
250 &["FileId(1) 81..84 StructLiteral"], 253 &["FileId(1) 64..67 StructLiteral"],
251 ); 254 );
252 } 255 }
253 256
254 #[test] 257 #[test]
255 fn test_struct_literal_for_tuple() { 258 fn test_struct_literal_for_tuple() {
256 let code = r#" 259 let refs = get_all_refs(
257 struct Foo<|>(i32); 260 r#"
258 261struct Foo<|>(i32);
259 fn main() {
260 let f: Foo;
261 f = Foo(1);
262 }"#;
263 262
264 let refs = get_all_refs(code); 263fn main() {
264 let f: Foo;
265 f = Foo(1);
266}
267"#,
268 );
265 check_result( 269 check_result(
266 refs, 270 refs,
267 "Foo STRUCT_DEF FileId(1) 5..21 12..15 Other", 271 "Foo STRUCT_DEF FileId(1) 0..16 7..10 Other",
268 &["FileId(1) 71..74 StructLiteral"], 272 &["FileId(1) 54..57 StructLiteral"],
269 ); 273 );
270 } 274 }
271 275
272 #[test] 276 #[test]
273 fn test_find_all_refs_for_local() { 277 fn test_find_all_refs_for_local() {
274 let code = r#" 278 let refs = get_all_refs(
275 fn main() { 279 r#"
276 let mut i = 1; 280fn main() {
277 let j = 1; 281 let mut i = 1;
278 i = i<|> + j; 282 let j = 1;
283 i = i<|> + j;
279 284
280 { 285 {
281 i = 0; 286 i = 0;
282 } 287 }
283
284 i = 5;
285 }"#;
286 288
287 let refs = get_all_refs(code); 289 i = 5;
290}"#,
291 );
288 check_result( 292 check_result(
289 refs, 293 refs,
290 "i BIND_PAT FileId(1) 33..34 Other Write", 294 "i BIND_PAT FileId(1) 24..25 Other Write",
291 &[ 295 &[
292 "FileId(1) 67..68 Other Write", 296 "FileId(1) 50..51 Other Write",
293 "FileId(1) 71..72 Other Read", 297 "FileId(1) 54..55 Other Read",
294 "FileId(1) 101..102 Other Write", 298 "FileId(1) 76..77 Other Write",
295 "FileId(1) 127..128 Other Write", 299 "FileId(1) 94..95 Other Write",
296 ], 300 ],
297 ); 301 );
298 } 302 }
299 303
300 #[test] 304 #[test]
301 fn search_filters_by_range() { 305 fn search_filters_by_range() {
302 let code = r#" 306 let refs = get_all_refs(
303 fn foo() { 307 r#"
304 let spam<|> = 92; 308fn foo() {
305 spam + spam 309 let spam<|> = 92;
306 } 310 spam + spam
307 fn bar() { 311}
308 let spam = 92; 312fn bar() {
309 spam + spam 313 let spam = 92;
310 } 314 spam + spam
311 "#; 315}
312 let refs = get_all_refs(code); 316"#,
317 );
313 check_result( 318 check_result(
314 refs, 319 refs,
315 "spam BIND_PAT FileId(1) 44..48 Other", 320 "spam BIND_PAT FileId(1) 19..23 Other",
316 &["FileId(1) 71..75 Other Read", "FileId(1) 78..82 Other Read"], 321 &["FileId(1) 34..38 Other Read", "FileId(1) 41..45 Other Read"],
317 ); 322 );
318 } 323 }
319 324
320 #[test] 325 #[test]
321 fn test_find_all_refs_for_param_inside() { 326 fn test_find_all_refs_for_param_inside() {
322 let code = r#" 327 let refs = get_all_refs(
323 fn foo(i : u32) -> u32 { 328 r#"
324 i<|> 329fn foo(i : u32) -> u32 {
325 }"#; 330 i<|>
326 331}
327 let refs = get_all_refs(code); 332"#,
328 check_result(refs, "i BIND_PAT FileId(1) 12..13 Other", &["FileId(1) 38..39 Other Read"]); 333 );
334 check_result(refs, "i BIND_PAT FileId(1) 7..8 Other", &["FileId(1) 29..30 Other Read"]);
329 } 335 }
330 336
331 #[test] 337 #[test]
332 fn test_find_all_refs_for_fn_param() { 338 fn test_find_all_refs_for_fn_param() {
333 let code = r#" 339 let refs = get_all_refs(
334 fn foo(i<|> : u32) -> u32 { 340 r#"
335 i 341fn foo(i<|> : u32) -> u32 {
336 }"#; 342 i
337 343}
338 let refs = get_all_refs(code); 344"#,
339 check_result(refs, "i BIND_PAT FileId(1) 12..13 Other", &["FileId(1) 38..39 Other Read"]); 345 );
346 check_result(refs, "i BIND_PAT FileId(1) 7..8 Other", &["FileId(1) 29..30 Other Read"]);
340 } 347 }
341 348
342 #[test] 349 #[test]
343 fn test_find_all_refs_field_name() { 350 fn test_find_all_refs_field_name() {
344 let code = r#" 351 let refs = get_all_refs(
345 //- /lib.rs 352 r#"
346 struct Foo { 353//- /lib.rs
347 pub spam<|>: u32, 354struct Foo {
348 } 355 pub spam<|>: u32,
349 356}
350 fn main(s: Foo) {
351 let f = s.spam;
352 }
353 "#;
354 357
355 let refs = get_all_refs(code); 358fn main(s: Foo) {
359 let f = s.spam;
360}
361"#,
362 );
356 check_result( 363 check_result(
357 refs, 364 refs,
358 "spam RECORD_FIELD_DEF FileId(1) 66..79 70..74 Other", 365 "spam RECORD_FIELD_DEF FileId(1) 17..30 21..25 Other",
359 &["FileId(1) 152..156 Other Read"], 366 &["FileId(1) 67..71 Other Read"],
360 ); 367 );
361 } 368 }
362 369
363 #[test] 370 #[test]
364 fn test_find_all_refs_impl_item_name() { 371 fn test_find_all_refs_impl_item_name() {
365 let code = r#" 372 let refs = get_all_refs(
366 //- /lib.rs 373 r#"
367 struct Foo; 374struct Foo;
368 impl Foo { 375impl Foo {
369 fn f<|>(&self) { } 376 fn f<|>(&self) { }
370 } 377}
371 "#; 378"#,
372 379 );
373 let refs = get_all_refs(code); 380 check_result(refs, "f FN_DEF FileId(1) 27..43 30..31 Other", &[]);
374 check_result(refs, "f FN_DEF FileId(1) 88..104 91..92 Other", &[]);
375 } 381 }
376 382
377 #[test] 383 #[test]
378 fn test_find_all_refs_enum_var_name() { 384 fn test_find_all_refs_enum_var_name() {
379 let code = r#" 385 let refs = get_all_refs(
380 //- /lib.rs 386 r#"
381 enum Foo { 387enum Foo {
382 A, 388 A,
383 B<|>, 389 B<|>,
384 C, 390 C,
385 } 391}
386 "#; 392"#,
387 393 );
388 let refs = get_all_refs(code); 394 check_result(refs, "B ENUM_VARIANT FileId(1) 22..23 22..23 Other", &[]);
389 check_result(refs, "B ENUM_VARIANT FileId(1) 83..84 83..84 Other", &[]);
390 } 395 }
391 396
392 #[test] 397 #[test]
393 fn test_find_all_refs_two_modules() { 398 fn test_find_all_refs_two_modules() {
394 let code = r#" 399 let (analysis, pos) = analysis_and_position(
395 //- /lib.rs 400 r#"
396 pub mod foo; 401//- /lib.rs
397 pub mod bar; 402pub mod foo;
398 403pub mod bar;
399 fn f() { 404
400 let i = foo::Foo { n: 5 }; 405fn f() {
401 } 406 let i = foo::Foo { n: 5 };
402 407}
403 //- /foo.rs
404 use crate::bar;
405 408
406 pub struct Foo { 409//- /foo.rs
407 pub n: u32, 410use crate::bar;
408 }
409 411
410 fn f() { 412pub struct Foo {
411 let i = bar::Bar { n: 5 }; 413 pub n: u32,
412 } 414}
413 415
414 //- /bar.rs 416fn f() {
415 use crate::foo; 417 let i = bar::Bar { n: 5 };
418}
416 419
417 pub struct Bar { 420//- /bar.rs
418 pub n: u32, 421use crate::foo;
419 }
420 422
421 fn f() { 423pub struct Bar {
422 let i = foo::Foo<|> { n: 5 }; 424 pub n: u32,
423 } 425}
424 "#;
425 426
426 let (analysis, pos) = analysis_and_position(code); 427fn f() {
428 let i = foo::Foo<|> { n: 5 };
429}
430"#,
431 );
427 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 432 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
428 check_result( 433 check_result(
429 refs, 434 refs,
@@ -437,48 +442,48 @@ mod tests {
437 // which is the whole `foo.rs`, and the second one is in `use foo::Foo`. 442 // which is the whole `foo.rs`, and the second one is in `use foo::Foo`.
438 #[test] 443 #[test]
439 fn test_find_all_refs_decl_module() { 444 fn test_find_all_refs_decl_module() {
440 let code = r#" 445 let (analysis, pos) = analysis_and_position(
441 //- /lib.rs 446 r#"
442 mod foo<|>; 447//- /lib.rs
448mod foo<|>;
443 449
444 use foo::Foo; 450use foo::Foo;
445 451
446 fn f() { 452fn f() {
447 let i = Foo { n: 5 }; 453 let i = Foo { n: 5 };
448 } 454}
449
450 //- /foo.rs
451 pub struct Foo {
452 pub n: u32,
453 }
454 "#;
455 455
456 let (analysis, pos) = analysis_and_position(code); 456//- /foo.rs
457pub struct Foo {
458 pub n: u32,
459}
460"#,
461 );
457 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 462 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
458 check_result(refs, "foo SOURCE_FILE FileId(2) 0..35 Other", &["FileId(1) 14..17 Other"]); 463 check_result(refs, "foo SOURCE_FILE FileId(2) 0..35 Other", &["FileId(1) 14..17 Other"]);
459 } 464 }
460 465
461 #[test] 466 #[test]
462 fn test_find_all_refs_super_mod_vis() { 467 fn test_find_all_refs_super_mod_vis() {
463 let code = r#" 468 let (analysis, pos) = analysis_and_position(
464 //- /lib.rs 469 r#"
465 mod foo; 470//- /lib.rs
466 471mod foo;
467 //- /foo.rs
468 mod some;
469 use some::Foo;
470 472
471 fn f() { 473//- /foo.rs
472 let i = Foo { n: 5 }; 474mod some;
473 } 475use some::Foo;
474 476
475 //- /foo/some.rs 477fn f() {
476 pub(super) struct Foo<|> { 478 let i = Foo { n: 5 };
477 pub n: u32, 479}
478 }
479 "#;
480 480
481 let (analysis, pos) = analysis_and_position(code); 481//- /foo/some.rs
482pub(super) struct Foo<|> {
483 pub n: u32,
484}
485"#,
486 );
482 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 487 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
483 check_result( 488 check_result(
484 refs, 489 refs,
@@ -525,93 +530,98 @@ mod tests {
525 530
526 #[test] 531 #[test]
527 fn test_find_all_refs_macro_def() { 532 fn test_find_all_refs_macro_def() {
528 let code = r#" 533 let refs = get_all_refs(
529 #[macro_export] 534 r#"
530 macro_rules! m1<|> { () => (()) } 535#[macro_export]
531 536macro_rules! m1<|> { () => (()) }
532 fn foo() { 537
533 m1(); 538fn foo() {
534 m1(); 539 m1();
535 }"#; 540 m1();
536 541}
537 let refs = get_all_refs(code); 542"#,
543 );
538 check_result( 544 check_result(
539 refs, 545 refs,
540 "m1 MACRO_CALL FileId(1) 9..63 46..48 Other", 546 "m1 MACRO_CALL FileId(1) 0..46 29..31 Other",
541 &["FileId(1) 96..98 StructLiteral", "FileId(1) 114..116 StructLiteral"], 547 &["FileId(1) 63..65 StructLiteral", "FileId(1) 73..75 StructLiteral"],
542 ); 548 );
543 } 549 }
544 550
545 #[test] 551 #[test]
546 fn test_basic_highlight_read_write() { 552 fn test_basic_highlight_read_write() {
547 let code = r#" 553 let refs = get_all_refs(
548 fn foo() { 554 r#"
549 let mut i<|> = 0; 555fn foo() {
550 i = i + 1; 556 let mut i<|> = 0;
551 }"#; 557 i = i + 1;
552 558}
553 let refs = get_all_refs(code); 559"#,
560 );
554 check_result( 561 check_result(
555 refs, 562 refs,
556 "i BIND_PAT FileId(1) 40..41 Other Write", 563 "i BIND_PAT FileId(1) 23..24 Other Write",
557 &["FileId(1) 59..60 Other Write", "FileId(1) 63..64 Other Read"], 564 &["FileId(1) 34..35 Other Write", "FileId(1) 38..39 Other Read"],
558 ); 565 );
559 } 566 }
560 567
561 #[test] 568 #[test]
562 fn test_basic_highlight_field_read_write() { 569 fn test_basic_highlight_field_read_write() {
563 let code = r#" 570 let refs = get_all_refs(
564 struct S { 571 r#"
565 f: u32, 572struct S {
566 } 573 f: u32,
567 574}
568 fn foo() {
569 let mut s = S{f: 0};
570 s.f<|> = 0;
571 }"#;
572 575
573 let refs = get_all_refs(code); 576fn foo() {
577 let mut s = S{f: 0};
578 s.f<|> = 0;
579}
580"#,
581 );
574 check_result( 582 check_result(
575 refs, 583 refs,
576 "f RECORD_FIELD_DEF FileId(1) 32..38 32..33 Other", 584 "f RECORD_FIELD_DEF FileId(1) 15..21 15..16 Other",
577 &["FileId(1) 96..97 Other Read", "FileId(1) 117..118 Other Write"], 585 &["FileId(1) 55..56 Other Read", "FileId(1) 68..69 Other Write"],
578 ); 586 );
579 } 587 }
580 588
581 #[test] 589 #[test]
582 fn test_basic_highlight_decl_no_write() { 590 fn test_basic_highlight_decl_no_write() {
583 let code = r#" 591 let refs = get_all_refs(
584 fn foo() { 592 r#"
585 let i<|>; 593fn foo() {
586 i = 1; 594 let i<|>;
587 }"#; 595 i = 1;
588 596}
589 let refs = get_all_refs(code); 597"#,
590 check_result(refs, "i BIND_PAT FileId(1) 36..37 Other", &["FileId(1) 51..52 Other Write"]); 598 );
599 check_result(refs, "i BIND_PAT FileId(1) 19..20 Other", &["FileId(1) 26..27 Other Write"]);
591 } 600 }
592 601
593 #[test] 602 #[test]
594 fn test_find_struct_function_refs_outside_module() { 603 fn test_find_struct_function_refs_outside_module() {
595 let code = r#" 604 let refs = get_all_refs(
596 mod foo { 605 r#"
597 pub struct Foo; 606mod foo {
607 pub struct Foo;
598 608
599 impl Foo { 609 impl Foo {
600 pub fn new<|>() -> Foo { 610 pub fn new<|>() -> Foo {
601 Foo 611 Foo
602 }
603 }
604 } 612 }
613 }
614}
605 615
606 fn main() { 616fn main() {
607 let _f = foo::Foo::new(); 617 let _f = foo::Foo::new();
608 }"#; 618}
609 619"#,
610 let refs = get_all_refs(code); 620 );
611 check_result( 621 check_result(
612 refs, 622 refs,
613 "new FN_DEF FileId(1) 87..150 94..97 Other", 623 "new FN_DEF FileId(1) 54..101 61..64 Other",
614 &["FileId(1) 227..230 StructLiteral"], 624 &["FileId(1) 146..149 StructLiteral"],
615 ); 625 );
616 } 626 }
617 627
@@ -642,8 +652,8 @@ mod tests {
642 ); 652 );
643 } 653 }
644 654
645 fn get_all_refs(text: &str) -> ReferenceSearchResult { 655 fn get_all_refs(ra_fixture: &str) -> ReferenceSearchResult {
646 let (analysis, position) = single_file_with_position(text); 656 let (analysis, position) = analysis_and_position(ra_fixture);
647 analysis.find_all_refs(position, None).unwrap().unwrap() 657 analysis.find_all_refs(position, None).unwrap().unwrap()
648 } 658 }
649 659
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index 6edf565b5..7ebc0adcf 100644
--- a/crates/ra_ide/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
@@ -271,11 +271,10 @@ fn rename_reference(
271mod tests { 271mod tests {
272 use insta::assert_debug_snapshot; 272 use insta::assert_debug_snapshot;
273 use ra_text_edit::TextEditBuilder; 273 use ra_text_edit::TextEditBuilder;
274 use stdx::trim_indent;
274 use test_utils::{assert_eq_text, mark}; 275 use test_utils::{assert_eq_text, mark};
275 276
276 use crate::{ 277 use crate::{mock_analysis::analysis_and_position, FileId};
277 mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId,
278 };
279 278
280 #[test] 279 #[test]
281 fn test_rename_to_underscore() { 280 fn test_rename_to_underscore() {
@@ -309,7 +308,7 @@ mod tests {
309 308
310 #[test] 309 #[test]
311 fn test_rename_to_invalid_identifier() { 310 fn test_rename_to_invalid_identifier() {
312 let (analysis, position) = single_file_with_position( 311 let (analysis, position) = analysis_and_position(
313 " 312 "
314 fn main() { 313 fn main() {
315 let i<|> = 1; 314 let i<|> = 1;
@@ -1053,8 +1052,9 @@ pub mod foo<|>;
1053 ); 1052 );
1054 } 1053 }
1055 1054
1056 fn test_rename(text: &str, new_name: &str, expected: &str) { 1055 fn test_rename(ra_fixture_before: &str, new_name: &str, ra_fixture_after: &str) {
1057 let (analysis, position) = single_file_with_position(text); 1056 let ra_fixture_after = &trim_indent(ra_fixture_after);
1057 let (analysis, position) = analysis_and_position(ra_fixture_before);
1058 let source_change = analysis.rename(position, new_name).unwrap(); 1058 let source_change = analysis.rename(position, new_name).unwrap();
1059 let mut text_edit_builder = TextEditBuilder::default(); 1059 let mut text_edit_builder = TextEditBuilder::default();
1060 let mut file_id: Option<FileId> = None; 1060 let mut file_id: Option<FileId> = None;
@@ -1068,6 +1068,6 @@ pub mod foo<|>;
1068 } 1068 }
1069 let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string(); 1069 let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string();
1070 text_edit_builder.finish().apply(&mut result); 1070 text_edit_builder.finish().apply(&mut result);
1071 assert_eq_text!(expected, &*result); 1071 assert_eq_text!(ra_fixture_after, &*result);
1072 } 1072 }
1073} 1073}
diff --git a/crates/ra_ide/src/snapshots/highlight_doctest.html b/crates/ra_ide/src/snapshots/highlight_doctest.html
index ac546806e..e8155def7 100644
--- a/crates/ra_ide/src/snapshots/highlight_doctest.html
+++ b/crates/ra_ide/src/snapshots/highlight_doctest.html
@@ -5,6 +5,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
5 5
6.lifetime { color: #DFAF8F; font-style: italic; } 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.documentation { color: #629755; }
9.injected { opacity: 0.65 ; }
8.struct, .enum { color: #7CB8BB; } 10.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 11.enum_variant { color: #BDE0F3; }
10.string_literal { color: #CC9393; } 12.string_literal { color: #CC9393; }
@@ -33,7 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
33.control { font-style: italic; } 35.control { font-style: italic; }
34</style> 36</style>
35<pre><code><span class="comment documentation">/// ```</span> 37<pre><code><span class="comment documentation">/// ```</span>
36<span class="comment documentation">/// </span><span class="keyword">let</span> _ = <span class="string_literal">"early doctests should not go boom"</span>; 38<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> _ = </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="generic injected">;</span>
37<span class="comment documentation">/// ```</span> 39<span class="comment documentation">/// ```</span>
38<span class="keyword">struct</span> <span class="struct declaration">Foo</span> { 40<span class="keyword">struct</span> <span class="struct declaration">Foo</span> {
39 <span class="field declaration">bar</span>: <span class="builtin_type">bool</span>, 41 <span class="field declaration">bar</span>: <span class="builtin_type">bool</span>,
@@ -47,8 +49,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
47 <span class="comment documentation">/// # Examples</span> 49 <span class="comment documentation">/// # Examples</span>
48 <span class="comment documentation">///</span> 50 <span class="comment documentation">///</span>
49 <span class="comment documentation">/// ```</span> 51 <span class="comment documentation">/// ```</span>
50 <span class="comment documentation">/// #</span> <span class="attribute">#![</span><span class="function attribute">allow</span><span class="attribute">(unused_mut)]</span> 52 <span class="comment documentation">/// #</span><span class="generic injected"> </span><span class="attribute injected">#![</span><span class="function attribute injected">allow</span><span class="attribute injected">(unused_mut)]</span>
51 <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span>: <span class="struct">Foo</span> = <span class="struct">Foo</span>::<span class="function">new</span>(); 53 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="keyword injected">mut</span><span class="generic injected"> </span><span class="variable declaration injected mutable">foo</span><span class="generic injected">: </span><span class="struct injected">Foo</span><span class="generic injected"> = </span><span class="struct injected">Foo</span><span class="generic injected">::</span><span class="function injected">new</span><span class="generic injected">();</span>
52 <span class="comment documentation">/// ```</span> 54 <span class="comment documentation">/// ```</span>
53 <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration">new</span>() -&gt; <span class="struct">Foo</span> { 55 <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration">new</span>() -&gt; <span class="struct">Foo</span> {
54 <span class="struct">Foo</span> { <span class="field">bar</span>: <span class="bool_literal">true</span> } 56 <span class="struct">Foo</span> { <span class="field">bar</span>: <span class="bool_literal">true</span> }
@@ -59,26 +61,26 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
59 <span class="comment documentation">/// # Examples</span> 61 <span class="comment documentation">/// # Examples</span>
60 <span class="comment documentation">///</span> 62 <span class="comment documentation">///</span>
61 <span class="comment documentation">/// ```</span> 63 <span class="comment documentation">/// ```</span>
62 <span class="comment documentation">/// </span><span class="keyword">use</span> <span class="module">x</span>::<span class="module">y</span>; 64 <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="generic injected"> </span><span class="module injected">x</span><span class="generic injected">::</span><span class="module injected">y</span><span class="generic injected">;</span>
63 <span class="comment documentation">///</span> 65 <span class="comment documentation">///</span>
64 <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">foo</span> = <span class="struct">Foo</span>::<span class="function">new</span>(); 66 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">foo</span><span class="generic injected"> = </span><span class="struct injected">Foo</span><span class="generic injected">::</span><span class="function injected">new</span><span class="generic injected">();</span>
65 <span class="comment documentation">///</span> 67 <span class="comment documentation">///</span>
66 <span class="comment documentation">/// </span><span class="comment">// calls bar on foo</span> 68 <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span>
67 <span class="comment documentation">/// </span><span class="macro">assert!</span>(foo.bar()); 69 <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="generic injected">(foo.bar());</span>
68 <span class="comment documentation">///</span> 70 <span class="comment documentation">///</span>
69 <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">bar</span> = <span class="variable">foo</span>.<span class="field">bar</span> || <span class="struct">Foo</span>::<span class="constant">bar</span>; 71 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">bar</span><span class="generic injected"> = </span><span class="variable injected">foo</span><span class="generic injected">.</span><span class="field injected">bar</span><span class="generic injected"> || </span><span class="struct injected">Foo</span><span class="generic injected">::</span><span class="constant injected">bar</span><span class="generic injected">;</span>
70 <span class="comment documentation">///</span> 72 <span class="comment documentation">///</span>
71 <span class="comment documentation">/// </span><span class="comment">/* multi-line 73 <span class="comment documentation">/// </span><span class="comment injected">/* multi-line
72 </span><span class="comment documentation">/// </span><span class="comment"> comment */</span> 74 </span><span class="comment documentation">/// </span><span class="comment injected"> comment */</span>
73 <span class="comment documentation">///</span> 75 <span class="comment documentation">///</span>
74 <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">multi_line_string</span> = <span class="string_literal">"Foo 76 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="generic injected"> = </span><span class="string_literal injected">"Foo
75 </span><span class="comment documentation">/// </span><span class="string_literal"> bar 77 </span><span class="comment documentation">/// </span><span class="string_literal injected"> bar
76 </span><span class="comment documentation">/// </span><span class="string_literal"> "</span>; 78 </span><span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="generic injected">;</span>
77 <span class="comment documentation">///</span> 79 <span class="comment documentation">///</span>
78 <span class="comment documentation">/// ```</span> 80 <span class="comment documentation">/// ```</span>
79 <span class="comment documentation">///</span> 81 <span class="comment documentation">///</span>
80 <span class="comment documentation">/// ```rust,no_run</span> 82 <span class="comment documentation">/// ```rust,no_run</span>
81 <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">foobar</span> = <span class="struct">Foo</span>::<span class="function">new</span>().<span class="function">bar</span>(); 83 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">foobar</span><span class="generic injected"> = </span><span class="struct injected">Foo</span><span class="generic injected">::</span><span class="function injected">new</span><span class="generic injected">().</span><span class="function injected">bar</span><span class="generic injected">();</span>
82 <span class="comment documentation">/// ```</span> 84 <span class="comment documentation">/// ```</span>
83 <span class="comment documentation">///</span> 85 <span class="comment documentation">///</span>
84 <span class="comment documentation">/// ```sh</span> 86 <span class="comment documentation">/// ```sh</span>
@@ -90,7 +92,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
90} 92}
91 93
92<span class="comment documentation">/// ```</span> 94<span class="comment documentation">/// ```</span>
93<span class="comment documentation">/// </span><span class="macro">noop!</span>(<span class="numeric_literal">1</span>); 95<span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="generic injected">(</span><span class="numeric_literal injected">1</span><span class="generic injected">);</span>
94<span class="comment documentation">/// ```</span> 96<span class="comment documentation">/// ```</span>
95<span class="macro">macro_rules!</span> <span class="macro declaration">noop</span> { 97<span class="macro">macro_rules!</span> <span class="macro declaration">noop</span> {
96 ($expr:expr) =&gt; { 98 ($expr:expr) =&gt; {
diff --git a/crates/ra_ide/src/snapshots/highlight_injection.html b/crates/ra_ide/src/snapshots/highlight_injection.html
index 47dbd7bc8..1b0349bae 100644
--- a/crates/ra_ide/src/snapshots/highlight_injection.html
+++ b/crates/ra_ide/src/snapshots/highlight_injection.html
@@ -5,6 +5,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
5 5
6.lifetime { color: #DFAF8F; font-style: italic; } 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.documentation { color: #629755; }
9.injected { opacity: 0.65 ; }
8.struct, .enum { color: #7CB8BB; } 10.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 11.enum_variant { color: #BDE0F3; }
10.string_literal { color: #CC9393; } 12.string_literal { color: #CC9393; }
diff --git a/crates/ra_ide/src/snapshots/highlight_strings.html b/crates/ra_ide/src/snapshots/highlight_strings.html
index b46fa44c6..d184b5691 100644
--- a/crates/ra_ide/src/snapshots/highlight_strings.html
+++ b/crates/ra_ide/src/snapshots/highlight_strings.html
@@ -5,6 +5,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
5 5
6.lifetime { color: #DFAF8F; font-style: italic; } 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.documentation { color: #629755; }
9.injected { opacity: 0.65 ; }
8.struct, .enum { color: #7CB8BB; } 10.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 11.enum_variant { color: #BDE0F3; }
10.string_literal { color: #CC9393; } 12.string_literal { color: #CC9393; }
diff --git a/crates/ra_ide/src/snapshots/highlight_unsafe.html b/crates/ra_ide/src/snapshots/highlight_unsafe.html
index 73438fbb4..6936e949f 100644
--- a/crates/ra_ide/src/snapshots/highlight_unsafe.html
+++ b/crates/ra_ide/src/snapshots/highlight_unsafe.html
@@ -5,6 +5,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
5 5
6.lifetime { color: #DFAF8F; font-style: italic; } 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.documentation { color: #629755; }
9.injected { opacity: 0.65 ; }
8.struct, .enum { color: #7CB8BB; } 10.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 11.enum_variant { color: #BDE0F3; }
10.string_literal { color: #CC9393; } 12.string_literal { color: #CC9393; }
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index 0c4f0a018..8d0b38f95 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -5,6 +5,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
5 5
6.lifetime { color: #DFAF8F; font-style: italic; } 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.documentation { color: #629755; }
9.injected { opacity: 0.65 ; }
8.struct, .enum { color: #7CB8BB; } 10.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 11.enum_variant { color: #BDE0F3; }
10.string_literal { color: #CC9393; } 12.string_literal { color: #CC9393; }
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
index a74a70069..9516c7441 100644
--- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html
+++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
@@ -5,6 +5,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
5 5
6.lifetime { color: #DFAF8F; font-style: italic; } 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.documentation { color: #629755; }
9.injected { opacity: 0.65 ; }
8.struct, .enum { color: #7CB8BB; } 10.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 11.enum_variant { color: #BDE0F3; }
10.string_literal { color: #CC9393; } 12.string_literal { color: #CC9393; }
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 448645bdc..028b55902 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -236,7 +236,7 @@ pub(crate) fn highlight(
236 }); 236 });
237 } 237 }
238 } 238 }
239 stack.pop_and_inject(false); 239 stack.pop_and_inject(None);
240 } 240 }
241 } else if let Some(string) = 241 } else if let Some(string) =
242 element_to_highlight.as_token().cloned().and_then(ast::RawString::cast) 242 element_to_highlight.as_token().cloned().and_then(ast::RawString::cast)
@@ -324,16 +324,27 @@ impl HighlightedRangeStack {
324 cloned 324 cloned
325 } 325 }
326 326
327 /// Remove the `HighlightRange` of `parent` that's currently covered by `child`.
328 fn intersect_partial(parent: &mut HighlightedRange, child: &HighlightedRange) {
329 assert!(
330 parent.range.start() <= child.range.start()
331 && parent.range.end() >= child.range.start()
332 && child.range.end() > parent.range.end()
333 );
334
335 parent.range = TextRange::new(parent.range.start(), child.range.start());
336 }
337
327 /// Similar to `pop`, but can modify arbitrary prior ranges (where `pop`) 338 /// Similar to `pop`, but can modify arbitrary prior ranges (where `pop`)
328 /// can only modify the last range currently on the stack. 339 /// can only modify the last range currently on the stack.
329 /// Can be used to do injections that span multiple ranges, like the 340 /// Can be used to do injections that span multiple ranges, like the
330 /// doctest injection below. 341 /// doctest injection below.
331 /// If `delete` is set to true, the parent range is deleted instead of 342 /// If `overwrite_parent` is non-optional, the highlighting of the parent range
332 /// intersected. 343 /// is overwritten with the argument.
333 /// 344 ///
334 /// Note that `pop` can be simulated by `pop_and_inject(false)` but the 345 /// Note that `pop` can be simulated by `pop_and_inject(false)` but the
335 /// latter is computationally more expensive. 346 /// latter is computationally more expensive.
336 fn pop_and_inject(&mut self, delete: bool) { 347 fn pop_and_inject(&mut self, overwrite_parent: Option<Highlight>) {
337 let mut children = self.stack.pop().unwrap(); 348 let mut children = self.stack.pop().unwrap();
338 let prev = self.stack.last_mut().unwrap(); 349 let prev = self.stack.last_mut().unwrap();
339 children.sort_by_key(|range| range.range.start()); 350 children.sort_by_key(|range| range.range.start());
@@ -343,26 +354,45 @@ impl HighlightedRangeStack {
343 if let Some(idx) = 354 if let Some(idx) =
344 prev.iter().position(|parent| parent.range.contains_range(child.range)) 355 prev.iter().position(|parent| parent.range.contains_range(child.range))
345 { 356 {
357 if let Some(tag) = overwrite_parent {
358 prev[idx].highlight = tag;
359 }
360
346 let cloned = Self::intersect(&mut prev[idx], &child); 361 let cloned = Self::intersect(&mut prev[idx], &child);
347 let insert_idx = if delete || prev[idx].range.is_empty() { 362 let insert_idx = if prev[idx].range.is_empty() {
348 prev.remove(idx); 363 prev.remove(idx);
349 idx 364 idx
350 } else { 365 } else {
351 idx + 1 366 idx + 1
352 }; 367 };
353 prev.insert(insert_idx, child); 368 prev.insert(insert_idx, child);
354 if !delete && !cloned.range.is_empty() { 369 if !cloned.range.is_empty() {
355 prev.insert(insert_idx + 1, cloned); 370 prev.insert(insert_idx + 1, cloned);
356 } 371 }
357 } else if let Some(_idx) =
358 prev.iter().position(|parent| parent.range.contains(child.range.start()))
359 {
360 unreachable!("child range should be completely contained in parent range");
361 } else { 372 } else {
362 let idx = prev 373 let maybe_idx =
363 .binary_search_by_key(&child.range.start(), |range| range.range.start()) 374 prev.iter().position(|parent| parent.range.contains(child.range.start()));
364 .unwrap_or_else(|x| x); 375 match (overwrite_parent, maybe_idx) {
365 prev.insert(idx, child); 376 (Some(_), Some(idx)) => {
377 Self::intersect_partial(&mut prev[idx], &child);
378 let insert_idx = if prev[idx].range.is_empty() {
379 prev.remove(idx);
380 idx
381 } else {
382 idx + 1
383 };
384 prev.insert(insert_idx, child);
385 }
386 (_, None) => {
387 let idx = prev
388 .binary_search_by_key(&child.range.start(), |range| range.range.start())
389 .unwrap_or_else(|x| x);
390 prev.insert(idx, child);
391 }
392 _ => {
393 unreachable!("child range should be completely contained in parent range");
394 }
395 }
366 } 396 }
367 } 397 }
368 } 398 }
@@ -516,11 +546,9 @@ fn highlight_element(
516 let ty = sema.type_of_expr(&expr)?; 546 let ty = sema.type_of_expr(&expr)?;
517 if !ty.is_raw_ptr() { 547 if !ty.is_raw_ptr() {
518 return None; 548 return None;
549 } else {
550 HighlightTag::Operator | HighlightModifier::Unsafe
519 } 551 }
520
521 let mut h = Highlight::new(HighlightTag::Operator);
522 h |= HighlightModifier::Unsafe;
523 h
524 } 552 }
525 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { 553 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
526 Highlight::new(HighlightTag::Macro) 554 Highlight::new(HighlightTag::Macro)
diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs
index 99b6b25ab..0c74f7370 100644
--- a/crates/ra_ide/src/syntax_highlighting/html.rs
+++ b/crates/ra_ide/src/syntax_highlighting/html.rs
@@ -64,6 +64,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
64 64
65.lifetime { color: #DFAF8F; font-style: italic; } 65.lifetime { color: #DFAF8F; font-style: italic; }
66.comment { color: #7F9F7F; } 66.comment { color: #7F9F7F; }
67.documentation { color: #629755; }
68.injected { opacity: 0.65 ; }
67.struct, .enum { color: #7CB8BB; } 69.struct, .enum { color: #7CB8BB; }
68.enum_variant { color: #BDE0F3; } 70.enum_variant { color: #BDE0F3; }
69.string_literal { color: #CC9393; } 71.string_literal { color: #CC9393; }
diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs
index 9d82b4009..181c21256 100644
--- a/crates/ra_ide/src/syntax_highlighting/injection.rs
+++ b/crates/ra_ide/src/syntax_highlighting/injection.rs
@@ -8,8 +8,8 @@ use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize};
8use stdx::SepBy; 8use stdx::SepBy;
9 9
10use crate::{ 10use crate::{
11 call_info::ActiveParameter, Analysis, HighlightModifier, HighlightTag, HighlightedRange, 11 call_info::ActiveParameter, Analysis, Highlight, HighlightModifier, HighlightTag,
12 RootDatabase, 12 HighlightedRange, RootDatabase,
13}; 13};
14 14
15use super::HighlightedRangeStack; 15use super::HighlightedRangeStack;
@@ -172,6 +172,7 @@ pub(super) fn highlight_doc_comment(
172 h.range.end() + end_offset.unwrap_or(start_offset) - h.range.start(), 172 h.range.end() + end_offset.unwrap_or(start_offset) - h.range.start(),
173 ); 173 );
174 174
175 h.highlight |= HighlightModifier::Injected;
175 stack.add(h); 176 stack.add(h);
176 } 177 }
177 } 178 }
@@ -181,6 +182,7 @@ pub(super) fn highlight_doc_comment(
181 for comment in new_comments { 182 for comment in new_comments {
182 stack.add(comment); 183 stack.add(comment);
183 } 184 }
184 stack.pop_and_inject(false); 185 stack.pop_and_inject(None);
185 stack.pop_and_inject(true); 186 stack
187 .pop_and_inject(Some(Highlight::from(HighlightTag::Generic) | HighlightModifier::Injected));
186} 188}
diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs
index 93bbb4b4d..e8e251cfc 100644
--- a/crates/ra_ide/src/syntax_highlighting/tags.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tags.rs
@@ -27,6 +27,7 @@ pub enum HighlightTag {
27 Field, 27 Field,
28 FormatSpecifier, 28 FormatSpecifier,
29 Function, 29 Function,
30 Generic,
30 Keyword, 31 Keyword,
31 Lifetime, 32 Lifetime,
32 Macro, 33 Macro,
@@ -57,6 +58,7 @@ pub enum HighlightModifier {
57 /// not. 58 /// not.
58 Definition, 59 Definition,
59 Documentation, 60 Documentation,
61 Injected,
60 Mutable, 62 Mutable,
61 Unsafe, 63 Unsafe,
62} 64}
@@ -77,6 +79,7 @@ impl HighlightTag {
77 HighlightTag::Field => "field", 79 HighlightTag::Field => "field",
78 HighlightTag::FormatSpecifier => "format_specifier", 80 HighlightTag::FormatSpecifier => "format_specifier",
79 HighlightTag::Function => "function", 81 HighlightTag::Function => "function",
82 HighlightTag::Generic => "generic",
80 HighlightTag::Keyword => "keyword", 83 HighlightTag::Keyword => "keyword",
81 HighlightTag::Lifetime => "lifetime", 84 HighlightTag::Lifetime => "lifetime",
82 HighlightTag::Macro => "macro", 85 HighlightTag::Macro => "macro",
@@ -110,6 +113,7 @@ impl HighlightModifier {
110 HighlightModifier::ControlFlow, 113 HighlightModifier::ControlFlow,
111 HighlightModifier::Definition, 114 HighlightModifier::Definition,
112 HighlightModifier::Documentation, 115 HighlightModifier::Documentation,
116 HighlightModifier::Injected,
113 HighlightModifier::Mutable, 117 HighlightModifier::Mutable,
114 HighlightModifier::Unsafe, 118 HighlightModifier::Unsafe,
115 ]; 119 ];
@@ -120,6 +124,7 @@ impl HighlightModifier {
120 HighlightModifier::ControlFlow => "control", 124 HighlightModifier::ControlFlow => "control",
121 HighlightModifier::Definition => "declaration", 125 HighlightModifier::Definition => "declaration",
122 HighlightModifier::Documentation => "documentation", 126 HighlightModifier::Documentation => "documentation",
127 HighlightModifier::Injected => "injected",
123 HighlightModifier::Mutable => "mutable", 128 HighlightModifier::Mutable => "mutable",
124 HighlightModifier::Unsafe => "unsafe", 129 HighlightModifier::Unsafe => "unsafe",
125 } 130 }
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index b1f48f03b..b7fad9719 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -2,10 +2,7 @@ use std::fs;
2 2
3use test_utils::{assert_eq_text, project_dir, read_text}; 3use test_utils::{assert_eq_text, project_dir, read_text};
4 4
5use crate::{ 5use crate::{mock_analysis::single_file, FileRange, TextRange};
6 mock_analysis::{single_file, MockAnalysis},
7 FileRange, TextRange,
8};
9 6
10#[test] 7#[test]
11fn test_highlighting() { 8fn test_highlighting() {
@@ -127,12 +124,10 @@ fn accidentally_quadratic() {
127 let file = project_dir().join("crates/ra_syntax/test_data/accidentally_quadratic"); 124 let file = project_dir().join("crates/ra_syntax/test_data/accidentally_quadratic");
128 let src = fs::read_to_string(file).unwrap(); 125 let src = fs::read_to_string(file).unwrap();
129 126
130 let mut mock = MockAnalysis::new(); 127 let (analysis, file_id) = single_file(&src);
131 let file_id = mock.add_file("/main.rs", &src);
132 let host = mock.analysis_host();
133 128
134 // let t = std::time::Instant::now(); 129 // let t = std::time::Instant::now();
135 let _ = host.analysis().highlight(file_id).unwrap(); 130 let _ = analysis.highlight(file_id).unwrap();
136 // eprintln!("elapsed: {:?}", t.elapsed()); 131 // eprintln!("elapsed: {:?}", t.elapsed());
137} 132}
138 133
@@ -140,16 +135,17 @@ fn accidentally_quadratic() {
140fn test_ranges() { 135fn test_ranges() {
141 let (analysis, file_id) = single_file( 136 let (analysis, file_id) = single_file(
142 r#" 137 r#"
143 #[derive(Clone, Debug)] 138#[derive(Clone, Debug)]
144 struct Foo { 139struct Foo {
145 pub x: i32, 140 pub x: i32,
146 pub y: i32, 141 pub y: i32,
147 }"#, 142}
143"#,
148 ); 144 );
149 145
150 // The "x" 146 // The "x"
151 let highlights = &analysis 147 let highlights = &analysis
152 .highlight_range(FileRange { file_id, range: TextRange::at(82.into(), 1.into()) }) 148 .highlight_range(FileRange { file_id, range: TextRange::at(45.into(), 1.into()) })
153 .unwrap(); 149 .unwrap();
154 150
155 assert_eq!(&highlights[0].highlight.to_string(), "field.declaration"); 151 assert_eq!(&highlights[0].highlight.to_string(), "field.declaration");
diff --git a/crates/ra_ide/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs
index a341684fd..f716a3861 100644
--- a/crates/ra_ide/src/syntax_tree.rs
+++ b/crates/ra_ide/src/syntax_tree.rs
@@ -104,7 +104,7 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<St
104mod tests { 104mod tests {
105 use test_utils::assert_eq_text; 105 use test_utils::assert_eq_text;
106 106
107 use crate::mock_analysis::{single_file, single_file_with_range}; 107 use crate::mock_analysis::{analysis_and_range, single_file};
108 108
109 #[test] 109 #[test]
110 fn test_syntax_tree_without_range() { 110 fn test_syntax_tree_without_range() {
@@ -184,7 +184,7 @@ [email protected]
184 184
185 #[test] 185 #[test]
186 fn test_syntax_tree_with_range() { 186 fn test_syntax_tree_with_range() {
187 let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim()); 187 let (analysis, range) = analysis_and_range(r#"<|>fn foo() {}<|>"#.trim());
188 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); 188 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
189 189
190 assert_eq_text!( 190 assert_eq_text!(
@@ -206,7 +206,7 @@ [email protected]
206 .trim() 206 .trim()
207 ); 207 );
208 208
209 let (analysis, range) = single_file_with_range( 209 let (analysis, range) = analysis_and_range(
210 r#"fn test() { 210 r#"fn test() {
211 <|>assert!(" 211 <|>assert!("
212 fn foo() { 212 fn foo() {
@@ -242,7 +242,7 @@ [email protected]
242 242
243 #[test] 243 #[test]
244 fn test_syntax_tree_inside_string() { 244 fn test_syntax_tree_inside_string() {
245 let (analysis, range) = single_file_with_range( 245 let (analysis, range) = analysis_and_range(
246 r#"fn test() { 246 r#"fn test() {
247 assert!(" 247 assert!("
248<|>fn foo() { 248<|>fn foo() {
@@ -276,7 +276,7 @@ [email protected]
276 ); 276 );
277 277
278 // With a raw string 278 // With a raw string
279 let (analysis, range) = single_file_with_range( 279 let (analysis, range) = analysis_and_range(
280 r###"fn test() { 280 r###"fn test() {
281 assert!(r#" 281 assert!(r#"
282<|>fn foo() { 282<|>fn foo() {
@@ -310,7 +310,7 @@ [email protected]
310 ); 310 );
311 311
312 // With a raw string 312 // With a raw string
313 let (analysis, range) = single_file_with_range( 313 let (analysis, range) = analysis_and_range(
314 r###"fn test() { 314 r###"fn test() {
315 assert!(r<|>#" 315 assert!(r<|>#"
316fn foo() { 316fn foo() {
diff --git a/crates/ra_ide/src/typing/on_enter.rs b/crates/ra_ide/src/typing/on_enter.rs
index a40d8af9c..2faaa8ff0 100644
--- a/crates/ra_ide/src/typing/on_enter.rs
+++ b/crates/ra_ide/src/typing/on_enter.rs
@@ -75,23 +75,22 @@ fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> {
75 75
76#[cfg(test)] 76#[cfg(test)]
77mod tests { 77mod tests {
78 use test_utils::{assert_eq_text, extract_offset}; 78 use test_utils::assert_eq_text;
79 79
80 use crate::mock_analysis::single_file; 80 use crate::mock_analysis::analysis_and_position;
81 81 use stdx::trim_indent;
82 use super::*;
83 82
84 fn apply_on_enter(before: &str) -> Option<String> { 83 fn apply_on_enter(before: &str) -> Option<String> {
85 let (offset, before) = extract_offset(before); 84 let (analysis, position) = analysis_and_position(&before);
86 let (analysis, file_id) = single_file(&before); 85 let result = analysis.on_enter(position).unwrap()?;
87 let result = analysis.on_enter(FilePosition { offset, file_id }).unwrap()?;
88 86
89 let mut actual = before.to_string(); 87 let mut actual = analysis.file_text(position.file_id).unwrap().to_string();
90 result.apply(&mut actual); 88 result.apply(&mut actual);
91 Some(actual) 89 Some(actual)
92 } 90 }
93 91
94 fn do_check(ra_fixture_before: &str, ra_fixture_after: &str) { 92 fn do_check(ra_fixture_before: &str, ra_fixture_after: &str) {
93 let ra_fixture_after = &trim_indent(ra_fixture_after);
95 let actual = apply_on_enter(ra_fixture_before).unwrap(); 94 let actual = apply_on_enter(ra_fixture_before).unwrap();
96 assert_eq_text!(ra_fixture_after, &actual); 95 assert_eq_text!(ra_fixture_after, &actual);
97 } 96 }
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml
index e4a60f4c0..818947014 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/ra_project_model/Cargo.toml
@@ -18,6 +18,7 @@ ra_cfg = { path = "../ra_cfg" }
18ra_db = { path = "../ra_db" } 18ra_db = { path = "../ra_db" }
19ra_toolchain = { path = "../ra_toolchain" } 19ra_toolchain = { path = "../ra_toolchain" }
20ra_proc_macro = { path = "../ra_proc_macro" } 20ra_proc_macro = { path = "../ra_proc_macro" }
21paths = { path = "../paths" }
21 22
22serde = { version = "1.0.106", features = ["derive"] } 23serde = { version = "1.0.106", features = ["derive"] }
23serde_json = "1.0.48" 24serde_json = "1.0.48"
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 4b7444039..8ce63ab3c 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -1,14 +1,10 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{ 3use std::{ffi::OsStr, ops, path::Path, process::Command};
4 ffi::OsStr,
5 ops,
6 path::{Path, PathBuf},
7 process::Command,
8};
9 4
10use anyhow::{Context, Result}; 5use anyhow::{Context, Result};
11use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId}; 6use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId};
7use paths::{AbsPath, AbsPathBuf};
12use ra_arena::{Arena, Idx}; 8use ra_arena::{Arena, Idx};
13use ra_db::Edition; 9use ra_db::Edition;
14use rustc_hash::FxHashMap; 10use rustc_hash::FxHashMap;
@@ -20,11 +16,14 @@ use rustc_hash::FxHashMap;
20/// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, 16/// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates,
21/// while this knows about `Packages` & `Targets`: purely cargo-related 17/// while this knows about `Packages` & `Targets`: purely cargo-related
22/// concepts. 18/// concepts.
19///
20/// We use absolute paths here, `cargo metadata` guarantees to always produce
21/// abs paths.
23#[derive(Debug, Clone)] 22#[derive(Debug, Clone)]
24pub struct CargoWorkspace { 23pub struct CargoWorkspace {
25 packages: Arena<PackageData>, 24 packages: Arena<PackageData>,
26 targets: Arena<TargetData>, 25 targets: Arena<TargetData>,
27 workspace_root: PathBuf, 26 workspace_root: AbsPathBuf,
28} 27}
29 28
30impl ops::Index<Package> for CargoWorkspace { 29impl ops::Index<Package> for CargoWorkspace {
@@ -80,15 +79,15 @@ pub type Target = Idx<TargetData>;
80pub struct PackageData { 79pub struct PackageData {
81 pub version: String, 80 pub version: String,
82 pub name: String, 81 pub name: String,
83 pub manifest: PathBuf, 82 pub manifest: AbsPathBuf,
84 pub targets: Vec<Target>, 83 pub targets: Vec<Target>,
85 pub is_member: bool, 84 pub is_member: bool,
86 pub dependencies: Vec<PackageDependency>, 85 pub dependencies: Vec<PackageDependency>,
87 pub edition: Edition, 86 pub edition: Edition,
88 pub features: Vec<String>, 87 pub features: Vec<String>,
89 pub cfgs: Vec<String>, 88 pub cfgs: Vec<String>,
90 pub out_dir: Option<PathBuf>, 89 pub out_dir: Option<AbsPathBuf>,
91 pub proc_macro_dylib_path: Option<PathBuf>, 90 pub proc_macro_dylib_path: Option<AbsPathBuf>,
92} 91}
93 92
94#[derive(Debug, Clone)] 93#[derive(Debug, Clone)]
@@ -101,7 +100,7 @@ pub struct PackageDependency {
101pub struct TargetData { 100pub struct TargetData {
102 pub package: Package, 101 pub package: Package,
103 pub name: String, 102 pub name: String,
104 pub root: PathBuf, 103 pub root: AbsPathBuf,
105 pub kind: TargetKind, 104 pub kind: TargetKind,
106 pub is_proc_macro: bool, 105 pub is_proc_macro: bool,
107} 106}
@@ -135,7 +134,7 @@ impl TargetKind {
135} 134}
136 135
137impl PackageData { 136impl PackageData {
138 pub fn root(&self) -> &Path { 137 pub fn root(&self) -> &AbsPath {
139 self.manifest.parent().unwrap() 138 self.manifest.parent().unwrap()
140 } 139 }
141} 140}
@@ -193,7 +192,7 @@ impl CargoWorkspace {
193 let pkg = packages.alloc(PackageData { 192 let pkg = packages.alloc(PackageData {
194 name, 193 name,
195 version: version.to_string(), 194 version: version.to_string(),
196 manifest: manifest_path, 195 manifest: AbsPathBuf::assert(manifest_path),
197 targets: Vec::new(), 196 targets: Vec::new(),
198 is_member, 197 is_member,
199 edition, 198 edition,
@@ -210,7 +209,7 @@ impl CargoWorkspace {
210 let tgt = targets.alloc(TargetData { 209 let tgt = targets.alloc(TargetData {
211 package: pkg, 210 package: pkg,
212 name: meta_tgt.name, 211 name: meta_tgt.name,
213 root: meta_tgt.src_path.clone(), 212 root: AbsPathBuf::assert(meta_tgt.src_path.clone()),
214 kind: TargetKind::new(meta_tgt.kind.as_slice()), 213 kind: TargetKind::new(meta_tgt.kind.as_slice()),
215 is_proc_macro, 214 is_proc_macro,
216 }); 215 });
@@ -246,16 +245,17 @@ impl CargoWorkspace {
246 packages[source].features.extend(node.features); 245 packages[source].features.extend(node.features);
247 } 246 }
248 247
249 Ok(CargoWorkspace { packages, targets, workspace_root: meta.workspace_root }) 248 let workspace_root = AbsPathBuf::assert(meta.workspace_root);
249 Ok(CargoWorkspace { packages, targets, workspace_root: workspace_root })
250 } 250 }
251 251
252 pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + ExactSizeIterator + 'a { 252 pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + ExactSizeIterator + 'a {
253 self.packages.iter().map(|(id, _pkg)| id) 253 self.packages.iter().map(|(id, _pkg)| id)
254 } 254 }
255 255
256 pub fn target_by_root(&self, root: &Path) -> Option<Target> { 256 pub fn target_by_root(&self, root: &AbsPath) -> Option<Target> {
257 self.packages() 257 self.packages()
258 .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| self[it].root == root)) 258 .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| &self[it].root == root))
259 .next() 259 .next()
260 .copied() 260 .copied()
261 } 261 }
@@ -279,8 +279,8 @@ impl CargoWorkspace {
279 279
280#[derive(Debug, Clone, Default)] 280#[derive(Debug, Clone, Default)]
281pub struct ExternResources { 281pub struct ExternResources {
282 out_dirs: FxHashMap<PackageId, PathBuf>, 282 out_dirs: FxHashMap<PackageId, AbsPathBuf>,
283 proc_dylib_paths: FxHashMap<PackageId, PathBuf>, 283 proc_dylib_paths: FxHashMap<PackageId, AbsPathBuf>,
284 cfgs: FxHashMap<PackageId, Vec<String>>, 284 cfgs: FxHashMap<PackageId, Vec<String>>,
285} 285}
286 286
@@ -308,6 +308,7 @@ pub fn load_extern_resources(
308 if let Ok(message) = message { 308 if let Ok(message) = message {
309 match message { 309 match message {
310 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => { 310 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => {
311 let out_dir = AbsPathBuf::assert(out_dir);
311 res.out_dirs.insert(package_id.clone(), out_dir); 312 res.out_dirs.insert(package_id.clone(), out_dir);
312 res.cfgs.insert(package_id, cfgs); 313 res.cfgs.insert(package_id, cfgs);
313 } 314 }
@@ -317,7 +318,8 @@ pub fn load_extern_resources(
317 // Skip rmeta file 318 // Skip rmeta file
318 if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name)) 319 if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name))
319 { 320 {
320 res.proc_dylib_paths.insert(package_id, filename.clone()); 321 let filename = AbsPathBuf::assert(filename.clone());
322 res.proc_dylib_paths.insert(package_id, filename);
321 } 323 }
322 } 324 }
323 } 325 }
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index fe3e81689..ac88532f0 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -7,11 +7,12 @@ mod sysroot;
7use std::{ 7use std::{
8 fs::{read_dir, File, ReadDir}, 8 fs::{read_dir, File, ReadDir},
9 io::{self, BufReader}, 9 io::{self, BufReader},
10 path::{Path, PathBuf}, 10 path::Path,
11 process::{Command, Output}, 11 process::{Command, Output},
12}; 12};
13 13
14use anyhow::{bail, Context, Result}; 14use anyhow::{bail, Context, Result};
15use paths::{AbsPath, AbsPathBuf};
15use ra_cfg::CfgOptions; 16use ra_cfg::CfgOptions;
16use ra_db::{CrateGraph, CrateName, Edition, Env, FileId}; 17use ra_db::{CrateGraph, CrateName, Edition, Env, FileId};
17use rustc_hash::{FxHashMap, FxHashSet}; 18use rustc_hash::{FxHashMap, FxHashSet};
@@ -29,7 +30,7 @@ pub enum ProjectWorkspace {
29 /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. 30 /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
30 Cargo { cargo: CargoWorkspace, sysroot: Sysroot }, 31 Cargo { cargo: CargoWorkspace, sysroot: Sysroot },
31 /// Project workspace was manually specified using a `rust-project.json` file. 32 /// Project workspace was manually specified using a `rust-project.json` file.
32 Json { project: JsonProject, project_location: PathBuf }, 33 Json { project: JsonProject, project_location: AbsPathBuf },
33} 34}
34 35
35/// `PackageRoot` describes a package root folder. 36/// `PackageRoot` describes a package root folder.
@@ -38,22 +39,22 @@ pub enum ProjectWorkspace {
38#[derive(Debug, Clone)] 39#[derive(Debug, Clone)]
39pub struct PackageRoot { 40pub struct PackageRoot {
40 /// Path to the root folder 41 /// Path to the root folder
41 path: PathBuf, 42 path: AbsPathBuf,
42 /// Is a member of the current workspace 43 /// Is a member of the current workspace
43 is_member: bool, 44 is_member: bool,
44 out_dir: Option<PathBuf>, 45 out_dir: Option<AbsPathBuf>,
45} 46}
46impl PackageRoot { 47impl PackageRoot {
47 pub fn new_member(path: PathBuf) -> PackageRoot { 48 pub fn new_member(path: AbsPathBuf) -> PackageRoot {
48 Self { path, is_member: true, out_dir: None } 49 Self { path, is_member: true, out_dir: None }
49 } 50 }
50 pub fn new_non_member(path: PathBuf) -> PackageRoot { 51 pub fn new_non_member(path: AbsPathBuf) -> PackageRoot {
51 Self { path, is_member: false, out_dir: None } 52 Self { path, is_member: false, out_dir: None }
52 } 53 }
53 pub fn path(&self) -> &Path { 54 pub fn path(&self) -> &AbsPath {
54 &self.path 55 &self.path
55 } 56 }
56 pub fn out_dir(&self) -> Option<&Path> { 57 pub fn out_dir(&self) -> Option<&AbsPath> {
57 self.out_dir.as_deref() 58 self.out_dir.as_deref()
58 } 59 }
59 pub fn is_member(&self) -> bool { 60 pub fn is_member(&self) -> bool {
@@ -63,12 +64,12 @@ impl PackageRoot {
63 64
64#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] 65#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
65pub enum ProjectManifest { 66pub enum ProjectManifest {
66 ProjectJson(PathBuf), 67 ProjectJson(AbsPathBuf),
67 CargoToml(PathBuf), 68 CargoToml(AbsPathBuf),
68} 69}
69 70
70impl ProjectManifest { 71impl ProjectManifest {
71 pub fn from_manifest_file(path: PathBuf) -> Result<ProjectManifest> { 72 pub fn from_manifest_file(path: AbsPathBuf) -> Result<ProjectManifest> {
72 if path.ends_with("rust-project.json") { 73 if path.ends_with("rust-project.json") {
73 return Ok(ProjectManifest::ProjectJson(path)); 74 return Ok(ProjectManifest::ProjectJson(path));
74 } 75 }
@@ -78,7 +79,7 @@ impl ProjectManifest {
78 bail!("project root must point to Cargo.toml or rust-project.json: {}", path.display()) 79 bail!("project root must point to Cargo.toml or rust-project.json: {}", path.display())
79 } 80 }
80 81
81 pub fn discover_single(path: &Path) -> Result<ProjectManifest> { 82 pub fn discover_single(path: &AbsPath) -> Result<ProjectManifest> {
82 let mut candidates = ProjectManifest::discover(path)?; 83 let mut candidates = ProjectManifest::discover(path)?;
83 let res = match candidates.pop() { 84 let res = match candidates.pop() {
84 None => bail!("no projects"), 85 None => bail!("no projects"),
@@ -91,23 +92,23 @@ impl ProjectManifest {
91 Ok(res) 92 Ok(res)
92 } 93 }
93 94
94 pub fn discover(path: &Path) -> io::Result<Vec<ProjectManifest>> { 95 pub fn discover(path: &AbsPath) -> io::Result<Vec<ProjectManifest>> {
95 if let Some(project_json) = find_in_parent_dirs(path, "rust-project.json") { 96 if let Some(project_json) = find_in_parent_dirs(path, "rust-project.json") {
96 return Ok(vec![ProjectManifest::ProjectJson(project_json)]); 97 return Ok(vec![ProjectManifest::ProjectJson(project_json)]);
97 } 98 }
98 return find_cargo_toml(path) 99 return find_cargo_toml(path)
99 .map(|paths| paths.into_iter().map(ProjectManifest::CargoToml).collect()); 100 .map(|paths| paths.into_iter().map(ProjectManifest::CargoToml).collect());
100 101
101 fn find_cargo_toml(path: &Path) -> io::Result<Vec<PathBuf>> { 102 fn find_cargo_toml(path: &AbsPath) -> io::Result<Vec<AbsPathBuf>> {
102 match find_in_parent_dirs(path, "Cargo.toml") { 103 match find_in_parent_dirs(path, "Cargo.toml") {
103 Some(it) => Ok(vec![it]), 104 Some(it) => Ok(vec![it]),
104 None => Ok(find_cargo_toml_in_child_dir(read_dir(path)?)), 105 None => Ok(find_cargo_toml_in_child_dir(read_dir(path)?)),
105 } 106 }
106 } 107 }
107 108
108 fn find_in_parent_dirs(path: &Path, target_file_name: &str) -> Option<PathBuf> { 109 fn find_in_parent_dirs(path: &AbsPath, target_file_name: &str) -> Option<AbsPathBuf> {
109 if path.ends_with(target_file_name) { 110 if path.ends_with(target_file_name) {
110 return Some(path.to_owned()); 111 return Some(path.to_path_buf());
111 } 112 }
112 113
113 let mut curr = Some(path); 114 let mut curr = Some(path);
@@ -123,17 +124,18 @@ impl ProjectManifest {
123 None 124 None
124 } 125 }
125 126
126 fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec<PathBuf> { 127 fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec<AbsPathBuf> {
127 // Only one level down to avoid cycles the easy way and stop a runaway scan with large projects 128 // Only one level down to avoid cycles the easy way and stop a runaway scan with large projects
128 entities 129 entities
129 .filter_map(Result::ok) 130 .filter_map(Result::ok)
130 .map(|it| it.path().join("Cargo.toml")) 131 .map(|it| it.path().join("Cargo.toml"))
131 .filter(|it| it.exists()) 132 .filter(|it| it.exists())
133 .map(AbsPathBuf::assert)
132 .collect() 134 .collect()
133 } 135 }
134 } 136 }
135 137
136 pub fn discover_all(paths: &[impl AsRef<Path>]) -> Vec<ProjectManifest> { 138 pub fn discover_all(paths: &[impl AsRef<AbsPath>]) -> Vec<ProjectManifest> {
137 let mut res = paths 139 let mut res = paths
138 .iter() 140 .iter()
139 .filter_map(|it| ProjectManifest::discover(it.as_ref()).ok()) 141 .filter_map(|it| ProjectManifest::discover(it.as_ref()).ok())
@@ -158,15 +160,12 @@ impl ProjectWorkspace {
158 format!("Failed to open json file {}", project_json.display()) 160 format!("Failed to open json file {}", project_json.display())
159 })?; 161 })?;
160 let reader = BufReader::new(file); 162 let reader = BufReader::new(file);
161 let project_location = match project_json.parent() { 163 let project_location = project_json.parent().unwrap().to_path_buf();
162 Some(parent) => PathBuf::from(parent),
163 None => PathBuf::new(),
164 };
165 ProjectWorkspace::Json { 164 ProjectWorkspace::Json {
166 project: from_reader(reader).with_context(|| { 165 project: from_reader(reader).with_context(|| {
167 format!("Failed to deserialize json file {}", project_json.display()) 166 format!("Failed to deserialize json file {}", project_json.display())
168 })?, 167 })?,
169 project_location: project_location, 168 project_location,
170 } 169 }
171 } 170 }
172 ProjectManifest::CargoToml(cargo_toml) => { 171 ProjectManifest::CargoToml(cargo_toml) => {
@@ -218,13 +217,13 @@ impl ProjectWorkspace {
218 } 217 }
219 } 218 }
220 219
221 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> { 220 pub fn proc_macro_dylib_paths(&self) -> Vec<AbsPathBuf> {
222 match self { 221 match self {
223 ProjectWorkspace::Json { project, .. } => project 222 ProjectWorkspace::Json { project, project_location } => project
224 .crates 223 .crates
225 .iter() 224 .iter()
226 .filter_map(|krate| krate.proc_macro_dylib_path.as_ref()) 225 .filter_map(|krate| krate.proc_macro_dylib_path.as_ref())
227 .cloned() 226 .map(|it| project_location.join(it))
228 .collect(), 227 .collect(),
229 ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo 228 ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo
230 .packages() 229 .packages()
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index a8a196e64..943ff92df 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -1,15 +1,12 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{ 3use std::{convert::TryFrom, env, ops, path::Path, process::Command};
4 env, ops,
5 path::{Path, PathBuf},
6 process::Command,
7};
8 4
9use anyhow::{bail, Result}; 5use anyhow::{bail, format_err, Result};
10use ra_arena::{Arena, Idx}; 6use ra_arena::{Arena, Idx};
11 7
12use crate::output; 8use crate::output;
9use paths::{AbsPath, AbsPathBuf};
13 10
14#[derive(Default, Debug, Clone)] 11#[derive(Default, Debug, Clone)]
15pub struct Sysroot { 12pub struct Sysroot {
@@ -21,7 +18,7 @@ pub type SysrootCrate = Idx<SysrootCrateData>;
21#[derive(Debug, Clone)] 18#[derive(Debug, Clone)]
22pub struct SysrootCrateData { 19pub struct SysrootCrateData {
23 pub name: String, 20 pub name: String,
24 pub root: PathBuf, 21 pub root: AbsPathBuf,
25 pub deps: Vec<SysrootCrate>, 22 pub deps: Vec<SysrootCrate>,
26} 23}
27 24
@@ -53,7 +50,7 @@ impl Sysroot {
53 self.crates.iter().map(|(id, _data)| id) 50 self.crates.iter().map(|(id, _data)| id)
54 } 51 }
55 52
56 pub fn discover(cargo_toml: &Path) -> Result<Sysroot> { 53 pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
57 let src = get_or_install_rust_src(cargo_toml)?; 54 let src = get_or_install_rust_src(cargo_toml)?;
58 let mut sysroot = Sysroot { crates: Arena::default() }; 55 let mut sysroot = Sysroot { crates: Arena::default() };
59 for name in SYSROOT_CRATES.trim().lines() { 56 for name in SYSROOT_CRATES.trim().lines() {
@@ -86,16 +83,18 @@ impl Sysroot {
86 } 83 }
87} 84}
88 85
89fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> { 86fn get_or_install_rust_src(cargo_toml: &AbsPath) -> Result<AbsPathBuf> {
90 if let Ok(path) = env::var("RUST_SRC_PATH") { 87 if let Ok(path) = env::var("RUST_SRC_PATH") {
91 return Ok(path.into()); 88 let path = AbsPathBuf::try_from(path.as_str())
89 .map_err(|path| format_err!("RUST_SRC_PATH must be absolute: {}", path.display()))?;
90 return Ok(path);
92 } 91 }
93 let current_dir = cargo_toml.parent().unwrap(); 92 let current_dir = cargo_toml.parent().unwrap();
94 let mut rustc = Command::new(ra_toolchain::rustc()); 93 let mut rustc = Command::new(ra_toolchain::rustc());
95 rustc.current_dir(current_dir).args(&["--print", "sysroot"]); 94 rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
96 let rustc_output = output(rustc)?; 95 let rustc_output = output(rustc)?;
97 let stdout = String::from_utf8(rustc_output.stdout)?; 96 let stdout = String::from_utf8(rustc_output.stdout)?;
98 let sysroot_path = Path::new(stdout.trim()); 97 let sysroot_path = AbsPath::assert(Path::new(stdout.trim()));
99 let src_path = sysroot_path.join("lib/rustlib/src/rust/src"); 98 let src_path = sysroot_path.join("lib/rustlib/src/rust/src");
100 99
101 if !src_path.exists() { 100 if !src_path.exists() {
@@ -116,7 +115,7 @@ fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> {
116} 115}
117 116
118impl SysrootCrateData { 117impl SysrootCrateData {
119 pub fn root_dir(&self) -> &Path { 118 pub fn root_dir(&self) -> &AbsPath {
120 self.root.parent().unwrap() 119 self.root.parent().unwrap()
121 } 120 }
122} 121}
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 99e3f7173..45204d1a3 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -3,6 +3,8 @@
3//! Based on cli flags, either spawns an LSP server, or runs a batch analysis 3//! Based on cli flags, either spawns an LSP server, or runs a batch analysis
4mod args; 4mod args;
5 5
6use std::convert::TryFrom;
7
6use lsp_server::Connection; 8use lsp_server::Connection;
7use rust_analyzer::{ 9use rust_analyzer::{
8 cli, 10 cli,
@@ -10,9 +12,11 @@ use rust_analyzer::{
10 from_json, Result, 12 from_json, Result,
11}; 13};
12 14
13use crate::args::HelpPrinted; 15use ra_db::AbsPathBuf;
14use ra_project_model::ProjectManifest; 16use ra_project_model::ProjectManifest;
15 17
18use crate::args::HelpPrinted;
19
16fn main() -> Result<()> { 20fn main() -> Result<()> {
17 setup_logging()?; 21 setup_logging()?;
18 let args = match args::Args::parse()? { 22 let args = match args::Args::parse()? {
@@ -20,6 +24,9 @@ fn main() -> Result<()> {
20 Err(HelpPrinted) => return Ok(()), 24 Err(HelpPrinted) => return Ok(()),
21 }; 25 };
22 match args.command { 26 match args.command {
27 args::Command::RunServer => run_server()?,
28 args::Command::ProcMacro => ra_proc_macro_srv::cli::run()?,
29
23 args::Command::Parse { no_dump } => cli::parse(no_dump)?, 30 args::Command::Parse { no_dump } => cli::parse(no_dump)?,
24 args::Command::Symbols => cli::symbols()?, 31 args::Command::Symbols => cli::symbols()?,
25 args::Command::Highlight { rainbow } => cli::highlight(rainbow)?, 32 args::Command::Highlight { rainbow } => cli::highlight(rainbow)?,
@@ -41,7 +48,6 @@ fn main() -> Result<()> {
41 load_output_dirs, 48 load_output_dirs,
42 with_proc_macro, 49 with_proc_macro,
43 )?, 50 )?,
44
45 args::Command::Bench { path, what, load_output_dirs, with_proc_macro } => { 51 args::Command::Bench { path, what, load_output_dirs, with_proc_macro } => {
46 cli::analysis_bench( 52 cli::analysis_bench(
47 args.verbosity, 53 args.verbosity,
@@ -51,13 +57,9 @@ fn main() -> Result<()> {
51 with_proc_macro, 57 with_proc_macro,
52 )? 58 )?
53 } 59 }
54
55 args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => { 60 args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => {
56 cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)? 61 cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)?
57 } 62 }
58
59 args::Command::ProcMacro => run_proc_macro_srv()?,
60 args::Command::RunServer => run_server()?,
61 args::Command::Version => println!("rust-analyzer {}", env!("REV")), 63 args::Command::Version => println!("rust-analyzer {}", env!("REV")),
62 } 64 }
63 Ok(()) 65 Ok(())
@@ -70,11 +72,6 @@ fn setup_logging() -> Result<()> {
70 Ok(()) 72 Ok(())
71} 73}
72 74
73fn run_proc_macro_srv() -> Result<()> {
74 ra_proc_macro_srv::cli::run()?;
75 Ok(())
76}
77
78fn run_server() -> Result<()> { 75fn run_server() -> Result<()> {
79 log::info!("lifecycle: server started"); 76 log::info!("lifecycle: server started");
80 77
@@ -103,14 +100,23 @@ fn run_server() -> Result<()> {
103 } 100 }
104 101
105 let config = { 102 let config = {
106 let mut config = Config::default(); 103 let root_path = match initialize_params
104 .root_uri
105 .and_then(|it| it.to_file_path().ok())
106 .and_then(|it| AbsPathBuf::try_from(it).ok())
107 {
108 Some(it) => it,
109 None => {
110 let cwd = std::env::current_dir()?;
111 AbsPathBuf::assert(cwd)
112 }
113 };
114
115 let mut config = Config::new(root_path);
107 if let Some(value) = &initialize_params.initialization_options { 116 if let Some(value) = &initialize_params.initialization_options {
108 config.update(value); 117 config.update(value);
109 } 118 }
110 config.update_caps(&initialize_params.capabilities); 119 config.update_caps(&initialize_params.capabilities);
111 let cwd = std::env::current_dir()?;
112 config.root_path =
113 initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
114 120
115 if config.linked_projects.is_empty() { 121 if config.linked_projects.is_empty() {
116 let workspace_roots = initialize_params 122 let workspace_roots = initialize_params
@@ -119,6 +125,7 @@ fn run_server() -> Result<()> {
119 workspaces 125 workspaces
120 .into_iter() 126 .into_iter()
121 .filter_map(|it| it.uri.to_file_path().ok()) 127 .filter_map(|it| it.uri.to_file_path().ok())
128 .filter_map(|it| AbsPathBuf::try_from(it).ok())
122 .collect::<Vec<_>>() 129 .collect::<Vec<_>>()
123 }) 130 })
124 .filter(|workspaces| !workspaces.is_empty()) 131 .filter(|workspaces| !workspaces.is_empty())
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 90868760b..2f4c29e06 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -121,7 +121,7 @@ pub fn analysis_stats(
121 let original_file = src.file_id.original_file(db); 121 let original_file = src.file_id.original_file(db);
122 let path = vfs.file_path(original_file); 122 let path = vfs.file_path(original_file);
123 let syntax_range = src.value.syntax().text_range(); 123 let syntax_range = src.value.syntax().text_range();
124 format_to!(msg, " ({:?} {:?})", path, syntax_range); 124 format_to!(msg, " ({} {:?})", path, syntax_range);
125 } 125 }
126 if verbosity.is_spammy() { 126 if verbosity.is_spammy() {
127 bar.println(msg.to_string()); 127 bar.println(msg.to_string());
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index 00bbbaf40..e910db6eb 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -16,7 +16,7 @@ pub fn load_cargo(
16 load_out_dirs_from_check: bool, 16 load_out_dirs_from_check: bool,
17 with_proc_macro: bool, 17 with_proc_macro: bool,
18) -> Result<(AnalysisHost, vfs::Vfs)> { 18) -> Result<(AnalysisHost, vfs::Vfs)> {
19 let root = std::env::current_dir()?.join(root); 19 let root = AbsPathBuf::assert(std::env::current_dir()?.join(root));
20 let root = ProjectManifest::discover_single(&root)?; 20 let root = ProjectManifest::discover_single(&root)?;
21 let ws = ProjectWorkspace::load( 21 let ws = ProjectWorkspace::load(
22 root, 22 root,
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index aa2c4ae15..0be34c43f 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -11,6 +11,7 @@ use std::{ffi::OsString, path::PathBuf};
11 11
12use crate::diagnostics::DiagnosticsConfig; 12use crate::diagnostics::DiagnosticsConfig;
13use lsp_types::ClientCapabilities; 13use lsp_types::ClientCapabilities;
14use ra_db::AbsPathBuf;
14use ra_flycheck::FlycheckConfig; 15use ra_flycheck::FlycheckConfig;
15use ra_ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig}; 16use ra_ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig};
16use ra_project_model::{CargoConfig, JsonProject, ProjectManifest}; 17use ra_project_model::{CargoConfig, JsonProject, ProjectManifest};
@@ -40,7 +41,7 @@ pub struct Config {
40 41
41 pub with_sysroot: bool, 42 pub with_sysroot: bool,
42 pub linked_projects: Vec<LinkedProject>, 43 pub linked_projects: Vec<LinkedProject>,
43 pub root_path: PathBuf, 44 pub root_path: AbsPathBuf,
44} 45}
45 46
46#[derive(Debug, Clone)] 47#[derive(Debug, Clone)]
@@ -131,8 +132,8 @@ pub struct ClientCapsConfig {
131 pub hover_actions: bool, 132 pub hover_actions: bool,
132} 133}
133 134
134impl Default for Config { 135impl Config {
135 fn default() -> Self { 136 pub fn new(root_path: AbsPathBuf) -> Self {
136 Config { 137 Config {
137 client_caps: ClientCapsConfig::default(), 138 client_caps: ClientCapsConfig::default(),
138 139
@@ -171,18 +172,16 @@ impl Default for Config {
171 lens: LensConfig::default(), 172 lens: LensConfig::default(),
172 hover: HoverConfig::default(), 173 hover: HoverConfig::default(),
173 linked_projects: Vec::new(), 174 linked_projects: Vec::new(),
174 root_path: PathBuf::new(), 175 root_path,
175 } 176 }
176 } 177 }
177}
178 178
179impl Config {
180 #[rustfmt::skip] 179 #[rustfmt::skip]
181 pub fn update(&mut self, value: &serde_json::Value) { 180 pub fn update(&mut self, value: &serde_json::Value) {
182 log::info!("Config::update({:#})", value); 181 log::info!("Config::update({:#})", value);
183 182
184 let client_caps = self.client_caps.clone(); 183 let client_caps = self.client_caps.clone();
185 *self = Default::default(); 184 *self = Config::new(self.root_path.clone());
186 self.client_caps = client_caps; 185 self.client_caps = client_caps;
187 186
188 set(value, "/withSysroot", &mut self.with_sysroot); 187 set(value, "/withSysroot", &mut self.with_sysroot);
@@ -279,9 +278,12 @@ impl Config {
279 self.linked_projects.clear(); 278 self.linked_projects.clear();
280 for linked_project in linked_projects { 279 for linked_project in linked_projects {
281 let linked_project = match linked_project { 280 let linked_project = match linked_project {
282 ManifestOrJsonProject::Manifest(it) => match ProjectManifest::from_manifest_file(it) { 281 ManifestOrJsonProject::Manifest(it) => {
283 Ok(it) => it.into(), 282 let path = self.root_path.join(it);
284 Err(_) => continue, 283 match ProjectManifest::from_manifest_file(path) {
284 Ok(it) => it.into(),
285 Err(_) => continue,
286 }
285 } 287 }
286 ManifestOrJsonProject::JsonProject(it) => it.into(), 288 ManifestOrJsonProject::JsonProject(it) => it.into(),
287 }; 289 };
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index e2ddb7933..f18694feb 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -310,11 +310,10 @@ impl ProjectFolders {
310 310
311 let mut file_set_roots: Vec<VfsPath> = vec![]; 311 let mut file_set_roots: Vec<VfsPath> = vec![];
312 312
313 let path = AbsPathBuf::try_from(path).unwrap();
314 let entry = if root.is_member() { 313 let entry = if root.is_member() {
315 vfs::loader::Entry::local_cargo_package(path.clone()) 314 vfs::loader::Entry::local_cargo_package(path.to_path_buf())
316 } else { 315 } else {
317 vfs::loader::Entry::cargo_package_dependency(path.clone()) 316 vfs::loader::Entry::cargo_package_dependency(path.to_path_buf())
318 }; 317 };
319 res.load.push(entry); 318 res.load.push(entry);
320 if root.is_member() { 319 if root.is_member() {
@@ -329,7 +328,7 @@ impl ProjectFolders {
329 } 328 }
330 file_set_roots.push(out_dir.into()); 329 file_set_roots.push(out_dir.into());
331 } 330 }
332 file_set_roots.push(path.into()); 331 file_set_roots.push(path.to_path_buf().into());
333 332
334 if root.is_member() { 333 if root.is_member() {
335 local_filesets.push(fsc.len()); 334 local_filesets.push(fsc.len());
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index 2ea63d33b..10fe40cb5 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -39,13 +39,14 @@ define_semantic_token_types![
39 (BOOLEAN, "boolean"), 39 (BOOLEAN, "boolean"),
40 (BUILTIN_TYPE, "builtinType"), 40 (BUILTIN_TYPE, "builtinType"),
41 (ENUM_MEMBER, "enumMember"), 41 (ENUM_MEMBER, "enumMember"),
42 (ESCAPE_SEQUENCE, "escapeSequence"),
43 (FORMAT_SPECIFIER, "formatSpecifier"),
44 (GENERIC, "generic"),
42 (LIFETIME, "lifetime"), 45 (LIFETIME, "lifetime"),
43 (SELF_KEYWORD, "selfKeyword"), 46 (SELF_KEYWORD, "selfKeyword"),
44 (TYPE_ALIAS, "typeAlias"), 47 (TYPE_ALIAS, "typeAlias"),
45 (UNION, "union"), 48 (UNION, "union"),
46 (UNRESOLVED_REFERENCE, "unresolvedReference"), 49 (UNRESOLVED_REFERENCE, "unresolvedReference"),
47 (FORMAT_SPECIFIER, "formatSpecifier"),
48 (ESCAPE_SEQUENCE, "escapeSequence"),
49]; 50];
50 51
51macro_rules! define_semantic_token_modifiers { 52macro_rules! define_semantic_token_modifiers {
@@ -68,6 +69,7 @@ macro_rules! define_semantic_token_modifiers {
68define_semantic_token_modifiers![ 69define_semantic_token_modifiers![
69 (CONSTANT, "constant"), 70 (CONSTANT, "constant"),
70 (CONTROL_FLOW, "controlFlow"), 71 (CONTROL_FLOW, "controlFlow"),
72 (INJECTED, "injected"),
71 (MUTABLE, "mutable"), 73 (MUTABLE, "mutable"),
72 (UNSAFE, "unsafe"), 74 (UNSAFE, "unsafe"),
73 (ATTRIBUTE_MODIFIER, "attribute"), 75 (ATTRIBUTE_MODIFIER, "attribute"),
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 7b45b169d..da9887a9a 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -295,6 +295,7 @@ fn semantic_token_type_and_modifiers(
295 HighlightTag::SelfType => lsp_types::SemanticTokenType::TYPE, 295 HighlightTag::SelfType => lsp_types::SemanticTokenType::TYPE,
296 HighlightTag::Field => lsp_types::SemanticTokenType::PROPERTY, 296 HighlightTag::Field => lsp_types::SemanticTokenType::PROPERTY,
297 HighlightTag::Function => lsp_types::SemanticTokenType::FUNCTION, 297 HighlightTag::Function => lsp_types::SemanticTokenType::FUNCTION,
298 HighlightTag::Generic => semantic_tokens::GENERIC,
298 HighlightTag::Module => lsp_types::SemanticTokenType::NAMESPACE, 299 HighlightTag::Module => lsp_types::SemanticTokenType::NAMESPACE,
299 HighlightTag::Constant => { 300 HighlightTag::Constant => {
300 mods |= semantic_tokens::CONSTANT; 301 mods |= semantic_tokens::CONSTANT;
@@ -331,6 +332,7 @@ fn semantic_token_type_and_modifiers(
331 HighlightModifier::Attribute => semantic_tokens::ATTRIBUTE_MODIFIER, 332 HighlightModifier::Attribute => semantic_tokens::ATTRIBUTE_MODIFIER,
332 HighlightModifier::Definition => lsp_types::SemanticTokenModifier::DECLARATION, 333 HighlightModifier::Definition => lsp_types::SemanticTokenModifier::DECLARATION,
333 HighlightModifier::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION, 334 HighlightModifier::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION,
335 HighlightModifier::Injected => semantic_tokens::INJECTED,
334 HighlightModifier::ControlFlow => semantic_tokens::CONTROL_FLOW, 336 HighlightModifier::ControlFlow => semantic_tokens::CONTROL_FLOW,
335 HighlightModifier::Mutable => semantic_tokens::MUTABLE, 337 HighlightModifier::Mutable => semantic_tokens::MUTABLE,
336 HighlightModifier::Unsafe => semantic_tokens::UNSAFE, 338 HighlightModifier::Unsafe => semantic_tokens::UNSAFE,
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs
index 001a2a104..49f194f7e 100644
--- a/crates/rust-analyzer/tests/heavy_tests/support.rs
+++ b/crates/rust-analyzer/tests/heavy_tests/support.rs
@@ -17,9 +17,10 @@ use serde_json::{to_string_pretty, Value};
17use tempfile::TempDir; 17use tempfile::TempDir;
18use test_utils::{find_mismatch, Fixture}; 18use test_utils::{find_mismatch, Fixture};
19 19
20use ra_db::AbsPathBuf;
20use ra_project_model::ProjectManifest; 21use ra_project_model::ProjectManifest;
21use rust_analyzer::{ 22use rust_analyzer::{
22 config::{ClientCapsConfig, Config, LinkedProject}, 23 config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject},
23 main_loop, 24 main_loop,
24}; 25};
25 26
@@ -70,10 +71,11 @@ impl<'a> Project<'a> {
70 fs::write(path.as_path(), entry.text.as_bytes()).unwrap(); 71 fs::write(path.as_path(), entry.text.as_bytes()).unwrap();
71 } 72 }
72 73
74 let tmp_dir_path = AbsPathBuf::assert(tmp_dir.path().to_path_buf());
73 let mut roots = 75 let mut roots =
74 self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect::<Vec<_>>(); 76 self.roots.into_iter().map(|root| tmp_dir_path.join(root)).collect::<Vec<_>>();
75 if roots.is_empty() { 77 if roots.is_empty() {
76 roots.push(tmp_dir.path().to_path_buf()); 78 roots.push(tmp_dir_path.clone());
77 } 79 }
78 let linked_projects = roots 80 let linked_projects = roots
79 .into_iter() 81 .into_iter()
@@ -90,9 +92,9 @@ impl<'a> Project<'a> {
90 }, 92 },
91 with_sysroot: self.with_sysroot, 93 with_sysroot: self.with_sysroot,
92 linked_projects, 94 linked_projects,
93 ..Config::default() 95 files: FilesConfig { watcher: FilesWatcher::Client, exclude: Vec::new() },
96 ..Config::new(tmp_dir_path)
94 }; 97 };
95
96 if let Some(f) = &self.config { 98 if let Some(f) = &self.config {
97 f(&mut config) 99 f(&mut config)
98 } 100 }
@@ -173,8 +175,14 @@ impl Server {
173 self.client.sender.send(r.into()).unwrap(); 175 self.client.sender.send(r.into()).unwrap();
174 while let Some(msg) = self.recv() { 176 while let Some(msg) = self.recv() {
175 match msg { 177 match msg {
176 Message::Request(req) if req.method == "window/workDoneProgress/create" => (), 178 Message::Request(req) => {
177 Message::Request(req) => panic!("unexpected request: {:?}", req), 179 if req.method != "window/workDoneProgress/create"
180 && !(req.method == "client/registerCapability"
181 && req.params.to_string().contains("workspace/didChangeWatchedFiles"))
182 {
183 panic!("unexpected request: {:?}", req)
184 }
185 }
178 Message::Notification(_) => (), 186 Message::Notification(_) => (),
179 Message::Response(res) => { 187 Message::Response(res) => {
180 assert_eq!(res.id, id); 188 assert_eq!(res.id, id);
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index 7e93fbcd6..fad8f7e2c 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -8,7 +8,7 @@ use stdx::{lines_with_ends, split_delim, trim_indent};
8pub struct Fixture { 8pub struct Fixture {
9 pub path: String, 9 pub path: String,
10 pub text: String, 10 pub text: String,
11 pub crate_name: Option<String>, 11 pub krate: Option<String>,
12 pub deps: Vec<String>, 12 pub deps: Vec<String>,
13 pub cfg_atoms: Vec<String>, 13 pub cfg_atoms: Vec<String>,
14 pub cfg_key_values: Vec<(String, String)>, 14 pub cfg_key_values: Vec<(String, String)>,
@@ -56,7 +56,7 @@ impl Fixture {
56 } 56 }
57 57
58 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo 58 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
59 pub fn parse_meta_line(meta: &str) -> Fixture { 59 fn parse_meta_line(meta: &str) -> Fixture {
60 assert!(meta.starts_with("//-")); 60 assert!(meta.starts_with("//-"));
61 let meta = meta["//-".len()..].trim(); 61 let meta = meta["//-".len()..].trim();
62 let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); 62 let components = meta.split_ascii_whitespace().collect::<Vec<_>>();
@@ -98,7 +98,7 @@ impl Fixture {
98 Fixture { 98 Fixture {
99 path, 99 path,
100 text: String::new(), 100 text: String::new(),
101 crate_name: krate, 101 krate: krate,
102 deps, 102 deps,
103 cfg_atoms, 103 cfg_atoms,
104 cfg_key_values, 104 cfg_key_values,
@@ -136,7 +136,7 @@ fn parse_fixture_gets_full_meta() {
136 let meta = &parsed[0]; 136 let meta = &parsed[0];
137 assert_eq!("mod m;\n", meta.text); 137 assert_eq!("mod m;\n", meta.text);
138 138
139 assert_eq!("foo", meta.crate_name.as_ref().unwrap()); 139 assert_eq!("foo", meta.krate.as_ref().unwrap());
140 assert_eq!("/lib.rs", meta.path); 140 assert_eq!("/lib.rs", meta.path);
141 assert_eq!(2, meta.env.len()); 141 assert_eq!(2, meta.env.len());
142} 142}
diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs
index 0a8a86c62..940f91d0e 100644
--- a/crates/vfs/src/vfs_path.rs
+++ b/crates/vfs/src/vfs_path.rs
@@ -5,7 +5,7 @@ use paths::{AbsPath, AbsPathBuf};
5 5
6/// Long-term, we want to support files which do not reside in the file-system, 6/// Long-term, we want to support files which do not reside in the file-system,
7/// so we treat VfsPaths as opaque identifiers. 7/// so we treat VfsPaths as opaque identifiers.
8#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] 8#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
9pub struct VfsPath(VfsPathRepr); 9pub struct VfsPath(VfsPathRepr);
10 10
11impl VfsPath { 11impl VfsPath {
@@ -50,7 +50,7 @@ impl VfsPath {
50 } 50 }
51} 51}
52 52
53#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] 53#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
54enum VfsPathRepr { 54enum VfsPathRepr {
55 PathBuf(AbsPathBuf), 55 PathBuf(AbsPathBuf),
56 VirtualPath(VirtualPath), 56 VirtualPath(VirtualPath),
@@ -71,6 +71,21 @@ impl fmt::Display for VfsPath {
71 } 71 }
72} 72}
73 73
74impl fmt::Debug for VfsPath {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 fmt::Debug::fmt(&self.0, f)
77 }
78}
79
80impl fmt::Debug for VfsPathRepr {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 match &self {
83 VfsPathRepr::PathBuf(it) => fmt::Debug::fmt(&it.display(), f),
84 VfsPathRepr::VirtualPath(VirtualPath(it)) => fmt::Debug::fmt(&it, f),
85 }
86 }
87}
88
74#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] 89#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
75struct VirtualPath(String); 90struct VirtualPath(String);
76 91
diff --git a/editors/code/rollup.config.js b/editors/code/rollup.config.js
index 58360eabb..4b4c47f4a 100644
--- a/editors/code/rollup.config.js
+++ b/editors/code/rollup.config.js
@@ -11,12 +11,7 @@ export default {
11 resolve({ 11 resolve({
12 preferBuiltins: true 12 preferBuiltins: true
13 }), 13 }),
14 commonjs({ 14 commonjs()
15 namedExports: {
16 // squelch missing import warnings
17 'vscode-languageclient': ['CreateFile', 'RenameFile', 'ErrorCodes', 'WorkDoneProgress', 'WorkDoneProgressBegin', 'WorkDoneProgressReport', 'WorkDoneProgressEnd']
18 }
19 })
20 ], 15 ],
21 external: [...nodeBuiltins, 'vscode'], 16 external: [...nodeBuiltins, 'vscode'],
22 output: { 17 output: {