aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r--crates/ide_db/src/helpers/insert_use/tests.rs84
-rw-r--r--crates/ide_db/src/helpers/merge_imports.rs16
-rw-r--r--crates/ide_db/src/search.rs177
-rw-r--r--crates/ide_db/src/ty_filter.rs6
4 files changed, 164 insertions, 119 deletions
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs
index 048c213e2..248227d29 100644
--- a/crates/ide_db/src/helpers/insert_use/tests.rs
+++ b/crates/ide_db/src/helpers/insert_use/tests.rs
@@ -44,7 +44,7 @@ fn insert_not_group_empty() {
44 44
45#[test] 45#[test]
46fn insert_existing() { 46fn insert_existing() {
47 check_full("std::fs", "use std::fs;", "use std::fs;") 47 check_crate("std::fs", "use std::fs;", "use std::fs;")
48} 48}
49 49
50#[test] 50#[test]
@@ -249,7 +249,7 @@ use self::fmt;",
249 249
250#[test] 250#[test]
251fn insert_no_imports() { 251fn insert_no_imports() {
252 check_full( 252 check_crate(
253 "foo::bar", 253 "foo::bar",
254 "fn main() {}", 254 "fn main() {}",
255 r"use foo::bar; 255 r"use foo::bar;
@@ -263,7 +263,7 @@ fn insert_empty_file() {
263 cov_mark::check!(insert_group_empty_file); 263 cov_mark::check!(insert_group_empty_file);
264 // empty files will get two trailing newlines 264 // empty files will get two trailing newlines
265 // this is due to the test case insert_no_imports above 265 // this is due to the test case insert_no_imports above
266 check_full( 266 check_crate(
267 "foo::bar", 267 "foo::bar",
268 "", 268 "",
269 r"use foo::bar; 269 r"use foo::bar;
@@ -290,7 +290,7 @@ fn insert_empty_module() {
290#[test] 290#[test]
291fn insert_after_inner_attr() { 291fn insert_after_inner_attr() {
292 cov_mark::check!(insert_group_empty_inner_attr); 292 cov_mark::check!(insert_group_empty_inner_attr);
293 check_full( 293 check_crate(
294 "foo::bar", 294 "foo::bar",
295 r"#![allow(unused_imports)]", 295 r"#![allow(unused_imports)]",
296 r"#![allow(unused_imports)] 296 r"#![allow(unused_imports)]
@@ -301,7 +301,7 @@ use foo::bar;",
301 301
302#[test] 302#[test]
303fn insert_after_inner_attr2() { 303fn insert_after_inner_attr2() {
304 check_full( 304 check_crate(
305 "foo::bar", 305 "foo::bar",
306 r"#![allow(unused_imports)] 306 r"#![allow(unused_imports)]
307 307
@@ -371,12 +371,12 @@ fn main() {}"#,
371 371
372#[test] 372#[test]
373fn merge_groups() { 373fn merge_groups() {
374 check_last("std::io", r"use std::fmt;", r"use std::{fmt, io};") 374 check_module("std::io", r"use std::fmt;", r"use std::{fmt, io};")
375} 375}
376 376
377#[test] 377#[test]
378fn merge_groups_last() { 378fn merge_groups_last() {
379 check_last( 379 check_module(
380 "std::io", 380 "std::io",
381 r"use std::fmt::{Result, Display};", 381 r"use std::fmt::{Result, Display};",
382 r"use std::fmt::{Result, Display}; 382 r"use std::fmt::{Result, Display};
@@ -386,12 +386,12 @@ use std::io;",
386 386
387#[test] 387#[test]
388fn merge_last_into_self() { 388fn merge_last_into_self() {
389 check_last("foo::bar::baz", r"use foo::bar;", r"use foo::bar::{self, baz};"); 389 check_module("foo::bar::baz", r"use foo::bar;", r"use foo::bar::{self, baz};");
390} 390}
391 391
392#[test] 392#[test]
393fn merge_groups_full() { 393fn merge_groups_full() {
394 check_full( 394 check_crate(
395 "std::io", 395 "std::io",
396 r"use std::fmt::{Result, Display};", 396 r"use std::fmt::{Result, Display};",
397 r"use std::{fmt::{Result, Display}, io};", 397 r"use std::{fmt::{Result, Display}, io};",
@@ -400,17 +400,21 @@ fn merge_groups_full() {
400 400
401#[test] 401#[test]
402fn merge_groups_long_full() { 402fn merge_groups_long_full() {
403 check_full("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};") 403 check_crate("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};")
404} 404}
405 405
406#[test] 406#[test]
407fn merge_groups_long_last() { 407fn merge_groups_long_last() {
408 check_last("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};") 408 check_module(
409 "std::foo::bar::Baz",
410 r"use std::foo::bar::Qux;",
411 r"use std::foo::bar::{Baz, Qux};",
412 )
409} 413}
410 414
411#[test] 415#[test]
412fn merge_groups_long_full_list() { 416fn merge_groups_long_full_list() {
413 check_full( 417 check_crate(
414 "std::foo::bar::Baz", 418 "std::foo::bar::Baz",
415 r"use std::foo::bar::{Qux, Quux};", 419 r"use std::foo::bar::{Qux, Quux};",
416 r"use std::foo::bar::{Baz, Quux, Qux};", 420 r"use std::foo::bar::{Baz, Quux, Qux};",
@@ -419,7 +423,7 @@ fn merge_groups_long_full_list() {
419 423
420#[test] 424#[test]
421fn merge_groups_long_last_list() { 425fn merge_groups_long_last_list() {
422 check_last( 426 check_module(
423 "std::foo::bar::Baz", 427 "std::foo::bar::Baz",
424 r"use std::foo::bar::{Qux, Quux};", 428 r"use std::foo::bar::{Qux, Quux};",
425 r"use std::foo::bar::{Baz, Quux, Qux};", 429 r"use std::foo::bar::{Baz, Quux, Qux};",
@@ -428,7 +432,7 @@ fn merge_groups_long_last_list() {
428 432
429#[test] 433#[test]
430fn merge_groups_long_full_nested() { 434fn merge_groups_long_full_nested() {
431 check_full( 435 check_crate(
432 "std::foo::bar::Baz", 436 "std::foo::bar::Baz",
433 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", 437 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
434 r"use std::foo::bar::{Baz, Qux, quux::{Fez, Fizz}};", 438 r"use std::foo::bar::{Baz, Qux, quux::{Fez, Fizz}};",
@@ -437,7 +441,7 @@ fn merge_groups_long_full_nested() {
437 441
438#[test] 442#[test]
439fn merge_groups_long_last_nested() { 443fn merge_groups_long_last_nested() {
440 check_last( 444 check_module(
441 "std::foo::bar::Baz", 445 "std::foo::bar::Baz",
442 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", 446 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
443 r"use std::foo::bar::Baz; 447 r"use std::foo::bar::Baz;
@@ -447,7 +451,7 @@ use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
447 451
448#[test] 452#[test]
449fn merge_groups_full_nested_deep() { 453fn merge_groups_full_nested_deep() {
450 check_full( 454 check_crate(
451 "std::foo::bar::quux::Baz", 455 "std::foo::bar::quux::Baz",
452 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", 456 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
453 r"use std::foo::bar::{Qux, quux::{Baz, Fez, Fizz}};", 457 r"use std::foo::bar::{Qux, quux::{Baz, Fez, Fizz}};",
@@ -456,7 +460,7 @@ fn merge_groups_full_nested_deep() {
456 460
457#[test] 461#[test]
458fn merge_groups_full_nested_long() { 462fn merge_groups_full_nested_long() {
459 check_full( 463 check_crate(
460 "std::foo::bar::Baz", 464 "std::foo::bar::Baz",
461 r"use std::{foo::bar::Qux};", 465 r"use std::{foo::bar::Qux};",
462 r"use std::{foo::bar::{Baz, Qux}};", 466 r"use std::{foo::bar::{Baz, Qux}};",
@@ -465,7 +469,7 @@ fn merge_groups_full_nested_long() {
465 469
466#[test] 470#[test]
467fn merge_groups_last_nested_long() { 471fn merge_groups_last_nested_long() {
468 check_full( 472 check_crate(
469 "std::foo::bar::Baz", 473 "std::foo::bar::Baz",
470 r"use std::{foo::bar::Qux};", 474 r"use std::{foo::bar::Qux};",
471 r"use std::{foo::bar::{Baz, Qux}};", 475 r"use std::{foo::bar::{Baz, Qux}};",
@@ -474,7 +478,7 @@ fn merge_groups_last_nested_long() {
474 478
475#[test] 479#[test]
476fn merge_groups_skip_pub() { 480fn merge_groups_skip_pub() {
477 check_full( 481 check_crate(
478 "std::io", 482 "std::io",
479 r"pub use std::fmt::{Result, Display};", 483 r"pub use std::fmt::{Result, Display};",
480 r"pub use std::fmt::{Result, Display}; 484 r"pub use std::fmt::{Result, Display};
@@ -484,7 +488,7 @@ use std::io;",
484 488
485#[test] 489#[test]
486fn merge_groups_skip_pub_crate() { 490fn merge_groups_skip_pub_crate() {
487 check_full( 491 check_crate(
488 "std::io", 492 "std::io",
489 r"pub(crate) use std::fmt::{Result, Display};", 493 r"pub(crate) use std::fmt::{Result, Display};",
490 r"pub(crate) use std::fmt::{Result, Display}; 494 r"pub(crate) use std::fmt::{Result, Display};
@@ -494,7 +498,7 @@ use std::io;",
494 498
495#[test] 499#[test]
496fn merge_groups_skip_attributed() { 500fn merge_groups_skip_attributed() {
497 check_full( 501 check_crate(
498 "std::io", 502 "std::io",
499 r#" 503 r#"
500#[cfg(feature = "gated")] use std::fmt::{Result, Display}; 504#[cfg(feature = "gated")] use std::fmt::{Result, Display};
@@ -509,7 +513,7 @@ use std::io;
509#[test] 513#[test]
510#[ignore] // FIXME: Support this 514#[ignore] // FIXME: Support this
511fn split_out_merge() { 515fn split_out_merge() {
512 check_last( 516 check_module(
513 "std::fmt::Result", 517 "std::fmt::Result",
514 r"use std::{fmt, io};", 518 r"use std::{fmt, io};",
515 r"use std::fmt::{self, Result}; 519 r"use std::fmt::{self, Result};
@@ -519,29 +523,33 @@ use std::io;",
519 523
520#[test] 524#[test]
521fn merge_into_module_import() { 525fn merge_into_module_import() {
522 check_full("std::fmt::Result", r"use std::{fmt, io};", r"use std::{fmt::{self, Result}, io};") 526 check_crate("std::fmt::Result", r"use std::{fmt, io};", r"use std::{fmt::{self, Result}, io};")
523} 527}
524 528
525#[test] 529#[test]
526fn merge_groups_self() { 530fn merge_groups_self() {
527 check_full("std::fmt::Debug", r"use std::fmt;", r"use std::fmt::{self, Debug};") 531 check_crate("std::fmt::Debug", r"use std::fmt;", r"use std::fmt::{self, Debug};")
528} 532}
529 533
530#[test] 534#[test]
531fn merge_mod_into_glob() { 535fn merge_mod_into_glob() {
532 check_full("token::TokenKind", r"use token::TokenKind::*;", r"use token::TokenKind::{*, self};") 536 check_crate(
537 "token::TokenKind",
538 r"use token::TokenKind::*;",
539 r"use token::TokenKind::{*, self};",
540 )
533 // FIXME: have it emit `use token::TokenKind::{self, *}`? 541 // FIXME: have it emit `use token::TokenKind::{self, *}`?
534} 542}
535 543
536#[test] 544#[test]
537fn merge_self_glob() { 545fn merge_self_glob() {
538 check_full("self", r"use self::*;", r"use self::{*, self};") 546 check_crate("self", r"use self::*;", r"use self::{*, self};")
539 // FIXME: have it emit `use {self, *}`? 547 // FIXME: have it emit `use {self, *}`?
540} 548}
541 549
542#[test] 550#[test]
543fn merge_glob_nested() { 551fn merge_glob_nested() {
544 check_full( 552 check_crate(
545 "foo::bar::quux::Fez", 553 "foo::bar::quux::Fez",
546 r"use foo::bar::{Baz, quux::*};", 554 r"use foo::bar::{Baz, quux::*};",
547 r"use foo::bar::{Baz, quux::{self::*, Fez}};", 555 r"use foo::bar::{Baz, quux::{self::*, Fez}};",
@@ -550,7 +558,7 @@ fn merge_glob_nested() {
550 558
551#[test] 559#[test]
552fn merge_nested_considers_first_segments() { 560fn merge_nested_considers_first_segments() {
553 check_full( 561 check_crate(
554 "hir_ty::display::write_bounds_like_dyn_trait", 562 "hir_ty::display::write_bounds_like_dyn_trait",
555 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter}, method_resolution};", 563 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter}, method_resolution};",
556 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter, write_bounds_like_dyn_trait}, method_resolution};", 564 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter, write_bounds_like_dyn_trait}, method_resolution};",
@@ -559,7 +567,7 @@ fn merge_nested_considers_first_segments() {
559 567
560#[test] 568#[test]
561fn skip_merge_last_too_long() { 569fn skip_merge_last_too_long() {
562 check_last( 570 check_module(
563 "foo::bar", 571 "foo::bar",
564 r"use foo::bar::baz::Qux;", 572 r"use foo::bar::baz::Qux;",
565 r"use foo::bar; 573 r"use foo::bar;
@@ -569,7 +577,7 @@ use foo::bar::baz::Qux;",
569 577
570#[test] 578#[test]
571fn skip_merge_last_too_long2() { 579fn skip_merge_last_too_long2() {
572 check_last( 580 check_module(
573 "foo::bar::baz::Qux", 581 "foo::bar::baz::Qux",
574 r"use foo::bar;", 582 r"use foo::bar;",
575 r"use foo::bar; 583 r"use foo::bar;
@@ -592,7 +600,7 @@ fn merge_last_fail() {
592 check_merge_only_fail( 600 check_merge_only_fail(
593 r"use foo::bar::{baz::{Qux, Fez}};", 601 r"use foo::bar::{baz::{Qux, Fez}};",
594 r"use foo::bar::{baaz::{Quux, Feez}};", 602 r"use foo::bar::{baaz::{Quux, Feez}};",
595 MergeBehavior::Last, 603 MergeBehavior::Module,
596 ); 604 );
597} 605}
598 606
@@ -601,7 +609,7 @@ fn merge_last_fail1() {
601 check_merge_only_fail( 609 check_merge_only_fail(
602 r"use foo::bar::{baz::{Qux, Fez}};", 610 r"use foo::bar::{baz::{Qux, Fez}};",
603 r"use foo::bar::baaz::{Quux, Feez};", 611 r"use foo::bar::baaz::{Quux, Feez};",
604 MergeBehavior::Last, 612 MergeBehavior::Module,
605 ); 613 );
606} 614}
607 615
@@ -610,7 +618,7 @@ fn merge_last_fail2() {
610 check_merge_only_fail( 618 check_merge_only_fail(
611 r"use foo::bar::baz::{Qux, Fez};", 619 r"use foo::bar::baz::{Qux, Fez};",
612 r"use foo::bar::{baaz::{Quux, Feez}};", 620 r"use foo::bar::{baaz::{Quux, Feez}};",
613 MergeBehavior::Last, 621 MergeBehavior::Module,
614 ); 622 );
615} 623}
616 624
@@ -619,7 +627,7 @@ fn merge_last_fail3() {
619 check_merge_only_fail( 627 check_merge_only_fail(
620 r"use foo::bar::baz::{Qux, Fez};", 628 r"use foo::bar::baz::{Qux, Fez};",
621 r"use foo::bar::baaz::{Quux, Feez};", 629 r"use foo::bar::baaz::{Quux, Feez};",
622 MergeBehavior::Last, 630 MergeBehavior::Module,
623 ); 631 );
624} 632}
625 633
@@ -648,12 +656,12 @@ fn check(
648 assert_eq_text!(ra_fixture_after, &result); 656 assert_eq_text!(ra_fixture_after, &result);
649} 657}
650 658
651fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 659fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
652 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Full), false, true) 660 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Crate), false, true)
653} 661}
654 662
655fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 663fn check_module(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
656 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Last), false, true) 664 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Module), false, true)
657} 665}
658 666
659fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 667fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
diff --git a/crates/ide_db/src/helpers/merge_imports.rs b/crates/ide_db/src/helpers/merge_imports.rs
index 3f5bbef7f..af2a51a4d 100644
--- a/crates/ide_db/src/helpers/merge_imports.rs
+++ b/crates/ide_db/src/helpers/merge_imports.rs
@@ -9,19 +9,19 @@ use syntax::ast::{
9/// What type of merges are allowed. 9/// What type of merges are allowed.
10#[derive(Copy, Clone, Debug, PartialEq, Eq)] 10#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11pub enum MergeBehavior { 11pub enum MergeBehavior {
12 /// Merge everything together creating deeply nested imports. 12 /// Merge imports from the same crate into a single use statement.
13 Full, 13 Crate,
14 /// Only merge the last import level, doesn't allow import nesting. 14 /// Merge imports from the same module into a single use statement.
15 Last, 15 Module,
16} 16}
17 17
18impl MergeBehavior { 18impl MergeBehavior {
19 #[inline] 19 #[inline]
20 fn is_tree_allowed(&self, tree: &ast::UseTree) -> bool { 20 fn is_tree_allowed(&self, tree: &ast::UseTree) -> bool {
21 match self { 21 match self {
22 MergeBehavior::Full => true, 22 MergeBehavior::Crate => true,
23 // only simple single segment paths are allowed 23 // only simple single segment paths are allowed
24 MergeBehavior::Last => { 24 MergeBehavior::Module => {
25 tree.use_tree_list().is_none() && tree.path().map(path_len) <= Some(1) 25 tree.use_tree_list().is_none() && tree.path().map(path_len) <= Some(1)
26 } 26 }
27 } 27 }
@@ -137,7 +137,7 @@ fn recursive_merge(
137 None, 137 None,
138 false, 138 false,
139 ); 139 );
140 use_trees.insert(idx, make::glob_use_tree()); 140 use_trees.insert(idx, make::use_tree_glob());
141 continue; 141 continue;
142 } 142 }
143 143
@@ -153,7 +153,7 @@ fn recursive_merge(
153 } 153 }
154 } 154 }
155 Err(_) 155 Err(_)
156 if merge == MergeBehavior::Last 156 if merge == MergeBehavior::Module
157 && use_trees.len() > 0 157 && use_trees.len() > 0
158 && rhs_t.use_tree_list().is_some() => 158 && rhs_t.use_tree_list().is_some() =>
159 { 159 {
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs
index 8f899ea56..67840602b 100644
--- a/crates/ide_db/src/search.rs
+++ b/crates/ide_db/src/search.rs
@@ -233,6 +233,13 @@ impl Definition {
233 }; 233 };
234 } 234 }
235 235
236 if let Definition::SelfType(impl_) = self {
237 return match impl_.source(db).map(|src| src.value.syntax().text_range()) {
238 Some(range) => SearchScope::file_range(FileRange { file_id, range }),
239 None => SearchScope::single_file(file_id),
240 };
241 }
242
236 if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self { 243 if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self {
237 let range = match param.parent(db) { 244 let range = match param.parent(db) {
238 hir::GenericDef::Function(it) => { 245 hir::GenericDef::Function(it) => {
@@ -297,7 +304,7 @@ impl Definition {
297 } 304 }
298 305
299 pub fn usages<'a>(&'a self, sema: &'a Semantics<RootDatabase>) -> FindUsages<'a> { 306 pub fn usages<'a>(&'a self, sema: &'a Semantics<RootDatabase>) -> FindUsages<'a> {
300 FindUsages { def: self, sema, scope: None, include_self_kw_refs: false } 307 FindUsages { def: self, sema, scope: None, include_self_kw_refs: None }
301 } 308 }
302} 309}
303 310
@@ -305,12 +312,13 @@ pub struct FindUsages<'a> {
305 def: &'a Definition, 312 def: &'a Definition,
306 sema: &'a Semantics<'a, RootDatabase>, 313 sema: &'a Semantics<'a, RootDatabase>,
307 scope: Option<SearchScope>, 314 scope: Option<SearchScope>,
308 include_self_kw_refs: bool, 315 include_self_kw_refs: Option<hir::Type>,
309} 316}
310 317
311impl<'a> FindUsages<'a> { 318impl<'a> FindUsages<'a> {
312 pub fn include_self_kw_refs(mut self, include: bool) -> FindUsages<'a> { 319 /// Enable searching for `Self` when the definition is a type.
313 self.include_self_kw_refs = include; 320 pub fn include_self_refs(mut self) -> FindUsages<'a> {
321 self.include_self_kw_refs = def_to_ty(self.sema, self.def);
314 self 322 self
315 } 323 }
316 324
@@ -354,13 +362,18 @@ impl<'a> FindUsages<'a> {
354 } 362 }
355 }; 363 };
356 364
357 let name = match self.def.name(sema.db) { 365 let name = self.def.name(sema.db).or_else(|| {
358 Some(it) => it.to_string(), 366 self.include_self_kw_refs.as_ref().and_then(|ty| {
367 ty.as_adt()
368 .map(|adt| adt.name(self.sema.db))
369 .or_else(|| ty.as_builtin().map(|builtin| builtin.name()))
370 })
371 });
372 let name = match name {
373 Some(name) => name.to_string(),
359 None => return, 374 None => return,
360 }; 375 };
361 376 let name = name.as_str();
362 let pat = name.as_str();
363 let search_for_self = self.include_self_kw_refs;
364 377
365 for (file_id, search_range) in search_scope { 378 for (file_id, search_range) in search_scope {
366 let text = sema.db.file_text(file_id); 379 let text = sema.db.file_text(file_id);
@@ -369,51 +382,63 @@ impl<'a> FindUsages<'a> {
369 382
370 let tree = Lazy::new(|| sema.parse(file_id).syntax().clone()); 383 let tree = Lazy::new(|| sema.parse(file_id).syntax().clone());
371 384
372 let mut handle_match = |idx: usize| -> bool { 385 for (idx, _) in text.match_indices(name) {
373 let offset: TextSize = idx.try_into().unwrap(); 386 let offset: TextSize = idx.try_into().unwrap();
374 if !search_range.contains_inclusive(offset) { 387 if !search_range.contains_inclusive(offset) {
375 return false; 388 continue;
376 } 389 }
377 390
378 if let Some(name) = sema.find_node_at_offset_with_descend(&tree, offset) { 391 if let Some(name) = sema.find_node_at_offset_with_descend(&tree, offset) {
379 match name { 392 if match name {
380 ast::NameLike::NameRef(name_ref) => { 393 ast::NameLike::NameRef(name_ref) => self.found_name_ref(&name_ref, sink),
381 if self.found_name_ref(&name_ref, sink) { 394 ast::NameLike::Name(name) => self.found_name(&name, sink),
382 return true; 395 ast::NameLike::Lifetime(lifetime) => self.found_lifetime(&lifetime, sink),
383 } 396 } {
384 } 397 return;
385 ast::NameLike::Name(name) => {
386 if self.found_name(&name, sink) {
387 return true;
388 }
389 }
390 ast::NameLike::Lifetime(lifetime) => {
391 if self.found_lifetime(&lifetime, sink) {
392 return true;
393 }
394 }
395 } 398 }
396 } 399 }
397
398 return false;
399 };
400
401 for (idx, _) in text.match_indices(pat) {
402 if handle_match(idx) {
403 return;
404 }
405 } 400 }
406 401 if let Some(self_ty) = &self.include_self_kw_refs {
407 if search_for_self {
408 for (idx, _) in text.match_indices("Self") { 402 for (idx, _) in text.match_indices("Self") {
409 if handle_match(idx) { 403 let offset: TextSize = idx.try_into().unwrap();
410 return; 404 if !search_range.contains_inclusive(offset) {
405 continue;
406 }
407
408 if let Some(ast::NameLike::NameRef(name_ref)) =
409 sema.find_node_at_offset_with_descend(&tree, offset)
410 {
411 if self.found_self_ty_name_ref(&self_ty, &name_ref, sink) {
412 return;
413 }
411 } 414 }
412 } 415 }
413 } 416 }
414 } 417 }
415 } 418 }
416 419
420 fn found_self_ty_name_ref(
421 &self,
422 self_ty: &hir::Type,
423 name_ref: &ast::NameRef,
424 sink: &mut dyn FnMut(FileId, FileReference) -> bool,
425 ) -> bool {
426 match NameRefClass::classify(self.sema, &name_ref) {
427 Some(NameRefClass::Definition(Definition::SelfType(impl_)))
428 if impl_.self_ty(self.sema.db) == *self_ty =>
429 {
430 let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
431 let reference = FileReference {
432 range,
433 name: ast::NameLike::NameRef(name_ref.clone()),
434 access: None,
435 };
436 sink(file_id, reference)
437 }
438 _ => false,
439 }
440 }
441
417 fn found_lifetime( 442 fn found_lifetime(
418 &self, 443 &self,
419 lifetime: &ast::Lifetime, 444 lifetime: &ast::Lifetime,
@@ -429,7 +454,7 @@ impl<'a> FindUsages<'a> {
429 }; 454 };
430 sink(file_id, reference) 455 sink(file_id, reference)
431 } 456 }
432 _ => false, // not a usage 457 _ => false,
433 } 458 }
434 } 459 }
435 460
@@ -448,42 +473,35 @@ impl<'a> FindUsages<'a> {
448 }; 473 };
449 sink(file_id, reference) 474 sink(file_id, reference)
450 } 475 }
451 Some(NameRefClass::Definition(Definition::SelfType(impl_))) => { 476 Some(NameRefClass::Definition(def)) if self.include_self_kw_refs.is_some() => {
452 let ty = impl_.self_ty(self.sema.db); 477 if self.include_self_kw_refs == def_to_ty(self.sema, &def) {
453 478 let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
454 if let Some(adt) = ty.as_adt() { 479 let reference = FileReference {
455 if &Definition::ModuleDef(ModuleDef::Adt(adt)) == self.def { 480 range,
456 let FileRange { file_id, range } = 481 name: ast::NameLike::NameRef(name_ref.clone()),
457 self.sema.original_range(name_ref.syntax()); 482 access: reference_access(&def, &name_ref),
458 let reference = FileReference { 483 };
459 range, 484 sink(file_id, reference)
460 name: ast::NameLike::NameRef(name_ref.clone()), 485 } else {
461 access: None, 486 false
462 };
463 return sink(file_id, reference);
464 }
465 } 487 }
466
467 false
468 } 488 }
469 Some(NameRefClass::FieldShorthand { local_ref: local, field_ref: field }) => { 489 Some(NameRefClass::FieldShorthand { local_ref: local, field_ref: field }) => {
470 let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); 490 let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
471 let reference = match self.def { 491 let access = match self.def {
472 Definition::Field(_) if &field == self.def => FileReference { 492 Definition::Field(_) if &field == self.def => {
473 range, 493 reference_access(&field, &name_ref)
474 name: ast::NameLike::NameRef(name_ref.clone()), 494 }
475 access: reference_access(&field, &name_ref), 495 Definition::Local(l) if &local == l => {
476 }, 496 reference_access(&Definition::Local(local), &name_ref)
477 Definition::Local(l) if &local == l => FileReference { 497 }
478 range, 498 _ => return false,
479 name: ast::NameLike::NameRef(name_ref.clone()),
480 access: reference_access(&Definition::Local(local), &name_ref),
481 },
482 _ => return false, // not a usage
483 }; 499 };
500 let reference =
501 FileReference { range, name: ast::NameLike::NameRef(name_ref.clone()), access };
484 sink(file_id, reference) 502 sink(file_id, reference)
485 } 503 }
486 _ => false, // not a usage 504 _ => false,
487 } 505 }
488 } 506 }
489 507
@@ -513,11 +531,30 @@ impl<'a> FindUsages<'a> {
513 FileReference { range, name: ast::NameLike::Name(name.clone()), access: None }; 531 FileReference { range, name: ast::NameLike::Name(name.clone()), access: None };
514 sink(file_id, reference) 532 sink(file_id, reference)
515 } 533 }
516 _ => false, // not a usage 534 _ => false,
517 } 535 }
518 } 536 }
519} 537}
520 538
539fn def_to_ty(sema: &Semantics<RootDatabase>, def: &Definition) -> Option<hir::Type> {
540 match def {
541 Definition::ModuleDef(def) => match def {
542 ModuleDef::Adt(adt) => Some(adt.ty(sema.db)),
543 ModuleDef::TypeAlias(it) => Some(it.ty(sema.db)),
544 ModuleDef::BuiltinType(it) => {
545 let graph = sema.db.crate_graph();
546 let krate = graph.iter().next()?;
547 let root_file = graph[krate].root_file_id;
548 let module = sema.to_module_def(root_file)?;
549 Some(it.ty(sema.db, module))
550 }
551 _ => None,
552 },
553 Definition::SelfType(it) => Some(it.self_ty(sema.db)),
554 _ => None,
555 }
556}
557
521fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { 558fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> {
522 // Only Locals and Fields have accesses for now. 559 // Only Locals and Fields have accesses for now.
523 if !matches!(def, Definition::Local(_) | Definition::Field(_)) { 560 if !matches!(def, Definition::Local(_) | Definition::Field(_)) {
diff --git a/crates/ide_db/src/ty_filter.rs b/crates/ide_db/src/ty_filter.rs
index 988ecd060..00678bf3e 100644
--- a/crates/ide_db/src/ty_filter.rs
+++ b/crates/ide_db/src/ty_filter.rs
@@ -43,7 +43,7 @@ impl TryEnum {
43 pub fn sad_pattern(self) -> ast::Pat { 43 pub fn sad_pattern(self) -> ast::Pat {
44 match self { 44 match self {
45 TryEnum::Result => make::tuple_struct_pat( 45 TryEnum::Result => make::tuple_struct_pat(
46 make::path_unqualified(make::path_segment(make::name_ref("Err"))), 46 make::ext::ident_path("Err"),
47 iter::once(make::wildcard_pat().into()), 47 iter::once(make::wildcard_pat().into()),
48 ) 48 )
49 .into(), 49 .into(),
@@ -54,12 +54,12 @@ impl TryEnum {
54 pub fn happy_pattern(self) -> ast::Pat { 54 pub fn happy_pattern(self) -> ast::Pat {
55 match self { 55 match self {
56 TryEnum::Result => make::tuple_struct_pat( 56 TryEnum::Result => make::tuple_struct_pat(
57 make::path_unqualified(make::path_segment(make::name_ref("Ok"))), 57 make::ext::ident_path("Ok"),
58 iter::once(make::wildcard_pat().into()), 58 iter::once(make::wildcard_pat().into()),
59 ) 59 )
60 .into(), 60 .into(),
61 TryEnum::Option => make::tuple_struct_pat( 61 TryEnum::Option => make::tuple_struct_pat(
62 make::path_unqualified(make::path_segment(make::name_ref("Some"))), 62 make::ext::ident_path("Some"),
63 iter::once(make::wildcard_pat().into()), 63 iter::once(make::wildcard_pat().into()),
64 ) 64 )
65 .into(), 65 .into(),