|  | use base_db::salsa; | 
|  | use expect_test::{Expect, expect}; | 
|  |  | 
|  | use crate::{ | 
|  | CompletionConfig, | 
|  | context::{CompletionAnalysis, NameContext, NameKind, NameRefKind}, | 
|  | tests::{TEST_CONFIG, check_edit, check_edit_with_config}, | 
|  | }; | 
|  |  | 
|  | fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { | 
|  | check_with_config(TEST_CONFIG, ra_fixture, expect); | 
|  | } | 
|  |  | 
|  | fn check_with_config( | 
|  | config: CompletionConfig<'_>, | 
|  | #[rust_analyzer::rust_fixture] ra_fixture: &str, | 
|  | expect: Expect, | 
|  | ) { | 
|  | let (db, position) = crate::tests::position(ra_fixture); | 
|  | let (ctx, analysis) = crate::context::CompletionContext::new(&db, position, &config).unwrap(); | 
|  |  | 
|  | let mut acc = crate::completions::Completions::default(); | 
|  | salsa::attach(ctx.db, || { | 
|  | if let CompletionAnalysis::Name(NameContext { kind: NameKind::IdentPat(pat_ctx), .. }) = | 
|  | &analysis | 
|  | { | 
|  | crate::completions::flyimport::import_on_the_fly_pat(&mut acc, &ctx, pat_ctx); | 
|  | } | 
|  | if let CompletionAnalysis::NameRef(name_ref_ctx) = &analysis { | 
|  | match &name_ref_ctx.kind { | 
|  | NameRefKind::Path(path) => { | 
|  | crate::completions::flyimport::import_on_the_fly_path(&mut acc, &ctx, path); | 
|  | } | 
|  | NameRefKind::DotAccess(dot_access) => { | 
|  | crate::completions::flyimport::import_on_the_fly_dot( | 
|  | &mut acc, &ctx, dot_access, | 
|  | ); | 
|  | } | 
|  | NameRefKind::Pattern(pattern) => { | 
|  | crate::completions::flyimport::import_on_the_fly_pat(&mut acc, &ctx, pattern); | 
|  | } | 
|  | _ => (), | 
|  | } | 
|  | } | 
|  | }); | 
|  |  | 
|  | expect.assert_eq(&super::render_completion_list(Vec::from(acc))); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn function_fuzzy_completion() { | 
|  | check_edit( | 
|  | "stdin", | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod io { | 
|  | pub fn stdin() {} | 
|  | }; | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | stdi$0 | 
|  | } | 
|  | "#, | 
|  | r#" | 
|  | use dep::io::stdin; | 
|  |  | 
|  | fn main() { | 
|  | stdin();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn macro_fuzzy_completion() { | 
|  | check_edit( | 
|  | "macro_with_curlies!", | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | /// Please call me as macro_with_curlies! {} | 
|  | #[macro_export] | 
|  | macro_rules! macro_with_curlies { | 
|  | () => {} | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | curli$0 | 
|  | } | 
|  | "#, | 
|  | r#" | 
|  | use dep::macro_with_curlies; | 
|  |  | 
|  | fn main() { | 
|  | macro_with_curlies! {$0} | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn struct_fuzzy_completion() { | 
|  | check_edit( | 
|  | "ThirdStruct", | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub struct FirstStruct; | 
|  | pub mod some_module { | 
|  | pub struct SecondStruct; | 
|  | pub struct ThirdStruct; | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | use dep::{FirstStruct, some_module::SecondStruct}; | 
|  |  | 
|  | fn main() { | 
|  | this$0 | 
|  | } | 
|  | "#, | 
|  | r#" | 
|  | use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}}; | 
|  |  | 
|  | fn main() { | 
|  | ThirdStruct | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn short_paths_are_prefix_matched() { | 
|  | cov_mark::check!(flyimport_prefix_on_short_path); | 
|  |  | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub struct Barc; | 
|  | pub struct Rcar; | 
|  | pub struct Rc; | 
|  | pub const RC: () = (); | 
|  | pub mod some_module { | 
|  | pub struct Bar; | 
|  | pub struct Rcar; | 
|  | pub struct Rc; | 
|  | pub const RC: () = (); | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | Rc$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | st Rc (use dep::Rc)                    Rc | 
|  | st Rcar (use dep::Rcar)              Rcar | 
|  | st Rc (use dep::some_module::Rc)       Rc | 
|  | st Rcar (use dep::some_module::Rcar) Rcar | 
|  | "#]], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub struct Barc; | 
|  | pub struct Rcar; | 
|  | pub struct Rc; | 
|  | pub const RC: () = (); | 
|  | pub mod some_module { | 
|  | pub struct Bar; | 
|  | pub struct Rcar; | 
|  | pub struct Rc; | 
|  | pub const RC: () = (); | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | rc$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | ct RC (use dep::RC)                    () | 
|  | st Rc (use dep::Rc)                    Rc | 
|  | st Rcar (use dep::Rcar)              Rcar | 
|  | ct RC (use dep::some_module::RC)       () | 
|  | st Rc (use dep::some_module::Rc)       Rc | 
|  | st Rcar (use dep::some_module::Rcar) Rcar | 
|  | "#]], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub struct Barc; | 
|  | pub struct Rcar; | 
|  | pub struct Rc; | 
|  | pub const RC: () = (); | 
|  | pub mod some_module { | 
|  | pub struct Bar; | 
|  | pub struct Rcar; | 
|  | pub struct Rc; | 
|  | pub const RC: () = (); | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | RC$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | ct RC (use dep::RC)              () | 
|  | ct RC (use dep::some_module::RC) () | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn fuzzy_completions_come_in_specific_order() { | 
|  | cov_mark::check!(certain_fuzzy_order_test); | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub struct FirstStruct; | 
|  | pub mod some_module { | 
|  | // already imported, omitted | 
|  | pub struct SecondStruct; | 
|  | // does not contain all letters from the query, omitted | 
|  | pub struct UnrelatedOne; | 
|  | // contains all letters from the query, but not in sequence, displayed last | 
|  | pub struct ThiiiiiirdStruct; | 
|  | // contains all letters from the query, but not in the beginning, displayed second | 
|  | pub struct AfterThirdStruct; | 
|  | // contains all letters from the query in the beginning, displayed first | 
|  | pub struct ThirdStruct; | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | use dep::{FirstStruct, some_module::SecondStruct}; | 
|  |  | 
|  | fn main() { | 
|  | hir$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | st ThirdStruct (use dep::some_module::ThirdStruct)                ThirdStruct | 
|  | st AfterThirdStruct (use dep::some_module::AfterThirdStruct) AfterThirdStruct | 
|  | st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct) ThiiiiiirdStruct | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_function_fuzzy_completion() { | 
|  | let fixture = r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::wei$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | fn weird_function() (use dep::test_mod::TestTrait) fn() | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "weird_function", | 
|  | fixture, | 
|  | r#" | 
|  | use dep::test_mod::TestTrait; | 
|  |  | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::weird_function();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_const_fuzzy_completion() { | 
|  | let fixture = r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::spe$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "SPECIAL_CONST", | 
|  | fixture, | 
|  | r#" | 
|  | use dep::test_mod::TestTrait; | 
|  |  | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::SPECIAL_CONST | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_method_fuzzy_completion() { | 
|  | let fixture = r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | let test_struct = dep::test_mod::TestStruct {}; | 
|  | test_struct.ran$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | me random_method() (use dep::test_mod::TestTrait) fn(&self) | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "random_method", | 
|  | fixture, | 
|  | r#" | 
|  | use dep::test_mod::TestTrait; | 
|  |  | 
|  | fn main() { | 
|  | let test_struct = dep::test_mod::TestStruct {}; | 
|  | test_struct.random_method();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_method_fuzzy_completion_aware_of_fundamental_boxes() { | 
|  | let fixture = r#" | 
|  | //- /fundamental.rs crate:fundamental | 
|  | #[lang = "owned_box"] | 
|  | #[fundamental] | 
|  | pub struct Box<T>(T); | 
|  | //- /foo.rs crate:foo | 
|  | pub trait TestTrait { | 
|  | fn some_method(&self); | 
|  | } | 
|  | //- /main.rs crate:main deps:foo,fundamental | 
|  | struct TestStruct; | 
|  |  | 
|  | impl foo::TestTrait for fundamental::Box<TestStruct> { | 
|  | fn some_method(&self) {} | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | let t = fundamental::Box(TestStruct); | 
|  | t.$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | me some_method() (use foo::TestTrait) fn(&self) | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "some_method", | 
|  | fixture, | 
|  | r#" | 
|  | use foo::TestTrait; | 
|  |  | 
|  | struct TestStruct; | 
|  |  | 
|  | impl foo::TestTrait for fundamental::Box<TestStruct> { | 
|  | fn some_method(&self) {} | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | let t = fundamental::Box(TestStruct); | 
|  | t.some_method();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_method_fuzzy_completion_aware_of_fundamental_references() { | 
|  | let fixture = r#" | 
|  | //- /foo.rs crate:foo | 
|  | pub trait TestTrait { | 
|  | fn some_method(&self); | 
|  | } | 
|  | //- /main.rs crate:main deps:foo | 
|  | struct TestStruct; | 
|  |  | 
|  | impl foo::TestTrait for &TestStruct { | 
|  | fn some_method(&self) {} | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | let t = &TestStruct; | 
|  | t.$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | me some_method() (use foo::TestTrait) fn(&self) | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "some_method", | 
|  | fixture, | 
|  | r#" | 
|  | use foo::TestTrait; | 
|  |  | 
|  | struct TestStruct; | 
|  |  | 
|  | impl foo::TestTrait for &TestStruct { | 
|  | fn some_method(&self) {} | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | let t = &TestStruct; | 
|  | t.some_method();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_completions_handle_associated_types() { | 
|  | let fixture = r#" | 
|  | //- /foo.rs crate:foo | 
|  | pub trait NotInScope { | 
|  | fn not_in_scope(&self); | 
|  | } | 
|  |  | 
|  | pub trait Wrapper { | 
|  | type Inner: NotInScope; | 
|  | fn inner(&self) -> Self::Inner; | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:foo | 
|  | use foo::Wrapper; | 
|  |  | 
|  | fn completion<T: Wrapper>(whatever: T) { | 
|  | whatever.inner().$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | me not_in_scope() (use foo::NotInScope) fn(&self) | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "not_in_scope", | 
|  | fixture, | 
|  | r#" | 
|  | use foo::{NotInScope, Wrapper}; | 
|  |  | 
|  | fn completion<T: Wrapper>(whatever: T) { | 
|  | whatever.inner().not_in_scope();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_method_fuzzy_completion_aware_of_unit_type() { | 
|  | let fixture = r#" | 
|  | //- /test_trait.rs crate:test_trait | 
|  | pub trait TestInto<T> { | 
|  | fn into(self) -> T; | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:test_trait | 
|  | struct A; | 
|  |  | 
|  | impl test_trait::TestInto<A> for () { | 
|  | fn into(self) -> A { | 
|  | A | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | let a = (); | 
|  | a.$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | me into() (use test_trait::TestInto) fn(self) -> T | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_method_from_alias() { | 
|  | let fixture = r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub trait TestTrait { | 
|  | fn random_method(); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | fn random_method() {} | 
|  | } | 
|  | pub type TestAlias = TestStruct; | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | dep::test_mod::TestAlias::ran$0 | 
|  | } | 
|  | "#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | fn random_method() (use dep::test_mod::TestTrait) fn() | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "random_method", | 
|  | fixture, | 
|  | r#" | 
|  | use dep::test_mod::TestTrait; | 
|  |  | 
|  | fn main() { | 
|  | dep::test_mod::TestAlias::random_method();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn no_trait_type_fuzzy_completion() { | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::hum$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn does_not_propose_names_in_scope() { | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | use dep::test_mod::TestStruct; | 
|  | fn main() { | 
|  | TestSt$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn does_not_propose_traits_in_scope() { | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | use dep::test_mod::{TestStruct, TestTrait}; | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::hum$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn blanket_trait_impl_import() { | 
|  | check_edit( | 
|  | "another_function", | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | pub struct TestStruct {} | 
|  | pub trait TestTrait { | 
|  | fn another_function(); | 
|  | } | 
|  | impl<T> TestTrait for T { | 
|  | fn another_function() {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::ano$0 | 
|  | } | 
|  | "#, | 
|  | r#" | 
|  | use dep::test_mod::TestTrait; | 
|  |  | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::another_function();$0 | 
|  | } | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn zero_input_deprecated_assoc_item_completion() { | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | #[deprecated] | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | let test_struct = dep::test_mod::TestStruct {}; | 
|  | test_struct.$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod test_mod { | 
|  | #[deprecated] | 
|  | pub trait TestTrait { | 
|  | const SPECIAL_CONST: u8; | 
|  | type HumbleType; | 
|  | fn weird_function(); | 
|  | fn random_method(&self); | 
|  | } | 
|  | pub struct TestStruct {} | 
|  | impl TestTrait for TestStruct { | 
|  | const SPECIAL_CONST: u8 = 42; | 
|  | type HumbleType = (); | 
|  | fn weird_function() {} | 
|  | fn random_method(&self) {} | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | dep::test_mod::TestStruct::$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | ct SPECIAL_CONST (use dep::test_mod::TestTrait)           u8 DEPRECATED | 
|  | fn weird_function() (use dep::test_mod::TestTrait)      fn() DEPRECATED | 
|  | me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn no_completions_in_use_statements() { | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod io { | 
|  | pub fn stdin() {} | 
|  | }; | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | use stdi$0 | 
|  |  | 
|  | fn main() {} | 
|  | "#, | 
|  | expect![[]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn prefix_config_usage() { | 
|  | let fixture = r#" | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  | } | 
|  | } | 
|  |  | 
|  | use crate::foo::bar; | 
|  |  | 
|  | fn main() { | 
|  | Ite$0 | 
|  | }"#; | 
|  | let mut config = TEST_CONFIG; | 
|  |  | 
|  | config.insert_use.prefix_kind = hir::PrefixKind::ByCrate; | 
|  | check_edit_with_config( | 
|  | config.clone(), | 
|  | "Item", | 
|  | fixture, | 
|  | r#" | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  | } | 
|  | } | 
|  |  | 
|  | use crate::foo::bar::{self, Item}; | 
|  |  | 
|  | fn main() { | 
|  | Item | 
|  | }"#, | 
|  | ); | 
|  |  | 
|  | config.insert_use.prefix_kind = hir::PrefixKind::BySelf; | 
|  | check_edit_with_config( | 
|  | config.clone(), | 
|  | "Item", | 
|  | fixture, | 
|  | r#" | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  | } | 
|  | } | 
|  |  | 
|  | use crate::foo::bar; | 
|  |  | 
|  | use self::foo::bar::Item; | 
|  |  | 
|  | fn main() { | 
|  | Item | 
|  | }"#, | 
|  | ); | 
|  |  | 
|  | config.insert_use.prefix_kind = hir::PrefixKind::Plain; | 
|  | check_edit_with_config( | 
|  | config, | 
|  | "Item", | 
|  | fixture, | 
|  | r#" | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  | } | 
|  | } | 
|  |  | 
|  | use foo::bar::Item; | 
|  |  | 
|  | use crate::foo::bar; | 
|  |  | 
|  | fn main() { | 
|  | Item | 
|  | }"#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn config_prefer_absolute() { | 
|  | let fixture = r#" | 
|  | //- /lib.rs crate:dep | 
|  | pub mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  | } | 
|  | } | 
|  |  | 
|  | //- /main.rs crate:main deps:dep | 
|  | use ::dep::foo::bar; | 
|  |  | 
|  | fn main() { | 
|  | Ite$0 | 
|  | }"#; | 
|  | let mut config = TEST_CONFIG; | 
|  | config.prefer_absolute = true; | 
|  |  | 
|  | check_edit_with_config( | 
|  | config.clone(), | 
|  | "Item", | 
|  | fixture, | 
|  | r#" | 
|  | use ::dep::foo::bar::{self, Item}; | 
|  |  | 
|  | fn main() { | 
|  | Item | 
|  | }"#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn unresolved_qualifier() { | 
|  | let fixture = r#" | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub mod baz { | 
|  | pub struct Item; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | bar::baz::Ite$0 | 
|  | }"#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | st Item (use foo::bar) Item | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "Item", | 
|  | fixture, | 
|  | r#" | 
|  | use foo::bar; | 
|  |  | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub mod baz { | 
|  | pub struct Item; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | bar::baz::Item | 
|  | }"#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn unresolved_assoc_item_container() { | 
|  | let fixture = r#" | 
|  | mod foo { | 
|  | pub struct Item; | 
|  |  | 
|  | impl Item { | 
|  | pub const TEST_ASSOC: usize = 3; | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | Item::TEST_A$0 | 
|  | }"#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | ct TEST_ASSOC (use foo::Item) usize | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "TEST_ASSOC", | 
|  | fixture, | 
|  | r#" | 
|  | use foo::Item; | 
|  |  | 
|  | mod foo { | 
|  | pub struct Item; | 
|  |  | 
|  | impl Item { | 
|  | pub const TEST_ASSOC: usize = 3; | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | Item::TEST_ASSOC | 
|  | }"#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn unresolved_assoc_item_container_with_path() { | 
|  | let fixture = r#" | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  |  | 
|  | impl Item { | 
|  | pub const TEST_ASSOC: usize = 3; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | bar::Item::TEST_A$0 | 
|  | }"#; | 
|  |  | 
|  | check( | 
|  | fixture, | 
|  | expect![[r#" | 
|  | ct TEST_ASSOC (use foo::bar) usize | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check_edit( | 
|  | "TEST_ASSOC", | 
|  | fixture, | 
|  | r#" | 
|  | use foo::bar; | 
|  |  | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  |  | 
|  | impl Item { | 
|  | pub const TEST_ASSOC: usize = 3; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | bar::Item::TEST_ASSOC | 
|  | }"#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn fuzzy_unresolved_path() { | 
|  | check( | 
|  | r#" | 
|  | mod foo { | 
|  | pub mod bar { | 
|  | pub struct Item; | 
|  |  | 
|  | impl Item { | 
|  | pub const TEST_ASSOC: usize = 3; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | bar::ASS$0 | 
|  | }"#, | 
|  | expect![[]], | 
|  | ) | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn unqualified_assoc_items_are_omitted() { | 
|  | check( | 
|  | r#" | 
|  | mod something { | 
|  | pub trait BaseTrait { | 
|  | fn test_function() -> i32; | 
|  | } | 
|  |  | 
|  | pub struct Item1; | 
|  | pub struct Item2; | 
|  |  | 
|  | impl BaseTrait for Item1 { | 
|  | fn test_function() -> i32 { | 
|  | 1 | 
|  | } | 
|  | } | 
|  |  | 
|  | impl BaseTrait for Item2 { | 
|  | fn test_function() -> i32 { | 
|  | 2 | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | test_f$0 | 
|  | }"#, | 
|  | expect![[]], | 
|  | ) | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn case_matters() { | 
|  | check( | 
|  | r#" | 
|  | mod foo { | 
|  | pub const TEST_CONST: usize = 3; | 
|  | pub fn test_function() -> i32 { | 
|  | 4 | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | TES$0 | 
|  | }"#, | 
|  | expect![[r#" | 
|  | ct TEST_CONST (use foo::TEST_CONST) usize | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check( | 
|  | r#" | 
|  | mod foo { | 
|  | pub const TEST_CONST: usize = 3; | 
|  | pub fn test_function() -> i32 { | 
|  | 4 | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | tes$0 | 
|  | }"#, | 
|  | expect![[r#" | 
|  | ct TEST_CONST (use foo::TEST_CONST)               usize | 
|  | fn test_function() (use foo::test_function) fn() -> i32 | 
|  | "#]], | 
|  | ); | 
|  |  | 
|  | check( | 
|  | r#" | 
|  | mod foo { | 
|  | pub const TEST_CONST: usize = 3; | 
|  | pub fn test_function() -> i32 { | 
|  | 4 | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | Tes$0 | 
|  | }"#, | 
|  | expect![""], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn no_fuzzy_during_fields_of_record_lit_syntax() { | 
|  | check( | 
|  | r#" | 
|  | mod m { | 
|  | pub fn some_fn() -> i32 { | 
|  | 42 | 
|  | } | 
|  | } | 
|  | struct Foo { | 
|  | some_field: i32, | 
|  | } | 
|  | fn main() { | 
|  | let _ = Foo { so$0 }; | 
|  | } | 
|  | "#, | 
|  | expect![[]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn fuzzy_after_fields_of_record_lit_syntax() { | 
|  | check( | 
|  | r#" | 
|  | mod m { | 
|  | pub fn some_fn() -> i32 { | 
|  | 42 | 
|  | } | 
|  | } | 
|  | struct Foo { | 
|  | some_field: i32, | 
|  | } | 
|  | fn main() { | 
|  | let _ = Foo { some_field: som$0 }; | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | fn some_fn() (use m::some_fn) fn() -> i32 | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn no_flyimports_in_traits_and_impl_declarations() { | 
|  | check( | 
|  | r#" | 
|  | mod m { | 
|  | pub fn some_fn() -> i32 { | 
|  | 42 | 
|  | } | 
|  | } | 
|  | trait Foo { | 
|  | som$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  |  | 
|  | check( | 
|  | r#" | 
|  | mod m { | 
|  | pub fn some_fn() -> i32 { | 
|  | 42 | 
|  | } | 
|  | } | 
|  | struct Foo; | 
|  | impl Foo { | 
|  | som$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  |  | 
|  | check( | 
|  | r#" | 
|  | mod m { | 
|  | pub fn some_fn() -> i32 { | 
|  | 42 | 
|  | } | 
|  | } | 
|  | struct Foo; | 
|  | trait Bar {} | 
|  | impl Bar for Foo { | 
|  | som$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn no_inherent_candidates_proposed() { | 
|  | check( | 
|  | r#" | 
|  | mod baz { | 
|  | pub trait DefDatabase { | 
|  | fn method1(&self); | 
|  | } | 
|  | pub trait HirDatabase: DefDatabase { | 
|  | fn method2(&self); | 
|  | } | 
|  | } | 
|  |  | 
|  | mod bar { | 
|  | fn test(db: &dyn crate::baz::HirDatabase) { | 
|  | db.metho$0 | 
|  | } | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | mod baz { | 
|  | pub trait DefDatabase { | 
|  | fn method1(&self); | 
|  | } | 
|  | pub trait HirDatabase: DefDatabase { | 
|  | fn method2(&self); | 
|  | } | 
|  | } | 
|  |  | 
|  | mod bar { | 
|  | fn test(db: &impl crate::baz::HirDatabase) { | 
|  | db.metho$0 | 
|  | } | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | mod baz { | 
|  | pub trait DefDatabase { | 
|  | fn method1(&self); | 
|  | } | 
|  | pub trait HirDatabase: DefDatabase { | 
|  | fn method2(&self); | 
|  | } | 
|  | } | 
|  |  | 
|  | mod bar { | 
|  | fn test<T: crate::baz::HirDatabase>(db: T) { | 
|  | db.metho$0 | 
|  | } | 
|  | } | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn respects_doc_hidden() { | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:lib deps:dep | 
|  | fn f() { | 
|  | ().fro$0 | 
|  | } | 
|  |  | 
|  | //- /dep.rs crate:dep | 
|  | #[doc(hidden)] | 
|  | pub trait Private { | 
|  | fn frob(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> Private for T {} | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | //- /lib.rs crate:lib deps:dep | 
|  | fn f() { | 
|  | ().fro$0 | 
|  | } | 
|  |  | 
|  | //- /dep.rs crate:dep | 
|  | pub trait Private { | 
|  | #[doc(hidden)] | 
|  | fn frob(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> Private for T {} | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn regression_9760() { | 
|  | check( | 
|  | r#" | 
|  | struct Struct; | 
|  | fn main() {} | 
|  |  | 
|  | mod mud { | 
|  | fn func() { | 
|  | let struct_instance = Stru$0 | 
|  | } | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | st Struct (use crate::Struct) Struct | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_pattern() { | 
|  | check( | 
|  | r#" | 
|  | mod module { | 
|  | pub struct FooStruct {} | 
|  | pub const FooConst: () = (); | 
|  | pub fn foo_fun() {} | 
|  | } | 
|  | fn function() { | 
|  | let foo$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | ct FooConst (use module::FooConst) | 
|  | st FooStruct (use module::FooStruct) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_pattern_no_unstable_item_on_stable() { | 
|  | check( | 
|  | r#" | 
|  | //- /main.rs crate:main deps:std | 
|  | fn function() { | 
|  | let foo$0 | 
|  | } | 
|  | //- /std.rs crate:std | 
|  | #[unstable] | 
|  | pub struct FooStruct {} | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_pattern_unstable_path() { | 
|  | check( | 
|  | r#" | 
|  | //- /main.rs crate:main deps:std | 
|  | fn function() { | 
|  | let foo$0 | 
|  | } | 
|  | //- /std.rs crate:std | 
|  | #[unstable] | 
|  | pub mod unstable { | 
|  | pub struct FooStruct {} | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | //- toolchain:nightly | 
|  | //- /main.rs crate:main deps:std | 
|  | fn function() { | 
|  | let foo$0 | 
|  | } | 
|  | //- /std.rs crate:std | 
|  | #[unstable] | 
|  | pub mod unstable { | 
|  | pub struct FooStruct {} | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | st FooStruct (use std::unstable::FooStruct) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_pattern_unstable_item_on_nightly() { | 
|  | check( | 
|  | r#" | 
|  | //- toolchain:nightly | 
|  | //- /main.rs crate:main deps:std | 
|  | fn function() { | 
|  | let foo$0 | 
|  | } | 
|  | //- /std.rs crate:std | 
|  | #[unstable] | 
|  | pub struct FooStruct {} | 
|  | "#, | 
|  | expect![[r#" | 
|  | st FooStruct (use std::FooStruct) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_item_name() { | 
|  | check( | 
|  | r#" | 
|  | mod module { | 
|  | pub struct Struct; | 
|  | } | 
|  | struct Str$0 | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_rename() { | 
|  | check( | 
|  | r#" | 
|  | mod module { | 
|  | pub struct Struct; | 
|  | } | 
|  | use self as Str$0; | 
|  | "#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_enum_variant() { | 
|  | check( | 
|  | r#" | 
|  | mod foo { | 
|  | pub struct Barbara; | 
|  | } | 
|  |  | 
|  | enum Foo { | 
|  | Barba$0() | 
|  | } | 
|  | }"#, | 
|  | expect![[r#""#]], | 
|  | ); | 
|  |  | 
|  | check( | 
|  | r#" | 
|  | mod foo { | 
|  | pub struct Barbara; | 
|  | } | 
|  |  | 
|  | enum Foo { | 
|  | Barba(Barba$0) | 
|  | } | 
|  | }"#, | 
|  | expect![[r#" | 
|  | st Barbara (use foo::Barbara) Barbara | 
|  | "#]], | 
|  | ) | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_attribute() { | 
|  | check( | 
|  | r#" | 
|  | //- proc_macros:identity | 
|  | #[ide$0] | 
|  | struct Foo; | 
|  | "#, | 
|  | expect![[r#" | 
|  | at identity (use proc_macros::identity) proc_macro identity | 
|  | "#]], | 
|  | ); | 
|  | check_edit( | 
|  | "identity", | 
|  | r#" | 
|  | //- proc_macros:identity | 
|  | #[ide$0] | 
|  | struct Foo; | 
|  | "#, | 
|  | r#" | 
|  | use proc_macros::identity; | 
|  |  | 
|  | #[identity] | 
|  | struct Foo; | 
|  | "#, | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_in_type_bound_omits_types() { | 
|  | check( | 
|  | r#" | 
|  | mod module { | 
|  | pub struct CompletemeStruct; | 
|  | pub type CompletemeType = (); | 
|  | pub enum CompletemeEnum {} | 
|  | pub trait CompletemeTrait {} | 
|  | } | 
|  |  | 
|  | fn f<T>() where T: Comp$0 | 
|  | "#, | 
|  | expect![[r#" | 
|  | tt CompletemeTrait (use module::CompletemeTrait) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_source_file() { | 
|  | check( | 
|  | r#" | 
|  | //- /main.rs crate:main deps:dep | 
|  | def$0 | 
|  | //- /lib.rs crate:dep | 
|  | #[macro_export] | 
|  | macro_rules! define_struct { | 
|  | () => { | 
|  | pub struct Foo; | 
|  | }; | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | ma define_struct!(…) (use dep::define_struct) macro_rules! define_struct | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn macro_use_prelude_is_in_scope() { | 
|  | check( | 
|  | r#" | 
|  | //- /main.rs crate:main deps:dep | 
|  | #[macro_use] | 
|  | extern crate dep; | 
|  |  | 
|  | fn main() { | 
|  | print$0 | 
|  | } | 
|  | //- /lib.rs crate:dep | 
|  | #[macro_export] | 
|  | macro_rules! println { | 
|  | () => {} | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ) | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn no_completions_for_external_doc_hidden_in_path() { | 
|  | check( | 
|  | r#" | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | Span$0 | 
|  | } | 
|  | //- /lib.rs crate:dep | 
|  | #[doc(hidden)] | 
|  | pub mod bridge { | 
|  | pub mod server { | 
|  | pub trait Span | 
|  | } | 
|  | } | 
|  | pub mod bridge2 { | 
|  | #[doc(hidden)] | 
|  | pub mod server2 { | 
|  | pub trait Span | 
|  | } | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | // unless re-exported | 
|  | check( | 
|  | r#" | 
|  | //- /main.rs crate:main deps:dep | 
|  | fn main() { | 
|  | Span$0 | 
|  | } | 
|  | //- /lib.rs crate:dep | 
|  | #[doc(hidden)] | 
|  | pub mod bridge { | 
|  | pub mod server { | 
|  | pub trait Span | 
|  | } | 
|  | } | 
|  | pub use bridge::server::Span; | 
|  | pub mod bridge2 { | 
|  | #[doc(hidden)] | 
|  | pub mod server2 { | 
|  | pub trait Span2 | 
|  | } | 
|  | } | 
|  | pub use bridge2::server2::Span2; | 
|  | "#, | 
|  | expect![[r#" | 
|  | tt Span (use dep::Span) | 
|  | tt Span2 (use dep::Span2) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn flyimport_only_traits_in_impl_trait_block() { | 
|  | check( | 
|  | r#" | 
|  | //- /main.rs crate:main deps:dep | 
|  | pub struct Bar; | 
|  |  | 
|  | impl Foo$0 for Bar { } | 
|  | //- /lib.rs crate:dep | 
|  | pub trait FooTrait; | 
|  |  | 
|  | pub struct FooStruct; | 
|  | "#, | 
|  | expect![[r#" | 
|  | tt FooTrait (use dep::FooTrait) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn primitive_mod() { | 
|  | check( | 
|  | r#" | 
|  | //- minicore: str | 
|  | fn main() { | 
|  | str::from$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | fn from_utf8_unchecked(…) (use core::str) const unsafe fn(&[u8]) -> &str | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn trait_impl_on_slice_method_on_deref_slice_type() { | 
|  | check( | 
|  | r#" | 
|  | //- minicore: deref, sized | 
|  | struct SliceDeref; | 
|  | impl core::ops::Deref for SliceDeref { | 
|  | type Target = [()]; | 
|  |  | 
|  | fn deref(&self) -> &Self::Target { | 
|  | &[] | 
|  | } | 
|  | } | 
|  | fn main() { | 
|  | SliceDeref.choose$0(); | 
|  | } | 
|  | mod module { | 
|  | pub(super) trait SliceRandom { | 
|  | type Item; | 
|  |  | 
|  | fn choose(&self); | 
|  | } | 
|  |  | 
|  | impl<T> SliceRandom for [T] { | 
|  | type Item = T; | 
|  |  | 
|  | fn choose(&self) {} | 
|  | } | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | me choose (use module::SliceRandom) fn(&self) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn re_export_aliased() { | 
|  | check( | 
|  | r#" | 
|  | mod outer { | 
|  | mod inner { | 
|  | pub struct BarStruct; | 
|  | pub fn bar_fun() {} | 
|  | pub mod bar {} | 
|  | } | 
|  | pub use inner::bar as foo; | 
|  | pub use inner::bar_fun as foo_fun; | 
|  | pub use inner::BarStruct as FooStruct; | 
|  | } | 
|  | fn function() { | 
|  | foo$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | st FooStruct (use outer::FooStruct) BarStruct | 
|  | md foo (use outer::foo) | 
|  | fn foo_fun() (use outer::foo_fun)        fn() | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn re_export_aliased_pattern() { | 
|  | check( | 
|  | r#" | 
|  | mod outer { | 
|  | mod inner { | 
|  | pub struct BarStruct; | 
|  | pub fn bar_fun() {} | 
|  | pub mod bar {} | 
|  | } | 
|  | pub use inner::bar as foo; | 
|  | pub use inner::bar_fun as foo_fun; | 
|  | pub use inner::BarStruct as FooStruct; | 
|  | } | 
|  | fn function() { | 
|  | let foo$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | st FooStruct (use outer::FooStruct) | 
|  | md foo (use outer::foo) | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn intrinsics() { | 
|  | check( | 
|  | r#" | 
|  | //- /core.rs crate:core | 
|  | pub mod intrinsics { | 
|  | extern "rust-intrinsic" { | 
|  | pub fn transmute<Src, Dst>(src: Src) -> Dst; | 
|  | } | 
|  | } | 
|  | pub mod mem { | 
|  | pub use crate::intrinsics::transmute; | 
|  | } | 
|  | //- /main.rs crate:main deps:core | 
|  | fn function() { | 
|  | transmute$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | fn transmute(…) (use core::mem::transmute) unsafe fn(Src) -> Dst | 
|  | "#]], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | //- /core.rs crate:core | 
|  | pub mod intrinsics { | 
|  | extern "rust-intrinsic" { | 
|  | pub fn transmute<Src, Dst>(src: Src) -> Dst; | 
|  | } | 
|  | } | 
|  | pub mod mem { | 
|  | pub use crate::intrinsics::transmute; | 
|  | } | 
|  | //- /main.rs crate:main deps:core | 
|  | fn function() { | 
|  | mem::transmute$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | fn transmute(…) (use core::mem) unsafe fn(Src) -> Dst | 
|  | "#]], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn excluded_trait_item_included_when_exact_match() { | 
|  | // FIXME: This does not work, we need to change the code. | 
|  | check_with_config( | 
|  | CompletionConfig { | 
|  | exclude_traits: &["ra_test_fixture::module2::ExcludedTrait".to_owned()], | 
|  | ..TEST_CONFIG | 
|  | }, | 
|  | r#" | 
|  | mod module2 { | 
|  | pub trait ExcludedTrait { | 
|  | fn foo(&self) {} | 
|  | fn bar(&self) {} | 
|  | fn baz(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> ExcludedTrait for T {} | 
|  | } | 
|  |  | 
|  | fn foo() { | 
|  | true.foo$0 | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn excluded_via_attr() { | 
|  | check( | 
|  | r#" | 
|  | mod module2 { | 
|  | #[rust_analyzer::completions(ignore_flyimport)] | 
|  | pub trait ExcludedTrait { | 
|  | fn foo(&self) {} | 
|  | fn bar(&self) {} | 
|  | fn baz(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> ExcludedTrait for T {} | 
|  | } | 
|  |  | 
|  | fn foo() { | 
|  | true.$0 | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | mod module2 { | 
|  | #[rust_analyzer::completions(ignore_flyimport_methods)] | 
|  | pub trait ExcludedTrait { | 
|  | fn foo(&self) {} | 
|  | fn bar(&self) {} | 
|  | fn baz(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> ExcludedTrait for T {} | 
|  | } | 
|  |  | 
|  | fn foo() { | 
|  | true.$0 | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | mod module2 { | 
|  | #[rust_analyzer::completions(ignore_methods)] | 
|  | pub trait ExcludedTrait { | 
|  | fn foo(&self) {} | 
|  | fn bar(&self) {} | 
|  | fn baz(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> ExcludedTrait for T {} | 
|  | } | 
|  |  | 
|  | fn foo() { | 
|  | true.$0 | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | mod module2 { | 
|  | #[rust_analyzer::completions(ignore_flyimport)] | 
|  | pub trait ExcludedTrait { | 
|  | fn foo(&self) {} | 
|  | fn bar(&self) {} | 
|  | fn baz(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> ExcludedTrait for T {} | 
|  | } | 
|  |  | 
|  | fn foo() { | 
|  | ExcludedTrait$0 | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | mod module2 { | 
|  | #[rust_analyzer::completions(ignore_methods)] | 
|  | pub trait ExcludedTrait { | 
|  | fn foo(&self) {} | 
|  | fn bar(&self) {} | 
|  | fn baz(&self) {} | 
|  | } | 
|  |  | 
|  | impl<T> ExcludedTrait for T {} | 
|  | } | 
|  |  | 
|  | fn foo() { | 
|  | ExcludedTrait$0 | 
|  | } | 
|  | "#, | 
|  | expect![[r#" | 
|  | tt ExcludedTrait (use module2::ExcludedTrait) | 
|  | "#]], | 
|  | ); | 
|  | check( | 
|  | r#" | 
|  | mod module2 { | 
|  | #[rust_analyzer::completions(ignore_flyimport)] | 
|  | pub struct Foo {} | 
|  | } | 
|  |  | 
|  | fn foo() { | 
|  | Foo$0 | 
|  | } | 
|  | "#, | 
|  | expect![""], | 
|  | ); | 
|  | } |