aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock20
-rw-r--r--crates/assists/src/handlers/generate_function.rs2
-rw-r--r--crates/completion/src/completions/attribute.rs16
-rw-r--r--crates/completion/src/completions/dot.rs8
-rw-r--r--crates/completion/src/completions/keyword.rs142
-rw-r--r--crates/completion/src/completions/mod_.rs4
-rw-r--r--crates/completion/src/completions/pattern.rs4
-rw-r--r--crates/completion/src/completions/postfix.rs62
-rw-r--r--crates/completion/src/completions/qualified_path.rs56
-rw-r--r--crates/completion/src/completions/record.rs4
-rw-r--r--crates/completion/src/completions/snippet.rs4
-rw-r--r--crates/completion/src/completions/trait_impl.rs4
-rw-r--r--crates/completion/src/completions/unqualified_path.rs172
-rw-r--r--crates/completion/src/test_utils.rs3
-rw-r--r--crates/hir_def/src/attr.rs208
-rw-r--r--crates/hir_def/src/item_tree.rs5
-rw-r--r--crates/hir_def/src/item_tree/lower.rs7
-rw-r--r--crates/hir_def/src/nameres/collector.rs59
-rw-r--r--crates/hir_def/src/nameres/tests.rs4
-rw-r--r--crates/hir_def/src/nameres/tests/diagnostics.rs18
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs8
-rw-r--r--crates/hir_def/src/path.rs12
-rw-r--r--crates/hir_expand/src/name.rs2
-rw-r--r--crates/ide/src/call_hierarchy.rs52
-rw-r--r--crates/ide/src/display.rs3
-rw-r--r--crates/ide/src/display/navigation_target.rs188
-rw-r--r--crates/ide/src/file_structure.rs80
-rw-r--r--crates/ide/src/goto_definition.rs4
-rw-r--r--crates/ide/src/hover.rs438
-rw-r--r--crates/ide/src/lib.rs16
-rw-r--r--crates/ide/src/parent_module.rs6
-rw-r--r--crates/ide/src/references.rs72
-rw-r--r--crates/ide/src/references/rename.rs35
-rw-r--r--crates/ide/src/runnables.rs179
-rw-r--r--crates/ide/src/syntax_highlighting.rs126
-rw-r--r--crates/ide/src/syntax_highlighting/format.rs6
-rw-r--r--crates/ide/src/syntax_highlighting/injection.rs3
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs94
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html12
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html24
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_injection.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html10
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html36
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs15
-rw-r--r--crates/ide_db/src/helpers/insert_use/tests.rs14
-rw-r--r--crates/ide_db/src/symbol_index.rs48
-rw-r--r--crates/parser/src/grammar.rs4
-rw-r--r--crates/parser/src/lib.rs3
-rw-r--r--crates/rust-analyzer/src/handlers.rs19
-rw-r--r--crates/rust-analyzer/src/to_proto.rs109
-rw-r--r--crates/syntax/src/ast/make.rs3
-rw-r--r--crates/syntax/src/lib.rs7
-rw-r--r--editors/code/src/main.ts11
53 files changed, 1269 insertions, 1174 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 31a850797..1051c4ec6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,9 +26,9 @@ dependencies = [
26 26
27[[package]] 27[[package]]
28name = "anyhow" 28name = "anyhow"
29version = "1.0.35" 29version = "1.0.36"
30source = "registry+https://github.com/rust-lang/crates.io-index" 30source = "registry+https://github.com/rust-lang/crates.io-index"
31checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4" 31checksum = "68803225a7b13e47191bab76f2687382b60d259e8cf37f6e1893658b84bb9479"
32 32
33[[package]] 33[[package]]
34name = "anymap" 34name = "anymap"
@@ -685,9 +685,9 @@ dependencies = [
685 685
686[[package]] 686[[package]]
687name = "indexmap" 687name = "indexmap"
688version = "1.6.0" 688version = "1.6.1"
689source = "registry+https://github.com/rust-lang/crates.io-index" 689source = "registry+https://github.com/rust-lang/crates.io-index"
690checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" 690checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
691dependencies = [ 691dependencies = [
692 "autocfg", 692 "autocfg",
693 "hashbrown", 693 "hashbrown",
@@ -1105,9 +1105,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
1105 1105
1106[[package]] 1106[[package]]
1107name = "perf-event" 1107name = "perf-event"
1108version = "0.4.5" 1108version = "0.4.6"
1109source = "registry+https://github.com/rust-lang/crates.io-index" 1109source = "registry+https://github.com/rust-lang/crates.io-index"
1110checksum = "273069d0b956939ba75e8b5663328b9b7f0dc2e262b3306c6be66c4d87e2240a" 1110checksum = "b7a1c2678a77d65edf773bd900f5b87f0944ac3421949842a2c6a4efe42d6c66"
1111dependencies = [ 1111dependencies = [
1112 "libc", 1112 "libc",
1113 "perf-event-open-sys", 1113 "perf-event-open-sys",
@@ -1990,18 +1990,18 @@ dependencies = [
1990 1990
1991[[package]] 1991[[package]]
1992name = "xshell" 1992name = "xshell"
1993version = "0.1.7" 1993version = "0.1.8"
1994source = "registry+https://github.com/rust-lang/crates.io-index" 1994source = "registry+https://github.com/rust-lang/crates.io-index"
1995checksum = "ed0728d188f2ae530490b7d92435728aba53c6aed06d07e1951da9bd4c1d0798" 1995checksum = "ed373ede30cea03e8c0af22f48ee1ba80efbf06fec8b4746977e6ee703878de0"
1996dependencies = [ 1996dependencies = [
1997 "xshell-macros", 1997 "xshell-macros",
1998] 1998]
1999 1999
2000[[package]] 2000[[package]]
2001name = "xshell-macros" 2001name = "xshell-macros"
2002version = "0.1.7" 2002version = "0.1.8"
2003source = "registry+https://github.com/rust-lang/crates.io-index" 2003source = "registry+https://github.com/rust-lang/crates.io-index"
2004checksum = "367f903cc3f8bc4f4b2400d47dfa6c9e3e121ffb51a30cf0fb67a72c0a0f9617" 2004checksum = "7f6af9f8119104697b0105989a73c578ce33f922d9d6f3dae0e8ae3d538db321"
2005 2005
2006[[package]] 2006[[package]]
2007name = "xtask" 2007name = "xtask"
diff --git a/crates/assists/src/handlers/generate_function.rs b/crates/assists/src/handlers/generate_function.rs
index 758188a42..f4cf155b6 100644
--- a/crates/assists/src/handlers/generate_function.rs
+++ b/crates/assists/src/handlers/generate_function.rs
@@ -145,7 +145,7 @@ impl FunctionBuilder {
145 self.type_params, 145 self.type_params,
146 self.params, 146 self.params,
147 fn_body, 147 fn_body,
148 Some(make::ret_type(make::ty("()"))), 148 Some(make::ret_type(make::ty_unit())),
149 ); 149 );
150 let leading_ws; 150 let leading_ws;
151 let trailing_ws; 151 let trailing_ws;
diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs
index acce2e7e7..19ce2482f 100644
--- a/crates/completion/src/completions/attribute.rs
+++ b/crates/completion/src/completions/attribute.rs
@@ -428,8 +428,8 @@ struct Test {}
428 at Hash 428 at Hash
429 at PartialEq 429 at PartialEq
430 at PartialEq, Eq 430 at PartialEq, Eq
431 at PartialEq, Eq, PartialOrd, Ord
432 at PartialEq, PartialOrd 431 at PartialEq, PartialOrd
432 at PartialEq, Eq, PartialOrd, Ord
433 "#]], 433 "#]],
434 ); 434 );
435 } 435 }
@@ -457,10 +457,10 @@ struct Test {}
457 at Clone, Copy 457 at Clone, Copy
458 at Debug 458 at Debug
459 at Default 459 at Default
460 at Eq
461 at Eq, PartialOrd, Ord
462 at Hash 460 at Hash
461 at Eq
463 at PartialOrd 462 at PartialOrd
463 at Eq, PartialOrd, Ord
464 "#]], 464 "#]],
465 ) 465 )
466 } 466 }
@@ -472,14 +472,14 @@ struct Test {}
472 expect![[r#" 472 expect![[r#"
473 at allow(…) 473 at allow(…)
474 at automatically_derived 474 at automatically_derived
475 at cfg(…)
476 at cfg_attr(…) 475 at cfg_attr(…)
476 at cfg(…)
477 at cold 477 at cold
478 at deny(…) 478 at deny(…)
479 at deprecated = "…" 479 at deprecated = "…"
480 at derive(…) 480 at derive(…)
481 at doc = "…"
482 at export_name = "…" 481 at export_name = "…"
482 at doc = "…"
483 at forbid(…) 483 at forbid(…)
484 at ignore = "…" 484 at ignore = "…"
485 at inline(…) 485 at inline(…)
@@ -518,15 +518,15 @@ struct Test {}
518 expect![[r#" 518 expect![[r#"
519 at allow(…) 519 at allow(…)
520 at automatically_derived 520 at automatically_derived
521 at cfg(…)
522 at cfg_attr(…) 521 at cfg_attr(…)
522 at cfg(…)
523 at cold 523 at cold
524 at crate_name = "" 524 at crate_name = ""
525 at deny(…) 525 at deny(…)
526 at deprecated = "…" 526 at deprecated = "…"
527 at derive(…) 527 at derive(…)
528 at doc = "…"
529 at export_name = "…" 528 at export_name = "…"
529 at doc = "…"
530 at feature(…) 530 at feature(…)
531 at forbid(…) 531 at forbid(…)
532 at global_allocator 532 at global_allocator
@@ -538,8 +538,8 @@ struct Test {}
538 at macro_export 538 at macro_export
539 at macro_use 539 at macro_use
540 at must_use = "…" 540 at must_use = "…"
541 at no_implicit_prelude
542 at no_link 541 at no_link
542 at no_implicit_prelude
543 at no_main 543 at no_main
544 at no_mangle 544 at no_mangle
545 at no_std 545 at no_std
diff --git a/crates/completion/src/completions/dot.rs b/crates/completion/src/completions/dot.rs
index c9875045a..551ef1771 100644
--- a/crates/completion/src/completions/dot.rs
+++ b/crates/completion/src/completions/dot.rs
@@ -82,8 +82,8 @@ impl S {
82fn foo(s: S) { s.<|> } 82fn foo(s: S) { s.<|> }
83"#, 83"#,
84 expect![[r#" 84 expect![[r#"
85 me bar() fn bar(&self)
86 fd foo u32 85 fd foo u32
86 me bar() fn bar(&self)
87 "#]], 87 "#]],
88 ); 88 );
89 } 89 }
@@ -98,8 +98,8 @@ impl S {
98} 98}
99"#, 99"#,
100 expect![[r#" 100 expect![[r#"
101 me foo() fn foo(self)
102 fd the_field (u32,) 101 fd the_field (u32,)
102 me foo() fn foo(self)
103 "#]], 103 "#]],
104 ) 104 )
105 } 105 }
@@ -114,8 +114,8 @@ impl A {
114} 114}
115"#, 115"#,
116 expect![[r#" 116 expect![[r#"
117 me foo() fn foo(&self)
118 fd the_field (u32, i32) 117 fd the_field (u32, i32)
118 me foo() fn foo(&self)
119 "#]], 119 "#]],
120 ) 120 )
121 } 121 }
@@ -147,8 +147,8 @@ mod inner {
147fn foo(a: inner::A) { a.<|> } 147fn foo(a: inner::A) { a.<|> }
148"#, 148"#,
149 expect![[r#" 149 expect![[r#"
150 fd crate_field u32
151 fd pub_field u32 150 fd pub_field u32
151 fd crate_field u32
152 fd super_field u32 152 fd super_field u32
153 "#]], 153 "#]],
154 ); 154 );
diff --git a/crates/completion/src/completions/keyword.rs b/crates/completion/src/completions/keyword.rs
index 720349b9d..1859dec70 100644
--- a/crates/completion/src/completions/keyword.rs
+++ b/crates/completion/src/completions/keyword.rs
@@ -223,21 +223,21 @@ mod tests {
223 check( 223 check(
224 r"m<|>", 224 r"m<|>",
225 expect![[r#" 225 expect![[r#"
226 kw const
227 kw enum
228 kw extern
229 kw fn 226 kw fn
227 kw use
230 kw impl 228 kw impl
231 kw mod
232 kw pub
233 kw pub(crate)
234 kw static
235 kw struct
236 kw trait 229 kw trait
237 kw type 230 kw enum
231 kw struct
238 kw union 232 kw union
233 kw mod
234 kw const
235 kw type
236 kw static
237 kw extern
239 kw unsafe 238 kw unsafe
240 kw use 239 kw pub(crate)
240 kw pub
241 "#]], 241 "#]],
242 ); 242 );
243 } 243 }
@@ -247,23 +247,23 @@ mod tests {
247 check( 247 check(
248 r"fn quux() { <|> }", 248 r"fn quux() { <|> }",
249 expect![[r#" 249 expect![[r#"
250 kw const
251 kw extern
252 kw fn 250 kw fn
251 kw use
252 kw impl
253 kw trait
254 kw match
255 kw while
256 kw loop
253 kw if 257 kw if
254 kw if let 258 kw if let
255 kw impl
256 kw let 259 kw let
257 kw loop
258 kw match
259 kw mod 260 kw mod
260 kw return 261 kw const
261 kw static
262 kw trait
263 kw type 262 kw type
263 kw static
264 kw extern
264 kw unsafe 265 kw unsafe
265 kw use 266 kw return
266 kw while
267 "#]], 267 "#]],
268 ); 268 );
269 } 269 }
@@ -273,23 +273,23 @@ mod tests {
273 check( 273 check(
274 r"fn quux() { if true { <|> } }", 274 r"fn quux() { if true { <|> } }",
275 expect![[r#" 275 expect![[r#"
276 kw const
277 kw extern
278 kw fn 276 kw fn
277 kw use
278 kw impl
279 kw trait
280 kw match
281 kw while
282 kw loop
279 kw if 283 kw if
280 kw if let 284 kw if let
281 kw impl
282 kw let 285 kw let
283 kw loop
284 kw match
285 kw mod 286 kw mod
286 kw return 287 kw const
287 kw static
288 kw trait
289 kw type 288 kw type
289 kw static
290 kw extern
290 kw unsafe 291 kw unsafe
291 kw use 292 kw return
292 kw while
293 "#]], 293 "#]],
294 ); 294 );
295 } 295 }
@@ -299,25 +299,25 @@ mod tests {
299 check( 299 check(
300 r#"fn quux() { if true { () } <|> }"#, 300 r#"fn quux() { if true { () } <|> }"#,
301 expect![[r#" 301 expect![[r#"
302 kw const
303 kw else
304 kw else if
305 kw extern
306 kw fn 302 kw fn
303 kw use
304 kw impl
305 kw trait
306 kw match
307 kw while
308 kw loop
307 kw if 309 kw if
308 kw if let 310 kw if let
309 kw impl
310 kw let 311 kw let
311 kw loop 312 kw else
312 kw match 313 kw else if
313 kw mod 314 kw mod
314 kw return 315 kw const
315 kw static
316 kw trait
317 kw type 316 kw type
317 kw static
318 kw extern
318 kw unsafe 319 kw unsafe
319 kw use 320 kw return
320 kw while
321 "#]], 321 "#]],
322 ); 322 );
323 check_edit( 323 check_edit(
@@ -336,13 +336,13 @@ fn quux() -> i32 {
336} 336}
337"#, 337"#,
338 expect![[r#" 338 expect![[r#"
339 kw match
340 kw while
341 kw loop
339 kw if 342 kw if
340 kw if let 343 kw if let
341 kw loop
342 kw match
343 kw return
344 kw unsafe 344 kw unsafe
345 kw while 345 kw return
346 "#]], 346 "#]],
347 ); 347 );
348 } 348 }
@@ -352,8 +352,8 @@ fn quux() -> i32 {
352 check( 352 check(
353 r"trait My { <|> }", 353 r"trait My { <|> }",
354 expect![[r#" 354 expect![[r#"
355 kw const
356 kw fn 355 kw fn
356 kw const
357 kw type 357 kw type
358 kw unsafe 358 kw unsafe
359 "#]], 359 "#]],
@@ -365,12 +365,12 @@ fn quux() -> i32 {
365 check( 365 check(
366 r"impl My { <|> }", 366 r"impl My { <|> }",
367 expect![[r#" 367 expect![[r#"
368 kw const
369 kw fn 368 kw fn
370 kw pub 369 kw const
371 kw pub(crate)
372 kw type 370 kw type
373 kw unsafe 371 kw unsafe
372 kw pub(crate)
373 kw pub
374 "#]], 374 "#]],
375 ); 375 );
376 } 376 }
@@ -380,25 +380,25 @@ fn quux() -> i32 {
380 check( 380 check(
381 r"fn my() { loop { <|> } }", 381 r"fn my() { loop { <|> } }",
382 expect![[r#" 382 expect![[r#"
383 kw break
384 kw const
385 kw continue
386 kw extern
387 kw fn 383 kw fn
384 kw use
385 kw impl
386 kw trait
387 kw match
388 kw while
389 kw loop
388 kw if 390 kw if
389 kw if let 391 kw if let
390 kw impl
391 kw let 392 kw let
392 kw loop
393 kw match
394 kw mod 393 kw mod
395 kw return 394 kw const
396 kw static
397 kw trait
398 kw type 395 kw type
396 kw static
397 kw extern
399 kw unsafe 398 kw unsafe
400 kw use 399 kw continue
401 kw while 400 kw break
401 kw return
402 "#]], 402 "#]],
403 ); 403 );
404 } 404 }
@@ -409,8 +409,8 @@ fn quux() -> i32 {
409 r"unsafe <|>", 409 r"unsafe <|>",
410 expect![[r#" 410 expect![[r#"
411 kw fn 411 kw fn
412 kw impl
413 kw trait 412 kw trait
413 kw impl
414 "#]], 414 "#]],
415 ); 415 );
416 } 416 }
@@ -421,8 +421,8 @@ fn quux() -> i32 {
421 r"fn my_fn() { unsafe <|> }", 421 r"fn my_fn() { unsafe <|> }",
422 expect![[r#" 422 expect![[r#"
423 kw fn 423 kw fn
424 kw impl
425 kw trait 424 kw trait
425 kw impl
426 "#]], 426 "#]],
427 ); 427 );
428 } 428 }
@@ -542,12 +542,12 @@ pub mod future {
542 check( 542 check(
543 r#"fn main() { let _ = <|> }"#, 543 r#"fn main() { let _ = <|> }"#,
544 expect![[r#" 544 expect![[r#"
545 kw match
546 kw while
547 kw loop
545 kw if 548 kw if
546 kw if let 549 kw if let
547 kw loop
548 kw match
549 kw return 550 kw return
550 kw while
551 "#]], 551 "#]],
552 ) 552 )
553 } 553 }
@@ -562,8 +562,8 @@ struct Foo {
562} 562}
563"#, 563"#,
564 expect![[r#" 564 expect![[r#"
565 kw pub
566 kw pub(crate) 565 kw pub(crate)
566 kw pub
567 "#]], 567 "#]],
568 ) 568 )
569 } 569 }
@@ -600,12 +600,12 @@ fn foo() {
600} 600}
601"#, 601"#,
602 expect![[r#" 602 expect![[r#"
603 kw match
604 kw while
605 kw loop
603 kw if 606 kw if
604 kw if let 607 kw if let
605 kw loop
606 kw match
607 kw return 608 kw return
608 kw while
609 "#]], 609 "#]],
610 ); 610 );
611 } 611 }
diff --git a/crates/completion/src/completions/mod_.rs b/crates/completion/src/completions/mod_.rs
index c96f84171..f77864b77 100644
--- a/crates/completion/src/completions/mod_.rs
+++ b/crates/completion/src/completions/mod_.rs
@@ -170,8 +170,8 @@ mod tests {
170 fn ignored_bar() {} 170 fn ignored_bar() {}
171 "#, 171 "#,
172 expect![[r#" 172 expect![[r#"
173 md bar;
174 md foo; 173 md foo;
174 md bar;
175 "#]], 175 "#]],
176 ); 176 );
177 } 177 }
@@ -207,8 +207,8 @@ mod tests {
207 fn ignored_bar() {} 207 fn ignored_bar() {}
208 "#, 208 "#,
209 expect![[r#" 209 expect![[r#"
210 md bar;
211 md foo; 210 md foo;
211 md bar;
212 "#]], 212 "#]],
213 ); 213 );
214 } 214 }
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs
index 4f63ff0ef..0c98e4412 100644
--- a/crates/completion/src/completions/pattern.rs
+++ b/crates/completion/src/completions/pattern.rs
@@ -66,10 +66,10 @@ fn foo() {
66} 66}
67"#, 67"#,
68 expect![[r#" 68 expect![[r#"
69 st Bar
70 en E 69 en E
71 ev X ()
72 ct Z 70 ct Z
71 st Bar
72 ev X ()
73 md m 73 md m
74 "#]], 74 "#]],
75 ); 75 );
diff --git a/crates/completion/src/completions/postfix.rs b/crates/completion/src/completions/postfix.rs
index c8ba63cd3..d6db82a93 100644
--- a/crates/completion/src/completions/postfix.rs
+++ b/crates/completion/src/completions/postfix.rs
@@ -315,20 +315,20 @@ fn main() {
315} 315}
316"#, 316"#,
317 expect![[r#" 317 expect![[r#"
318 sn box Box::new(expr)
319 sn call function(expr)
320 sn dbg dbg!(expr)
321 sn dbgr dbg!(&expr)
322 sn if if expr {} 318 sn if if expr {}
323 sn let let 319 sn while while expr {}
324 sn letm let mut
325 sn match match expr {}
326 sn not !expr 320 sn not !expr
327 sn ok Ok(expr)
328 sn ref &expr 321 sn ref &expr
329 sn refm &mut expr 322 sn refm &mut expr
323 sn match match expr {}
324 sn box Box::new(expr)
325 sn ok Ok(expr)
330 sn some Some(expr) 326 sn some Some(expr)
331 sn while while expr {} 327 sn dbg dbg!(expr)
328 sn dbgr dbg!(&expr)
329 sn call function(expr)
330 sn let let
331 sn letm let mut
332 "#]], 332 "#]],
333 ); 333 );
334 } 334 }
@@ -347,18 +347,18 @@ fn main() {
347} 347}
348"#, 348"#,
349 expect![[r#" 349 expect![[r#"
350 sn box Box::new(expr)
351 sn call function(expr)
352 sn dbg dbg!(expr)
353 sn dbgr dbg!(&expr)
354 sn if if expr {} 350 sn if if expr {}
355 sn match match expr {} 351 sn while while expr {}
356 sn not !expr 352 sn not !expr
357 sn ok Ok(expr)
358 sn ref &expr 353 sn ref &expr
359 sn refm &mut expr 354 sn refm &mut expr
355 sn match match expr {}
356 sn box Box::new(expr)
357 sn ok Ok(expr)
360 sn some Some(expr) 358 sn some Some(expr)
361 sn while while expr {} 359 sn dbg dbg!(expr)
360 sn dbgr dbg!(&expr)
361 sn call function(expr)
362 "#]], 362 "#]],
363 ); 363 );
364 } 364 }
@@ -373,17 +373,17 @@ fn main() {
373} 373}
374"#, 374"#,
375 expect![[r#" 375 expect![[r#"
376 sn ref &expr
377 sn refm &mut expr
378 sn match match expr {}
376 sn box Box::new(expr) 379 sn box Box::new(expr)
377 sn call function(expr) 380 sn ok Ok(expr)
381 sn some Some(expr)
378 sn dbg dbg!(expr) 382 sn dbg dbg!(expr)
379 sn dbgr dbg!(&expr) 383 sn dbgr dbg!(&expr)
384 sn call function(expr)
380 sn let let 385 sn let let
381 sn letm let mut 386 sn letm let mut
382 sn match match expr {}
383 sn ok Ok(expr)
384 sn ref &expr
385 sn refm &mut expr
386 sn some Some(expr)
387 "#]], 387 "#]],
388 ) 388 )
389 } 389 }
@@ -398,20 +398,20 @@ fn main() {
398} 398}
399"#, 399"#,
400 expect![[r#" 400 expect![[r#"
401 sn box Box::new(expr)
402 sn call function(expr)
403 sn dbg dbg!(expr)
404 sn dbgr dbg!(&expr)
405 sn if if expr {} 401 sn if if expr {}
406 sn let let 402 sn while while expr {}
407 sn letm let mut
408 sn match match expr {}
409 sn not !expr 403 sn not !expr
410 sn ok Ok(expr)
411 sn ref &expr 404 sn ref &expr
412 sn refm &mut expr 405 sn refm &mut expr
406 sn match match expr {}
407 sn box Box::new(expr)
408 sn ok Ok(expr)
413 sn some Some(expr) 409 sn some Some(expr)
414 sn while while expr {} 410 sn dbg dbg!(expr)
411 sn dbgr dbg!(&expr)
412 sn call function(expr)
413 sn let let
414 sn letm let mut
415 "#]], 415 "#]],
416 ); 416 );
417 } 417 }
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs
index bc23bea3f..1300f00b2 100644
--- a/crates/completion/src/completions/qualified_path.rs
+++ b/crates/completion/src/completions/qualified_path.rs
@@ -199,22 +199,22 @@ use self::{foo::*, bar<|>};
199 check_builtin( 199 check_builtin(
200 r#"fn main() { let _: <|> = 92; }"#, 200 r#"fn main() { let _: <|> = 92; }"#,
201 expect![[r#" 201 expect![[r#"
202 bt u32
202 bt bool 203 bt bool
203 bt char 204 bt u8
205 bt isize
206 bt u16
207 bt u64
208 bt u128
204 bt f32 209 bt f32
205 bt f64
206 bt i128 210 bt i128
207 bt i16 211 bt i16
208 bt i32 212 bt str
209 bt i64 213 bt i64
214 bt char
215 bt f64
216 bt i32
210 bt i8 217 bt i8
211 bt isize
212 bt str
213 bt u128
214 bt u16
215 bt u32
216 bt u64
217 bt u8
218 bt usize 218 bt usize
219 "#]], 219 "#]],
220 ); 220 );
@@ -279,8 +279,8 @@ struct Spam;
279use crate::Sp<|> 279use crate::Sp<|>
280"#, 280"#,
281 expect![[r#" 281 expect![[r#"
282 st Spam
283 md foo 282 md foo
283 st Spam
284 "#]], 284 "#]],
285 ); 285 );
286 } 286 }
@@ -296,8 +296,8 @@ struct Spam;
296use crate::{Sp<|>}; 296use crate::{Sp<|>};
297"#, 297"#,
298 expect![[r#" 298 expect![[r#"
299 st Spam
300 md foo 299 md foo
300 st Spam
301 "#]], 301 "#]],
302 ); 302 );
303 } 303 }
@@ -330,8 +330,8 @@ enum E { Foo, Bar(i32) }
330fn foo() { let _ = E::<|> } 330fn foo() { let _ = E::<|> }
331"#, 331"#,
332 expect![[r#" 332 expect![[r#"
333 ev Bar(…) (i32)
334 ev Foo () 333 ev Foo ()
334 ev Bar(…) (i32)
335 "#]], 335 "#]],
336 ); 336 );
337 } 337 }
@@ -353,10 +353,10 @@ impl S {
353fn foo() { let _ = S::<|> } 353fn foo() { let _ = S::<|> }
354"#, 354"#,
355 expect![[r#" 355 expect![[r#"
356 ct C const C: i32 = 42;
357 ta T type T = i32;
358 fn a() fn a() 356 fn a() fn a()
359 me b(…) fn b(&self) 357 me b(…) fn b(&self)
358 ct C const C: i32 = 42;
359 ta T type T = i32;
360 "#]], 360 "#]],
361 ); 361 );
362 } 362 }
@@ -381,9 +381,9 @@ mod m {
381fn foo() { let _ = S::<|> } 381fn foo() { let _ = S::<|> }
382"#, 382"#,
383 expect![[r#" 383 expect![[r#"
384 fn public_method() pub(crate) fn public_method()
384 ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1; 385 ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1;
385 ta PublicType pub(crate) type PublicType = u32; 386 ta PublicType pub(crate) type PublicType = u32;
386 fn public_method() pub(crate) fn public_method()
387 "#]], 387 "#]],
388 ); 388 );
389 } 389 }
@@ -503,14 +503,14 @@ trait Sub: Super {
503fn foo<T: Sub>() { T::<|> } 503fn foo<T: Sub>() { T::<|> }
504"#, 504"#,
505 expect![[r#" 505 expect![[r#"
506 ct C2 const C2: ();
507 ct CONST const CONST: u8;
508 ta SubTy type SubTy; 506 ta SubTy type SubTy;
509 ta Ty type Ty; 507 ta Ty type Ty;
510 fn func() fn func() 508 ct C2 const C2: ();
511 me method(…) fn method(&self)
512 fn subfunc() fn subfunc() 509 fn subfunc() fn subfunc()
513 me submethod(…) fn submethod(&self) 510 me submethod(…) fn submethod(&self)
511 ct CONST const CONST: u8;
512 fn func() fn func()
513 me method(…) fn method(&self)
514 "#]], 514 "#]],
515 ); 515 );
516 } 516 }
@@ -543,12 +543,12 @@ impl<T> Sub for Wrap<T> {
543} 543}
544"#, 544"#,
545 expect![[r#" 545 expect![[r#"
546 ct C2 const C2: () = ();
547 ct CONST const CONST: u8 = 0;
548 ta SubTy type SubTy; 546 ta SubTy type SubTy;
549 ta Ty type Ty; 547 ta Ty type Ty;
548 ct CONST const CONST: u8 = 0;
550 fn func() fn func() 549 fn func() fn func()
551 me method(…) fn method(&self) 550 me method(…) fn method(&self)
551 ct C2 const C2: () = ();
552 fn subfunc() fn subfunc() 552 fn subfunc() fn subfunc()
553 me submethod(…) fn submethod(&self) 553 me submethod(…) fn submethod(&self)
554 "#]], 554 "#]],
@@ -567,8 +567,8 @@ impl T { fn bar() {} }
567fn main() { T::<|>; } 567fn main() { T::<|>; }
568"#, 568"#,
569 expect![[r#" 569 expect![[r#"
570 fn bar() fn bar()
571 fn foo() fn foo() 570 fn foo() fn foo()
571 fn bar() fn bar()
572 "#]], 572 "#]],
573 ); 573 );
574 } 574 }
@@ -583,9 +583,9 @@ macro_rules! foo { () => {} }
583fn main() { let _ = crate::<|> } 583fn main() { let _ = crate::<|> }
584 "#, 584 "#,
585 expect![[r##" 585 expect![[r##"
586 fn main() fn main()
586 ma foo!(…) #[macro_export] 587 ma foo!(…) #[macro_export]
587 macro_rules! foo 588 macro_rules! foo
588 fn main() fn main()
589 "##]], 589 "##]],
590 ); 590 );
591 } 591 }
@@ -603,8 +603,8 @@ mod a {
603} 603}
604"#, 604"#,
605 expect![[r#" 605 expect![[r#"
606 ct A
607 md b 606 md b
607 ct A
608 "#]], 608 "#]],
609 ); 609 );
610 } 610 }
@@ -628,8 +628,8 @@ mod p {
628"#, 628"#,
629 expect![[r#" 629 expect![[r#"
630 ct RIGHT_CONST 630 ct RIGHT_CONST
631 st RightType
632 fn right_fn() fn wrong_fn() 631 fn right_fn() fn wrong_fn()
632 st RightType
633 "#]], 633 "#]],
634 ); 634 );
635 635
@@ -675,8 +675,8 @@ fn main() { m!(self::f<|>); }
675fn foo() {} 675fn foo() {}
676"#, 676"#,
677 expect![[r#" 677 expect![[r#"
678 fn foo() fn foo()
679 fn main() fn main() 678 fn main() fn main()
679 fn foo() fn foo()
680 "#]], 680 "#]],
681 ); 681 );
682 } 682 }
@@ -747,8 +747,8 @@ fn main() {
747} 747}
748"#, 748"#,
749 expect![[r#" 749 expect![[r#"
750 fn foo(…) fn foo(a: i32, b: i32)
751 fn main() fn main() 750 fn main() fn main()
751 fn foo(…) fn foo(a: i32, b: i32)
752 "#]], 752 "#]],
753 ); 753 );
754 } 754 }
diff --git a/crates/completion/src/completions/record.rs b/crates/completion/src/completions/record.rs
index eaa44c97d..91bf4a8ad 100644
--- a/crates/completion/src/completions/record.rs
+++ b/crates/completion/src/completions/record.rs
@@ -94,9 +94,9 @@ fn process(f: S) {
94 check_snippet( 94 check_snippet(
95 test_code, 95 test_code,
96 expect![[r#" 96 expect![[r#"
97 fd ..Default::default()
98 sn pd 97 sn pd
99 sn ppd 98 sn ppd
99 fd ..Default::default()
100 "#]], 100 "#]],
101 ); 101 );
102 } 102 }
@@ -160,8 +160,8 @@ fn process(e: E) {
160} 160}
161"#, 161"#,
162 expect![[r#" 162 expect![[r#"
163 fd bar ()
164 fd foo u32 163 fd foo u32
164 fd bar ()
165 "#]], 165 "#]],
166 ); 166 );
167 } 167 }
diff --git a/crates/completion/src/completions/snippet.rs b/crates/completion/src/completions/snippet.rs
index 6f0c00078..842590130 100644
--- a/crates/completion/src/completions/snippet.rs
+++ b/crates/completion/src/completions/snippet.rs
@@ -105,9 +105,9 @@ mod tests {
105} 105}
106"#, 106"#,
107 expect![[r#" 107 expect![[r#"
108 sn macro_rules
109 sn tfn (Test function)
110 sn tmod (Test module) 108 sn tmod (Test module)
109 sn tfn (Test function)
110 sn macro_rules
111 "#]], 111 "#]],
112 ) 112 )
113 } 113 }
diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs
index e2fe44aff..c4e0d0669 100644
--- a/crates/completion/src/completions/trait_impl.rs
+++ b/crates/completion/src/completions/trait_impl.rs
@@ -266,10 +266,10 @@ impl Test for T {
266} 266}
267"#, 267"#,
268 expect![[" 268 expect![["
269ta type TestType = \n\
269ct const TEST_CONST: u16 = \n\ 270ct const TEST_CONST: u16 = \n\
270fn fn test() 271fn fn test()
271ta type TestType = \n\ 272"]],
272 "]],
273 ); 273 );
274 } 274 }
275 275
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index 93869f92e..099ffb4d4 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -1,7 +1,7 @@
1//! Completion of names from the current scope, e.g. locals and imported items. 1//! Completion of names from the current scope, e.g. locals and imported items.
2 2
3use either::Either; 3use either::Either;
4use hir::{Adt, ModuleDef, ScopeDef, Type}; 4use hir::{Adt, ModPath, ModuleDef, ScopeDef, Type};
5use ide_db::helpers::insert_use::ImportScope; 5use ide_db::helpers::insert_use::ImportScope;
6use ide_db::imports_locator; 6use ide_db::imports_locator;
7use syntax::AstNode; 7use syntax::AstNode;
@@ -146,13 +146,9 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
146 .filter(|(mod_path, _)| mod_path.len() > 1) 146 .filter(|(mod_path, _)| mod_path.len() > 1)
147 .collect::<Vec<_>>(); 147 .collect::<Vec<_>>();
148 148
149 let user_input_lowercased = potential_import_name.to_lowercase();
149 all_mod_paths.sort_by_cached_key(|(mod_path, _)| { 150 all_mod_paths.sort_by_cached_key(|(mod_path, _)| {
150 if let Some(name) = mod_path.segments.last().map(|name| name.to_string().to_lowercase()) { 151 compute_fuzzy_completion_order_key(mod_path, &user_input_lowercased)
151 if name.contains(&potential_import_name.to_lowercase()) {
152 return 0;
153 }
154 }
155 1
156 }); 152 });
157 153
158 acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| { 154 acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| {
@@ -165,21 +161,48 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
165 Some(()) 161 Some(())
166} 162}
167 163
164fn compute_fuzzy_completion_order_key(
165 proposed_mod_path: &ModPath,
166 user_input_lowercased: &str,
167) -> usize {
168 mark::hit!(certain_fuzzy_order_test);
169 let proposed_import_name = match proposed_mod_path.segments.last() {
170 Some(name) => name.to_string().to_lowercase(),
171 None => return usize::MAX,
172 };
173 match proposed_import_name.match_indices(user_input_lowercased).next() {
174 Some((first_matching_index, _)) => first_matching_index,
175 None => usize::MAX,
176 }
177}
178
168#[cfg(test)] 179#[cfg(test)]
169mod tests { 180mod tests {
170 use expect_test::{expect, Expect}; 181 use expect_test::{expect, Expect};
171 use test_utils::mark; 182 use test_utils::mark;
172 183
173 use crate::{ 184 use crate::{
174 test_utils::{check_edit, check_edit_with_config, completion_list}, 185 test_utils::{check_edit, check_edit_with_config, completion_list_with_config},
175 CompletionConfig, CompletionKind, 186 CompletionConfig, CompletionKind,
176 }; 187 };
177 188
178 fn check(ra_fixture: &str, expect: Expect) { 189 fn check(ra_fixture: &str, expect: Expect) {
179 let actual = completion_list(ra_fixture, CompletionKind::Reference); 190 check_with_config(CompletionConfig::default(), ra_fixture, expect);
191 }
192
193 fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
194 let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
180 expect.assert_eq(&actual) 195 expect.assert_eq(&actual)
181 } 196 }
182 197
198 fn fuzzy_completion_config() -> CompletionConfig {
199 let mut completion_config = CompletionConfig::default();
200 completion_config
201 .active_resolve_capabilities
202 .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
203 completion_config
204 }
205
183 #[test] 206 #[test]
184 fn self_fulfilling_completion() { 207 fn self_fulfilling_completion() {
185 mark::check!(self_fulfilling_completion); 208 mark::check!(self_fulfilling_completion);
@@ -255,9 +278,9 @@ fn quux(x: i32) {
255} 278}
256"#, 279"#,
257 expect![[r#" 280 expect![[r#"
258 fn quux(…) fn quux(x: i32)
259 bn x i32
260 bn y i32 281 bn y i32
282 bn x i32
283 fn quux(…) fn quux(x: i32)
261 "#]], 284 "#]],
262 ); 285 );
263 } 286 }
@@ -277,8 +300,8 @@ fn quux() {
277} 300}
278"#, 301"#,
279 expect![[r#" 302 expect![[r#"
280 bn a
281 bn b i32 303 bn b i32
304 bn a
282 fn quux() fn quux() 305 fn quux() fn quux()
283 "#]], 306 "#]],
284 ); 307 );
@@ -293,8 +316,8 @@ fn quux() {
293} 316}
294"#, 317"#,
295 expect![[r#" 318 expect![[r#"
296 fn quux() fn quux()
297 bn x 319 bn x
320 fn quux() fn quux()
298 "#]], 321 "#]],
299 ); 322 );
300 } 323 }
@@ -335,9 +358,9 @@ fn main() {
335 check( 358 check(
336 r#"struct S<T> { x: <|>}"#, 359 r#"struct S<T> { x: <|>}"#,
337 expect![[r#" 360 expect![[r#"
338 st S<…>
339 tp Self 361 tp Self
340 tp T 362 tp T
363 st S<…>
341 "#]], 364 "#]],
342 ); 365 );
343 } 366 }
@@ -362,9 +385,9 @@ enum E {}
362fn quux() { <|> } 385fn quux() { <|> }
363"#, 386"#,
364 expect![[r#" 387 expect![[r#"
365 en E
366 st S 388 st S
367 fn quux() fn quux() 389 fn quux() fn quux()
390 en E
368 "#]], 391 "#]],
369 ); 392 );
370 } 393 }
@@ -416,8 +439,8 @@ mod m {
416} 439}
417"#, 440"#,
418 expect![[r#" 441 expect![[r#"
419 st Bar
420 fn quux() fn quux() 442 fn quux() fn quux()
443 st Bar
421 "#]], 444 "#]],
422 ); 445 );
423 } 446 }
@@ -462,8 +485,8 @@ fn foo() {
462 check( 485 check(
463 r#"impl S { fn foo(&self) { <|> } }"#, 486 r#"impl S { fn foo(&self) { <|> } }"#,
464 expect![[r#" 487 expect![[r#"
465 tp Self
466 bn self &{unknown} 488 bn self &{unknown}
489 tp Self
467 "#]], 490 "#]],
468 ); 491 );
469 } 492 }
@@ -482,9 +505,9 @@ use prelude::*;
482mod prelude { struct Option; } 505mod prelude { struct Option; }
483"#, 506"#,
484 expect![[r#" 507 expect![[r#"
485 st Option
486 fn foo() fn foo() 508 fn foo() fn foo()
487 md std 509 md std
510 st Option
488 "#]], 511 "#]],
489 ); 512 );
490 } 513 }
@@ -509,10 +532,10 @@ use prelude::*;
509mod prelude { struct String; } 532mod prelude { struct String; }
510"#, 533"#,
511 expect![[r#" 534 expect![[r#"
512 st String
513 md core
514 fn foo() fn foo() 535 fn foo() fn foo()
515 md std 536 md std
537 md core
538 st String
516 "#]], 539 "#]],
517 ); 540 );
518 } 541 }
@@ -538,13 +561,13 @@ mod m2 {
538fn main() { let v = <|> } 561fn main() { let v = <|> }
539"#, 562"#,
540 expect![[r##" 563 expect![[r##"
541 ma bar!(…) macro_rules! bar 564 md m1
542 ma baz!(…) #[macro_export] 565 ma baz!(…) #[macro_export]
543 macro_rules! baz 566 macro_rules! baz
544 ma foo!(…) macro_rules! foo
545 md m1
546 md m2
547 fn main() fn main() 567 fn main() fn main()
568 md m2
569 ma bar!(…) macro_rules! bar
570 ma foo!(…) macro_rules! foo
548 "##]], 571 "##]],
549 ); 572 );
550 } 573 }
@@ -557,8 +580,8 @@ macro_rules! foo { () => {} }
557fn foo() { <|> } 580fn foo() { <|> }
558"#, 581"#,
559 expect![[r#" 582 expect![[r#"
560 ma foo!(…) macro_rules! foo
561 fn foo() fn foo() 583 fn foo() fn foo()
584 ma foo!(…) macro_rules! foo
562 "#]], 585 "#]],
563 ); 586 );
564 } 587 }
@@ -571,8 +594,8 @@ macro_rules! foo { () => {} }
571fn main() { let x: <|> } 594fn main() { let x: <|> }
572"#, 595"#,
573 expect![[r#" 596 expect![[r#"
574 ma foo!(…) macro_rules! foo
575 fn main() fn main() 597 fn main() fn main()
598 ma foo!(…) macro_rules! foo
576 "#]], 599 "#]],
577 ); 600 );
578 } 601 }
@@ -585,8 +608,8 @@ macro_rules! foo { () => {} }
585fn main() { <|> } 608fn main() { <|> }
586"#, 609"#,
587 expect![[r#" 610 expect![[r#"
588 ma foo!(…) macro_rules! foo
589 fn main() fn main() 611 fn main() fn main()
612 ma foo!(…) macro_rules! foo
590 "#]], 613 "#]],
591 ); 614 );
592 } 615 }
@@ -618,10 +641,10 @@ fn quux(x: i32) {
618} 641}
619"#, 642"#,
620 expect![[r#" 643 expect![[r#"
621 ma m!(…) macro_rules! m
622 fn quux(…) fn quux(x: i32)
623 bn x i32
624 bn y i32 644 bn y i32
645 bn x i32
646 fn quux(…) fn quux(x: i32)
647 ma m!(…) macro_rules! m
625 "#]], 648 "#]],
626 ); 649 );
627 } 650 }
@@ -637,10 +660,10 @@ fn quux(x: i32) {
637} 660}
638", 661",
639 expect![[r#" 662 expect![[r#"
640 ma m!(…) macro_rules! m
641 fn quux(…) fn quux(x: i32)
642 bn x i32
643 bn y i32 663 bn y i32
664 bn x i32
665 fn quux(…) fn quux(x: i32)
666 ma m!(…) macro_rules! m
644 "#]], 667 "#]],
645 ); 668 );
646 } 669 }
@@ -656,10 +679,10 @@ fn quux(x: i32) {
656} 679}
657"#, 680"#,
658 expect![[r#" 681 expect![[r#"
659 ma m!(…) macro_rules! m
660 fn quux(…) fn quux(x: i32)
661 bn x i32
662 bn y i32 682 bn y i32
683 bn x i32
684 fn quux(…) fn quux(x: i32)
685 ma m!(…) macro_rules! m
663 "#]], 686 "#]],
664 ); 687 );
665 } 688 }
@@ -673,8 +696,8 @@ use spam::Quux;
673fn main() { <|> } 696fn main() { <|> }
674"#, 697"#,
675 expect![[r#" 698 expect![[r#"
676 ?? Quux
677 fn main() fn main() 699 fn main() fn main()
700 ?? Quux
678 "#]], 701 "#]],
679 ); 702 );
680 } 703 }
@@ -690,10 +713,10 @@ fn main() {
690} 713}
691"#, 714"#,
692 expect![[r#" 715 expect![[r#"
693 en Foo
694 ev Foo::Bar () 716 ev Foo::Bar ()
695 ev Foo::Baz () 717 ev Foo::Baz ()
696 ev Foo::Quux () 718 ev Foo::Quux ()
719 en Foo
697 "#]], 720 "#]],
698 ) 721 )
699 } 722 }
@@ -710,10 +733,10 @@ fn main() {
710} 733}
711"#, 734"#,
712 expect![[r#" 735 expect![[r#"
713 en Foo
714 ev Foo::Bar () 736 ev Foo::Bar ()
715 ev Foo::Baz () 737 ev Foo::Baz ()
716 ev Foo::Quux () 738 ev Foo::Quux ()
739 en Foo
717 "#]], 740 "#]],
718 ) 741 )
719 } 742 }
@@ -726,10 +749,10 @@ enum Foo { Bar, Baz, Quux }
726fn main() { let foo: Foo = Q<|> } 749fn main() { let foo: Foo = Q<|> }
727"#, 750"#,
728 expect![[r#" 751 expect![[r#"
729 en Foo
730 ev Foo::Bar () 752 ev Foo::Bar ()
731 ev Foo::Baz () 753 ev Foo::Baz ()
732 ev Foo::Quux () 754 ev Foo::Quux ()
755 en Foo
733 fn main() fn main() 756 fn main() fn main()
734 "#]], 757 "#]],
735 ) 758 )
@@ -743,9 +766,9 @@ mod m { pub enum E { V } }
743fn f() -> m::E { V<|> } 766fn f() -> m::E { V<|> }
744"#, 767"#,
745 expect![[r#" 768 expect![[r#"
746 fn f() fn f() -> m::E
747 md m
748 ev m::E::V () 769 ev m::E::V ()
770 md m
771 fn f() fn f() -> m::E
749 "#]], 772 "#]],
750 ) 773 )
751 } 774 }
@@ -772,22 +795,17 @@ struct MyStruct {}
772impl My<|> 795impl My<|>
773"#, 796"#,
774 expect![[r#" 797 expect![[r#"
775 st MyStruct
776 tt MyTrait
777 tp Self 798 tp Self
799 tt MyTrait
800 st MyStruct
778 "#]], 801 "#]],
779 ) 802 )
780 } 803 }
781 804
782 #[test] 805 #[test]
783 fn function_fuzzy_completion() { 806 fn function_fuzzy_completion() {
784 let mut completion_config = CompletionConfig::default();
785 completion_config
786 .active_resolve_capabilities
787 .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
788
789 check_edit_with_config( 807 check_edit_with_config(
790 completion_config, 808 fuzzy_completion_config(),
791 "stdin", 809 "stdin",
792 r#" 810 r#"
793//- /lib.rs crate:dep 811//- /lib.rs crate:dep
@@ -812,13 +830,8 @@ fn main() {
812 830
813 #[test] 831 #[test]
814 fn macro_fuzzy_completion() { 832 fn macro_fuzzy_completion() {
815 let mut completion_config = CompletionConfig::default();
816 completion_config
817 .active_resolve_capabilities
818 .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
819
820 check_edit_with_config( 833 check_edit_with_config(
821 completion_config, 834 fuzzy_completion_config(),
822 "macro_with_curlies!", 835 "macro_with_curlies!",
823 r#" 836 r#"
824//- /lib.rs crate:dep 837//- /lib.rs crate:dep
@@ -845,13 +858,8 @@ fn main() {
845 858
846 #[test] 859 #[test]
847 fn struct_fuzzy_completion() { 860 fn struct_fuzzy_completion() {
848 let mut completion_config = CompletionConfig::default();
849 completion_config
850 .active_resolve_capabilities
851 .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
852
853 check_edit_with_config( 861 check_edit_with_config(
854 completion_config, 862 fuzzy_completion_config(),
855 "ThirdStruct", 863 "ThirdStruct",
856 r#" 864 r#"
857//- /lib.rs crate:dep 865//- /lib.rs crate:dep
@@ -877,4 +885,44 @@ fn main() {
877"#, 885"#,
878 ); 886 );
879 } 887 }
888
889 #[test]
890 fn fuzzy_completions_come_in_specific_order() {
891 mark::check!(certain_fuzzy_order_test);
892 check_with_config(
893 fuzzy_completion_config(),
894 r#"
895//- /lib.rs crate:dep
896pub struct FirstStruct;
897pub mod some_module {
898 // already imported, omitted
899 pub struct SecondStruct;
900 // does not contain all letters from the query, omitted
901 pub struct UnrelatedOne;
902 // contains all letters from the query, but not in sequence, displayed last
903 pub struct ThiiiiiirdStruct;
904 // contains all letters from the query, but not in the beginning, displayed second
905 pub struct AfterThirdStruct;
906 // contains all letters from the query in the begginning, displayed first
907 pub struct ThirdStruct;
908}
909
910//- /main.rs crate:main deps:dep
911use dep::{FirstStruct, some_module::SecondStruct};
912
913fn main() {
914 hir<|>
915}
916"#,
917 expect![[r#"
918 fn main() fn main()
919 st SecondStruct
920 st FirstStruct
921 md dep
922 st dep::some_module::ThirdStruct
923 st dep::some_module::AfterThirdStruct
924 st dep::some_module::ThiiiiiirdStruct
925 "#]],
926 );
927 }
880} 928}
diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs
index db896b2df..eb0c16f52 100644
--- a/crates/completion/src/test_utils.rs
+++ b/crates/completion/src/test_utils.rs
@@ -47,9 +47,8 @@ pub(crate) fn completion_list_with_config(
47 code: &str, 47 code: &str,
48 kind: CompletionKind, 48 kind: CompletionKind,
49) -> String { 49) -> String {
50 let mut kind_completions: Vec<CompletionItem> = 50 let kind_completions: Vec<CompletionItem> =
51 get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect(); 51 get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect();
52 kind_completions.sort_by_key(|c| c.label().to_owned());
53 let label_width = kind_completions 52 let label_width = kind_completions
54 .iter() 53 .iter()
55 .map(|it| monospace_width(it.label())) 54 .map(|it| monospace_width(it.label()))
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 9cd0b72aa..042e119b1 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -5,20 +5,21 @@ use std::{ops, sync::Arc};
5use base_db::CrateId; 5use base_db::CrateId;
6use cfg::{CfgExpr, CfgOptions}; 6use cfg::{CfgExpr, CfgOptions};
7use either::Either; 7use either::Either;
8use hir_expand::{hygiene::Hygiene, AstId, InFile}; 8use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile};
9use itertools::Itertools; 9use itertools::Itertools;
10use mbe::ast_to_token_tree; 10use mbe::ast_to_token_tree;
11use syntax::{ 11use syntax::{
12 ast::{self, AstNode, AttrsOwner}, 12 ast::{self, AstNode, AttrsOwner},
13 match_ast, AstToken, SmolStr, SyntaxNode, 13 match_ast, AstToken, SmolStr, SyntaxNode,
14}; 14};
15use test_utils::mark;
15use tt::Subtree; 16use tt::Subtree;
16 17
17use crate::{ 18use crate::{
18 db::DefDatabase, 19 db::DefDatabase,
19 item_tree::{ItemTreeId, ItemTreeNode}, 20 item_tree::{ItemTreeId, ItemTreeNode},
20 nameres::ModuleSource, 21 nameres::ModuleSource,
21 path::ModPath, 22 path::{ModPath, PathKind},
22 src::HasChildSource, 23 src::HasChildSource,
23 AdtId, AttrDefId, Lookup, 24 AdtId, AttrDefId, Lookup,
24}; 25};
@@ -41,7 +42,7 @@ impl From<Documentation> for String {
41 42
42/// Syntactical attributes, without filtering of `cfg_attr`s. 43/// Syntactical attributes, without filtering of `cfg_attr`s.
43#[derive(Default, Debug, Clone, PartialEq, Eq)] 44#[derive(Default, Debug, Clone, PartialEq, Eq)]
44pub struct RawAttrs { 45pub(crate) struct RawAttrs {
45 entries: Option<Arc<[Attr]>>, 46 entries: Option<Arc<[Attr]>>,
46} 47}
47 48
@@ -71,35 +72,34 @@ impl ops::Deref for Attrs {
71} 72}
72 73
73impl RawAttrs { 74impl RawAttrs {
74 pub const EMPTY: Self = Self { entries: None }; 75 pub(crate) const EMPTY: Self = Self { entries: None };
75 76
76 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self { 77 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self {
77 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) 78 let attrs: Vec<_> = collect_attrs(owner).collect();
78 .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));
79
80 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
81 let attrs = outer_attrs
82 .chain(inner_attrs.into_iter().flatten())
83 .map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene)));
84
85 let outer_docs =
86 ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer);
87 let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| {
88 (
89 docs_text.syntax().text_range().start(),
90 docs_text.doc_comment().map(|doc| Attr {
91 input: Some(AttrInput::Literal(SmolStr::new(doc))),
92 path: ModPath::from(hir_expand::name!(doc)),
93 }),
94 )
95 });
96 // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
97 let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
98 let entries = if attrs.is_empty() { 79 let entries = if attrs.is_empty() {
99 // Avoid heap allocation 80 // Avoid heap allocation
100 None 81 None
101 } else { 82 } else {
102 Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect()) 83 Some(
84 attrs
85 .into_iter()
86 .enumerate()
87 .flat_map(|(i, attr)| match attr {
88 Either::Left(attr) => Attr::from_src(attr, hygiene).map(|attr| (i, attr)),
89 Either::Right(comment) => comment.doc_comment().map(|doc| {
90 (
91 i,
92 Attr {
93 index: 0,
94 input: Some(AttrInput::Literal(SmolStr::new(doc))),
95 path: ModPath::from(hir_expand::name!(doc)),
96 },
97 )
98 }),
99 })
100 .map(|(i, attr)| Attr { index: i as u32, ..attr })
101 .collect(),
102 )
103 }; 103 };
104 Self { entries } 104 Self { entries }
105 } 105 }
@@ -122,9 +122,69 @@ impl RawAttrs {
122 } 122 }
123 123
124 /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. 124 /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`.
125 pub(crate) fn filter(self, _db: &dyn DefDatabase, _krate: CrateId) -> Attrs { 125 pub(crate) fn filter(self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
126 // FIXME actually implement this 126 let has_cfg_attrs = self.iter().any(|attr| {
127 Attrs(self) 127 attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr])
128 });
129 if !has_cfg_attrs {
130 return Attrs(self);
131 }
132
133 let crate_graph = db.crate_graph();
134 let new_attrs = self
135 .iter()
136 .filter_map(|attr| {
137 let attr = attr.clone();
138 let is_cfg_attr =
139 attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]);
140 if !is_cfg_attr {
141 return Some(attr);
142 }
143
144 let subtree = match &attr.input {
145 Some(AttrInput::TokenTree(it)) => it,
146 _ => return Some(attr),
147 };
148
149 // Input subtree is: `(cfg, attr)`
150 // Split it up into a `cfg` and an `attr` subtree.
151 // FIXME: There should be a common API for this.
152 let mut saw_comma = false;
153 let (mut cfg, attr): (Vec<_>, Vec<_>) =
154 subtree.clone().token_trees.into_iter().partition(|tree| {
155 if saw_comma {
156 return false;
157 }
158
159 match tree {
160 tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
161 saw_comma = true;
162 }
163 _ => {}
164 }
165
166 true
167 });
168 cfg.pop(); // `,` ends up in here
169
170 let attr = Subtree { delimiter: None, token_trees: attr };
171 let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg };
172 let cfg = CfgExpr::parse(&cfg);
173
174 let cfg_options = &crate_graph[krate].cfg_options;
175 if cfg_options.check(&cfg) == Some(false) {
176 None
177 } else {
178 mark::hit!(cfg_attr_active);
179
180 let attr = ast::Attr::parse(&format!("#[{}]", attr)).ok()?;
181 let hygiene = Hygiene::new_unhygienic(); // FIXME
182 Attr::from_src(attr, &hygiene)
183 }
184 })
185 .collect();
186
187 Attrs(RawAttrs { entries: Some(new_attrs) })
128 } 188 }
129} 189}
130 190
@@ -180,24 +240,11 @@ impl Attrs {
180 raw_attrs.filter(db, def.krate(db)) 240 raw_attrs.filter(db, def.krate(db))
181 } 241 }
182 242
183 pub fn merge(&self, other: Attrs) -> Attrs {
184 match (&self.0.entries, &other.0.entries) {
185 (None, None) => Attrs::EMPTY,
186 (Some(entries), None) | (None, Some(entries)) => {
187 Attrs(RawAttrs { entries: Some(entries.clone()) })
188 }
189 (Some(a), Some(b)) => {
190 Attrs(RawAttrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) })
191 }
192 }
193 }
194
195 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { 243 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
196 AttrQuery { attrs: self, key } 244 AttrQuery { attrs: self, key }
197 } 245 }
198 246
199 pub fn cfg(&self) -> Option<CfgExpr> { 247 pub fn cfg(&self) -> Option<CfgExpr> {
200 // FIXME: handle cfg_attr :-)
201 let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse).collect::<Vec<_>>(); 248 let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse).collect::<Vec<_>>();
202 match cfgs.len() { 249 match cfgs.len() {
203 0 => None, 250 0 => None,
@@ -268,6 +315,7 @@ fn inner_attributes(
268 315
269#[derive(Debug, Clone, PartialEq, Eq)] 316#[derive(Debug, Clone, PartialEq, Eq)]
270pub struct Attr { 317pub struct Attr {
318 index: u32,
271 pub(crate) path: ModPath, 319 pub(crate) path: ModPath,
272 pub(crate) input: Option<AttrInput>, 320 pub(crate) input: Option<AttrInput>,
273} 321}
@@ -294,7 +342,59 @@ impl Attr {
294 } else { 342 } else {
295 None 343 None
296 }; 344 };
297 Some(Attr { path, input }) 345 Some(Attr { index: 0, path, input })
346 }
347
348 /// Maps this lowered `Attr` back to its original syntax node.
349 ///
350 /// `owner` must be the original owner of the attribute.
351 ///
352 /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of
353 /// the attribute represented by `Attr`.
354 pub fn to_src(&self, owner: &dyn AttrsOwner) -> Either<ast::Attr, ast::Comment> {
355 collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| {
356 panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax())
357 })
358 }
359
360 /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths
361 /// to derive macros.
362 ///
363 /// Returns `None` when the attribute is not a well-formed `#[derive]` attribute.
364 pub(crate) fn parse_derive(&self) -> Option<impl Iterator<Item = ModPath>> {
365 if self.path.as_ident() != Some(&hir_expand::name![derive]) {
366 return None;
367 }
368
369 match &self.input {
370 Some(AttrInput::TokenTree(args)) => {
371 let mut counter = 0;
372 let paths = args
373 .token_trees
374 .iter()
375 .group_by(move |tt| {
376 match tt {
377 tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
378 counter += 1;
379 }
380 _ => {}
381 }
382 counter
383 })
384 .into_iter()
385 .map(|(_, tts)| {
386 let segments = tts.filter_map(|tt| match tt {
387 tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => Some(id.as_name()),
388 _ => None,
389 });
390 ModPath::from_segments(PathKind::Plain, segments)
391 })
392 .collect::<Vec<_>>();
393
394 Some(paths.into_iter())
395 }
396 _ => None,
397 }
298 } 398 }
299} 399}
300 400
@@ -323,7 +423,7 @@ impl<'a> AttrQuery<'a> {
323 self.attrs().next().is_some() 423 self.attrs().next().is_some()
324 } 424 }
325 425
326 fn attrs(self) -> impl Iterator<Item = &'a Attr> { 426 pub(crate) fn attrs(self) -> impl Iterator<Item = &'a Attr> {
327 let key = self.key; 427 let key = self.key;
328 self.attrs 428 self.attrs
329 .iter() 429 .iter()
@@ -344,3 +444,23 @@ fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase
344 let mod_item = N::id_to_mod_item(id.value); 444 let mod_item = N::id_to_mod_item(id.value);
345 tree.raw_attrs(mod_item.into()).clone() 445 tree.raw_attrs(mod_item.into()).clone()
346} 446}
447
448fn collect_attrs(owner: &dyn AttrsOwner) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> {
449 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
450 .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));
451
452 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
453 let attrs = outer_attrs
454 .chain(inner_attrs.into_iter().flatten())
455 .map(|attr| (attr.syntax().text_range().start(), Either::Left(attr)));
456
457 let outer_docs =
458 ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer);
459 let docs = outer_docs
460 .chain(inner_docs.into_iter().flatten())
461 .map(|docs_text| (docs_text.syntax().text_range().start(), Either::Right(docs_text)));
462 // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
463 let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
464
465 attrs.into_iter().map(|(_, attr)| attr)
466}
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 5eb7cae7f..100dbf5d6 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -12,7 +12,7 @@ use std::{
12}; 12};
13 13
14use arena::{Arena, Idx, RawId}; 14use arena::{Arena, Idx, RawId};
15use ast::{AstNode, AttrsOwner, NameOwner, StructKind}; 15use ast::{AstNode, NameOwner, StructKind};
16use base_db::CrateId; 16use base_db::CrateId;
17use either::Either; 17use either::Either;
18use hir_expand::{ 18use hir_expand::{
@@ -495,7 +495,6 @@ pub struct Import {
495 pub alias: Option<ImportAlias>, 495 pub alias: Option<ImportAlias>,
496 pub visibility: RawVisibilityId, 496 pub visibility: RawVisibilityId,
497 pub is_glob: bool, 497 pub is_glob: bool,
498 pub is_prelude: bool,
499 /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many 498 /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many
500 /// `Import`s can map to the same `use` item. 499 /// `Import`s can map to the same `use` item.
501 pub ast_id: FileAstId<ast::Use>, 500 pub ast_id: FileAstId<ast::Use>,
@@ -511,8 +510,6 @@ pub struct ExternCrate {
511 pub name: Name, 510 pub name: Name,
512 pub alias: Option<ImportAlias>, 511 pub alias: Option<ImportAlias>,
513 pub visibility: RawVisibilityId, 512 pub visibility: RawVisibilityId,
514 /// Whether this is a `#[macro_use] extern crate ...`.
515 pub is_macro_use: bool,
516 pub ast_id: FileAstId<ast::ExternCrate>, 513 pub ast_id: FileAstId<ast::ExternCrate>,
517} 514}
518 515
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index c8f090c22..3b206ef85 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -485,8 +485,6 @@ impl Ctx {
485 } 485 }
486 486
487 fn lower_use(&mut self, use_item: &ast::Use) -> Vec<FileItemTreeId<Import>> { 487 fn lower_use(&mut self, use_item: &ast::Use) -> Vec<FileItemTreeId<Import>> {
488 // FIXME: cfg_attr
489 let is_prelude = use_item.has_atom_attr("prelude_import");
490 let visibility = self.lower_visibility(use_item); 488 let visibility = self.lower_visibility(use_item);
491 let ast_id = self.source_ast_id_map.ast_id(use_item); 489 let ast_id = self.source_ast_id_map.ast_id(use_item);
492 490
@@ -502,7 +500,6 @@ impl Ctx {
502 alias, 500 alias,
503 visibility, 501 visibility,
504 is_glob, 502 is_glob,
505 is_prelude,
506 ast_id, 503 ast_id,
507 index: imports.len(), 504 index: imports.len(),
508 }))); 505 })));
@@ -522,10 +519,8 @@ impl Ctx {
522 }); 519 });
523 let visibility = self.lower_visibility(extern_crate); 520 let visibility = self.lower_visibility(extern_crate);
524 let ast_id = self.source_ast_id_map.ast_id(extern_crate); 521 let ast_id = self.source_ast_id_map.ast_id(extern_crate);
525 // FIXME: cfg_attr
526 let is_macro_use = extern_crate.has_atom_attr("macro_use");
527 522
528 let res = ExternCrate { name, alias, visibility, is_macro_use, ast_id }; 523 let res = ExternCrate { name, alias, visibility, ast_id };
529 Some(id(self.data().extern_crates.alloc(res))) 524 Some(id(self.data().extern_crates.alloc(res)))
530 } 525 }
531 526
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index b114a6fe4..a636ec77d 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -136,23 +136,35 @@ struct Import {
136} 136}
137 137
138impl Import { 138impl Import {
139 fn from_use(tree: &ItemTree, id: ItemTreeId<item_tree::Import>) -> Self { 139 fn from_use(
140 db: &dyn DefDatabase,
141 krate: CrateId,
142 tree: &ItemTree,
143 id: ItemTreeId<item_tree::Import>,
144 ) -> Self {
140 let it = &tree[id.value]; 145 let it = &tree[id.value];
146 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
141 let visibility = &tree[it.visibility]; 147 let visibility = &tree[it.visibility];
142 Self { 148 Self {
143 path: it.path.clone(), 149 path: it.path.clone(),
144 alias: it.alias.clone(), 150 alias: it.alias.clone(),
145 visibility: visibility.clone(), 151 visibility: visibility.clone(),
146 is_glob: it.is_glob, 152 is_glob: it.is_glob,
147 is_prelude: it.is_prelude, 153 is_prelude: attrs.by_key("prelude_import").exists(),
148 is_extern_crate: false, 154 is_extern_crate: false,
149 is_macro_use: false, 155 is_macro_use: false,
150 source: ImportSource::Import(id), 156 source: ImportSource::Import(id),
151 } 157 }
152 } 158 }
153 159
154 fn from_extern_crate(tree: &ItemTree, id: ItemTreeId<item_tree::ExternCrate>) -> Self { 160 fn from_extern_crate(
161 db: &dyn DefDatabase,
162 krate: CrateId,
163 tree: &ItemTree,
164 id: ItemTreeId<item_tree::ExternCrate>,
165 ) -> Self {
155 let it = &tree[id.value]; 166 let it = &tree[id.value];
167 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
156 let visibility = &tree[it.visibility]; 168 let visibility = &tree[it.visibility];
157 Self { 169 Self {
158 path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())), 170 path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
@@ -161,7 +173,7 @@ impl Import {
161 is_glob: false, 173 is_glob: false,
162 is_prelude: false, 174 is_prelude: false,
163 is_extern_crate: true, 175 is_extern_crate: true,
164 is_macro_use: it.is_macro_use, 176 is_macro_use: attrs.by_key("macro_use").exists(),
165 source: ImportSource::ExternCrate(id), 177 source: ImportSource::ExternCrate(id),
166 } 178 }
167 } 179 }
@@ -930,7 +942,12 @@ impl ModCollector<'_, '_> {
930 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { 942 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) {
931 if let ModItem::ExternCrate(id) = item { 943 if let ModItem::ExternCrate(id) = item {
932 let import = self.item_tree[*id].clone(); 944 let import = self.item_tree[*id].clone();
933 if import.is_macro_use { 945 let attrs = self.item_tree.attrs(
946 self.def_collector.db,
947 krate,
948 ModItem::from(*id).into(),
949 );
950 if attrs.by_key("macro_use").exists() {
934 self.def_collector.import_macros_from_extern_crate(self.module_id, &import); 951 self.def_collector.import_macros_from_extern_crate(self.module_id, &import);
935 } 952 }
936 } 953 }
@@ -956,6 +973,8 @@ impl ModCollector<'_, '_> {
956 self.def_collector.unresolved_imports.push(ImportDirective { 973 self.def_collector.unresolved_imports.push(ImportDirective {
957 module_id: self.module_id, 974 module_id: self.module_id,
958 import: Import::from_use( 975 import: Import::from_use(
976 self.def_collector.db,
977 krate,
959 &self.item_tree, 978 &self.item_tree,
960 InFile::new(self.file_id, import_id), 979 InFile::new(self.file_id, import_id),
961 ), 980 ),
@@ -966,6 +985,8 @@ impl ModCollector<'_, '_> {
966 self.def_collector.unresolved_imports.push(ImportDirective { 985 self.def_collector.unresolved_imports.push(ImportDirective {
967 module_id: self.module_id, 986 module_id: self.module_id,
968 import: Import::from_extern_crate( 987 import: Import::from_extern_crate(
988 self.def_collector.db,
989 krate,
969 &self.item_tree, 990 &self.item_tree,
970 InFile::new(self.file_id, import_id), 991 InFile::new(self.file_id, import_id),
971 ), 992 ),
@@ -1268,20 +1289,20 @@ impl ModCollector<'_, '_> {
1268 } 1289 }
1269 1290
1270 fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) { 1291 fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) {
1271 for derive_subtree in attrs.by_key("derive").tt_values() { 1292 for derive in attrs.by_key("derive").attrs() {
1272 // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree 1293 match derive.parse_derive() {
1273 for tt in &derive_subtree.token_trees { 1294 Some(derive_macros) => {
1274 let ident = match &tt { 1295 for path in derive_macros {
1275 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident, 1296 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
1276 tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok 1297 self.def_collector
1277 _ => continue, // anything else would be an error (which we currently ignore) 1298 .unexpanded_attribute_macros
1278 }; 1299 .push(DeriveDirective { module_id: self.module_id, ast_id });
1279 let path = ModPath::from_tt_ident(ident); 1300 }
1280 1301 }
1281 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); 1302 None => {
1282 self.def_collector 1303 // FIXME: diagnose
1283 .unexpanded_attribute_macros 1304 log::debug!("malformed derive: {:?}", derive);
1284 .push(DeriveDirective { module_id: self.module_id, ast_id }); 1305 }
1285 } 1306 }
1286 } 1307 }
1287 } 1308 }
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs
index a4d1fb8f3..c459fa66d 100644
--- a/crates/hir_def/src/nameres/tests.rs
+++ b/crates/hir_def/src/nameres/tests.rs
@@ -13,8 +13,8 @@ use test_utils::mark;
13 13
14use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; 14use crate::{db::DefDatabase, nameres::*, test_db::TestDB};
15 15
16fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> { 16fn compute_crate_def_map(ra_fixture: &str) -> Arc<CrateDefMap> {
17 let db = TestDB::with_files(fixture); 17 let db = TestDB::with_files(ra_fixture);
18 let krate = db.crate_graph().iter().next().unwrap(); 18 let krate = db.crate_graph().iter().next().unwrap();
19 db.crate_def_map(krate) 19 db.crate_def_map(krate)
20} 20}
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs
index 1a7b98831..58d69d3c6 100644
--- a/crates/hir_def/src/nameres/tests/diagnostics.rs
+++ b/crates/hir_def/src/nameres/tests/diagnostics.rs
@@ -1,4 +1,5 @@
1use base_db::fixture::WithFixture; 1use base_db::fixture::WithFixture;
2use test_utils::mark;
2 3
3use crate::test_db::TestDB; 4use crate::test_db::TestDB;
4 5
@@ -119,3 +120,20 @@ fn inactive_item() {
119 "#, 120 "#,
120 ); 121 );
121} 122}
123
124/// Tests that `cfg` attributes behind `cfg_attr` is handled properly.
125#[test]
126fn inactive_via_cfg_attr() {
127 mark::check!(cfg_attr_active);
128 check_diagnostics(
129 r#"
130 //- /lib.rs
131 #[cfg_attr(not(never), cfg(no))] fn f() {}
132 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: no is disabled
133
134 #[cfg_attr(not(never), cfg(not(no)))] fn f() {}
135
136 #[cfg_attr(never, cfg(no))] fn g() {}
137 "#,
138 );
139}
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index 6fe2ee78a..f9bf5bc72 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -632,11 +632,11 @@ pub struct bar;
632#[test] 632#[test]
633fn expand_derive() { 633fn expand_derive() {
634 let map = compute_crate_def_map( 634 let map = compute_crate_def_map(
635 " 635 r#"
636 //- /main.rs crate:main deps:core 636 //- /main.rs crate:main deps:core
637 use core::*; 637 use core::Copy;
638 638
639 #[derive(Copy, Clone)] 639 #[derive(Copy, core::Clone)]
640 struct Foo; 640 struct Foo;
641 641
642 //- /core.rs crate:core 642 //- /core.rs crate:core
@@ -645,7 +645,7 @@ fn expand_derive() {
645 645
646 #[rustc_builtin_macro] 646 #[rustc_builtin_macro]
647 pub macro Clone {} 647 pub macro Clone {}
648 ", 648 "#,
649 ); 649 );
650 assert_eq!(map.modules[map.root].scope.impls().len(), 2); 650 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
651} 651}
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs
index 00a69a8a6..e2bf85bbc 100644
--- a/crates/hir_def/src/path.rs
+++ b/crates/hir_def/src/path.rs
@@ -9,11 +9,8 @@ use std::{
9 9
10use crate::{body::LowerCtx, type_ref::LifetimeRef}; 10use crate::{body::LowerCtx, type_ref::LifetimeRef};
11use base_db::CrateId; 11use base_db::CrateId;
12use hir_expand::{ 12use hir_expand::{hygiene::Hygiene, name::Name};
13 hygiene::Hygiene, 13use syntax::ast;
14 name::{AsName, Name},
15};
16use syntax::ast::{self};
17 14
18use crate::{ 15use crate::{
19 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
@@ -56,11 +53,6 @@ impl ModPath {
56 ModPath { kind, segments } 53 ModPath { kind, segments }
57 } 54 }
58 55
59 /// Converts an `tt::Ident` into a single-identifier `Path`.
60 pub(crate) fn from_tt_ident(ident: &tt::Ident) -> ModPath {
61 ident.as_name().into()
62 }
63
64 /// Calls `cb` with all paths, represented by this use item. 56 /// Calls `cb` with all paths, represented by this use item.
65 pub(crate) fn expand_use_item( 57 pub(crate) fn expand_use_item(
66 item_src: InFile<ast::Use>, 58 item_src: InFile<ast::Use>,
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 7fb4caea3..2f44876a8 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -152,7 +152,9 @@ pub mod known {
152 str, 152 str,
153 // Special names 153 // Special names
154 macro_rules, 154 macro_rules,
155 derive,
155 doc, 156 doc,
157 cfg_attr,
156 // Components of known path (value or mod name) 158 // Components of known path (value or mod name)
157 std, 159 std,
158 core, 160 core,
diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs
index 8ad50a2ee..60e0cd4ad 100644
--- a/crates/ide/src/call_hierarchy.rs
+++ b/crates/ide/src/call_hierarchy.rs
@@ -181,8 +181,8 @@ fn caller() {
181 call<|>ee(); 181 call<|>ee();
182} 182}
183"#, 183"#,
184 "callee FN FileId(0) 0..14 3..9", 184 "callee Function FileId(0) 0..14 3..9",
185 &["caller FN FileId(0) 15..44 18..24 : [33..39]"], 185 &["caller Function FileId(0) 15..44 18..24 : [33..39]"],
186 &[], 186 &[],
187 ); 187 );
188 } 188 }
@@ -197,8 +197,8 @@ fn caller() {
197 callee(); 197 callee();
198} 198}
199"#, 199"#,
200 "callee FN FileId(0) 0..14 3..9", 200 "callee Function FileId(0) 0..14 3..9",
201 &["caller FN FileId(0) 15..44 18..24 : [33..39]"], 201 &["caller Function FileId(0) 15..44 18..24 : [33..39]"],
202 &[], 202 &[],
203 ); 203 );
204 } 204 }
@@ -214,8 +214,8 @@ fn caller() {
214 callee(); 214 callee();
215} 215}
216"#, 216"#,
217 "callee FN FileId(0) 0..14 3..9", 217 "callee Function FileId(0) 0..14 3..9",
218 &["caller FN FileId(0) 15..58 18..24 : [33..39, 47..53]"], 218 &["caller Function FileId(0) 15..58 18..24 : [33..39, 47..53]"],
219 &[], 219 &[],
220 ); 220 );
221 } 221 }
@@ -234,10 +234,10 @@ fn caller2() {
234 callee(); 234 callee();
235} 235}
236"#, 236"#,
237 "callee FN FileId(0) 0..14 3..9", 237 "callee Function FileId(0) 0..14 3..9",
238 &[ 238 &[
239 "caller1 FN FileId(0) 15..45 18..25 : [34..40]", 239 "caller1 Function FileId(0) 15..45 18..25 : [34..40]",
240 "caller2 FN FileId(0) 47..77 50..57 : [66..72]", 240 "caller2 Function FileId(0) 47..77 50..57 : [66..72]",
241 ], 241 ],
242 &[], 242 &[],
243 ); 243 );
@@ -263,10 +263,10 @@ mod tests {
263 } 263 }
264} 264}
265"#, 265"#,
266 "callee FN FileId(0) 0..14 3..9", 266 "callee Function FileId(0) 0..14 3..9",
267 &[ 267 &[
268 "caller1 FN FileId(0) 15..45 18..25 : [34..40]", 268 "caller1 Function FileId(0) 15..45 18..25 : [34..40]",
269 "test_caller FN FileId(0) 95..149 110..121 : [134..140]", 269 "test_caller Function FileId(0) 95..149 110..121 : [134..140]",
270 ], 270 ],
271 &[], 271 &[],
272 ); 272 );
@@ -287,8 +287,8 @@ fn caller() {
287//- /foo/mod.rs 287//- /foo/mod.rs
288pub fn callee() {} 288pub fn callee() {}
289"#, 289"#,
290 "callee FN FileId(1) 0..18 7..13", 290 "callee Function FileId(1) 0..18 7..13",
291 &["caller FN FileId(0) 27..56 30..36 : [45..51]"], 291 &["caller Function FileId(0) 27..56 30..36 : [45..51]"],
292 &[], 292 &[],
293 ); 293 );
294 } 294 }
@@ -304,9 +304,9 @@ fn call<|>er() {
304 callee(); 304 callee();
305} 305}
306"#, 306"#,
307 "caller FN FileId(0) 15..58 18..24", 307 "caller Function FileId(0) 15..58 18..24",
308 &[], 308 &[],
309 &["callee FN FileId(0) 0..14 3..9 : [33..39, 47..53]"], 309 &["callee Function FileId(0) 0..14 3..9 : [33..39, 47..53]"],
310 ); 310 );
311 } 311 }
312 312
@@ -325,9 +325,9 @@ fn call<|>er() {
325//- /foo/mod.rs 325//- /foo/mod.rs
326pub fn callee() {} 326pub fn callee() {}
327"#, 327"#,
328 "caller FN FileId(0) 27..56 30..36", 328 "caller Function FileId(0) 27..56 30..36",
329 &[], 329 &[],
330 &["callee FN FileId(1) 0..18 7..13 : [45..51]"], 330 &["callee Function FileId(1) 0..18 7..13 : [45..51]"],
331 ); 331 );
332 } 332 }
333 333
@@ -348,9 +348,9 @@ fn caller3() {
348 348
349} 349}
350"#, 350"#,
351 "caller2 FN FileId(0) 33..64 36..43", 351 "caller2 Function FileId(0) 33..64 36..43",
352 &["caller1 FN FileId(0) 0..31 3..10 : [19..26]"], 352 &["caller1 Function FileId(0) 0..31 3..10 : [19..26]"],
353 &["caller3 FN FileId(0) 66..83 69..76 : [52..59]"], 353 &["caller3 Function FileId(0) 66..83 69..76 : [52..59]"],
354 ); 354 );
355 } 355 }
356 356
@@ -368,9 +368,9 @@ fn main() {
368 a<|>() 368 a<|>()
369} 369}
370"#, 370"#,
371 "a FN FileId(0) 0..18 3..4", 371 "a Function FileId(0) 0..18 3..4",
372 &["main FN FileId(0) 31..52 34..38 : [47..48]"], 372 &["main Function FileId(0) 31..52 34..38 : [47..48]"],
373 &["b FN FileId(0) 20..29 23..24 : [13..14]"], 373 &["b Function FileId(0) 20..29 23..24 : [13..14]"],
374 ); 374 );
375 375
376 check_hierarchy( 376 check_hierarchy(
@@ -385,8 +385,8 @@ fn main() {
385 a() 385 a()
386} 386}
387"#, 387"#,
388 "b FN FileId(0) 20..29 23..24", 388 "b Function FileId(0) 20..29 23..24",
389 &["a FN FileId(0) 0..18 3..4 : [13..14]"], 389 &["a Function FileId(0) 0..18 3..4 : [13..14]"],
390 &[], 390 &[],
391 ); 391 );
392 } 392 }
diff --git a/crates/ide/src/display.rs b/crates/ide/src/display.rs
index 0650915c5..bae9e40df 100644
--- a/crates/ide/src/display.rs
+++ b/crates/ide/src/display.rs
@@ -1,10 +1,9 @@
1//! This module contains utilities for turning SyntaxNodes and HIR types 1//! This module contains utilities for turning SyntaxNodes and HIR types
2//! into types that may be used to render in a UI. 2//! into types that may be used to render in a UI.
3 3
4mod navigation_target; 4pub(crate) mod navigation_target;
5mod short_label; 5mod short_label;
6 6
7pub use navigation_target::NavigationTarget;
8pub(crate) use navigation_target::{ToNav, TryToNav}; 7pub(crate) use navigation_target::{ToNav, TryToNav};
9pub(crate) use short_label::ShortLabel; 8pub(crate) use short_label::ShortLabel;
10 9
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 48acb8c93..7d0514105 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -1,26 +1,51 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::fmt;
4
3use either::Either; 5use either::Either;
4use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource}; 6use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource};
5use ide_db::base_db::{FileId, SourceDatabase}; 7use ide_db::{
8 base_db::{FileId, SourceDatabase},
9 symbol_index::FileSymbolKind,
10};
6use ide_db::{defs::Definition, RootDatabase}; 11use ide_db::{defs::Definition, RootDatabase};
7use syntax::{ 12use syntax::{
8 ast::{self, NameOwner}, 13 ast::{self, NameOwner},
9 match_ast, AstNode, SmolStr, 14 match_ast, AstNode, SmolStr, TextRange,
10 SyntaxKind::{self, IDENT_PAT, LIFETIME_PARAM, TYPE_PARAM},
11 TextRange,
12}; 15};
13 16
14use crate::FileSymbol; 17use crate::FileSymbol;
15 18
16use super::short_label::ShortLabel; 19use super::short_label::ShortLabel;
17 20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
22pub enum SymbolKind {
23 Module,
24 Impl,
25 Field,
26 TypeParam,
27 LifetimeParam,
28 ValueParam,
29 SelfParam,
30 Local,
31 Function,
32 Const,
33 Static,
34 Struct,
35 Enum,
36 Variant,
37 Union,
38 TypeAlias,
39 Trait,
40 Macro,
41}
42
18/// `NavigationTarget` represents and element in the editor's UI which you can 43/// `NavigationTarget` represents and element in the editor's UI which you can
19/// click on to navigate to a particular piece of code. 44/// click on to navigate to a particular piece of code.
20/// 45///
21/// Typically, a `NavigationTarget` corresponds to some element in the source 46/// Typically, a `NavigationTarget` corresponds to some element in the source
22/// code, like a function or a struct, but this is not strictly required. 47/// code, like a function or a struct, but this is not strictly required.
23#[derive(Debug, Clone, PartialEq, Eq, Hash)] 48#[derive(Clone, PartialEq, Eq, Hash)]
24pub struct NavigationTarget { 49pub struct NavigationTarget {
25 pub file_id: FileId, 50 pub file_id: FileId,
26 /// Range which encompasses the whole element. 51 /// Range which encompasses the whole element.
@@ -40,12 +65,30 @@ pub struct NavigationTarget {
40 /// Clients should place the cursor on this range when navigating to this target. 65 /// Clients should place the cursor on this range when navigating to this target.
41 pub focus_range: Option<TextRange>, 66 pub focus_range: Option<TextRange>,
42 pub name: SmolStr, 67 pub name: SmolStr,
43 pub kind: SyntaxKind, 68 pub kind: Option<SymbolKind>,
44 pub container_name: Option<SmolStr>, 69 pub container_name: Option<SmolStr>,
45 pub description: Option<String>, 70 pub description: Option<String>,
46 pub docs: Option<Documentation>, 71 pub docs: Option<Documentation>,
47} 72}
48 73
74impl fmt::Debug for NavigationTarget {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 let mut f = f.debug_struct("NavigationTarget");
77 macro_rules! opt {
78 ($($name:ident)*) => {$(
79 if let Some(it) = &self.$name {
80 f.field(stringify!($name), it);
81 }
82 )*}
83 }
84 f.field("file_id", &self.file_id).field("full_range", &self.full_range);
85 opt!(focus_range);
86 f.field("name", &self.name);
87 opt!(kind container_name description docs);
88 f.finish()
89 }
90}
91
49pub(crate) trait ToNav { 92pub(crate) trait ToNav {
50 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget; 93 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget;
51} 94}
@@ -69,7 +112,7 @@ impl NavigationTarget {
69 name, 112 name,
70 None, 113 None,
71 frange.range, 114 frange.range,
72 src.value.syntax().kind(), 115 SymbolKind::Module,
73 ); 116 );
74 res.docs = module.attrs(db).docs(); 117 res.docs = module.attrs(db).docs();
75 res.description = src.value.short_label(); 118 res.description = src.value.short_label();
@@ -86,8 +129,13 @@ impl NavigationTarget {
86 129
87 #[cfg(test)] 130 #[cfg(test)]
88 pub(crate) fn debug_render(&self) -> String { 131 pub(crate) fn debug_render(&self) -> String {
89 let mut buf = 132 let mut buf = format!(
90 format!("{} {:?} {:?} {:?}", self.name, self.kind, self.file_id, self.full_range); 133 "{} {:?} {:?} {:?}",
134 self.name,
135 self.kind.unwrap(),
136 self.file_id,
137 self.full_range
138 );
91 if let Some(focus_range) = self.focus_range { 139 if let Some(focus_range) = self.focus_range {
92 buf.push_str(&format!(" {:?}", focus_range)) 140 buf.push_str(&format!(" {:?}", focus_range))
93 } 141 }
@@ -101,6 +149,7 @@ impl NavigationTarget {
101 pub(crate) fn from_named( 149 pub(crate) fn from_named(
102 db: &RootDatabase, 150 db: &RootDatabase,
103 node: InFile<&dyn ast::NameOwner>, 151 node: InFile<&dyn ast::NameOwner>,
152 kind: SymbolKind,
104 ) -> NavigationTarget { 153 ) -> NavigationTarget {
105 let name = 154 let name =
106 node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); 155 node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_"));
@@ -108,13 +157,7 @@ impl NavigationTarget {
108 node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range); 157 node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range);
109 let frange = node.map(|it| it.syntax()).original_file_range(db); 158 let frange = node.map(|it| it.syntax()).original_file_range(db);
110 159
111 NavigationTarget::from_syntax( 160 NavigationTarget::from_syntax(frange.file_id, name, focus_range, frange.range, kind)
112 frange.file_id,
113 name,
114 focus_range,
115 frange.range,
116 node.value.syntax().kind(),
117 )
118 } 161 }
119 162
120 fn from_syntax( 163 fn from_syntax(
@@ -122,12 +165,12 @@ impl NavigationTarget {
122 name: SmolStr, 165 name: SmolStr,
123 focus_range: Option<TextRange>, 166 focus_range: Option<TextRange>,
124 full_range: TextRange, 167 full_range: TextRange,
125 kind: SyntaxKind, 168 kind: SymbolKind,
126 ) -> NavigationTarget { 169 ) -> NavigationTarget {
127 NavigationTarget { 170 NavigationTarget {
128 file_id, 171 file_id,
129 name, 172 name,
130 kind, 173 kind: Some(kind),
131 full_range, 174 full_range,
132 focus_range, 175 focus_range,
133 container_name: None, 176 container_name: None,
@@ -142,7 +185,17 @@ impl ToNav for FileSymbol {
142 NavigationTarget { 185 NavigationTarget {
143 file_id: self.file_id, 186 file_id: self.file_id,
144 name: self.name.clone(), 187 name: self.name.clone(),
145 kind: self.kind, 188 kind: Some(match self.kind {
189 FileSymbolKind::Function => SymbolKind::Function,
190 FileSymbolKind::Struct => SymbolKind::Struct,
191 FileSymbolKind::Enum => SymbolKind::Enum,
192 FileSymbolKind::Trait => SymbolKind::Trait,
193 FileSymbolKind::Module => SymbolKind::Module,
194 FileSymbolKind::TypeAlias => SymbolKind::TypeAlias,
195 FileSymbolKind::Const => SymbolKind::Const,
196 FileSymbolKind::Static => SymbolKind::Static,
197 FileSymbolKind::Macro => SymbolKind::Macro,
198 }),
146 full_range: self.range, 199 full_range: self.range,
147 focus_range: self.name_range, 200 focus_range: self.name_range,
148 container_name: self.container_name.clone(), 201 container_name: self.container_name.clone(),
@@ -191,16 +244,36 @@ impl TryToNav for hir::ModuleDef {
191 } 244 }
192} 245}
193 246
194pub(crate) trait ToNavFromAst {} 247pub(crate) trait ToNavFromAst {
195impl ToNavFromAst for hir::Function {} 248 const KIND: SymbolKind;
196impl ToNavFromAst for hir::Const {} 249}
197impl ToNavFromAst for hir::Static {} 250impl ToNavFromAst for hir::Function {
198impl ToNavFromAst for hir::Struct {} 251 const KIND: SymbolKind = SymbolKind::Function;
199impl ToNavFromAst for hir::Enum {} 252}
200impl ToNavFromAst for hir::EnumVariant {} 253impl ToNavFromAst for hir::Const {
201impl ToNavFromAst for hir::Union {} 254 const KIND: SymbolKind = SymbolKind::Const;
202impl ToNavFromAst for hir::TypeAlias {} 255}
203impl ToNavFromAst for hir::Trait {} 256impl ToNavFromAst for hir::Static {
257 const KIND: SymbolKind = SymbolKind::Static;
258}
259impl ToNavFromAst for hir::Struct {
260 const KIND: SymbolKind = SymbolKind::Struct;
261}
262impl ToNavFromAst for hir::Enum {
263 const KIND: SymbolKind = SymbolKind::Enum;
264}
265impl ToNavFromAst for hir::EnumVariant {
266 const KIND: SymbolKind = SymbolKind::Variant;
267}
268impl ToNavFromAst for hir::Union {
269 const KIND: SymbolKind = SymbolKind::Union;
270}
271impl ToNavFromAst for hir::TypeAlias {
272 const KIND: SymbolKind = SymbolKind::TypeAlias;
273}
274impl ToNavFromAst for hir::Trait {
275 const KIND: SymbolKind = SymbolKind::Trait;
276}
204 277
205impl<D> ToNav for D 278impl<D> ToNav for D
206where 279where
@@ -209,8 +282,11 @@ where
209{ 282{
210 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 283 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
211 let src = self.source(db); 284 let src = self.source(db);
212 let mut res = 285 let mut res = NavigationTarget::from_named(
213 NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); 286 db,
287 src.as_ref().map(|it| it as &dyn ast::NameOwner),
288 D::KIND,
289 );
214 res.docs = self.docs(db); 290 res.docs = self.docs(db);
215 res.description = src.value.short_label(); 291 res.description = src.value.short_label();
216 res 292 res
@@ -228,7 +304,7 @@ impl ToNav for hir::Module {
228 } 304 }
229 }; 305 };
230 let frange = src.with_value(syntax).original_file_range(db); 306 let frange = src.with_value(syntax).original_file_range(db);
231 NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind()) 307 NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, SymbolKind::Module)
232 } 308 }
233} 309}
234 310
@@ -252,7 +328,7 @@ impl ToNav for hir::Impl {
252 "impl".into(), 328 "impl".into(),
253 focus_range, 329 focus_range,
254 frange.range, 330 frange.range,
255 src.value.syntax().kind(), 331 SymbolKind::Impl,
256 ) 332 )
257 } 333 }
258} 334}
@@ -263,7 +339,8 @@ impl ToNav for hir::Field {
263 339
264 match &src.value { 340 match &src.value {
265 FieldSource::Named(it) => { 341 FieldSource::Named(it) => {
266 let mut res = NavigationTarget::from_named(db, src.with_value(it)); 342 let mut res =
343 NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field);
267 res.docs = self.docs(db); 344 res.docs = self.docs(db);
268 res.description = it.short_label(); 345 res.description = it.short_label();
269 res 346 res
@@ -275,7 +352,7 @@ impl ToNav for hir::Field {
275 "".into(), 352 "".into(),
276 None, 353 None,
277 frange.range, 354 frange.range,
278 it.syntax().kind(), 355 SymbolKind::Field,
279 ) 356 )
280 } 357 }
281 } 358 }
@@ -286,8 +363,11 @@ impl ToNav for hir::MacroDef {
286 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 363 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
287 let src = self.source(db); 364 let src = self.source(db);
288 log::debug!("nav target {:#?}", src.value.syntax()); 365 log::debug!("nav target {:#?}", src.value.syntax());
289 let mut res = 366 let mut res = NavigationTarget::from_named(
290 NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); 367 db,
368 src.as_ref().map(|it| it as &dyn ast::NameOwner),
369 SymbolKind::Macro,
370 );
291 res.docs = self.docs(db); 371 res.docs = self.docs(db);
292 res 372 res
293 } 373 }
@@ -327,10 +407,11 @@ impl ToNav for hir::Local {
327 Some(it) => it.to_string().into(), 407 Some(it) => it.to_string().into(),
328 None => "".into(), 408 None => "".into(),
329 }; 409 };
410 let kind = if self.is_param(db) { SymbolKind::ValueParam } else { SymbolKind::Local };
330 NavigationTarget { 411 NavigationTarget {
331 file_id: full_range.file_id, 412 file_id: full_range.file_id,
332 name, 413 name,
333 kind: IDENT_PAT, 414 kind: Some(kind),
334 full_range: full_range.range, 415 full_range: full_range.range,
335 focus_range: None, 416 focus_range: None,
336 container_name: None, 417 container_name: None,
@@ -354,7 +435,7 @@ impl ToNav for hir::TypeParam {
354 NavigationTarget { 435 NavigationTarget {
355 file_id: src.file_id.original_file(db), 436 file_id: src.file_id.original_file(db),
356 name: self.name(db).to_string().into(), 437 name: self.name(db).to_string().into(),
357 kind: TYPE_PARAM, 438 kind: Some(SymbolKind::TypeParam),
358 full_range, 439 full_range,
359 focus_range, 440 focus_range,
360 container_name: None, 441 container_name: None,
@@ -371,7 +452,7 @@ impl ToNav for hir::LifetimeParam {
371 NavigationTarget { 452 NavigationTarget {
372 file_id: src.file_id.original_file(db), 453 file_id: src.file_id.original_file(db),
373 name: self.name(db).to_string().into(), 454 name: self.name(db).to_string().into(),
374 kind: LIFETIME_PARAM, 455 kind: Some(SymbolKind::LifetimeParam),
375 full_range, 456 full_range,
376 focus_range: Some(full_range), 457 focus_range: Some(full_range),
377 container_name: None, 458 container_name: None,
@@ -428,34 +509,21 @@ fn foo() { enum FooInner { } }
428 0, 509 0,
429 ), 510 ),
430 full_range: 0..17, 511 full_range: 0..17,
431 focus_range: Some( 512 focus_range: 5..13,
432 5..13,
433 ),
434 name: "FooInner", 513 name: "FooInner",
435 kind: ENUM, 514 kind: Enum,
436 container_name: None, 515 description: "enum FooInner",
437 description: Some(
438 "enum FooInner",
439 ),
440 docs: None,
441 }, 516 },
442 NavigationTarget { 517 NavigationTarget {
443 file_id: FileId( 518 file_id: FileId(
444 0, 519 0,
445 ), 520 ),
446 full_range: 29..46, 521 full_range: 29..46,
447 focus_range: Some( 522 focus_range: 34..42,
448 34..42,
449 ),
450 name: "FooInner", 523 name: "FooInner",
451 kind: ENUM, 524 kind: Enum,
452 container_name: Some( 525 container_name: "foo",
453 "foo", 526 description: "enum FooInner",
454 ),
455 description: Some(
456 "enum FooInner",
457 ),
458 docs: None,
459 }, 527 },
460 ] 528 ]
461 "#]] 529 "#]]
diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs
index c51531391..32556dad3 100644
--- a/crates/ide/src/file_structure.rs
+++ b/crates/ide/src/file_structure.rs
@@ -1,15 +1,17 @@
1use syntax::{ 1use syntax::{
2 ast::{self, AttrsOwner, GenericParamsOwner, NameOwner}, 2 ast::{self, AttrsOwner, GenericParamsOwner, NameOwner},
3 match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, WalkEvent, 3 match_ast, AstNode, SourceFile, SyntaxNode, TextRange, WalkEvent,
4}; 4};
5 5
6use crate::SymbolKind;
7
6#[derive(Debug, Clone)] 8#[derive(Debug, Clone)]
7pub struct StructureNode { 9pub struct StructureNode {
8 pub parent: Option<usize>, 10 pub parent: Option<usize>,
9 pub label: String, 11 pub label: String,
10 pub navigation_range: TextRange, 12 pub navigation_range: TextRange,
11 pub node_range: TextRange, 13 pub node_range: TextRange,
12 pub kind: SyntaxKind, 14 pub kind: SymbolKind,
13 pub detail: Option<String>, 15 pub detail: Option<String>,
14 pub deprecated: bool, 16 pub deprecated: bool,
15} 17}
@@ -51,25 +53,27 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
51} 53}
52 54
53fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { 55fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
54 fn decl<N: NameOwner + AttrsOwner>(node: N) -> Option<StructureNode> { 56 fn decl<N: NameOwner + AttrsOwner>(node: N, kind: SymbolKind) -> Option<StructureNode> {
55 decl_with_detail(&node, None) 57 decl_with_detail(&node, None, kind)
56 } 58 }
57 59
58 fn decl_with_type_ref<N: NameOwner + AttrsOwner>( 60 fn decl_with_type_ref<N: NameOwner + AttrsOwner>(
59 node: &N, 61 node: &N,
60 type_ref: Option<ast::Type>, 62 type_ref: Option<ast::Type>,
63 kind: SymbolKind,
61 ) -> Option<StructureNode> { 64 ) -> Option<StructureNode> {
62 let detail = type_ref.map(|type_ref| { 65 let detail = type_ref.map(|type_ref| {
63 let mut detail = String::new(); 66 let mut detail = String::new();
64 collapse_ws(type_ref.syntax(), &mut detail); 67 collapse_ws(type_ref.syntax(), &mut detail);
65 detail 68 detail
66 }); 69 });
67 decl_with_detail(node, detail) 70 decl_with_detail(node, detail, kind)
68 } 71 }
69 72
70 fn decl_with_detail<N: NameOwner + AttrsOwner>( 73 fn decl_with_detail<N: NameOwner + AttrsOwner>(
71 node: &N, 74 node: &N,
72 detail: Option<String>, 75 detail: Option<String>,
76 kind: SymbolKind,
73 ) -> Option<StructureNode> { 77 ) -> Option<StructureNode> {
74 let name = node.name()?; 78 let name = node.name()?;
75 79
@@ -78,7 +82,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
78 label: name.text().to_string(), 82 label: name.text().to_string(),
79 navigation_range: name.syntax().text_range(), 83 navigation_range: name.syntax().text_range(),
80 node_range: node.syntax().text_range(), 84 node_range: node.syntax().text_range(),
81 kind: node.syntax().kind(), 85 kind,
82 detail, 86 detail,
83 deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"), 87 deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"),
84 }) 88 })
@@ -117,18 +121,18 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
117 collapse_ws(ret_type.syntax(), &mut detail); 121 collapse_ws(ret_type.syntax(), &mut detail);
118 } 122 }
119 123
120 decl_with_detail(&it, Some(detail)) 124 decl_with_detail(&it, Some(detail), SymbolKind::Function)
121 }, 125 },
122 ast::Struct(it) => decl(it), 126 ast::Struct(it) => decl(it, SymbolKind::Struct),
123 ast::Union(it) => decl(it), 127 ast::Union(it) => decl(it, SymbolKind::Union),
124 ast::Enum(it) => decl(it), 128 ast::Enum(it) => decl(it, SymbolKind::Enum),
125 ast::Variant(it) => decl(it), 129 ast::Variant(it) => decl(it, SymbolKind::Variant),
126 ast::Trait(it) => decl(it), 130 ast::Trait(it) => decl(it, SymbolKind::Trait),
127 ast::Module(it) => decl(it), 131 ast::Module(it) => decl(it, SymbolKind::Module),
128 ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty()), 132 ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::TypeAlias),
129 ast::RecordField(it) => decl_with_type_ref(&it, it.ty()), 133 ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Field),
130 ast::Const(it) => decl_with_type_ref(&it, it.ty()), 134 ast::Const(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Const),
131 ast::Static(it) => decl_with_type_ref(&it, it.ty()), 135 ast::Static(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Static),
132 ast::Impl(it) => { 136 ast::Impl(it) => {
133 let target_type = it.self_ty()?; 137 let target_type = it.self_ty()?;
134 let target_trait = it.trait_(); 138 let target_trait = it.trait_();
@@ -144,13 +148,13 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
144 label, 148 label,
145 navigation_range: target_type.syntax().text_range(), 149 navigation_range: target_type.syntax().text_range(),
146 node_range: it.syntax().text_range(), 150 node_range: it.syntax().text_range(),
147 kind: it.syntax().kind(), 151 kind: SymbolKind::Impl,
148 detail: None, 152 detail: None,
149 deprecated: false, 153 deprecated: false,
150 }; 154 };
151 Some(node) 155 Some(node)
152 }, 156 },
153 ast::MacroRules(it) => decl(it), 157 ast::MacroRules(it) => decl(it, SymbolKind::Macro),
154 _ => None, 158 _ => None,
155 } 159 }
156 } 160 }
@@ -222,7 +226,7 @@ fn very_obsolete() {}
222 label: "Foo", 226 label: "Foo",
223 navigation_range: 8..11, 227 navigation_range: 8..11,
224 node_range: 1..26, 228 node_range: 1..26,
225 kind: STRUCT, 229 kind: Struct,
226 detail: None, 230 detail: None,
227 deprecated: false, 231 deprecated: false,
228 }, 232 },
@@ -233,7 +237,7 @@ fn very_obsolete() {}
233 label: "x", 237 label: "x",
234 navigation_range: 18..19, 238 navigation_range: 18..19,
235 node_range: 18..24, 239 node_range: 18..24,
236 kind: RECORD_FIELD, 240 kind: Field,
237 detail: Some( 241 detail: Some(
238 "i32", 242 "i32",
239 ), 243 ),
@@ -244,7 +248,7 @@ fn very_obsolete() {}
244 label: "m", 248 label: "m",
245 navigation_range: 32..33, 249 navigation_range: 32..33,
246 node_range: 28..158, 250 node_range: 28..158,
247 kind: MODULE, 251 kind: Module,
248 detail: None, 252 detail: None,
249 deprecated: false, 253 deprecated: false,
250 }, 254 },
@@ -255,7 +259,7 @@ fn very_obsolete() {}
255 label: "bar1", 259 label: "bar1",
256 navigation_range: 43..47, 260 navigation_range: 43..47,
257 node_range: 40..52, 261 node_range: 40..52,
258 kind: FN, 262 kind: Function,
259 detail: Some( 263 detail: Some(
260 "fn()", 264 "fn()",
261 ), 265 ),
@@ -268,7 +272,7 @@ fn very_obsolete() {}
268 label: "bar2", 272 label: "bar2",
269 navigation_range: 60..64, 273 navigation_range: 60..64,
270 node_range: 57..81, 274 node_range: 57..81,
271 kind: FN, 275 kind: Function,
272 detail: Some( 276 detail: Some(
273 "fn<T>(t: T) -> T", 277 "fn<T>(t: T) -> T",
274 ), 278 ),
@@ -281,7 +285,7 @@ fn very_obsolete() {}
281 label: "bar3", 285 label: "bar3",
282 navigation_range: 89..93, 286 navigation_range: 89..93,
283 node_range: 86..156, 287 node_range: 86..156,
284 kind: FN, 288 kind: Function,
285 detail: Some( 289 detail: Some(
286 "fn<A, B>(a: A, b: B) -> Vec< u32 >", 290 "fn<A, B>(a: A, b: B) -> Vec< u32 >",
287 ), 291 ),
@@ -292,7 +296,7 @@ fn very_obsolete() {}
292 label: "E", 296 label: "E",
293 navigation_range: 165..166, 297 navigation_range: 165..166,
294 node_range: 160..180, 298 node_range: 160..180,
295 kind: ENUM, 299 kind: Enum,
296 detail: None, 300 detail: None,
297 deprecated: false, 301 deprecated: false,
298 }, 302 },
@@ -303,7 +307,7 @@ fn very_obsolete() {}
303 label: "X", 307 label: "X",
304 navigation_range: 169..170, 308 navigation_range: 169..170,
305 node_range: 169..170, 309 node_range: 169..170,
306 kind: VARIANT, 310 kind: Variant,
307 detail: None, 311 detail: None,
308 deprecated: false, 312 deprecated: false,
309 }, 313 },
@@ -314,7 +318,7 @@ fn very_obsolete() {}
314 label: "Y", 318 label: "Y",
315 navigation_range: 172..173, 319 navigation_range: 172..173,
316 node_range: 172..178, 320 node_range: 172..178,
317 kind: VARIANT, 321 kind: Variant,
318 detail: None, 322 detail: None,
319 deprecated: false, 323 deprecated: false,
320 }, 324 },
@@ -323,7 +327,7 @@ fn very_obsolete() {}
323 label: "T", 327 label: "T",
324 navigation_range: 186..187, 328 navigation_range: 186..187,
325 node_range: 181..193, 329 node_range: 181..193,
326 kind: TYPE_ALIAS, 330 kind: TypeAlias,
327 detail: Some( 331 detail: Some(
328 "()", 332 "()",
329 ), 333 ),
@@ -334,7 +338,7 @@ fn very_obsolete() {}
334 label: "S", 338 label: "S",
335 navigation_range: 201..202, 339 navigation_range: 201..202,
336 node_range: 194..213, 340 node_range: 194..213,
337 kind: STATIC, 341 kind: Static,
338 detail: Some( 342 detail: Some(
339 "i32", 343 "i32",
340 ), 344 ),
@@ -345,7 +349,7 @@ fn very_obsolete() {}
345 label: "C", 349 label: "C",
346 navigation_range: 220..221, 350 navigation_range: 220..221,
347 node_range: 214..232, 351 node_range: 214..232,
348 kind: CONST, 352 kind: Const,
349 detail: Some( 353 detail: Some(
350 "i32", 354 "i32",
351 ), 355 ),
@@ -356,7 +360,7 @@ fn very_obsolete() {}
356 label: "impl E", 360 label: "impl E",
357 navigation_range: 239..240, 361 navigation_range: 239..240,
358 node_range: 234..243, 362 node_range: 234..243,
359 kind: IMPL, 363 kind: Impl,
360 detail: None, 364 detail: None,
361 deprecated: false, 365 deprecated: false,
362 }, 366 },
@@ -365,7 +369,7 @@ fn very_obsolete() {}
365 label: "impl fmt::Debug for E", 369 label: "impl fmt::Debug for E",
366 navigation_range: 265..266, 370 navigation_range: 265..266,
367 node_range: 245..269, 371 node_range: 245..269,
368 kind: IMPL, 372 kind: Impl,
369 detail: None, 373 detail: None,
370 deprecated: false, 374 deprecated: false,
371 }, 375 },
@@ -374,7 +378,7 @@ fn very_obsolete() {}
374 label: "mc", 378 label: "mc",
375 navigation_range: 284..286, 379 navigation_range: 284..286,
376 node_range: 271..303, 380 node_range: 271..303,
377 kind: MACRO_RULES, 381 kind: Macro,
378 detail: None, 382 detail: None,
379 deprecated: false, 383 deprecated: false,
380 }, 384 },
@@ -383,7 +387,7 @@ fn very_obsolete() {}
383 label: "mcexp", 387 label: "mcexp",
384 navigation_range: 334..339, 388 navigation_range: 334..339,
385 node_range: 305..356, 389 node_range: 305..356,
386 kind: MACRO_RULES, 390 kind: Macro,
387 detail: None, 391 detail: None,
388 deprecated: false, 392 deprecated: false,
389 }, 393 },
@@ -392,7 +396,7 @@ fn very_obsolete() {}
392 label: "mcexp", 396 label: "mcexp",
393 navigation_range: 387..392, 397 navigation_range: 387..392,
394 node_range: 358..409, 398 node_range: 358..409,
395 kind: MACRO_RULES, 399 kind: Macro,
396 detail: None, 400 detail: None,
397 deprecated: false, 401 deprecated: false,
398 }, 402 },
@@ -401,7 +405,7 @@ fn very_obsolete() {}
401 label: "obsolete", 405 label: "obsolete",
402 navigation_range: 428..436, 406 navigation_range: 428..436,
403 node_range: 411..441, 407 node_range: 411..441,
404 kind: FN, 408 kind: Function,
405 detail: Some( 409 detail: Some(
406 "fn()", 410 "fn()",
407 ), 411 ),
@@ -412,7 +416,7 @@ fn very_obsolete() {}
412 label: "very_obsolete", 416 label: "very_obsolete",
413 navigation_range: 481..494, 417 navigation_range: 481..494,
414 node_range: 443..499, 418 node_range: 443..499,
415 kind: FN, 419 kind: Function,
416 detail: Some( 420 detail: Some(
417 "fn()", 421 "fn()",
418 ), 422 ),
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 173509b08..7a12e9965 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -9,7 +9,7 @@ use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset,
9 9
10use crate::{ 10use crate::{
11 display::{ToNav, TryToNav}, 11 display::{ToNav, TryToNav},
12 FilePosition, NavigationTarget, RangeInfo, 12 FilePosition, NavigationTarget, RangeInfo, SymbolKind,
13}; 13};
14 14
15// Feature: Go to Definition 15// Feature: Go to Definition
@@ -86,7 +86,7 @@ fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<Nav
86 full_range: self_param.syntax().text_range(), 86 full_range: self_param.syntax().text_range(),
87 focus_range: Some(self_token.text_range()), 87 focus_range: Some(self_token.text_range()),
88 name: self_token.text().clone(), 88 name: self_token.text().clone(),
89 kind: self_token.kind(), 89 kind: Some(SymbolKind::SelfParam),
90 container_name: None, 90 container_name: None,
91 description: None, 91 description: None,
92 docs: None, 92 docs: None,
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index da6bb726a..b06fa5f15 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -2187,14 +2187,9 @@ fn foo_<|>test() {}
2187 0, 2187 0,
2188 ), 2188 ),
2189 full_range: 0..24, 2189 full_range: 0..24,
2190 focus_range: Some( 2190 focus_range: 11..19,
2191 11..19,
2192 ),
2193 name: "foo_test", 2191 name: "foo_test",
2194 kind: FN, 2192 kind: Function,
2195 container_name: None,
2196 description: None,
2197 docs: None,
2198 }, 2193 },
2199 kind: Test { 2194 kind: Test {
2200 test_id: Path( 2195 test_id: Path(
@@ -2230,14 +2225,9 @@ mod tests<|> {
2230 0, 2225 0,
2231 ), 2226 ),
2232 full_range: 0..46, 2227 full_range: 0..46,
2233 focus_range: Some( 2228 focus_range: 4..9,
2234 4..9,
2235 ),
2236 name: "tests", 2229 name: "tests",
2237 kind: MODULE, 2230 kind: Module,
2238 container_name: None,
2239 description: None,
2240 docs: None,
2241 }, 2231 },
2242 kind: TestMod { 2232 kind: TestMod {
2243 path: "tests", 2233 path: "tests",
@@ -2269,16 +2259,10 @@ fn main() { let s<|>t = S{ f1:0 }; }
2269 0, 2259 0,
2270 ), 2260 ),
2271 full_range: 0..19, 2261 full_range: 0..19,
2272 focus_range: Some( 2262 focus_range: 7..8,
2273 7..8,
2274 ),
2275 name: "S", 2263 name: "S",
2276 kind: STRUCT, 2264 kind: Struct,
2277 container_name: None, 2265 description: "struct S",
2278 description: Some(
2279 "struct S",
2280 ),
2281 docs: None,
2282 }, 2266 },
2283 }, 2267 },
2284 ], 2268 ],
@@ -2308,16 +2292,10 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; }
2308 0, 2292 0,
2309 ), 2293 ),
2310 full_range: 17..37, 2294 full_range: 17..37,
2311 focus_range: Some( 2295 focus_range: 24..25,
2312 24..25,
2313 ),
2314 name: "S", 2296 name: "S",
2315 kind: STRUCT, 2297 kind: Struct,
2316 container_name: None, 2298 description: "struct S",
2317 description: Some(
2318 "struct S",
2319 ),
2320 docs: None,
2321 }, 2299 },
2322 }, 2300 },
2323 HoverGotoTypeData { 2301 HoverGotoTypeData {
@@ -2327,16 +2305,10 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; }
2327 0, 2305 0,
2328 ), 2306 ),
2329 full_range: 0..16, 2307 full_range: 0..16,
2330 focus_range: Some( 2308 focus_range: 7..10,
2331 7..10,
2332 ),
2333 name: "Arg", 2309 name: "Arg",
2334 kind: STRUCT, 2310 kind: Struct,
2335 container_name: None, 2311 description: "struct Arg",
2336 description: Some(
2337 "struct Arg",
2338 ),
2339 docs: None,
2340 }, 2312 },
2341 }, 2313 },
2342 ], 2314 ],
@@ -2366,16 +2338,10 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; }
2366 0, 2338 0,
2367 ), 2339 ),
2368 full_range: 17..37, 2340 full_range: 17..37,
2369 focus_range: Some( 2341 focus_range: 24..25,
2370 24..25,
2371 ),
2372 name: "S", 2342 name: "S",
2373 kind: STRUCT, 2343 kind: Struct,
2374 container_name: None, 2344 description: "struct S",
2375 description: Some(
2376 "struct S",
2377 ),
2378 docs: None,
2379 }, 2345 },
2380 }, 2346 },
2381 HoverGotoTypeData { 2347 HoverGotoTypeData {
@@ -2385,16 +2351,10 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; }
2385 0, 2351 0,
2386 ), 2352 ),
2387 full_range: 0..16, 2353 full_range: 0..16,
2388 focus_range: Some( 2354 focus_range: 7..10,
2389 7..10,
2390 ),
2391 name: "Arg", 2355 name: "Arg",
2392 kind: STRUCT, 2356 kind: Struct,
2393 container_name: None, 2357 description: "struct Arg",
2394 description: Some(
2395 "struct Arg",
2396 ),
2397 docs: None,
2398 }, 2358 },
2399 }, 2359 },
2400 ], 2360 ],
@@ -2427,16 +2387,10 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); }
2427 0, 2387 0,
2428 ), 2388 ),
2429 full_range: 0..14, 2389 full_range: 0..14,
2430 focus_range: Some( 2390 focus_range: 7..8,
2431 7..8,
2432 ),
2433 name: "A", 2391 name: "A",
2434 kind: STRUCT, 2392 kind: Struct,
2435 container_name: None, 2393 description: "struct A",
2436 description: Some(
2437 "struct A",
2438 ),
2439 docs: None,
2440 }, 2394 },
2441 }, 2395 },
2442 HoverGotoTypeData { 2396 HoverGotoTypeData {
@@ -2446,16 +2400,10 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); }
2446 0, 2400 0,
2447 ), 2401 ),
2448 full_range: 15..29, 2402 full_range: 15..29,
2449 focus_range: Some( 2403 focus_range: 22..23,
2450 22..23,
2451 ),
2452 name: "B", 2404 name: "B",
2453 kind: STRUCT, 2405 kind: Struct,
2454 container_name: None, 2406 description: "struct B",
2455 description: Some(
2456 "struct B",
2457 ),
2458 docs: None,
2459 }, 2407 },
2460 }, 2408 },
2461 HoverGotoTypeData { 2409 HoverGotoTypeData {
@@ -2465,16 +2413,10 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); }
2465 0, 2413 0,
2466 ), 2414 ),
2467 full_range: 42..60, 2415 full_range: 42..60,
2468 focus_range: Some( 2416 focus_range: 53..54,
2469 53..54,
2470 ),
2471 name: "C", 2417 name: "C",
2472 kind: STRUCT, 2418 kind: Struct,
2473 container_name: None, 2419 description: "pub struct C",
2474 description: Some(
2475 "pub struct C",
2476 ),
2477 docs: None,
2478 }, 2420 },
2479 }, 2421 },
2480 ], 2422 ],
@@ -2504,16 +2446,10 @@ fn main() { let s<|>t = foo(); }
2504 0, 2446 0,
2505 ), 2447 ),
2506 full_range: 0..12, 2448 full_range: 0..12,
2507 focus_range: Some( 2449 focus_range: 6..9,
2508 6..9,
2509 ),
2510 name: "Foo", 2450 name: "Foo",
2511 kind: TRAIT, 2451 kind: Trait,
2512 container_name: None, 2452 description: "trait Foo",
2513 description: Some(
2514 "trait Foo",
2515 ),
2516 docs: None,
2517 }, 2453 },
2518 }, 2454 },
2519 ], 2455 ],
@@ -2544,16 +2480,10 @@ fn main() { let s<|>t = foo(); }
2544 0, 2480 0,
2545 ), 2481 ),
2546 full_range: 0..15, 2482 full_range: 0..15,
2547 focus_range: Some( 2483 focus_range: 6..9,
2548 6..9,
2549 ),
2550 name: "Foo", 2484 name: "Foo",
2551 kind: TRAIT, 2485 kind: Trait,
2552 container_name: None, 2486 description: "trait Foo",
2553 description: Some(
2554 "trait Foo",
2555 ),
2556 docs: None,
2557 }, 2487 },
2558 }, 2488 },
2559 HoverGotoTypeData { 2489 HoverGotoTypeData {
@@ -2563,16 +2493,10 @@ fn main() { let s<|>t = foo(); }
2563 0, 2493 0,
2564 ), 2494 ),
2565 full_range: 16..25, 2495 full_range: 16..25,
2566 focus_range: Some( 2496 focus_range: 23..24,
2567 23..24,
2568 ),
2569 name: "S", 2497 name: "S",
2570 kind: STRUCT, 2498 kind: Struct,
2571 container_name: None, 2499 description: "struct S",
2572 description: Some(
2573 "struct S",
2574 ),
2575 docs: None,
2576 }, 2500 },
2577 }, 2501 },
2578 ], 2502 ],
@@ -2603,16 +2527,10 @@ fn main() { let s<|>t = foo(); }
2603 0, 2527 0,
2604 ), 2528 ),
2605 full_range: 0..12, 2529 full_range: 0..12,
2606 focus_range: Some( 2530 focus_range: 6..9,
2607 6..9,
2608 ),
2609 name: "Foo", 2531 name: "Foo",
2610 kind: TRAIT, 2532 kind: Trait,
2611 container_name: None, 2533 description: "trait Foo",
2612 description: Some(
2613 "trait Foo",
2614 ),
2615 docs: None,
2616 }, 2534 },
2617 }, 2535 },
2618 HoverGotoTypeData { 2536 HoverGotoTypeData {
@@ -2622,16 +2540,10 @@ fn main() { let s<|>t = foo(); }
2622 0, 2540 0,
2623 ), 2541 ),
2624 full_range: 13..25, 2542 full_range: 13..25,
2625 focus_range: Some( 2543 focus_range: 19..22,
2626 19..22,
2627 ),
2628 name: "Bar", 2544 name: "Bar",
2629 kind: TRAIT, 2545 kind: Trait,
2630 container_name: None, 2546 description: "trait Bar",
2631 description: Some(
2632 "trait Bar",
2633 ),
2634 docs: None,
2635 }, 2547 },
2636 }, 2548 },
2637 ], 2549 ],
@@ -2665,16 +2577,10 @@ fn main() { let s<|>t = foo(); }
2665 0, 2577 0,
2666 ), 2578 ),
2667 full_range: 0..15, 2579 full_range: 0..15,
2668 focus_range: Some( 2580 focus_range: 6..9,
2669 6..9,
2670 ),
2671 name: "Foo", 2581 name: "Foo",
2672 kind: TRAIT, 2582 kind: Trait,
2673 container_name: None, 2583 description: "trait Foo",
2674 description: Some(
2675 "trait Foo",
2676 ),
2677 docs: None,
2678 }, 2584 },
2679 }, 2585 },
2680 HoverGotoTypeData { 2586 HoverGotoTypeData {
@@ -2684,16 +2590,10 @@ fn main() { let s<|>t = foo(); }
2684 0, 2590 0,
2685 ), 2591 ),
2686 full_range: 16..31, 2592 full_range: 16..31,
2687 focus_range: Some( 2593 focus_range: 22..25,
2688 22..25,
2689 ),
2690 name: "Bar", 2594 name: "Bar",
2691 kind: TRAIT, 2595 kind: Trait,
2692 container_name: None, 2596 description: "trait Bar",
2693 description: Some(
2694 "trait Bar",
2695 ),
2696 docs: None,
2697 }, 2597 },
2698 }, 2598 },
2699 HoverGotoTypeData { 2599 HoverGotoTypeData {
@@ -2703,16 +2603,10 @@ fn main() { let s<|>t = foo(); }
2703 0, 2603 0,
2704 ), 2604 ),
2705 full_range: 32..44, 2605 full_range: 32..44,
2706 focus_range: Some( 2606 focus_range: 39..41,
2707 39..41,
2708 ),
2709 name: "S1", 2607 name: "S1",
2710 kind: STRUCT, 2608 kind: Struct,
2711 container_name: None, 2609 description: "struct S1",
2712 description: Some(
2713 "struct S1",
2714 ),
2715 docs: None,
2716 }, 2610 },
2717 }, 2611 },
2718 HoverGotoTypeData { 2612 HoverGotoTypeData {
@@ -2722,16 +2616,10 @@ fn main() { let s<|>t = foo(); }
2722 0, 2616 0,
2723 ), 2617 ),
2724 full_range: 45..57, 2618 full_range: 45..57,
2725 focus_range: Some( 2619 focus_range: 52..54,
2726 52..54,
2727 ),
2728 name: "S2", 2620 name: "S2",
2729 kind: STRUCT, 2621 kind: Struct,
2730 container_name: None, 2622 description: "struct S2",
2731 description: Some(
2732 "struct S2",
2733 ),
2734 docs: None,
2735 }, 2623 },
2736 }, 2624 },
2737 ], 2625 ],
@@ -2759,16 +2647,10 @@ fn foo(ar<|>g: &impl Foo) {}
2759 0, 2647 0,
2760 ), 2648 ),
2761 full_range: 0..12, 2649 full_range: 0..12,
2762 focus_range: Some( 2650 focus_range: 6..9,
2763 6..9,
2764 ),
2765 name: "Foo", 2651 name: "Foo",
2766 kind: TRAIT, 2652 kind: Trait,
2767 container_name: None, 2653 description: "trait Foo",
2768 description: Some(
2769 "trait Foo",
2770 ),
2771 docs: None,
2772 }, 2654 },
2773 }, 2655 },
2774 ], 2656 ],
@@ -2799,16 +2681,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
2799 0, 2681 0,
2800 ), 2682 ),
2801 full_range: 0..12, 2683 full_range: 0..12,
2802 focus_range: Some( 2684 focus_range: 6..9,
2803 6..9,
2804 ),
2805 name: "Foo", 2685 name: "Foo",
2806 kind: TRAIT, 2686 kind: Trait,
2807 container_name: None, 2687 description: "trait Foo",
2808 description: Some(
2809 "trait Foo",
2810 ),
2811 docs: None,
2812 }, 2688 },
2813 }, 2689 },
2814 HoverGotoTypeData { 2690 HoverGotoTypeData {
@@ -2818,16 +2694,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
2818 0, 2694 0,
2819 ), 2695 ),
2820 full_range: 13..28, 2696 full_range: 13..28,
2821 focus_range: Some( 2697 focus_range: 19..22,
2822 19..22,
2823 ),
2824 name: "Bar", 2698 name: "Bar",
2825 kind: TRAIT, 2699 kind: Trait,
2826 container_name: None, 2700 description: "trait Bar",
2827 description: Some(
2828 "trait Bar",
2829 ),
2830 docs: None,
2831 }, 2701 },
2832 }, 2702 },
2833 HoverGotoTypeData { 2703 HoverGotoTypeData {
@@ -2837,16 +2707,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
2837 0, 2707 0,
2838 ), 2708 ),
2839 full_range: 29..39, 2709 full_range: 29..39,
2840 focus_range: Some( 2710 focus_range: 36..37,
2841 36..37,
2842 ),
2843 name: "S", 2711 name: "S",
2844 kind: STRUCT, 2712 kind: Struct,
2845 container_name: None, 2713 description: "struct S",
2846 description: Some(
2847 "struct S",
2848 ),
2849 docs: None,
2850 }, 2714 },
2851 }, 2715 },
2852 ], 2716 ],
@@ -2882,16 +2746,10 @@ mod future {
2882 0, 2746 0,
2883 ), 2747 ),
2884 full_range: 101..163, 2748 full_range: 101..163,
2885 focus_range: Some( 2749 focus_range: 140..146,
2886 140..146,
2887 ),
2888 name: "Future", 2750 name: "Future",
2889 kind: TRAIT, 2751 kind: Trait,
2890 container_name: None, 2752 description: "pub trait Future",
2891 description: Some(
2892 "pub trait Future",
2893 ),
2894 docs: None,
2895 }, 2753 },
2896 }, 2754 },
2897 HoverGotoTypeData { 2755 HoverGotoTypeData {
@@ -2901,16 +2759,10 @@ mod future {
2901 0, 2759 0,
2902 ), 2760 ),
2903 full_range: 0..9, 2761 full_range: 0..9,
2904 focus_range: Some( 2762 focus_range: 7..8,
2905 7..8,
2906 ),
2907 name: "S", 2763 name: "S",
2908 kind: STRUCT, 2764 kind: Struct,
2909 container_name: None, 2765 description: "struct S",
2910 description: Some(
2911 "struct S",
2912 ),
2913 docs: None,
2914 }, 2766 },
2915 }, 2767 },
2916 ], 2768 ],
@@ -2939,16 +2791,10 @@ fn foo(ar<|>g: &impl Foo<S>) {}
2939 0, 2791 0,
2940 ), 2792 ),
2941 full_range: 0..15, 2793 full_range: 0..15,
2942 focus_range: Some( 2794 focus_range: 6..9,
2943 6..9,
2944 ),
2945 name: "Foo", 2795 name: "Foo",
2946 kind: TRAIT, 2796 kind: Trait,
2947 container_name: None, 2797 description: "trait Foo",
2948 description: Some(
2949 "trait Foo",
2950 ),
2951 docs: None,
2952 }, 2798 },
2953 }, 2799 },
2954 HoverGotoTypeData { 2800 HoverGotoTypeData {
@@ -2958,16 +2804,10 @@ fn foo(ar<|>g: &impl Foo<S>) {}
2958 0, 2804 0,
2959 ), 2805 ),
2960 full_range: 16..27, 2806 full_range: 16..27,
2961 focus_range: Some( 2807 focus_range: 23..24,
2962 23..24,
2963 ),
2964 name: "S", 2808 name: "S",
2965 kind: STRUCT, 2809 kind: Struct,
2966 container_name: None, 2810 description: "struct S",
2967 description: Some(
2968 "struct S",
2969 ),
2970 docs: None,
2971 }, 2811 },
2972 }, 2812 },
2973 ], 2813 ],
@@ -3001,16 +2841,10 @@ fn main() { let s<|>t = foo(); }
3001 0, 2841 0,
3002 ), 2842 ),
3003 full_range: 42..55, 2843 full_range: 42..55,
3004 focus_range: Some( 2844 focus_range: 49..50,
3005 49..50,
3006 ),
3007 name: "B", 2845 name: "B",
3008 kind: STRUCT, 2846 kind: Struct,
3009 container_name: None, 2847 description: "struct B",
3010 description: Some(
3011 "struct B",
3012 ),
3013 docs: None,
3014 }, 2848 },
3015 }, 2849 },
3016 HoverGotoTypeData { 2850 HoverGotoTypeData {
@@ -3020,16 +2854,10 @@ fn main() { let s<|>t = foo(); }
3020 0, 2854 0,
3021 ), 2855 ),
3022 full_range: 0..12, 2856 full_range: 0..12,
3023 focus_range: Some( 2857 focus_range: 6..9,
3024 6..9,
3025 ),
3026 name: "Foo", 2858 name: "Foo",
3027 kind: TRAIT, 2859 kind: Trait,
3028 container_name: None, 2860 description: "trait Foo",
3029 description: Some(
3030 "trait Foo",
3031 ),
3032 docs: None,
3033 }, 2861 },
3034 }, 2862 },
3035 ], 2863 ],
@@ -3057,16 +2885,10 @@ fn foo(ar<|>g: &dyn Foo) {}
3057 0, 2885 0,
3058 ), 2886 ),
3059 full_range: 0..12, 2887 full_range: 0..12,
3060 focus_range: Some( 2888 focus_range: 6..9,
3061 6..9,
3062 ),
3063 name: "Foo", 2889 name: "Foo",
3064 kind: TRAIT, 2890 kind: Trait,
3065 container_name: None, 2891 description: "trait Foo",
3066 description: Some(
3067 "trait Foo",
3068 ),
3069 docs: None,
3070 }, 2892 },
3071 }, 2893 },
3072 ], 2894 ],
@@ -3095,16 +2917,10 @@ fn foo(ar<|>g: &dyn Foo<S>) {}
3095 0, 2917 0,
3096 ), 2918 ),
3097 full_range: 0..15, 2919 full_range: 0..15,
3098 focus_range: Some( 2920 focus_range: 6..9,
3099 6..9,
3100 ),
3101 name: "Foo", 2921 name: "Foo",
3102 kind: TRAIT, 2922 kind: Trait,
3103 container_name: None, 2923 description: "trait Foo",
3104 description: Some(
3105 "trait Foo",
3106 ),
3107 docs: None,
3108 }, 2924 },
3109 }, 2925 },
3110 HoverGotoTypeData { 2926 HoverGotoTypeData {
@@ -3114,16 +2930,10 @@ fn foo(ar<|>g: &dyn Foo<S>) {}
3114 0, 2930 0,
3115 ), 2931 ),
3116 full_range: 16..27, 2932 full_range: 16..27,
3117 focus_range: Some( 2933 focus_range: 23..24,
3118 23..24,
3119 ),
3120 name: "S", 2934 name: "S",
3121 kind: STRUCT, 2935 kind: Struct,
3122 container_name: None, 2936 description: "struct S",
3123 description: Some(
3124 "struct S",
3125 ),
3126 docs: None,
3127 }, 2937 },
3128 }, 2938 },
3129 ], 2939 ],
@@ -3155,16 +2965,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
3155 0, 2965 0,
3156 ), 2966 ),
3157 full_range: 0..21, 2967 full_range: 0..21,
3158 focus_range: Some( 2968 focus_range: 6..15,
3159 6..15,
3160 ),
3161 name: "ImplTrait", 2969 name: "ImplTrait",
3162 kind: TRAIT, 2970 kind: Trait,
3163 container_name: None, 2971 description: "trait ImplTrait",
3164 description: Some(
3165 "trait ImplTrait",
3166 ),
3167 docs: None,
3168 }, 2972 },
3169 }, 2973 },
3170 HoverGotoTypeData { 2974 HoverGotoTypeData {
@@ -3174,16 +2978,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
3174 0, 2978 0,
3175 ), 2979 ),
3176 full_range: 43..57, 2980 full_range: 43..57,
3177 focus_range: Some( 2981 focus_range: 50..51,
3178 50..51,
3179 ),
3180 name: "B", 2982 name: "B",
3181 kind: STRUCT, 2983 kind: Struct,
3182 container_name: None, 2984 description: "struct B",
3183 description: Some(
3184 "struct B",
3185 ),
3186 docs: None,
3187 }, 2985 },
3188 }, 2986 },
3189 HoverGotoTypeData { 2987 HoverGotoTypeData {
@@ -3193,16 +2991,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
3193 0, 2991 0,
3194 ), 2992 ),
3195 full_range: 22..42, 2993 full_range: 22..42,
3196 focus_range: Some( 2994 focus_range: 28..36,
3197 28..36,
3198 ),
3199 name: "DynTrait", 2995 name: "DynTrait",
3200 kind: TRAIT, 2996 kind: Trait,
3201 container_name: None, 2997 description: "trait DynTrait",
3202 description: Some(
3203 "trait DynTrait",
3204 ),
3205 docs: None,
3206 }, 2998 },
3207 }, 2999 },
3208 HoverGotoTypeData { 3000 HoverGotoTypeData {
@@ -3212,16 +3004,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
3212 0, 3004 0,
3213 ), 3005 ),
3214 full_range: 58..69, 3006 full_range: 58..69,
3215 focus_range: Some( 3007 focus_range: 65..66,
3216 65..66,
3217 ),
3218 name: "S", 3008 name: "S",
3219 kind: STRUCT, 3009 kind: Struct,
3220 container_name: None, 3010 description: "struct S",
3221 description: Some(
3222 "struct S",
3223 ),
3224 docs: None,
3225 }, 3011 },
3226 }, 3012 },
3227 ], 3013 ],
@@ -3260,16 +3046,10 @@ fn main() { let s<|>t = test().get(); }
3260 0, 3046 0,
3261 ), 3047 ),
3262 full_range: 0..62, 3048 full_range: 0..62,
3263 focus_range: Some( 3049 focus_range: 6..9,
3264 6..9,
3265 ),
3266 name: "Foo", 3050 name: "Foo",
3267 kind: TRAIT, 3051 kind: Trait,
3268 container_name: None, 3052 description: "trait Foo",
3269 description: Some(
3270 "trait Foo",
3271 ),
3272 docs: None,
3273 }, 3053 },
3274 }, 3054 },
3275 ], 3055 ],
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index c5c652cda..dbad9a84f 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -57,14 +57,14 @@ use ide_db::{
57 symbol_index::{self, FileSymbol}, 57 symbol_index::{self, FileSymbol},
58 LineIndexDatabase, 58 LineIndexDatabase,
59}; 59};
60use syntax::{SourceFile, TextRange, TextSize}; 60use syntax::SourceFile;
61 61
62use crate::display::ToNav; 62use crate::display::ToNav;
63 63
64pub use crate::{ 64pub use crate::{
65 call_hierarchy::CallItem, 65 call_hierarchy::CallItem,
66 diagnostics::{Diagnostic, DiagnosticsConfig, Fix, Severity}, 66 diagnostics::{Diagnostic, DiagnosticsConfig, Fix, Severity},
67 display::NavigationTarget, 67 display::navigation_target::{NavigationTarget, SymbolKind},
68 expand_macro::ExpandedMacro, 68 expand_macro::ExpandedMacro,
69 file_structure::StructureNode, 69 file_structure::StructureNode,
70 folding_ranges::{Fold, FoldKind}, 70 folding_ranges::{Fold, FoldKind},
@@ -79,22 +79,21 @@ pub use crate::{
79 HighlightedRange, 79 HighlightedRange,
80 }, 80 },
81}; 81};
82pub use assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist};
82pub use completion::{ 83pub use completion::{
83 CompletionConfig, CompletionItem, CompletionItemKind, CompletionResolveCapability, 84 CompletionConfig, CompletionItem, CompletionItemKind, CompletionResolveCapability,
84 CompletionScore, ImportEdit, InsertTextFormat, 85 CompletionScore, ImportEdit, InsertTextFormat,
85}; 86};
86pub use ide_db::{
87 call_info::CallInfo,
88 search::{Reference, ReferenceAccess, ReferenceKind},
89};
90
91pub use assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist};
92pub use hir::{Documentation, Semantics}; 87pub use hir::{Documentation, Semantics};
93pub use ide_db::base_db::{ 88pub use ide_db::base_db::{
94 Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, 89 Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot,
95 SourceRootId, 90 SourceRootId,
96}; 91};
97pub use ide_db::{ 92pub use ide_db::{
93 call_info::CallInfo,
94 search::{Reference, ReferenceAccess, ReferenceKind},
95};
96pub use ide_db::{
98 label::Label, 97 label::Label,
99 line_index::{LineCol, LineIndex}, 98 line_index::{LineCol, LineIndex},
100 search::SearchScope, 99 search::SearchScope,
@@ -103,6 +102,7 @@ pub use ide_db::{
103 RootDatabase, 102 RootDatabase,
104}; 103};
105pub use ssr::SsrError; 104pub use ssr::SsrError;
105pub use syntax::{TextRange, TextSize};
106pub use text_edit::{Indel, TextEdit}; 106pub use text_edit::{Indel, TextEdit};
107 107
108pub type Cancelable<T> = Result<T, Canceled>; 108pub type Cancelable<T> = Result<T, Canceled>;
diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs
index 6cc3b2991..be344a09b 100644
--- a/crates/ide/src/parent_module.rs
+++ b/crates/ide/src/parent_module.rs
@@ -78,7 +78,7 @@ mod tests {
78 ", 78 ",
79 ); 79 );
80 let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); 80 let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
81 nav.assert_match("foo MODULE FileId(0) 0..8"); 81 nav.assert_match("foo Module FileId(0) 0..8");
82 } 82 }
83 83
84 #[test] 84 #[test]
@@ -97,7 +97,7 @@ mod tests {
97 ", 97 ",
98 ); 98 );
99 let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); 99 let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
100 nav.assert_match("foo MODULE FileId(0) 0..8"); 100 nav.assert_match("foo Module FileId(0) 0..8");
101 } 101 }
102 102
103 #[test] 103 #[test]
@@ -113,7 +113,7 @@ mod tests {
113 ", 113 ",
114 ); 114 );
115 let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); 115 let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
116 nav.assert_match("baz MODULE FileId(0) 32..44"); 116 nav.assert_match("baz Module FileId(0) 32..44");
117 } 117 }
118 118
119 #[test] 119 #[test]
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 98190a86b..18ea19305 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -24,7 +24,7 @@ use syntax::{
24 match_ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TokenAtOffset, 24 match_ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TokenAtOffset,
25}; 25};
26 26
27use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; 27use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, SymbolKind};
28 28
29#[derive(Debug, Clone)] 29#[derive(Debug, Clone)]
30pub struct ReferenceSearchResult { 30pub struct ReferenceSearchResult {
@@ -278,7 +278,7 @@ fn try_find_self_references(
278 full_range: self_param.syntax().text_range(), 278 full_range: self_param.syntax().text_range(),
279 focus_range: Some(param_self_token.text_range()), 279 focus_range: Some(param_self_token.text_range()),
280 name: param_self_token.text().clone(), 280 name: param_self_token.text().clone(),
281 kind: param_self_token.kind(), 281 kind: Some(SymbolKind::SelfParam),
282 container_name: None, 282 container_name: None,
283 description: None, 283 description: None,
284 docs: None, 284 docs: None,
@@ -343,7 +343,7 @@ fn main() {
343} 343}
344"#, 344"#,
345 expect![[r#" 345 expect![[r#"
346 Foo STRUCT FileId(0) 0..26 7..10 Other 346 Foo Struct FileId(0) 0..26 7..10 Other
347 347
348 FileId(0) 101..104 StructLiteral 348 FileId(0) 101..104 StructLiteral
349 "#]], 349 "#]],
@@ -361,7 +361,7 @@ struct Foo<|> {}
361} 361}
362"#, 362"#,
363 expect![[r#" 363 expect![[r#"
364 Foo STRUCT FileId(0) 0..13 7..10 Other 364 Foo Struct FileId(0) 0..13 7..10 Other
365 365
366 FileId(0) 41..44 Other 366 FileId(0) 41..44 Other
367 FileId(0) 54..57 StructLiteral 367 FileId(0) 54..57 StructLiteral
@@ -380,7 +380,7 @@ struct Foo<T> <|>{}
380} 380}
381"#, 381"#,
382 expect![[r#" 382 expect![[r#"
383 Foo STRUCT FileId(0) 0..16 7..10 Other 383 Foo Struct FileId(0) 0..16 7..10 Other
384 384
385 FileId(0) 64..67 StructLiteral 385 FileId(0) 64..67 StructLiteral
386 "#]], 386 "#]],
@@ -399,7 +399,7 @@ fn main() {
399} 399}
400"#, 400"#,
401 expect![[r#" 401 expect![[r#"
402 Foo STRUCT FileId(0) 0..16 7..10 Other 402 Foo Struct FileId(0) 0..16 7..10 Other
403 403
404 FileId(0) 54..57 StructLiteral 404 FileId(0) 54..57 StructLiteral
405 "#]], 405 "#]],
@@ -420,7 +420,7 @@ fn main() {
420} 420}
421"#, 421"#,
422 expect![[r#" 422 expect![[r#"
423 Foo ENUM FileId(0) 0..26 5..8 Other 423 Foo Enum FileId(0) 0..26 5..8 Other
424 424
425 FileId(0) 63..66 EnumLiteral 425 FileId(0) 63..66 EnumLiteral
426 "#]], 426 "#]],
@@ -441,7 +441,7 @@ fn main() {
441} 441}
442"#, 442"#,
443 expect![[r#" 443 expect![[r#"
444 Foo ENUM FileId(0) 0..26 5..8 Other 444 Foo Enum FileId(0) 0..26 5..8 Other
445 445
446 FileId(0) 50..53 Other 446 FileId(0) 50..53 Other
447 FileId(0) 63..66 EnumLiteral 447 FileId(0) 63..66 EnumLiteral
@@ -463,7 +463,7 @@ fn main() {
463} 463}
464"#, 464"#,
465 expect![[r#" 465 expect![[r#"
466 Foo ENUM FileId(0) 0..32 5..8 Other 466 Foo Enum FileId(0) 0..32 5..8 Other
467 467
468 FileId(0) 73..76 EnumLiteral 468 FileId(0) 73..76 EnumLiteral
469 "#]], 469 "#]],
@@ -484,7 +484,7 @@ fn main() {
484} 484}
485"#, 485"#,
486 expect![[r#" 486 expect![[r#"
487 Foo ENUM FileId(0) 0..33 5..8 Other 487 Foo Enum FileId(0) 0..33 5..8 Other
488 488
489 FileId(0) 70..73 EnumLiteral 489 FileId(0) 70..73 EnumLiteral
490 "#]], 490 "#]],
@@ -507,7 +507,7 @@ fn main() {
507 i = 5; 507 i = 5;
508}"#, 508}"#,
509 expect![[r#" 509 expect![[r#"
510 i IDENT_PAT FileId(0) 24..25 Other Write 510 i Local FileId(0) 24..25 Other Write
511 511
512 FileId(0) 50..51 Other Write 512 FileId(0) 50..51 Other Write
513 FileId(0) 54..55 Other Read 513 FileId(0) 54..55 Other Read
@@ -531,7 +531,7 @@ fn bar() {
531} 531}
532"#, 532"#,
533 expect![[r#" 533 expect![[r#"
534 spam IDENT_PAT FileId(0) 19..23 Other 534 spam Local FileId(0) 19..23 Other
535 535
536 FileId(0) 34..38 Other Read 536 FileId(0) 34..38 Other Read
537 FileId(0) 41..45 Other Read 537 FileId(0) 41..45 Other Read
@@ -546,7 +546,7 @@ fn bar() {
546fn foo(i : u32) -> u32 { i<|> } 546fn foo(i : u32) -> u32 { i<|> }
547"#, 547"#,
548 expect![[r#" 548 expect![[r#"
549 i IDENT_PAT FileId(0) 7..8 Other 549 i ValueParam FileId(0) 7..8 Other
550 550
551 FileId(0) 25..26 Other Read 551 FileId(0) 25..26 Other Read
552 "#]], 552 "#]],
@@ -560,7 +560,7 @@ fn foo(i : u32) -> u32 { i<|> }
560fn foo(i<|> : u32) -> u32 { i } 560fn foo(i<|> : u32) -> u32 { i }
561"#, 561"#,
562 expect![[r#" 562 expect![[r#"
563 i IDENT_PAT FileId(0) 7..8 Other 563 i ValueParam FileId(0) 7..8 Other
564 564
565 FileId(0) 25..26 Other Read 565 FileId(0) 25..26 Other Read
566 "#]], 566 "#]],
@@ -581,7 +581,7 @@ fn main(s: Foo) {
581} 581}
582"#, 582"#,
583 expect![[r#" 583 expect![[r#"
584 spam RECORD_FIELD FileId(0) 17..30 21..25 Other 584 spam Field FileId(0) 17..30 21..25 Other
585 585
586 FileId(0) 67..71 Other Read 586 FileId(0) 67..71 Other Read
587 "#]], 587 "#]],
@@ -598,7 +598,7 @@ impl Foo {
598} 598}
599"#, 599"#,
600 expect![[r#" 600 expect![[r#"
601 f FN FileId(0) 27..43 30..31 Other 601 f Function FileId(0) 27..43 30..31 Other
602 602
603 "#]], 603 "#]],
604 ); 604 );
@@ -615,7 +615,7 @@ enum Foo {
615} 615}
616"#, 616"#,
617 expect![[r#" 617 expect![[r#"
618 B VARIANT FileId(0) 22..23 22..23 Other 618 B Variant FileId(0) 22..23 22..23 Other
619 619
620 "#]], 620 "#]],
621 ); 621 );
@@ -632,7 +632,7 @@ enum Foo {
632} 632}
633"#, 633"#,
634 expect![[r#" 634 expect![[r#"
635 field RECORD_FIELD FileId(0) 26..35 26..31 Other 635 field Field FileId(0) 26..35 26..31 Other
636 636
637 "#]], 637 "#]],
638 ); 638 );
@@ -673,7 +673,7 @@ fn f() {
673} 673}
674"#, 674"#,
675 expect![[r#" 675 expect![[r#"
676 Foo STRUCT FileId(1) 17..51 28..31 Other 676 Foo Struct FileId(1) 17..51 28..31 Other
677 677
678 FileId(0) 53..56 StructLiteral 678 FileId(0) 53..56 StructLiteral
679 FileId(2) 79..82 StructLiteral 679 FileId(2) 79..82 StructLiteral
@@ -703,7 +703,7 @@ pub struct Foo {
703} 703}
704"#, 704"#,
705 expect![[r#" 705 expect![[r#"
706 foo SOURCE_FILE FileId(1) 0..35 Other 706 foo Module FileId(1) 0..35 Other
707 707
708 FileId(0) 14..17 Other 708 FileId(0) 14..17 Other
709 "#]], 709 "#]],
@@ -731,7 +731,7 @@ pub(super) struct Foo<|> {
731} 731}
732"#, 732"#,
733 expect![[r#" 733 expect![[r#"
734 Foo STRUCT FileId(2) 0..41 18..21 Other 734 Foo Struct FileId(2) 0..41 18..21 Other
735 735
736 FileId(1) 20..23 Other 736 FileId(1) 20..23 Other
737 FileId(1) 47..50 StructLiteral 737 FileId(1) 47..50 StructLiteral
@@ -759,7 +759,7 @@ pub(super) struct Foo<|> {
759 code, 759 code,
760 None, 760 None,
761 expect![[r#" 761 expect![[r#"
762 quux FN FileId(0) 19..35 26..30 Other 762 quux Function FileId(0) 19..35 26..30 Other
763 763
764 FileId(1) 16..20 StructLiteral 764 FileId(1) 16..20 StructLiteral
765 FileId(2) 16..20 StructLiteral 765 FileId(2) 16..20 StructLiteral
@@ -770,7 +770,7 @@ pub(super) struct Foo<|> {
770 code, 770 code,
771 Some(SearchScope::single_file(FileId(2))), 771 Some(SearchScope::single_file(FileId(2))),
772 expect![[r#" 772 expect![[r#"
773 quux FN FileId(0) 19..35 26..30 Other 773 quux Function FileId(0) 19..35 26..30 Other
774 774
775 FileId(2) 16..20 StructLiteral 775 FileId(2) 16..20 StructLiteral
776 "#]], 776 "#]],
@@ -790,7 +790,7 @@ fn foo() {
790} 790}
791"#, 791"#,
792 expect![[r#" 792 expect![[r#"
793 m1 MACRO_RULES FileId(0) 0..46 29..31 Other 793 m1 Macro FileId(0) 0..46 29..31 Other
794 794
795 FileId(0) 63..65 StructLiteral 795 FileId(0) 63..65 StructLiteral
796 FileId(0) 73..75 StructLiteral 796 FileId(0) 73..75 StructLiteral
@@ -808,7 +808,7 @@ fn foo() {
808} 808}
809"#, 809"#,
810 expect![[r#" 810 expect![[r#"
811 i IDENT_PAT FileId(0) 23..24 Other Write 811 i Local FileId(0) 23..24 Other Write
812 812
813 FileId(0) 34..35 Other Write 813 FileId(0) 34..35 Other Write
814 FileId(0) 38..39 Other Read 814 FileId(0) 38..39 Other Read
@@ -830,7 +830,7 @@ fn foo() {
830} 830}
831"#, 831"#,
832 expect![[r#" 832 expect![[r#"
833 f RECORD_FIELD FileId(0) 15..21 15..16 Other 833 f Field FileId(0) 15..21 15..16 Other
834 834
835 FileId(0) 55..56 RecordFieldExprOrPat Read 835 FileId(0) 55..56 RecordFieldExprOrPat Read
836 FileId(0) 68..69 Other Write 836 FileId(0) 68..69 Other Write
@@ -848,7 +848,7 @@ fn foo() {
848} 848}
849"#, 849"#,
850 expect![[r#" 850 expect![[r#"
851 i IDENT_PAT FileId(0) 19..20 Other 851 i Local FileId(0) 19..20 Other
852 852
853 FileId(0) 26..27 Other Write 853 FileId(0) 26..27 Other Write
854 "#]], 854 "#]],
@@ -872,7 +872,7 @@ fn main() {
872} 872}
873"#, 873"#,
874 expect![[r#" 874 expect![[r#"
875 new FN FileId(0) 54..81 61..64 Other 875 new Function FileId(0) 54..81 61..64 Other
876 876
877 FileId(0) 126..129 StructLiteral 877 FileId(0) 126..129 StructLiteral
878 "#]], 878 "#]],
@@ -894,7 +894,7 @@ use crate::f;
894fn g() { f(); } 894fn g() { f(); }
895"#, 895"#,
896 expect![[r#" 896 expect![[r#"
897 f FN FileId(0) 22..31 25..26 Other 897 f Function FileId(0) 22..31 25..26 Other
898 898
899 FileId(1) 11..12 Other 899 FileId(1) 11..12 Other
900 FileId(1) 24..25 StructLiteral 900 FileId(1) 24..25 StructLiteral
@@ -917,7 +917,7 @@ fn f(s: S) {
917} 917}
918"#, 918"#,
919 expect![[r#" 919 expect![[r#"
920 field RECORD_FIELD FileId(0) 15..24 15..20 Other 920 field Field FileId(0) 15..24 15..20 Other
921 921
922 FileId(0) 68..73 FieldShorthandForField Read 922 FileId(0) 68..73 FieldShorthandForField Read
923 "#]], 923 "#]],
@@ -941,7 +941,7 @@ fn f(e: En) {
941} 941}
942"#, 942"#,
943 expect![[r#" 943 expect![[r#"
944 field RECORD_FIELD FileId(0) 32..41 32..37 Other 944 field Field FileId(0) 32..41 32..37 Other
945 945
946 FileId(0) 102..107 FieldShorthandForField Read 946 FileId(0) 102..107 FieldShorthandForField Read
947 "#]], 947 "#]],
@@ -965,7 +965,7 @@ fn f() -> m::En {
965} 965}
966"#, 966"#,
967 expect![[r#" 967 expect![[r#"
968 field RECORD_FIELD FileId(0) 56..65 56..61 Other 968 field Field FileId(0) 56..65 56..61 Other
969 969
970 FileId(0) 125..130 RecordFieldExprOrPat Read 970 FileId(0) 125..130 RecordFieldExprOrPat Read
971 "#]], 971 "#]],
@@ -990,7 +990,7 @@ impl Foo {
990} 990}
991"#, 991"#,
992 expect![[r#" 992 expect![[r#"
993 self SELF_KW FileId(0) 47..51 47..51 SelfKw Read 993 self SelfParam FileId(0) 47..51 47..51 SelfKw Read
994 994
995 FileId(0) 71..75 SelfKw Read 995 FileId(0) 71..75 SelfKw Read
996 FileId(0) 152..156 SelfKw Read 996 FileId(0) 152..156 SelfKw Read
@@ -1038,7 +1038,7 @@ fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> {
1038} 1038}
1039"#, 1039"#,
1040 expect![[r#" 1040 expect![[r#"
1041 'a LIFETIME_PARAM FileId(0) 55..57 55..57 Lifetime 1041 'a LifetimeParam FileId(0) 55..57 55..57 Lifetime
1042 1042
1043 FileId(0) 63..65 Lifetime 1043 FileId(0) 63..65 Lifetime
1044 FileId(0) 71..73 Lifetime 1044 FileId(0) 71..73 Lifetime
@@ -1056,7 +1056,7 @@ fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> {
1056type Foo<'a, T> where T: 'a<|> = &'a T; 1056type Foo<'a, T> where T: 'a<|> = &'a T;
1057"#, 1057"#,
1058 expect![[r#" 1058 expect![[r#"
1059 'a LIFETIME_PARAM FileId(0) 9..11 9..11 Lifetime 1059 'a LifetimeParam FileId(0) 9..11 9..11 Lifetime
1060 1060
1061 FileId(0) 25..27 Lifetime 1061 FileId(0) 25..27 Lifetime
1062 FileId(0) 31..33 Lifetime 1062 FileId(0) 31..33 Lifetime
@@ -1078,7 +1078,7 @@ impl<'a> Foo<'a> for &'a () {
1078} 1078}
1079"#, 1079"#,
1080 expect![[r#" 1080 expect![[r#"
1081 'a LIFETIME_PARAM FileId(0) 47..49 47..49 Lifetime 1081 'a LifetimeParam FileId(0) 47..49 47..49 Lifetime
1082 1082
1083 FileId(0) 55..57 Lifetime 1083 FileId(0) 55..57 Lifetime
1084 FileId(0) 64..66 Lifetime 1084 FileId(0) 64..66 Lifetime
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 56e923841..cd721b7eb 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -1488,4 +1488,39 @@ impl<'yeeee> Foo<'yeeee> for &'yeeee () {
1488"#, 1488"#,
1489 ) 1489 )
1490 } 1490 }
1491
1492 #[test]
1493 fn test_rename_bind_pat() {
1494 check(
1495 "new_name",
1496 r#"
1497fn main() {
1498 enum CustomOption<T> {
1499 None,
1500 Some(T),
1501 }
1502
1503 let test_variable = CustomOption::Some(22);
1504
1505 match test_variable {
1506 CustomOption::Some(foo<|>) if foo == 11 => {}
1507 _ => (),
1508 }
1509}"#,
1510 r#"
1511fn main() {
1512 enum CustomOption<T> {
1513 None,
1514 Some(T),
1515 }
1516
1517 let test_variable = CustomOption::Some(22);
1518
1519 match test_variable {
1520 CustomOption::Some(new_name) if new_name == 11 => {}
1521 _ => (),
1522 }
1523}"#,
1524 );
1525 }
1491} 1526}
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 2f465c195..ff386be80 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -12,7 +12,7 @@ use syntax::{
12 12
13use crate::{ 13use crate::{
14 display::{ToNav, TryToNav}, 14 display::{ToNav, TryToNav},
15 FileId, NavigationTarget, 15 FileId, NavigationTarget, SymbolKind,
16}; 16};
17 17
18#[derive(Debug, Clone)] 18#[derive(Debug, Clone)]
@@ -137,7 +137,11 @@ fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -
137 } 137 }
138 }; 138 };
139 139
140 let nav = NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &func)); 140 let nav = NavigationTarget::from_named(
141 sema.db,
142 InFile::new(file_id.into(), &func),
143 SymbolKind::Function,
144 );
141 let cfg = def.attrs(sema.db).cfg(); 145 let cfg = def.attrs(sema.db).cfg();
142 Some(Runnable { nav, kind, cfg }) 146 Some(Runnable { nav, kind, cfg })
143} 147}
@@ -204,7 +208,7 @@ fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Op
204 nav.focus_range = None; 208 nav.focus_range = None;
205 nav.description = None; 209 nav.description = None;
206 nav.docs = None; 210 nav.docs = None;
207 nav.kind = syntax::SyntaxKind::COMMENT; 211 nav.kind = None;
208 let res = Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfg() }; 212 let res = Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfg() };
209 Some(res) 213 Some(res)
210} 214}
@@ -348,14 +352,9 @@ fn bench() {}
348 0, 352 0,
349 ), 353 ),
350 full_range: 1..13, 354 full_range: 1..13,
351 focus_range: Some( 355 focus_range: 4..8,
352 4..8,
353 ),
354 name: "main", 356 name: "main",
355 kind: FN, 357 kind: Function,
356 container_name: None,
357 description: None,
358 docs: None,
359 }, 358 },
360 kind: Bin, 359 kind: Bin,
361 cfg: None, 360 cfg: None,
@@ -366,14 +365,9 @@ fn bench() {}
366 0, 365 0,
367 ), 366 ),
368 full_range: 15..39, 367 full_range: 15..39,
369 focus_range: Some( 368 focus_range: 26..34,
370 26..34,
371 ),
372 name: "test_foo", 369 name: "test_foo",
373 kind: FN, 370 kind: Function,
374 container_name: None,
375 description: None,
376 docs: None,
377 }, 371 },
378 kind: Test { 372 kind: Test {
379 test_id: Path( 373 test_id: Path(
@@ -391,14 +385,9 @@ fn bench() {}
391 0, 385 0,
392 ), 386 ),
393 full_range: 41..75, 387 full_range: 41..75,
394 focus_range: Some( 388 focus_range: 62..70,
395 62..70,
396 ),
397 name: "test_foo", 389 name: "test_foo",
398 kind: FN, 390 kind: Function,
399 container_name: None,
400 description: None,
401 docs: None,
402 }, 391 },
403 kind: Test { 392 kind: Test {
404 test_id: Path( 393 test_id: Path(
@@ -416,14 +405,9 @@ fn bench() {}
416 0, 405 0,
417 ), 406 ),
418 full_range: 77..99, 407 full_range: 77..99,
419 focus_range: Some( 408 focus_range: 89..94,
420 89..94,
421 ),
422 name: "bench", 409 name: "bench",
423 kind: FN, 410 kind: Function,
424 container_name: None,
425 description: None,
426 docs: None,
427 }, 411 },
428 kind: Bench { 412 kind: Bench {
429 test_id: Path( 413 test_id: Path(
@@ -513,14 +497,9 @@ struct StructWithRunnable(String);
513 0, 497 0,
514 ), 498 ),
515 full_range: 1..13, 499 full_range: 1..13,
516 focus_range: Some( 500 focus_range: 4..8,
517 4..8,
518 ),
519 name: "main", 501 name: "main",
520 kind: FN, 502 kind: Function,
521 container_name: None,
522 description: None,
523 docs: None,
524 }, 503 },
525 kind: Bin, 504 kind: Bin,
526 cfg: None, 505 cfg: None,
@@ -531,12 +510,7 @@ struct StructWithRunnable(String);
531 0, 510 0,
532 ), 511 ),
533 full_range: 15..74, 512 full_range: 15..74,
534 focus_range: None,
535 name: "should_have_runnable", 513 name: "should_have_runnable",
536 kind: COMMENT,
537 container_name: None,
538 description: None,
539 docs: None,
540 }, 514 },
541 kind: DocTest { 515 kind: DocTest {
542 test_id: Path( 516 test_id: Path(
@@ -551,12 +525,7 @@ struct StructWithRunnable(String);
551 0, 525 0,
552 ), 526 ),
553 full_range: 76..148, 527 full_range: 76..148,
554 focus_range: None,
555 name: "should_have_runnable_1", 528 name: "should_have_runnable_1",
556 kind: COMMENT,
557 container_name: None,
558 description: None,
559 docs: None,
560 }, 529 },
561 kind: DocTest { 530 kind: DocTest {
562 test_id: Path( 531 test_id: Path(
@@ -571,12 +540,7 @@ struct StructWithRunnable(String);
571 0, 540 0,
572 ), 541 ),
573 full_range: 150..254, 542 full_range: 150..254,
574 focus_range: None,
575 name: "should_have_runnable_2", 543 name: "should_have_runnable_2",
576 kind: COMMENT,
577 container_name: None,
578 description: None,
579 docs: None,
580 }, 544 },
581 kind: DocTest { 545 kind: DocTest {
582 test_id: Path( 546 test_id: Path(
@@ -591,12 +555,7 @@ struct StructWithRunnable(String);
591 0, 555 0,
592 ), 556 ),
593 full_range: 756..821, 557 full_range: 756..821,
594 focus_range: None,
595 name: "StructWithRunnable", 558 name: "StructWithRunnable",
596 kind: COMMENT,
597 container_name: None,
598 description: None,
599 docs: None,
600 }, 559 },
601 kind: DocTest { 560 kind: DocTest {
602 test_id: Path( 561 test_id: Path(
@@ -635,14 +594,9 @@ impl Data {
635 0, 594 0,
636 ), 595 ),
637 full_range: 1..13, 596 full_range: 1..13,
638 focus_range: Some( 597 focus_range: 4..8,
639 4..8,
640 ),
641 name: "main", 598 name: "main",
642 kind: FN, 599 kind: Function,
643 container_name: None,
644 description: None,
645 docs: None,
646 }, 600 },
647 kind: Bin, 601 kind: Bin,
648 cfg: None, 602 cfg: None,
@@ -653,12 +607,7 @@ impl Data {
653 0, 607 0,
654 ), 608 ),
655 full_range: 44..98, 609 full_range: 44..98,
656 focus_range: None,
657 name: "foo", 610 name: "foo",
658 kind: COMMENT,
659 container_name: None,
660 description: None,
661 docs: None,
662 }, 611 },
663 kind: DocTest { 612 kind: DocTest {
664 test_id: Path( 613 test_id: Path(
@@ -692,14 +641,9 @@ mod test_mod {
692 0, 641 0,
693 ), 642 ),
694 full_range: 1..51, 643 full_range: 1..51,
695 focus_range: Some( 644 focus_range: 5..13,
696 5..13,
697 ),
698 name: "test_mod", 645 name: "test_mod",
699 kind: MODULE, 646 kind: Module,
700 container_name: None,
701 description: None,
702 docs: None,
703 }, 647 },
704 kind: TestMod { 648 kind: TestMod {
705 path: "test_mod", 649 path: "test_mod",
@@ -712,14 +656,9 @@ mod test_mod {
712 0, 656 0,
713 ), 657 ),
714 full_range: 20..49, 658 full_range: 20..49,
715 focus_range: Some( 659 focus_range: 35..44,
716 35..44,
717 ),
718 name: "test_foo1", 660 name: "test_foo1",
719 kind: FN, 661 kind: Function,
720 container_name: None,
721 description: None,
722 docs: None,
723 }, 662 },
724 kind: Test { 663 kind: Test {
725 test_id: Path( 664 test_id: Path(
@@ -772,14 +711,9 @@ mod root_tests {
772 0, 711 0,
773 ), 712 ),
774 full_range: 22..323, 713 full_range: 22..323,
775 focus_range: Some( 714 focus_range: 26..40,
776 26..40,
777 ),
778 name: "nested_tests_0", 715 name: "nested_tests_0",
779 kind: MODULE, 716 kind: Module,
780 container_name: None,
781 description: None,
782 docs: None,
783 }, 717 },
784 kind: TestMod { 718 kind: TestMod {
785 path: "root_tests::nested_tests_0", 719 path: "root_tests::nested_tests_0",
@@ -792,14 +726,9 @@ mod root_tests {
792 0, 726 0,
793 ), 727 ),
794 full_range: 51..192, 728 full_range: 51..192,
795 focus_range: Some( 729 focus_range: 55..69,
796 55..69,
797 ),
798 name: "nested_tests_1", 730 name: "nested_tests_1",
799 kind: MODULE, 731 kind: Module,
800 container_name: None,
801 description: None,
802 docs: None,
803 }, 732 },
804 kind: TestMod { 733 kind: TestMod {
805 path: "root_tests::nested_tests_0::nested_tests_1", 734 path: "root_tests::nested_tests_0::nested_tests_1",
@@ -812,14 +741,9 @@ mod root_tests {
812 0, 741 0,
813 ), 742 ),
814 full_range: 84..126, 743 full_range: 84..126,
815 focus_range: Some( 744 focus_range: 107..121,
816 107..121,
817 ),
818 name: "nested_test_11", 745 name: "nested_test_11",
819 kind: FN, 746 kind: Function,
820 container_name: None,
821 description: None,
822 docs: None,
823 }, 747 },
824 kind: Test { 748 kind: Test {
825 test_id: Path( 749 test_id: Path(
@@ -837,14 +761,9 @@ mod root_tests {
837 0, 761 0,
838 ), 762 ),
839 full_range: 140..182, 763 full_range: 140..182,
840 focus_range: Some( 764 focus_range: 163..177,
841 163..177,
842 ),
843 name: "nested_test_12", 765 name: "nested_test_12",
844 kind: FN, 766 kind: Function,
845 container_name: None,
846 description: None,
847 docs: None,
848 }, 767 },
849 kind: Test { 768 kind: Test {
850 test_id: Path( 769 test_id: Path(
@@ -862,14 +781,9 @@ mod root_tests {
862 0, 781 0,
863 ), 782 ),
864 full_range: 202..286, 783 full_range: 202..286,
865 focus_range: Some( 784 focus_range: 206..220,
866 206..220,
867 ),
868 name: "nested_tests_2", 785 name: "nested_tests_2",
869 kind: MODULE, 786 kind: Module,
870 container_name: None,
871 description: None,
872 docs: None,
873 }, 787 },
874 kind: TestMod { 788 kind: TestMod {
875 path: "root_tests::nested_tests_0::nested_tests_2", 789 path: "root_tests::nested_tests_0::nested_tests_2",
@@ -882,14 +796,9 @@ mod root_tests {
882 0, 796 0,
883 ), 797 ),
884 full_range: 235..276, 798 full_range: 235..276,
885 focus_range: Some( 799 focus_range: 258..271,
886 258..271,
887 ),
888 name: "nested_test_2", 800 name: "nested_test_2",
889 kind: FN, 801 kind: Function,
890 container_name: None,
891 description: None,
892 docs: None,
893 }, 802 },
894 kind: Test { 803 kind: Test {
895 test_id: Path( 804 test_id: Path(
@@ -925,14 +834,9 @@ fn test_foo1() {}
925 0, 834 0,
926 ), 835 ),
927 full_range: 1..50, 836 full_range: 1..50,
928 focus_range: Some( 837 focus_range: 36..45,
929 36..45,
930 ),
931 name: "test_foo1", 838 name: "test_foo1",
932 kind: FN, 839 kind: Function,
933 container_name: None,
934 description: None,
935 docs: None,
936 }, 840 },
937 kind: Test { 841 kind: Test {
938 test_id: Path( 842 test_id: Path(
@@ -975,14 +879,9 @@ fn test_foo1() {}
975 0, 879 0,
976 ), 880 ),
977 full_range: 1..72, 881 full_range: 1..72,
978 focus_range: Some( 882 focus_range: 58..67,
979 58..67,
980 ),
981 name: "test_foo1", 883 name: "test_foo1",
982 kind: FN, 884 kind: Function,
983 container_name: None,
984 description: None,
985 docs: None,
986 }, 885 },
987 kind: Test { 886 kind: Test {
988 test_id: Path( 887 test_id: Path(
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 488969f1a..67ad7c63d 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -23,7 +23,7 @@ use crate::{
23 syntax_highlighting::{ 23 syntax_highlighting::{
24 format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight, 24 format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight,
25 }, 25 },
26 FileId, HighlightModifier, HighlightTag, 26 FileId, HighlightModifier, HighlightTag, SymbolKind,
27}; 27};
28 28
29pub(crate) use html::highlight_as_html; 29pub(crate) use html::highlight_as_html;
@@ -103,7 +103,7 @@ pub(crate) fn highlight(
103 if let Some(range) = macro_call_range(&mc) { 103 if let Some(range) = macro_call_range(&mc) {
104 stack.add(HighlightedRange { 104 stack.add(HighlightedRange {
105 range, 105 range,
106 highlight: HighlightTag::Macro.into(), 106 highlight: HighlightTag::Symbol(SymbolKind::Macro).into(),
107 binding_hash: None, 107 binding_hash: None,
108 }); 108 });
109 } 109 }
@@ -470,13 +470,13 @@ fn highlight_element(
470 }; 470 };
471 471
472 match name_kind { 472 match name_kind {
473 Some(NameClass::ExternCrate(_)) => HighlightTag::Module.into(), 473 Some(NameClass::ExternCrate(_)) => HighlightTag::Symbol(SymbolKind::Module).into(),
474 Some(NameClass::Definition(def)) => { 474 Some(NameClass::Definition(def)) => {
475 highlight_def(db, def) | HighlightModifier::Definition 475 highlight_def(db, def) | HighlightModifier::Definition
476 } 476 }
477 Some(NameClass::ConstReference(def)) => highlight_def(db, def), 477 Some(NameClass::ConstReference(def)) => highlight_def(db, def),
478 Some(NameClass::PatFieldShorthand { field_ref, .. }) => { 478 Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
479 let mut h = HighlightTag::Field.into(); 479 let mut h = HighlightTag::Symbol(SymbolKind::Field).into();
480 if let Definition::Field(field) = field_ref { 480 if let Definition::Field(field) = field_ref {
481 if let VariantDef::Union(_) = field.parent_def(db) { 481 if let VariantDef::Union(_) = field.parent_def(db) {
482 h |= HighlightModifier::Unsafe; 482 h |= HighlightModifier::Unsafe;
@@ -493,14 +493,16 @@ fn highlight_element(
493 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { 493 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => {
494 // even though we track whether we are in an attribute or not we still need this special case 494 // even though we track whether we are in an attribute or not we still need this special case
495 // as otherwise we would emit unresolved references for name refs inside attributes 495 // as otherwise we would emit unresolved references for name refs inside attributes
496 Highlight::from(HighlightTag::Function) 496 Highlight::from(HighlightTag::Symbol(SymbolKind::Function))
497 } 497 }
498 NAME_REF => { 498 NAME_REF => {
499 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); 499 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
500 highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { 500 highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| {
501 match NameRefClass::classify(sema, &name_ref) { 501 match NameRefClass::classify(sema, &name_ref) {
502 Some(name_kind) => match name_kind { 502 Some(name_kind) => match name_kind {
503 NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), 503 NameRefClass::ExternCrate(_) => {
504 HighlightTag::Symbol(SymbolKind::Module).into()
505 }
504 NameRefClass::Definition(def) => { 506 NameRefClass::Definition(def) => {
505 if let Definition::Local(local) = &def { 507 if let Definition::Local(local) = &def {
506 if let Some(name) = local.name(db) { 508 if let Some(name) = local.name(db) {
@@ -530,7 +532,9 @@ fn highlight_element(
530 532
531 h 533 h
532 } 534 }
533 NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), 535 NameRefClass::FieldShorthand { .. } => {
536 HighlightTag::Symbol(SymbolKind::Field).into()
537 }
534 }, 538 },
535 None if syntactic_name_ref_highlighting => { 539 None if syntactic_name_ref_highlighting => {
536 highlight_name_ref_by_syntax(name_ref, sema) 540 highlight_name_ref_by_syntax(name_ref, sema)
@@ -556,7 +560,7 @@ fn highlight_element(
556 CHAR => HighlightTag::CharLiteral.into(), 560 CHAR => HighlightTag::CharLiteral.into(),
557 QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow, 561 QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow,
558 LIFETIME => { 562 LIFETIME => {
559 let h = Highlight::new(HighlightTag::Lifetime); 563 let h = Highlight::new(HighlightTag::Symbol(SymbolKind::LifetimeParam));
560 match element.parent().map(|it| it.kind()) { 564 match element.parent().map(|it| it.kind()) {
561 Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition, 565 Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition,
562 _ => h, 566 _ => h,
@@ -580,7 +584,7 @@ fn highlight_element(
580 HighlightTag::Operator.into() 584 HighlightTag::Operator.into()
581 } 585 }
582 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { 586 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
583 HighlightTag::Macro.into() 587 HighlightTag::Symbol(SymbolKind::Macro).into()
584 } 588 }
585 T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { 589 T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => {
586 HighlightTag::BuiltinType.into() 590 HighlightTag::BuiltinType.into()
@@ -659,7 +663,7 @@ fn highlight_element(
659 .and_then(SyntaxNode::parent) 663 .and_then(SyntaxNode::parent)
660 .and_then(ast::Path::cast) 664 .and_then(ast::Path::cast)
661 .and_then(|p| sema.resolve_path(&p)); 665 .and_then(|p| sema.resolve_path(&p));
662 let mut h = HighlightTag::SelfKeyword.into(); 666 let mut h = HighlightTag::Symbol(SymbolKind::SelfParam).into();
663 if self_param_is_mut 667 if self_param_is_mut
664 || matches!(self_path, 668 || matches!(self_path,
665 Some(hir::PathResolution::Local(local)) 669 Some(hir::PathResolution::Local(local))
@@ -732,7 +736,8 @@ fn highlight_method_call(
732 method_call: &ast::MethodCallExpr, 736 method_call: &ast::MethodCallExpr,
733) -> Option<Highlight> { 737) -> Option<Highlight> {
734 let func = sema.resolve_method_call(&method_call)?; 738 let func = sema.resolve_method_call(&method_call)?;
735 let mut h = HighlightTag::Method.into(); 739 let mut h = HighlightTag::Symbol(SymbolKind::Function).into();
740 h |= HighlightModifier::Associated;
736 if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { 741 if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) {
737 h |= HighlightModifier::Unsafe; 742 h |= HighlightModifier::Unsafe;
738 } 743 }
@@ -756,35 +761,45 @@ fn highlight_method_call(
756 761
757fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { 762fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
758 match def { 763 match def {
759 Definition::Macro(_) => HighlightTag::Macro, 764 Definition::Macro(_) => HighlightTag::Symbol(SymbolKind::Macro),
760 Definition::Field(_) => HighlightTag::Field, 765 Definition::Field(_) => HighlightTag::Symbol(SymbolKind::Field),
761 Definition::ModuleDef(def) => match def { 766 Definition::ModuleDef(def) => match def {
762 hir::ModuleDef::Module(_) => HighlightTag::Module, 767 hir::ModuleDef::Module(_) => HighlightTag::Symbol(SymbolKind::Module),
763 hir::ModuleDef::Function(func) => { 768 hir::ModuleDef::Function(func) => {
764 let mut h = if func.as_assoc_item(db).is_some() { 769 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Function));
770 if func.as_assoc_item(db).is_some() {
771 h |= HighlightModifier::Associated;
765 if func.self_param(db).is_none() { 772 if func.self_param(db).is_none() {
766 Highlight::from(HighlightTag::Method) | HighlightModifier::Static 773 h |= HighlightModifier::Static
767 } else {
768 HighlightTag::Method.into()
769 } 774 }
770 } else { 775 }
771 HighlightTag::Function.into()
772 };
773 if func.is_unsafe(db) { 776 if func.is_unsafe(db) {
774 h |= HighlightModifier::Unsafe; 777 h |= HighlightModifier::Unsafe;
775 } 778 }
776 return h; 779 return h;
777 } 780 }
778 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, 781 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Symbol(SymbolKind::Struct),
779 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, 782 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Symbol(SymbolKind::Enum),
780 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, 783 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Symbol(SymbolKind::Union),
781 hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant, 784 hir::ModuleDef::EnumVariant(_) => HighlightTag::Symbol(SymbolKind::Variant),
782 hir::ModuleDef::Const(_) => HighlightTag::Constant, 785 hir::ModuleDef::Const(konst) => {
783 hir::ModuleDef::Trait(_) => HighlightTag::Trait, 786 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Const));
784 hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias, 787 if konst.as_assoc_item(db).is_some() {
788 h |= HighlightModifier::Associated
789 }
790 return h;
791 }
792 hir::ModuleDef::Trait(_) => HighlightTag::Symbol(SymbolKind::Trait),
793 hir::ModuleDef::TypeAlias(type_) => {
794 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::TypeAlias));
795 if type_.as_assoc_item(db).is_some() {
796 h |= HighlightModifier::Associated
797 }
798 return h;
799 }
785 hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType, 800 hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType,
786 hir::ModuleDef::Static(s) => { 801 hir::ModuleDef::Static(s) => {
787 let mut h = Highlight::new(HighlightTag::Static); 802 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Static));
788 if s.is_mut(db) { 803 if s.is_mut(db) {
789 h |= HighlightModifier::Mutable; 804 h |= HighlightModifier::Mutable;
790 h |= HighlightModifier::Unsafe; 805 h |= HighlightModifier::Unsafe;
@@ -792,11 +807,14 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
792 return h; 807 return h;
793 } 808 }
794 }, 809 },
795 Definition::SelfType(_) => HighlightTag::SelfType, 810 Definition::SelfType(_) => HighlightTag::Symbol(SymbolKind::Impl),
796 Definition::TypeParam(_) => HighlightTag::TypeParam, 811 Definition::TypeParam(_) => HighlightTag::Symbol(SymbolKind::TypeParam),
797 Definition::Local(local) => { 812 Definition::Local(local) => {
798 let tag = 813 let tag = if local.is_param(db) {
799 if local.is_param(db) { HighlightTag::ValueParam } else { HighlightTag::Local }; 814 HighlightTag::Symbol(SymbolKind::ValueParam)
815 } else {
816 HighlightTag::Symbol(SymbolKind::Local)
817 };
800 let mut h = Highlight::new(tag); 818 let mut h = Highlight::new(tag);
801 if local.is_mut(db) || local.ty(db).is_mutable_reference() { 819 if local.is_mut(db) || local.ty(db).is_mutable_reference() {
802 h |= HighlightModifier::Mutable; 820 h |= HighlightModifier::Mutable;
@@ -806,7 +824,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
806 } 824 }
807 return h; 825 return h;
808 } 826 }
809 Definition::LifetimeParam(_) => HighlightTag::Lifetime, 827 Definition::LifetimeParam(_) => HighlightTag::Symbol(SymbolKind::LifetimeParam),
810 } 828 }
811 .into() 829 .into()
812} 830}
@@ -820,19 +838,19 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
820 }; 838 };
821 839
822 let tag = match parent.kind() { 840 let tag = match parent.kind() {
823 STRUCT => HighlightTag::Struct, 841 STRUCT => HighlightTag::Symbol(SymbolKind::Struct),
824 ENUM => HighlightTag::Enum, 842 ENUM => HighlightTag::Symbol(SymbolKind::Enum),
825 UNION => HighlightTag::Union, 843 VARIANT => HighlightTag::Symbol(SymbolKind::Variant),
826 TRAIT => HighlightTag::Trait, 844 UNION => HighlightTag::Symbol(SymbolKind::Union),
827 TYPE_ALIAS => HighlightTag::TypeAlias, 845 TRAIT => HighlightTag::Symbol(SymbolKind::Trait),
828 TYPE_PARAM => HighlightTag::TypeParam, 846 TYPE_ALIAS => HighlightTag::Symbol(SymbolKind::TypeAlias),
829 RECORD_FIELD => HighlightTag::Field, 847 TYPE_PARAM => HighlightTag::Symbol(SymbolKind::TypeParam),
830 MODULE => HighlightTag::Module, 848 RECORD_FIELD => HighlightTag::Symbol(SymbolKind::Field),
831 FN => HighlightTag::Function, 849 MODULE => HighlightTag::Symbol(SymbolKind::Module),
832 CONST => HighlightTag::Constant, 850 FN => HighlightTag::Symbol(SymbolKind::Function),
833 STATIC => HighlightTag::Static, 851 CONST => HighlightTag::Symbol(SymbolKind::Const),
834 VARIANT => HighlightTag::EnumVariant, 852 STATIC => HighlightTag::Symbol(SymbolKind::Static),
835 IDENT_PAT => HighlightTag::Local, 853 IDENT_PAT => HighlightTag::Symbol(SymbolKind::Local),
836 _ => default, 854 _ => default,
837 }; 855 };
838 856
@@ -851,10 +869,10 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
851 METHOD_CALL_EXPR => { 869 METHOD_CALL_EXPR => {
852 return ast::MethodCallExpr::cast(parent) 870 return ast::MethodCallExpr::cast(parent)
853 .and_then(|method_call| highlight_method_call(sema, &method_call)) 871 .and_then(|method_call| highlight_method_call(sema, &method_call))
854 .unwrap_or_else(|| HighlightTag::Function.into()); 872 .unwrap_or_else(|| HighlightTag::Symbol(SymbolKind::Function).into());
855 } 873 }
856 FIELD_EXPR => { 874 FIELD_EXPR => {
857 let h = HighlightTag::Field; 875 let h = HighlightTag::Symbol(SymbolKind::Field);
858 let is_union = ast::FieldExpr::cast(parent) 876 let is_union = ast::FieldExpr::cast(parent)
859 .and_then(|field_expr| { 877 .and_then(|field_expr| {
860 let field = sema.resolve_field(&field_expr)?; 878 let field = sema.resolve_field(&field_expr)?;
@@ -881,9 +899,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
881 _ => { 899 _ => {
882 // within path, decide whether it is module or adt by checking for uppercase name 900 // within path, decide whether it is module or adt by checking for uppercase name
883 return if name.text().chars().next().unwrap_or_default().is_uppercase() { 901 return if name.text().chars().next().unwrap_or_default().is_uppercase() {
884 HighlightTag::Struct 902 HighlightTag::Symbol(SymbolKind::Struct)
885 } else { 903 } else {
886 HighlightTag::Module 904 HighlightTag::Symbol(SymbolKind::Module)
887 } 905 }
888 .into(); 906 .into();
889 } 907 }
@@ -894,11 +912,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
894 }; 912 };
895 913
896 match parent.kind() { 914 match parent.kind() {
897 CALL_EXPR => HighlightTag::Function.into(), 915 CALL_EXPR => HighlightTag::Symbol(SymbolKind::Function).into(),
898 _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { 916 _ => if name.text().chars().next().unwrap_or_default().is_uppercase() {
899 HighlightTag::Struct.into() 917 HighlightTag::Symbol(SymbolKind::Struct)
900 } else { 918 } else {
901 HighlightTag::Constant 919 HighlightTag::Symbol(SymbolKind::Const)
902 } 920 }
903 .into(), 921 .into(),
904 } 922 }
diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs
index 42f27df5d..26416022b 100644
--- a/crates/ide/src/syntax_highlighting/format.rs
+++ b/crates/ide/src/syntax_highlighting/format.rs
@@ -4,7 +4,9 @@ use syntax::{
4 AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, 4 AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange,
5}; 5};
6 6
7use crate::{syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange}; 7use crate::{
8 syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange, SymbolKind,
9};
8 10
9#[derive(Default)] 11#[derive(Default)]
10pub(super) struct FormatStringHighlighter { 12pub(super) struct FormatStringHighlighter {
@@ -71,6 +73,6 @@ fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HighlightTag> {
71 | FormatSpecifier::Asterisk 73 | FormatSpecifier::Asterisk
72 | FormatSpecifier::QuestionMark => HighlightTag::FormatSpecifier, 74 | FormatSpecifier::QuestionMark => HighlightTag::FormatSpecifier,
73 FormatSpecifier::Integer | FormatSpecifier::Zero => HighlightTag::NumericLiteral, 75 FormatSpecifier::Integer | FormatSpecifier::Zero => HighlightTag::NumericLiteral,
74 FormatSpecifier::Identifier => HighlightTag::Local, 76 FormatSpecifier::Identifier => HighlightTag::Symbol(SymbolKind::Local),
75 }) 77 })
76} 78}
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/injection.rs
index e97d1be1a..9eb184c74 100644
--- a/crates/ide/src/syntax_highlighting/injection.rs
+++ b/crates/ide/src/syntax_highlighting/injection.rs
@@ -179,6 +179,5 @@ pub(super) fn highlight_doc_comment(
179 stack.add(comment); 179 stack.add(comment);
180 } 180 }
181 stack.pop_and_inject(None); 181 stack.pop_and_inject(None);
182 stack 182 stack.pop_and_inject(Some(Highlight::from(HighlightTag::Dummy) | HighlightModifier::Injected));
183 .pop_and_inject(Some(Highlight::from(HighlightTag::Generic) | HighlightModifier::Injected));
184} 183}
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index ffd9588b8..974f54fa0 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -3,6 +3,8 @@
3 3
4use std::{fmt, ops}; 4use std::{fmt, ops};
5 5
6use crate::SymbolKind;
7
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
7pub struct Highlight { 9pub struct Highlight {
8 pub tag: HighlightTag, 10 pub tag: HighlightTag,
@@ -14,40 +16,25 @@ pub struct HighlightModifiers(u32);
14 16
15#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 17#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub enum HighlightTag { 18pub enum HighlightTag {
17 Attribute, 19 Symbol(SymbolKind),
20
18 BoolLiteral, 21 BoolLiteral,
19 BuiltinType, 22 BuiltinType,
20 ByteLiteral, 23 ByteLiteral,
21 CharLiteral, 24 CharLiteral,
25 NumericLiteral,
26 StringLiteral,
27 Attribute,
22 Comment, 28 Comment,
23 Constant,
24 Enum,
25 EnumVariant,
26 EscapeSequence, 29 EscapeSequence,
27 Field, 30 FormatSpecifier,
28 Function,
29 Generic,
30 Keyword, 31 Keyword,
31 Lifetime,
32 Macro,
33 Method,
34 Module,
35 NumericLiteral,
36 Punctuation, 32 Punctuation,
37 SelfKeyword,
38 SelfType,
39 Static,
40 StringLiteral,
41 Struct,
42 Trait,
43 TypeAlias,
44 TypeParam,
45 Union,
46 ValueParam,
47 Local,
48 UnresolvedReference,
49 FormatSpecifier,
50 Operator, 33 Operator,
34 UnresolvedReference,
35
36 // For things which don't have proper Tag, but want to use modifiers.
37 Dummy,
51} 38}
52 39
53#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 40#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@@ -64,48 +51,53 @@ pub enum HighlightModifier {
64 Injected, 51 Injected,
65 Mutable, 52 Mutable,
66 Consuming, 53 Consuming,
67 Unsafe,
68 Callable, 54 Callable,
69 /// Used for associated functions 55 /// Used for associated functions
70 Static, 56 Static,
57 /// Used for items in impls&traits.
58 Associated,
59
60 /// Keep this last!
61 Unsafe,
71} 62}
72 63
73impl HighlightTag { 64impl HighlightTag {
74 fn as_str(self) -> &'static str { 65 fn as_str(self) -> &'static str {
75 match self { 66 match self {
67 HighlightTag::Symbol(symbol) => match symbol {
68 SymbolKind::Const => "constant",
69 SymbolKind::Static => "static",
70 SymbolKind::Enum => "enum",
71 SymbolKind::Variant => "enum_variant",
72 SymbolKind::Struct => "struct",
73 SymbolKind::Union => "union",
74 SymbolKind::Field => "field",
75 SymbolKind::Module => "module",
76 SymbolKind::Trait => "trait",
77 SymbolKind::Function => "function",
78 SymbolKind::TypeAlias => "type_alias",
79 SymbolKind::TypeParam => "type_param",
80 SymbolKind::LifetimeParam => "lifetime",
81 SymbolKind::Macro => "macro",
82 SymbolKind::Local => "variable",
83 SymbolKind::ValueParam => "value_param",
84 SymbolKind::SelfParam => "self_keyword",
85 SymbolKind::Impl => "self_type",
86 },
76 HighlightTag::Attribute => "attribute", 87 HighlightTag::Attribute => "attribute",
77 HighlightTag::BoolLiteral => "bool_literal", 88 HighlightTag::BoolLiteral => "bool_literal",
78 HighlightTag::BuiltinType => "builtin_type", 89 HighlightTag::BuiltinType => "builtin_type",
79 HighlightTag::ByteLiteral => "byte_literal", 90 HighlightTag::ByteLiteral => "byte_literal",
80 HighlightTag::CharLiteral => "char_literal", 91 HighlightTag::CharLiteral => "char_literal",
81 HighlightTag::Comment => "comment", 92 HighlightTag::Comment => "comment",
82 HighlightTag::Constant => "constant",
83 HighlightTag::Enum => "enum",
84 HighlightTag::EnumVariant => "enum_variant",
85 HighlightTag::EscapeSequence => "escape_sequence", 93 HighlightTag::EscapeSequence => "escape_sequence",
86 HighlightTag::Field => "field",
87 HighlightTag::FormatSpecifier => "format_specifier", 94 HighlightTag::FormatSpecifier => "format_specifier",
88 HighlightTag::Function => "function", 95 HighlightTag::Dummy => "dummy",
89 HighlightTag::Generic => "generic",
90 HighlightTag::Keyword => "keyword", 96 HighlightTag::Keyword => "keyword",
91 HighlightTag::Lifetime => "lifetime",
92 HighlightTag::Punctuation => "punctuation", 97 HighlightTag::Punctuation => "punctuation",
93 HighlightTag::Macro => "macro",
94 HighlightTag::Method => "method",
95 HighlightTag::Module => "module",
96 HighlightTag::NumericLiteral => "numeric_literal", 98 HighlightTag::NumericLiteral => "numeric_literal",
97 HighlightTag::Operator => "operator", 99 HighlightTag::Operator => "operator",
98 HighlightTag::SelfKeyword => "self_keyword",
99 HighlightTag::SelfType => "self_type",
100 HighlightTag::Static => "static",
101 HighlightTag::StringLiteral => "string_literal", 100 HighlightTag::StringLiteral => "string_literal",
102 HighlightTag::Struct => "struct",
103 HighlightTag::Trait => "trait",
104 HighlightTag::TypeAlias => "type_alias",
105 HighlightTag::TypeParam => "type_param",
106 HighlightTag::Union => "union",
107 HighlightTag::ValueParam => "value_param",
108 HighlightTag::Local => "variable",
109 HighlightTag::UnresolvedReference => "unresolved_reference", 101 HighlightTag::UnresolvedReference => "unresolved_reference",
110 } 102 }
111 } 103 }
@@ -118,7 +110,7 @@ impl fmt::Display for HighlightTag {
118} 110}
119 111
120impl HighlightModifier { 112impl HighlightModifier {
121 const ALL: &'static [HighlightModifier] = &[ 113 const ALL: &'static [HighlightModifier; HighlightModifier::Unsafe as u8 as usize + 1] = &[
122 HighlightModifier::Attribute, 114 HighlightModifier::Attribute,
123 HighlightModifier::ControlFlow, 115 HighlightModifier::ControlFlow,
124 HighlightModifier::Definition, 116 HighlightModifier::Definition,
@@ -126,9 +118,10 @@ impl HighlightModifier {
126 HighlightModifier::Injected, 118 HighlightModifier::Injected,
127 HighlightModifier::Mutable, 119 HighlightModifier::Mutable,
128 HighlightModifier::Consuming, 120 HighlightModifier::Consuming,
129 HighlightModifier::Unsafe,
130 HighlightModifier::Callable, 121 HighlightModifier::Callable,
131 HighlightModifier::Static, 122 HighlightModifier::Static,
123 HighlightModifier::Associated,
124 HighlightModifier::Unsafe,
132 ]; 125 ];
133 126
134 fn as_str(self) -> &'static str { 127 fn as_str(self) -> &'static str {
@@ -143,6 +136,7 @@ impl HighlightModifier {
143 HighlightModifier::Unsafe => "unsafe", 136 HighlightModifier::Unsafe => "unsafe",
144 HighlightModifier::Callable => "callable", 137 HighlightModifier::Callable => "callable",
145 HighlightModifier::Static => "static", 138 HighlightModifier::Static => "static",
139 HighlightModifier::Associated => "associated",
146 } 140 }
147 } 141 }
148 142
@@ -209,6 +203,10 @@ impl ops::BitOr<HighlightModifier> for Highlight {
209} 203}
210 204
211impl HighlightModifiers { 205impl HighlightModifiers {
206 pub fn contains(self, m: HighlightModifier) -> bool {
207 self.0 & m.mask() == m.mask()
208 }
209
212 pub fn iter(self) -> impl Iterator<Item = HighlightModifier> { 210 pub fn iter(self) -> impl Iterator<Item = HighlightModifier> {
213 HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask()) 211 HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask())
214 } 212 }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
index 6fb606a47..db6f32d33 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
@@ -40,17 +40,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
40<span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="punctuation">{</span><span class="punctuation">}</span> 40<span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="punctuation">{</span><span class="punctuation">}</span>
41 41
42<span class="keyword">impl</span> <span class="struct">foo</span> <span class="punctuation">{</span> 42<span class="keyword">impl</span> <span class="struct">foo</span> <span class="punctuation">{</span>
43 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration static">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 43 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
44 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 44 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
45<span class="punctuation">}</span> 45<span class="punctuation">}</span>
46 46
47<span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="punctuation">{</span> 47<span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="punctuation">{</span>
48 <span class="keyword">fn</span> <span class="method declaration static">t_is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 48 <span class="keyword">fn</span> <span class="function declaration static associated">t_is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
49 <span class="keyword">fn</span> <span class="method declaration">t_is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 49 <span class="keyword">fn</span> <span class="function declaration associated">t_is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
50<span class="punctuation">}</span> 50<span class="punctuation">}</span>
51 51
52<span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="punctuation">{</span> 52<span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="punctuation">{</span>
53 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration static">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 53 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
54 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 54 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
55<span class="punctuation">}</span> 55<span class="punctuation">}</span>
56 </code></pre> \ No newline at end of file 56 </code></pre> \ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index 920956b51..4e511baa9 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -36,24 +36,24 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; } 36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
37</style> 37</style>
38<pre><code><span class="comment documentation">/// ```</span> 38<pre><code><span class="comment documentation">/// ```</span>
39<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="punctuation injected">_</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="punctuation injected">;</span><span class="punctuation injected"> 39<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="punctuation injected">_</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="punctuation injected">;</span><span class="punctuation injected">
40</span><span class="comment documentation">/// ```</span> 40</span><span class="comment documentation">/// ```</span>
41<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> 41<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span>
42 <span class="field declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span><span class="punctuation">,</span> 42 <span class="field declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span><span class="punctuation">,</span>
43<span class="punctuation">}</span> 43<span class="punctuation">}</span>
44 44
45<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> 45<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
46 <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="punctuation">;</span> 46 <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration associated">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="punctuation">;</span>
47 47
48 <span class="comment documentation">/// Constructs a new `Foo`.</span> 48 <span class="comment documentation">/// Constructs a new `Foo`.</span>
49 <span class="comment documentation">///</span> 49 <span class="comment documentation">///</span>
50 <span class="comment documentation">/// # Examples</span> 50 <span class="comment documentation">/// # Examples</span>
51 <span class="comment documentation">///</span> 51 <span class="comment documentation">///</span>
52 <span class="comment documentation">/// ```</span> 52 <span class="comment documentation">/// ```</span>
53 <span class="comment documentation">/// #</span><span class="generic injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="punctuation attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="punctuation attribute injected">)</span><span class="attribute attribute injected">]</span> 53 <span class="comment documentation">/// #</span><span class="dummy injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="punctuation attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="punctuation attribute injected">)</span><span class="attribute attribute injected">]</span>
54 <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="punctuation injected">:</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> 54 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="keyword injected">mut</span><span class="dummy injected"> </span><span class="variable declaration injected mutable">foo</span><span class="punctuation injected">:</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected">
55</span> <span class="comment documentation">/// ```</span> 55</span> <span class="comment documentation">/// ```</span>
56 <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="method declaration static">new</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="punctuation">{</span> 56 <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration static associated">new</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
57 <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">bar</span><span class="punctuation">:</span> <span class="bool_literal">true</span> <span class="punctuation">}</span> 57 <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">bar</span><span class="punctuation">:</span> <span class="bool_literal">true</span> <span class="punctuation">}</span>
58 <span class="punctuation">}</span> 58 <span class="punctuation">}</span>
59 59
@@ -62,32 +62,32 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
62 <span class="comment documentation">/// # Examples</span> 62 <span class="comment documentation">/// # Examples</span>
63 <span class="comment documentation">///</span> 63 <span class="comment documentation">///</span>
64 <span class="comment documentation">/// ```</span> 64 <span class="comment documentation">/// ```</span>
65 <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="generic injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="punctuation injected">;</span> 65 <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="dummy injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="punctuation injected">;</span>
66 <span class="comment documentation">///</span> 66 <span class="comment documentation">///</span>
67 <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="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> 67 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">foo</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span>
68 <span class="comment documentation">///</span> 68 <span class="comment documentation">///</span>
69 <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span> 69 <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span>
70 <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="punctuation injected">(</span><span class="generic injected">foo</span><span class="operator injected">.</span><span class="generic injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> 70 <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="punctuation injected">(</span><span class="dummy injected">foo</span><span class="operator injected">.</span><span class="dummy injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span>
71 <span class="comment documentation">///</span> 71 <span class="comment documentation">///</span>
72 <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="operator injected">=</span><span class="generic injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="generic injected"> </span><span class="operator injected">||</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="punctuation injected">;</span> 72 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">bar</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="dummy injected"> </span><span class="operator injected">||</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="punctuation injected">;</span>
73 <span class="comment documentation">///</span> 73 <span class="comment documentation">///</span>
74 <span class="comment documentation">/// </span><span class="comment injected">/* multi-line 74 <span class="comment documentation">/// </span><span class="comment injected">/* multi-line
75 </span><span class="comment documentation">/// </span><span class="comment injected"> comment */</span> 75 </span><span class="comment documentation">/// </span><span class="comment injected"> comment */</span>
76 <span class="comment documentation">///</span> 76 <span class="comment documentation">///</span>
77 <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="operator injected">=</span><span class="generic injected"> </span><span class="string_literal injected">"Foo 77 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="string_literal injected">"Foo
78 </span><span class="comment documentation">/// </span><span class="string_literal injected"> bar 78 </span><span class="comment documentation">/// </span><span class="string_literal injected"> bar
79 </span><span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="punctuation injected">;</span> 79 </span><span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="punctuation injected">;</span>
80 <span class="comment documentation">///</span> 80 <span class="comment documentation">///</span>
81 <span class="comment documentation">/// ```</span> 81 <span class="comment documentation">/// ```</span>
82 <span class="comment documentation">///</span> 82 <span class="comment documentation">///</span>
83 <span class="comment documentation">/// ```rust,no_run</span> 83 <span class="comment documentation">/// ```rust,no_run</span>
84 <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="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> 84 <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">foobar</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected">
85</span> <span class="comment documentation">/// ```</span> 85</span> <span class="comment documentation">/// ```</span>
86 <span class="comment documentation">///</span> 86 <span class="comment documentation">///</span>
87 <span class="comment documentation">/// ```sh</span> 87 <span class="comment documentation">/// ```sh</span>
88 <span class="comment documentation">/// echo 1</span> 88 <span class="comment documentation">/// echo 1</span>
89 <span class="comment documentation">/// ```</span> 89 <span class="comment documentation">/// ```</span>
90 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="punctuation">{</span> 90 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="punctuation">{</span>
91 <span class="bool_literal">true</span> 91 <span class="bool_literal">true</span>
92 <span class="punctuation">}</span> 92 <span class="punctuation">}</span>
93<span class="punctuation">}</span> 93<span class="punctuation">}</span>
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
index 31daf2bd0..7f18ad297 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -40,7 +40,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
40<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> 40<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
41 <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span> 41 <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span>
42 <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="punctuation">{</span> 42 <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="punctuation">{</span>
43 <span class="keyword">fn</span> <span class="method declaration static">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> 43 <span class="keyword">fn</span> <span class="function declaration static associated">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
44 <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="punctuation">,</span> <span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">;</span> 44 <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="punctuation">,</span> <span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">;</span>
45 <span class="punctuation">}</span> 45 <span class="punctuation">}</span>
46 <span class="punctuation">}</span><span class="string_literal">"#</span> 46 <span class="punctuation">}</span><span class="string_literal">"#</span>
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
index 67ec73f15..d26f48516 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -45,7 +45,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
45<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span> 45<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span>
46 46
47<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span> 47<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span>
48 <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="method declaration unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 48 <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
49<span class="punctuation">}</span> 49<span class="punctuation">}</span>
50 50
51<span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span> 51<span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span>
@@ -60,11 +60,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
60<span class="punctuation">}</span> 60<span class="punctuation">}</span>
61 61
62<span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="punctuation">{</span> 62<span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="punctuation">{</span>
63 <span class="keyword">fn</span> <span class="method declaration">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span><span class="punctuation">;</span> 63 <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span><span class="punctuation">;</span>
64<span class="punctuation">}</span> 64<span class="punctuation">}</span>
65 65
66<span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="punctuation">{</span> 66<span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="punctuation">{</span>
67 <span class="keyword">fn</span> <span class="method declaration">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 67 <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
68<span class="punctuation">}</span> 68<span class="punctuation">}</span>
69 69
70<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> 70<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
@@ -78,7 +78,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
78 <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> 78 <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
79 <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">a</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> 79 <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">a</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
80 <span class="punctuation">}</span> 80 <span class="punctuation">}</span>
81 <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="method unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 81 <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="function associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
82 82
83 <span class="comment">// unsafe deref</span> 83 <span class="comment">// unsafe deref</span>
84 <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="variable">x</span><span class="punctuation">;</span> 84 <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="variable">x</span><span class="punctuation">;</span>
@@ -94,6 +94,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
94 <span class="keyword">let</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">_a</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="punctuation">;</span> 94 <span class="keyword">let</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">_a</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="punctuation">;</span>
95 95
96 <span class="comment">// unsafe auto ref of packed field</span> 96 <span class="comment">// unsafe auto ref of packed field</span>
97 <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="method unsafe">calls_autoref</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 97 <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="function associated unsafe">calls_autoref</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
98 <span class="punctuation">}</span> 98 <span class="punctuation">}</span>
99<span class="punctuation">}</span></code></pre> \ No newline at end of file 99<span class="punctuation">}</span></code></pre> \ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 3530a5fdb..588e86a34 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -65,25 +65,25 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
65<span class="punctuation">}</span> 65<span class="punctuation">}</span>
66 66
67<span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span> 67<span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span>
68 <span class="keyword">fn</span> <span class="method declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="punctuation">;</span> 68 <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="punctuation">;</span>
69<span class="punctuation">}</span> 69<span class="punctuation">}</span>
70 70
71<span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span> 71<span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
72 <span class="keyword">fn</span> <span class="method declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> 72 <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
73 <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> 73 <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
74 <span class="punctuation">}</span> 74 <span class="punctuation">}</span>
75<span class="punctuation">}</span> 75<span class="punctuation">}</span>
76 76
77<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> 77<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
78 <span class="keyword">fn</span> <span class="method declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> 78 <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
79 <span class="value_param">f</span><span class="operator">.</span><span class="method consuming">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span> 79 <span class="value_param">f</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span>
80 <span class="punctuation">}</span> 80 <span class="punctuation">}</span>
81 81
82 <span class="keyword">fn</span> <span class="method declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> 82 <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
83 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> 83 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
84 <span class="punctuation">}</span> 84 <span class="punctuation">}</span>
85 85
86 <span class="keyword">fn</span> <span class="method declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> 86 <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
87 <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> 87 <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
88 <span class="punctuation">}</span> 88 <span class="punctuation">}</span>
89<span class="punctuation">}</span> 89<span class="punctuation">}</span>
@@ -94,15 +94,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
94<span class="punctuation">}</span> 94<span class="punctuation">}</span>
95 95
96<span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> 96<span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span>
97 <span class="keyword">fn</span> <span class="method declaration">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">FooCopy</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> 97 <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">FooCopy</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
98 <span class="value_param">f</span><span class="operator">.</span><span class="method">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span> 98 <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span>
99 <span class="punctuation">}</span> 99 <span class="punctuation">}</span>
100 100
101 <span class="keyword">fn</span> <span class="method declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> 101 <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
102 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> 102 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
103 <span class="punctuation">}</span> 103 <span class="punctuation">}</span>
104 104
105 <span class="keyword">fn</span> <span class="method declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> 105 <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
106 <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> 106 <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
107 <span class="punctuation">}</span> 107 <span class="punctuation">}</span>
108<span class="punctuation">}</span> 108<span class="punctuation">}</span>
@@ -178,17 +178,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
178 178
179 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> 179 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
180 <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> 180 <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
181 <span class="variable mutable">foo</span><span class="operator">.</span><span class="method">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 181 <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
182 <span class="variable mutable">foo</span><span class="operator">.</span><span class="method mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 182 <span class="variable mutable">foo</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
183 <span class="variable mutable">foo</span><span class="operator">.</span><span class="method consuming">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span> 183 <span class="variable mutable">foo</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span>
184 184
185 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> <span class="field">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> 185 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> <span class="field">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
186 <span class="variable mutable">copy</span><span class="operator">.</span><span class="method">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 186 <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
187 <span class="variable mutable">copy</span><span class="operator">.</span><span class="method mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 187 <span class="variable mutable">copy</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
188 <span class="variable mutable">copy</span><span class="operator">.</span><span class="method">baz</span><span class="punctuation">(</span><span class="variable mutable">copy</span><span class="punctuation">)</span><span class="punctuation">;</span> 188 <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="variable mutable">copy</span><span class="punctuation">)</span><span class="punctuation">;</span>
189 189
190 <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="punctuation">;</span> 190 <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="punctuation">;</span>
191 <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="method">baz</span><span class="punctuation">;</span> 191 <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="function associated">baz</span><span class="punctuation">;</span>
192 192
193 <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span> 193 <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span>
194 <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span> 194 <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span>
@@ -203,7 +203,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
203<span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span> 203<span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span>
204 204
205<span class="keyword">impl</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span> 205<span class="keyword">impl</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
206 <span class="keyword">fn</span> <span class="method declaration">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span> 206 <span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
207 <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span> 207 <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span>
208 <span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> 208 <span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
209 <span class="variable declaration">Nope</span> <span class="operator">=&gt;</span> <span class="variable">Nope</span><span class="punctuation">,</span> 209 <span class="variable declaration">Nope</span> <span class="operator">=&gt;</span> <span class="variable">Nope</span><span class="punctuation">,</span>
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index 9be36d59b..d6b498be3 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -9,7 +9,7 @@ use syntax::{
9 ast::{ 9 ast::{
10 self, 10 self,
11 edit::{AstNodeEdit, IndentLevel}, 11 edit::{AstNodeEdit, IndentLevel},
12 make, AstNode, PathSegmentKind, VisibilityOwner, 12 make, AstNode, AttrsOwner, PathSegmentKind, VisibilityOwner,
13 }, 13 },
14 AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, 14 AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken,
15}; 15};
@@ -180,6 +180,15 @@ fn eq_visibility(vis0: Option<ast::Visibility>, vis1: Option<ast::Visibility>) -
180 } 180 }
181} 181}
182 182
183fn eq_attrs(
184 attrs0: impl Iterator<Item = ast::Attr>,
185 attrs1: impl Iterator<Item = ast::Attr>,
186) -> bool {
187 let attrs0 = attrs0.map(|attr| attr.to_string());
188 let attrs1 = attrs1.map(|attr| attr.to_string());
189 attrs0.eq(attrs1)
190}
191
183pub fn try_merge_imports( 192pub fn try_merge_imports(
184 lhs: &ast::Use, 193 lhs: &ast::Use,
185 rhs: &ast::Use, 194 rhs: &ast::Use,
@@ -189,6 +198,10 @@ pub fn try_merge_imports(
189 if !eq_visibility(lhs.visibility(), rhs.visibility()) { 198 if !eq_visibility(lhs.visibility(), rhs.visibility()) {
190 return None; 199 return None;
191 } 200 }
201 if !eq_attrs(lhs.attrs(), rhs.attrs()) {
202 return None;
203 }
204
192 let lhs_tree = lhs.use_tree()?; 205 let lhs_tree = lhs.use_tree()?;
193 let rhs_tree = rhs.use_tree()?; 206 let rhs_tree = rhs.use_tree()?;
194 let merged = try_merge_trees(&lhs_tree, &rhs_tree, merge_behavior)?; 207 let merged = try_merge_trees(&lhs_tree, &rhs_tree, merge_behavior)?;
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs
index 9e194354e..a603fe87f 100644
--- a/crates/ide_db/src/helpers/insert_use/tests.rs
+++ b/crates/ide_db/src/helpers/insert_use/tests.rs
@@ -448,6 +448,20 @@ use std::io;",
448} 448}
449 449
450#[test] 450#[test]
451fn merge_groups_skip_attributed() {
452 check_full(
453 "std::io",
454 r#"
455#[cfg(feature = "gated")] use std::fmt::{Result, Display};
456"#,
457 r#"
458#[cfg(feature = "gated")] use std::fmt::{Result, Display};
459use std::io;
460"#,
461 )
462}
463
464#[test]
451#[ignore] // FIXME: Support this 465#[ignore] // FIXME: Support this
452fn split_out_merge() { 466fn split_out_merge() {
453 check_last( 467 check_last(
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs
index ca455fa03..0aa6a0765 100644
--- a/crates/ide_db/src/symbol_index.rs
+++ b/crates/ide_db/src/symbol_index.rs
@@ -39,7 +39,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
39use syntax::{ 39use syntax::{
40 ast::{self, NameOwner}, 40 ast::{self, NameOwner},
41 match_ast, AstNode, Parse, SmolStr, SourceFile, 41 match_ast, AstNode, Parse, SmolStr, SourceFile,
42 SyntaxKind::{self, *}, 42 SyntaxKind::*,
43 SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent, 43 SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent,
44}; 44};
45 45
@@ -323,7 +323,7 @@ impl Query {
323 let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value); 323 let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value);
324 324
325 for symbol in &symbol_index.symbols[start..end] { 325 for symbol in &symbol_index.symbols[start..end] {
326 if self.only_types && !is_type(symbol.kind) { 326 if self.only_types && !symbol.kind.is_type() {
327 continue; 327 continue;
328 } 328 }
329 if self.exact && symbol.name != self.query { 329 if self.exact && symbol.name != self.query {
@@ -341,23 +341,44 @@ impl Query {
341 } 341 }
342} 342}
343 343
344fn is_type(kind: SyntaxKind) -> bool {
345 matches!(kind, STRUCT | ENUM | TRAIT | TYPE_ALIAS)
346}
347
348/// The actual data that is stored in the index. It should be as compact as 344/// The actual data that is stored in the index. It should be as compact as
349/// possible. 345/// possible.
350#[derive(Debug, Clone, PartialEq, Eq, Hash)] 346#[derive(Debug, Clone, PartialEq, Eq, Hash)]
351pub struct FileSymbol { 347pub struct FileSymbol {
352 pub file_id: FileId, 348 pub file_id: FileId,
353 pub name: SmolStr, 349 pub name: SmolStr,
354 pub kind: SyntaxKind, 350 pub kind: FileSymbolKind,
355 pub range: TextRange, 351 pub range: TextRange,
356 pub ptr: SyntaxNodePtr, 352 pub ptr: SyntaxNodePtr,
357 pub name_range: Option<TextRange>, 353 pub name_range: Option<TextRange>,
358 pub container_name: Option<SmolStr>, 354 pub container_name: Option<SmolStr>,
359} 355}
360 356
357#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
358pub enum FileSymbolKind {
359 Function,
360 Struct,
361 Enum,
362 Trait,
363 Module,
364 TypeAlias,
365 Const,
366 Static,
367 Macro,
368}
369
370impl FileSymbolKind {
371 fn is_type(self: FileSymbolKind) -> bool {
372 matches!(
373 self,
374 FileSymbolKind::Struct
375 | FileSymbolKind::Enum
376 | FileSymbolKind::Trait
377 | FileSymbolKind::TypeAlias
378 )
379 }
380}
381
361fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec<FileSymbol> { 382fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec<FileSymbol> {
362 let mut symbols = Vec::new(); 383 let mut symbols = Vec::new();
363 let mut stack = Vec::new(); 384 let mut stack = Vec::new();
@@ -412,7 +433,18 @@ fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> {
412fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> { 433fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> {
413 to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol { 434 to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol {
414 name, 435 name,
415 kind: node.kind(), 436 kind: match node.kind() {
437 FN => FileSymbolKind::Function,
438 STRUCT => FileSymbolKind::Struct,
439 ENUM => FileSymbolKind::Enum,
440 TRAIT => FileSymbolKind::Trait,
441 MODULE => FileSymbolKind::Module,
442 TYPE_ALIAS => FileSymbolKind::TypeAlias,
443 CONST => FileSymbolKind::Const,
444 STATIC => FileSymbolKind::Static,
445 MACRO_RULES => FileSymbolKind::Macro,
446 kind => unreachable!("{:?}", kind),
447 },
416 range: node.text_range(), 448 range: node.text_range(),
417 ptr, 449 ptr,
418 file_id, 450 file_id,
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 23039eba4..1a078f6b4 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -133,6 +133,10 @@ pub(crate) mod fragments {
133 133
134 m.complete(p, MACRO_STMTS); 134 m.complete(p, MACRO_STMTS);
135 } 135 }
136
137 pub(crate) fn attr(p: &mut Parser) {
138 attributes::outer_attrs(p)
139 }
136} 140}
137 141
138pub(crate) fn reparser( 142pub(crate) fn reparser(
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index 41e62116f..ab8e4c70e 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -99,6 +99,8 @@ pub enum FragmentKind {
99 // FIXME: use separate fragment kinds for macro inputs and outputs? 99 // FIXME: use separate fragment kinds for macro inputs and outputs?
100 Items, 100 Items,
101 Statements, 101 Statements,
102
103 Attr,
102} 104}
103 105
104pub fn parse_fragment( 106pub fn parse_fragment(
@@ -118,6 +120,7 @@ pub fn parse_fragment(
118 FragmentKind::Statement => grammar::fragments::stmt, 120 FragmentKind::Statement => grammar::fragments::stmt,
119 FragmentKind::Items => grammar::fragments::macro_items, 121 FragmentKind::Items => grammar::fragments::macro_items,
120 FragmentKind::Statements => grammar::fragments::macro_stmts, 122 FragmentKind::Statements => grammar::fragments::macro_stmts,
123 FragmentKind::Attr => grammar::fragments::attr,
121 }; 124 };
122 parse_from_tokens(token_source, tree_sink, parser) 125 parse_from_tokens(token_source, tree_sink, parser)
123} 126}
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index af226c109..66f8bee99 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -9,7 +9,7 @@ use std::{
9 9
10use ide::{ 10use ide::{
11 CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, 11 CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData,
12 NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit, 12 NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, SymbolKind, TextEdit,
13}; 13};
14use itertools::Itertools; 14use itertools::Itertools;
15use lsp_server::ErrorCode; 15use lsp_server::ErrorCode;
@@ -27,7 +27,7 @@ use project_model::TargetKind;
27use serde::{Deserialize, Serialize}; 27use serde::{Deserialize, Serialize};
28use serde_json::to_value; 28use serde_json::to_value;
29use stdx::{format_to, split_once}; 29use stdx::{format_to, split_once};
30use syntax::{algo, ast, AstNode, SyntaxKind, TextRange, TextSize}; 30use syntax::{algo, ast, AstNode, TextRange, TextSize};
31 31
32use crate::{ 32use crate::{
33 cargo_target_spec::CargoTargetSpec, 33 cargo_target_spec::CargoTargetSpec,
@@ -385,7 +385,10 @@ pub(crate) fn handle_workspace_symbol(
385 #[allow(deprecated)] 385 #[allow(deprecated)]
386 let info = SymbolInformation { 386 let info = SymbolInformation {
387 name: nav.name.to_string(), 387 name: nav.name.to_string(),
388 kind: to_proto::symbol_kind(nav.kind), 388 kind: nav
389 .kind
390 .map(to_proto::symbol_kind)
391 .unwrap_or(lsp_types::SymbolKind::Variable),
389 tags: None, 392 tags: None,
390 location: to_proto::location_from_nav(snap, nav)?, 393 location: to_proto::location_from_nav(snap, nav)?,
391 container_name, 394 container_name,
@@ -1037,10 +1040,10 @@ pub(crate) fn handle_code_lens(
1037 .filter(|it| { 1040 .filter(|it| {
1038 matches!( 1041 matches!(
1039 it.kind, 1042 it.kind,
1040 SyntaxKind::TRAIT 1043 SymbolKind::Trait
1041 | SyntaxKind::STRUCT 1044 | SymbolKind::Struct
1042 | SyntaxKind::ENUM 1045 | SymbolKind::Enum
1043 | SyntaxKind::UNION 1046 | SymbolKind::Union
1044 ) 1047 )
1045 }) 1048 })
1046 .map(|it| { 1049 .map(|it| {
@@ -1263,7 +1266,7 @@ pub(crate) fn handle_call_hierarchy_prepare(
1263 let RangeInfo { range: _, info: navs } = nav_info; 1266 let RangeInfo { range: _, info: navs } = nav_info;
1264 let res = navs 1267 let res = navs
1265 .into_iter() 1268 .into_iter()
1266 .filter(|it| it.kind == SyntaxKind::FN) 1269 .filter(|it| it.kind == Some(SymbolKind::Function))
1267 .map(|it| to_proto::call_hierarchy_item(&snap, it)) 1270 .map(|it| to_proto::call_hierarchy_item(&snap, it))
1268 .collect::<Result<Vec<_>>>()?; 1271 .collect::<Result<Vec<_>>>()?;
1269 1272
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 72f77a016..e0561b5a7 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -5,14 +5,13 @@ use std::{
5}; 5};
6 6
7use ide::{ 7use ide::{
8 Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, 8 Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, FileId,
9 FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange, 9 FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag,
10 Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget, 10 HighlightedRange, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup,
11 ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit, 11 NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange,
12 SourceFileEdit, SymbolKind, TextEdit, TextRange, TextSize,
12}; 13};
13use ide_db::base_db::{FileId, FileRange};
14use itertools::Itertools; 14use itertools::Itertools;
15use syntax::{SyntaxKind, TextRange, TextSize};
16 15
17use crate::{ 16use crate::{
18 cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, 17 cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot,
@@ -30,21 +29,25 @@ pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Rang
30 lsp_types::Range::new(start, end) 29 lsp_types::Range::new(start, end)
31} 30}
32 31
33pub(crate) fn symbol_kind(syntax_kind: SyntaxKind) -> lsp_types::SymbolKind { 32pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind {
34 match syntax_kind { 33 match symbol_kind {
35 SyntaxKind::FN => lsp_types::SymbolKind::Function, 34 SymbolKind::Function => lsp_types::SymbolKind::Function,
36 SyntaxKind::STRUCT => lsp_types::SymbolKind::Struct, 35 SymbolKind::Struct => lsp_types::SymbolKind::Struct,
37 SyntaxKind::ENUM => lsp_types::SymbolKind::Enum, 36 SymbolKind::Enum => lsp_types::SymbolKind::Enum,
38 SyntaxKind::VARIANT => lsp_types::SymbolKind::EnumMember, 37 SymbolKind::Variant => lsp_types::SymbolKind::EnumMember,
39 SyntaxKind::TRAIT => lsp_types::SymbolKind::Interface, 38 SymbolKind::Trait => lsp_types::SymbolKind::Interface,
40 SyntaxKind::MACRO_CALL => lsp_types::SymbolKind::Function, 39 SymbolKind::Macro => lsp_types::SymbolKind::Function,
41 SyntaxKind::MODULE => lsp_types::SymbolKind::Module, 40 SymbolKind::Module => lsp_types::SymbolKind::Module,
42 SyntaxKind::TYPE_ALIAS => lsp_types::SymbolKind::TypeParameter, 41 SymbolKind::TypeAlias | SymbolKind::TypeParam => lsp_types::SymbolKind::TypeParameter,
43 SyntaxKind::RECORD_FIELD => lsp_types::SymbolKind::Field, 42 SymbolKind::Field => lsp_types::SymbolKind::Field,
44 SyntaxKind::STATIC => lsp_types::SymbolKind::Constant, 43 SymbolKind::Static => lsp_types::SymbolKind::Constant,
45 SyntaxKind::CONST => lsp_types::SymbolKind::Constant, 44 SymbolKind::Const => lsp_types::SymbolKind::Constant,
46 SyntaxKind::IMPL => lsp_types::SymbolKind::Object, 45 SymbolKind::Impl => lsp_types::SymbolKind::Object,
47 _ => lsp_types::SymbolKind::Variable, 46 SymbolKind::Local
47 | SymbolKind::SelfParam
48 | SymbolKind::LifetimeParam
49 | SymbolKind::ValueParam => lsp_types::SymbolKind::Variable,
50 SymbolKind::Union => lsp_types::SymbolKind::Struct,
48 } 51 }
49} 52}
50 53
@@ -369,34 +372,41 @@ fn semantic_token_type_and_modifiers(
369) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) { 372) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) {
370 let mut mods = semantic_tokens::ModifierSet::default(); 373 let mut mods = semantic_tokens::ModifierSet::default();
371 let type_ = match highlight.tag { 374 let type_ = match highlight.tag {
372 HighlightTag::Struct => lsp_types::SemanticTokenType::STRUCT, 375 HighlightTag::Symbol(symbol) => match symbol {
373 HighlightTag::Enum => lsp_types::SemanticTokenType::ENUM, 376 SymbolKind::Module => lsp_types::SemanticTokenType::NAMESPACE,
374 HighlightTag::Union => semantic_tokens::UNION, 377 SymbolKind::Impl => lsp_types::SemanticTokenType::TYPE,
375 HighlightTag::TypeAlias => semantic_tokens::TYPE_ALIAS, 378 SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY,
376 HighlightTag::Trait => lsp_types::SemanticTokenType::INTERFACE, 379 SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER,
380 SymbolKind::LifetimeParam => semantic_tokens::LIFETIME,
381 SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER,
382 SymbolKind::SelfParam => semantic_tokens::SELF_KEYWORD,
383 SymbolKind::Local => lsp_types::SemanticTokenType::VARIABLE,
384 SymbolKind::Function => {
385 if highlight.modifiers.contains(HighlightModifier::Associated) {
386 lsp_types::SemanticTokenType::METHOD
387 } else {
388 lsp_types::SemanticTokenType::FUNCTION
389 }
390 }
391 SymbolKind::Const => {
392 mods |= semantic_tokens::CONSTANT;
393 mods |= lsp_types::SemanticTokenModifier::STATIC;
394 lsp_types::SemanticTokenType::VARIABLE
395 }
396 SymbolKind::Static => {
397 mods |= lsp_types::SemanticTokenModifier::STATIC;
398 lsp_types::SemanticTokenType::VARIABLE
399 }
400 SymbolKind::Struct => lsp_types::SemanticTokenType::STRUCT,
401 SymbolKind::Enum => lsp_types::SemanticTokenType::ENUM,
402 SymbolKind::Variant => lsp_types::SemanticTokenType::ENUM_MEMBER,
403 SymbolKind::Union => semantic_tokens::UNION,
404 SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
405 SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
406 SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
407 },
377 HighlightTag::BuiltinType => semantic_tokens::BUILTIN_TYPE, 408 HighlightTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
378 HighlightTag::SelfKeyword => semantic_tokens::SELF_KEYWORD, 409 HighlightTag::Dummy => semantic_tokens::GENERIC,
379 HighlightTag::SelfType => lsp_types::SemanticTokenType::TYPE,
380 HighlightTag::Field => lsp_types::SemanticTokenType::PROPERTY,
381 HighlightTag::Function => lsp_types::SemanticTokenType::FUNCTION,
382 HighlightTag::Generic => semantic_tokens::GENERIC,
383 HighlightTag::Module => lsp_types::SemanticTokenType::NAMESPACE,
384 HighlightTag::Method => lsp_types::SemanticTokenType::METHOD,
385 HighlightTag::Constant => {
386 mods |= semantic_tokens::CONSTANT;
387 mods |= lsp_types::SemanticTokenModifier::STATIC;
388 lsp_types::SemanticTokenType::VARIABLE
389 }
390 HighlightTag::Static => {
391 mods |= lsp_types::SemanticTokenModifier::STATIC;
392 lsp_types::SemanticTokenType::VARIABLE
393 }
394 HighlightTag::EnumVariant => lsp_types::SemanticTokenType::ENUM_MEMBER,
395 HighlightTag::Macro => lsp_types::SemanticTokenType::MACRO,
396 HighlightTag::ValueParam => lsp_types::SemanticTokenType::PARAMETER,
397 HighlightTag::Local => lsp_types::SemanticTokenType::VARIABLE,
398 HighlightTag::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER,
399 HighlightTag::Lifetime => semantic_tokens::LIFETIME,
400 HighlightTag::ByteLiteral | HighlightTag::NumericLiteral => { 410 HighlightTag::ByteLiteral | HighlightTag::NumericLiteral => {
401 lsp_types::SemanticTokenType::NUMBER 411 lsp_types::SemanticTokenType::NUMBER
402 } 412 }
@@ -426,6 +436,7 @@ fn semantic_token_type_and_modifiers(
426 HighlightModifier::Unsafe => semantic_tokens::UNSAFE, 436 HighlightModifier::Unsafe => semantic_tokens::UNSAFE,
427 HighlightModifier::Callable => semantic_tokens::CALLABLE, 437 HighlightModifier::Callable => semantic_tokens::CALLABLE,
428 HighlightModifier::Static => lsp_types::SemanticTokenModifier::STATIC, 438 HighlightModifier::Static => lsp_types::SemanticTokenModifier::STATIC,
439 HighlightModifier::Associated => continue,
429 }; 440 };
430 mods |= modifier; 441 mods |= modifier;
431 } 442 }
@@ -719,7 +730,7 @@ pub(crate) fn call_hierarchy_item(
719) -> Result<lsp_types::CallHierarchyItem> { 730) -> Result<lsp_types::CallHierarchyItem> {
720 let name = target.name.to_string(); 731 let name = target.name.to_string();
721 let detail = target.description.clone(); 732 let detail = target.description.clone();
722 let kind = symbol_kind(target.kind); 733 let kind = target.kind.map(symbol_kind).unwrap_or(lsp_types::SymbolKind::Function);
723 let (uri, range, selection_range) = location_info(snap, target)?; 734 let (uri, range, selection_range) = location_info(snap, target)?;
724 Ok(lsp_types::CallHierarchyItem { 735 Ok(lsp_types::CallHierarchyItem {
725 name, 736 name,
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 16b079c42..ba7e5d2fb 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -20,6 +20,9 @@ pub fn name_ref(text: &str) -> ast::NameRef {
20pub fn ty(text: &str) -> ast::Type { 20pub fn ty(text: &str) -> ast::Type {
21 ast_from_text(&format!("impl {} for D {{}};", text)) 21 ast_from_text(&format!("impl {} for D {{}};", text))
22} 22}
23pub fn ty_unit() -> ast::Type {
24 ty("()")
25}
23 26
24pub fn assoc_item_list() -> ast::AssocItemList { 27pub fn assoc_item_list() -> ast::AssocItemList {
25 ast_from_text("impl C for D {};") 28 ast_from_text("impl C for D {};")
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index e753b11bb..4d272f367 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -205,6 +205,13 @@ impl ast::Type {
205 } 205 }
206} 206}
207 207
208impl ast::Attr {
209 /// Returns `text`, parsed as an attribute, but only if it has no errors.
210 pub fn parse(text: &str) -> Result<Self, ()> {
211 parsing::parse_text_fragment(text, parser::FragmentKind::Attr)
212 }
213}
214
208/// Matches a `SyntaxNode` against an `ast` type. 215/// Matches a `SyntaxNode` against an `ast` type.
209/// 216///
210/// # Example: 217/// # Example:
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 2f3dde8ac..191960960 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -132,6 +132,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
132 ctx.pushCleanup(activateTaskProvider(workspaceFolder, ctx.config)); 132 ctx.pushCleanup(activateTaskProvider(workspaceFolder, ctx.config));
133 133
134 activateInlayHints(ctx); 134 activateInlayHints(ctx);
135 warnAboutRustLangExtensionConflict();
135 136
136 vscode.workspace.onDidChangeConfiguration( 137 vscode.workspace.onDidChangeConfiguration(
137 _ => ctx?.client?.sendNotification('workspace/didChangeConfiguration', { settings: "" }), 138 _ => ctx?.client?.sendNotification('workspace/didChangeConfiguration', { settings: "" }),
@@ -399,3 +400,13 @@ async function queryForGithubToken(state: PersistentState): Promise<void> {
399 await state.updateGithubToken(newToken); 400 await state.updateGithubToken(newToken);
400 } 401 }
401} 402}
403
404function warnAboutRustLangExtensionConflict() {
405 const rustLangExt = vscode.extensions.getExtension("rust-lang.rust");
406 if (rustLangExt !== undefined) {
407 vscode.window.showWarningMessage(
408 "You have both rust-analyzer (matklad.rust-analyzer) and Rust (rust-lang.rust) " +
409 "plugins enabled. These are known to conflict and cause various functions of " +
410 "both plugins to not work correctly. You should disable one of them.", "Got it");
411 };
412}