aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db')
-rw-r--r--crates/ide_db/src/call_info.rs10
-rw-r--r--crates/ide_db/src/call_info/tests.rs27
-rw-r--r--crates/ide_db/src/helpers.rs4
-rw-r--r--crates/ide_db/src/helpers/famous_defs_fixture.rs8
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs22
5 files changed, 63 insertions, 8 deletions
diff --git a/crates/ide_db/src/call_info.rs b/crates/ide_db/src/call_info.rs
index e583a52f4..bad277a95 100644
--- a/crates/ide_db/src/call_info.rs
+++ b/crates/ide_db/src/call_info.rs
@@ -4,8 +4,9 @@ use either::Either;
4use hir::{HasAttrs, HirDisplay, Semantics, Type}; 4use hir::{HasAttrs, HirDisplay, Semantics, Type};
5use stdx::format_to; 5use stdx::format_to;
6use syntax::{ 6use syntax::{
7 algo,
7 ast::{self, ArgListOwner, NameOwner}, 8 ast::{self, ArgListOwner, NameOwner},
8 match_ast, AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize, 9 match_ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextSize,
9}; 10};
10 11
11use crate::RootDatabase; 12use crate::RootDatabase;
@@ -43,7 +44,12 @@ pub fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo>
43 let sema = Semantics::new(db); 44 let sema = Semantics::new(db);
44 let file = sema.parse(position.file_id); 45 let file = sema.parse(position.file_id);
45 let file = file.syntax(); 46 let file = file.syntax();
46 let token = file.token_at_offset(position.offset).next()?; 47 let token = file
48 .token_at_offset(position.offset)
49 .left_biased()
50 // if the cursor is sandwiched between two space tokens and the call is unclosed
51 // this prevents us from leaving the CallExpression
52 .and_then(|tok| algo::skip_trivia_token(tok, Direction::Prev))?;
47 let token = sema.descend_into_macros(token); 53 let token = sema.descend_into_macros(token);
48 54
49 let (callable, active_parameter) = call_info_impl(&sema, token)?; 55 let (callable, active_parameter) = call_info_impl(&sema, token)?;
diff --git a/crates/ide_db/src/call_info/tests.rs b/crates/ide_db/src/call_info/tests.rs
index 281a081a3..be1cc12de 100644
--- a/crates/ide_db/src/call_info/tests.rs
+++ b/crates/ide_db/src/call_info/tests.rs
@@ -522,3 +522,30 @@ fn main(f: fn(i32, f64) -> char) {
522 "#]], 522 "#]],
523 ) 523 )
524} 524}
525
526#[test]
527fn call_info_for_unclosed_call() {
528 check(
529 r#"
530fn foo(foo: u32, bar: u32) {}
531fn main() {
532 foo($0
533}"#,
534 expect![[r#"
535 fn foo(foo: u32, bar: u32)
536 (<foo: u32>, bar: u32)
537 "#]],
538 );
539 // check with surrounding space
540 check(
541 r#"
542fn foo(foo: u32, bar: u32) {}
543fn main() {
544 foo( $0
545}"#,
546 expect![[r#"
547 fn foo(foo: u32, bar: u32)
548 (<foo: u32>, bar: u32)
549 "#]],
550 )
551}
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs
index 66798ea3a..83a665b37 100644
--- a/crates/ide_db/src/helpers.rs
+++ b/crates/ide_db/src/helpers.rs
@@ -113,6 +113,10 @@ impl FamousDefs<'_, '_> {
113 self.find_module("core:iter") 113 self.find_module("core:iter")
114 } 114 }
115 115
116 pub fn core_ops_Deref(&self) -> Option<Trait> {
117 self.find_trait("core:ops:Deref")
118 }
119
116 fn find_trait(&self, path: &str) -> Option<Trait> { 120 fn find_trait(&self, path: &str) -> Option<Trait> {
117 match self.find_def(path)? { 121 match self.find_def(path)? {
118 hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), 122 hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
diff --git a/crates/ide_db/src/helpers/famous_defs_fixture.rs b/crates/ide_db/src/helpers/famous_defs_fixture.rs
index 4d79e064e..29ae12dcf 100644
--- a/crates/ide_db/src/helpers/famous_defs_fixture.rs
+++ b/crates/ide_db/src/helpers/famous_defs_fixture.rs
@@ -112,6 +112,12 @@ pub mod ops {
112 type Output; 112 type Output;
113 extern "rust-call" fn call_once(self, args: Args) -> Self::Output; 113 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
114 } 114 }
115
116 #[lang = "deref"]
117 pub trait Deref {
118 type Target: ?Sized;
119 fn deref(&self) -> &Self::Target;
120 }
115} 121}
116 122
117pub mod option { 123pub mod option {
@@ -141,3 +147,5 @@ mod return_keyword {}
141 147
142/// Docs for prim_str 148/// Docs for prim_str
143mod prim_str {} 149mod prim_str {}
150
151pub use core::ops; \ No newline at end of file
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs
index 8ce648367..91d6a4665 100644
--- a/crates/ide_db/src/helpers/import_assets.rs
+++ b/crates/ide_db/src/helpers/import_assets.rs
@@ -436,6 +436,8 @@ fn trait_applicable_items(
436 }) 436 })
437 .collect(); 437 .collect();
438 438
439 let related_dyn_traits =
440 trait_candidate.receiver_ty.applicable_inherent_traits(db).collect::<FxHashSet<_>>();
439 let mut located_imports = FxHashSet::default(); 441 let mut located_imports = FxHashSet::default();
440 442
441 if trait_assoc_item { 443 if trait_assoc_item {
@@ -451,12 +453,16 @@ fn trait_applicable_items(
451 return None; 453 return None;
452 } 454 }
453 } 455 }
456 let located_trait = assoc.containing_trait(db)?;
457 if related_dyn_traits.contains(&located_trait) {
458 return None;
459 }
454 460
455 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); 461 let trait_item = ItemInNs::from(ModuleDef::from(located_trait));
456 let original_item = assoc_to_item(assoc); 462 let original_item = assoc_to_item(assoc);
457 located_imports.insert(LocatedImport::new( 463 located_imports.insert(LocatedImport::new(
458 mod_path(item)?, 464 mod_path(trait_item)?,
459 item, 465 trait_item,
460 original_item, 466 original_item,
461 mod_path(original_item), 467 mod_path(original_item),
462 )); 468 ));
@@ -473,11 +479,15 @@ fn trait_applicable_items(
473 |_, function| { 479 |_, function| {
474 let assoc = function.as_assoc_item(db)?; 480 let assoc = function.as_assoc_item(db)?;
475 if required_assoc_items.contains(&assoc) { 481 if required_assoc_items.contains(&assoc) {
476 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); 482 let located_trait = assoc.containing_trait(db)?;
483 if related_dyn_traits.contains(&located_trait) {
484 return None;
485 }
486 let trait_item = ItemInNs::from(ModuleDef::from(located_trait));
477 let original_item = assoc_to_item(assoc); 487 let original_item = assoc_to_item(assoc);
478 located_imports.insert(LocatedImport::new( 488 located_imports.insert(LocatedImport::new(
479 mod_path(item)?, 489 mod_path(trait_item)?,
480 item, 490 trait_item,
481 original_item, 491 original_item,
482 mod_path(original_item), 492 mod_path(original_item),
483 )); 493 ));