]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/completions/flyimport.rs
df27e7a848a333e08ab431d38ff1a1e82f55eb25
[rust.git] / crates / ide_completion / src / completions / flyimport.rs
1 //! Feature: completion with imports-on-the-fly
2 //!
3 //! When completing names in the current scope, proposes additional imports from other modules or crates,
4 //! if they can be qualified in the scope and their name contains all symbols from the completion input.
5 //!
6 //! To be considered applicable, the name must contain all input symbols in the given order, not necessarily adjacent.
7 //! If any input symbol is not lowercased, the name must contain all symbols in exact case; otherwise the contaning is checked case-insensitively.
8 //!
9 //! ```
10 //! fn main() {
11 //!     pda$0
12 //! }
13 //! # pub mod std { pub mod marker { pub struct PhantomData { } } }
14 //! ```
15 //! ->
16 //! ```
17 //! use std::marker::PhantomData;
18 //!
19 //! fn main() {
20 //!     PhantomData
21 //! }
22 //! # pub mod std { pub mod marker { pub struct PhantomData { } } }
23 //! ```
24 //!
25 //! Also completes associated items, that require trait imports.
26 //! If any unresolved and/or partially-qualified path predeces the input, it will be taken into account.
27 //! Currently, only the imports with their import path ending with the whole qialifier will be proposed
28 //! (no fuzzy matching for qualifier).
29 //!
30 //! ```
31 //! mod foo {
32 //!     pub mod bar {
33 //!         pub struct Item;
34 //!
35 //!         impl Item {
36 //!             pub const TEST_ASSOC: usize = 3;
37 //!         }
38 //!     }
39 //! }
40 //!
41 //! fn main() {
42 //!     bar::Item::TEST_A$0
43 //! }
44 //! ```
45 //! ->
46 //! ```
47 //! use foo::bar;
48 //!
49 //! mod foo {
50 //!     pub mod bar {
51 //!         pub struct Item;
52 //!
53 //!         impl Item {
54 //!             pub const TEST_ASSOC: usize = 3;
55 //!         }
56 //!     }
57 //! }
58 //!
59 //! fn main() {
60 //!     bar::Item::TEST_ASSOC
61 //! }
62 //! ```
63 //!
64 //! NOTE: currently, if an assoc item comes from a trait that's not currently imported and it also has an unresolved and/or partially-qualified path,
65 //! no imports will be proposed.
66 //!
67 //! .Fuzzy search details
68 //!
69 //! To avoid an excessive amount of the results returned, completion input is checked for inclusion in the names only
70 //! (i.e. in `HashMap` in the `std::collections::HashMap` path).
71 //! For the same reasons, avoids searching for any path imports for inputs with their length less that 2 symbols
72 //! (but shows all associated items for any input length).
73 //!
74 //! .Import configuration
75 //!
76 //! It is possible to configure how use-trees are merged with the `importMergeBehavior` setting.
77 //! Mimics the corresponding behavior of the `Auto Import` feature.
78 //!
79 //! .LSP and performance implications
80 //!
81 //! The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits`
82 //! (case sensitive) resolve client capability in its client capabilities.
83 //! This way the server is able to defer the costly computations, doing them for a selected completion item only.
84 //! For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones,
85 //! which might be slow ergo the feature is automatically disabled.
86 //!
87 //! .Feature toggle
88 //!
89 //! The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.enableAutoimportCompletions` flag.
90 //! Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding
91 //! capability enabled.
92
93 use hir::ModPath;
94 use ide_db::helpers::{
95     import_assets::{ImportAssets, ImportCandidate},
96     insert_use::ImportScope,
97 };
98 use itertools::Itertools;
99 use syntax::{AstNode, SyntaxNode, T};
100
101 use crate::{
102     context::CompletionContext,
103     render::{render_resolution_with_import, RenderContext},
104     ImportEdit,
105 };
106
107 use super::Completions;
108
109 pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
110     if !ctx.config.enable_imports_on_the_fly {
111         return None;
112     }
113     if ctx.use_item_syntax.is_some()
114         || ctx.is_path_disallowed()
115         || ctx.expects_item()
116         || ctx.expects_assoc_item()
117     {
118         return None;
119     }
120     let potential_import_name = {
121         let token_kind = ctx.token.kind();
122         if matches!(token_kind, T![.] | T![::]) {
123             String::new()
124         } else {
125             ctx.token.to_string()
126         }
127     };
128
129     let _p = profile::span("import_on_the_fly").detail(|| potential_import_name.to_string());
130
131     let user_input_lowercased = potential_import_name.to_lowercase();
132     let import_assets = import_assets(ctx, potential_import_name)?;
133     let import_scope = ImportScope::find_insert_use_container_with_macros(
134         position_for_import(ctx, Some(import_assets.import_candidate()))?,
135         &ctx.sema,
136     )?;
137
138     acc.add_all(
139         import_assets
140             .search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind)
141             .into_iter()
142             .sorted_by_key(|located_import| {
143                 compute_fuzzy_completion_order_key(
144                     &located_import.import_path,
145                     &user_input_lowercased,
146                 )
147             })
148             .filter_map(|import| {
149                 render_resolution_with_import(
150                     RenderContext::new(ctx),
151                     ImportEdit { import, scope: import_scope.clone() },
152                 )
153             }),
154     );
155     Some(())
156 }
157
158 pub(crate) fn position_for_import<'a>(
159     ctx: &'a CompletionContext,
160     import_candidate: Option<&ImportCandidate>,
161 ) -> Option<&'a SyntaxNode> {
162     Some(match import_candidate {
163         Some(ImportCandidate::Path(_)) => ctx.name_ref_syntax.as_ref()?.syntax(),
164         Some(ImportCandidate::TraitAssocItem(_)) => ctx.path_qual.as_ref()?.syntax(),
165         Some(ImportCandidate::TraitMethod(_)) => ctx.dot_receiver.as_ref()?.syntax(),
166         None => ctx
167             .name_ref_syntax
168             .as_ref()
169             .map(|name_ref| name_ref.syntax())
170             .or_else(|| ctx.path_qual.as_ref().map(|path| path.syntax()))
171             .or_else(|| ctx.dot_receiver.as_ref().map(|expr| expr.syntax()))?,
172     })
173 }
174
175 fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAssets> {
176     let current_module = ctx.scope.module()?;
177     if let Some(dot_receiver) = &ctx.dot_receiver {
178         ImportAssets::for_fuzzy_method_call(
179             current_module,
180             ctx.sema.type_of_expr(dot_receiver)?,
181             fuzzy_name,
182             dot_receiver.syntax().clone(),
183         )
184     } else {
185         let fuzzy_name_length = fuzzy_name.len();
186         let approximate_node = match current_module.definition_source(ctx.db).value {
187             hir::ModuleSource::SourceFile(s) => s.syntax().clone(),
188             hir::ModuleSource::Module(m) => m.syntax().clone(),
189             hir::ModuleSource::BlockExpr(b) => b.syntax().clone(),
190         };
191         let assets_for_path = ImportAssets::for_fuzzy_path(
192             current_module,
193             ctx.path_qual.clone(),
194             fuzzy_name,
195             &ctx.sema,
196             approximate_node,
197         )?;
198
199         if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_))
200             && fuzzy_name_length < 2
201         {
202             cov_mark::hit!(ignore_short_input_for_path);
203             None
204         } else {
205             Some(assets_for_path)
206         }
207     }
208 }
209
210 fn compute_fuzzy_completion_order_key(
211     proposed_mod_path: &ModPath,
212     user_input_lowercased: &str,
213 ) -> usize {
214     cov_mark::hit!(certain_fuzzy_order_test);
215     let import_name = match proposed_mod_path.segments().last() {
216         Some(name) => name.to_string().to_lowercase(),
217         None => return usize::MAX,
218     };
219     match import_name.match_indices(user_input_lowercased).next() {
220         Some((first_matching_index, _)) => first_matching_index,
221         None => usize::MAX,
222     }
223 }
224
225 #[cfg(test)]
226 mod tests {
227     use expect_test::{expect, Expect};
228
229     use crate::{
230         item::CompletionKind,
231         test_utils::{check_edit, check_edit_with_config, completion_list, TEST_CONFIG},
232     };
233
234     fn check(ra_fixture: &str, expect: Expect) {
235         let actual = completion_list(ra_fixture, CompletionKind::Magic);
236         expect.assert_eq(&actual);
237     }
238
239     #[test]
240     fn function_fuzzy_completion() {
241         check_edit(
242             "stdin",
243             r#"
244 //- /lib.rs crate:dep
245 pub mod io {
246     pub fn stdin() {}
247 };
248
249 //- /main.rs crate:main deps:dep
250 fn main() {
251     stdi$0
252 }
253 "#,
254             r#"
255 use dep::io::stdin;
256
257 fn main() {
258     stdin()$0
259 }
260 "#,
261         );
262     }
263
264     #[test]
265     fn macro_fuzzy_completion() {
266         check_edit(
267             "macro_with_curlies!",
268             r#"
269 //- /lib.rs crate:dep
270 /// Please call me as macro_with_curlies! {}
271 #[macro_export]
272 macro_rules! macro_with_curlies {
273     () => {}
274 }
275
276 //- /main.rs crate:main deps:dep
277 fn main() {
278     curli$0
279 }
280 "#,
281             r#"
282 use dep::macro_with_curlies;
283
284 fn main() {
285     macro_with_curlies! {$0}
286 }
287 "#,
288         );
289     }
290
291     #[test]
292     fn struct_fuzzy_completion() {
293         check_edit(
294             "ThirdStruct",
295             r#"
296 //- /lib.rs crate:dep
297 pub struct FirstStruct;
298 pub mod some_module {
299     pub struct SecondStruct;
300     pub struct ThirdStruct;
301 }
302
303 //- /main.rs crate:main deps:dep
304 use dep::{FirstStruct, some_module::SecondStruct};
305
306 fn main() {
307     this$0
308 }
309 "#,
310             r#"
311 use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
312
313 fn main() {
314     ThirdStruct
315 }
316 "#,
317         );
318     }
319
320     #[test]
321     fn short_paths_are_ignored() {
322         cov_mark::check!(ignore_short_input_for_path);
323
324         check(
325             r#"
326 //- /lib.rs crate:dep
327 pub struct FirstStruct;
328 pub mod some_module {
329     pub struct SecondStruct;
330     pub struct ThirdStruct;
331 }
332
333 //- /main.rs crate:main deps:dep
334 use dep::{FirstStruct, some_module::SecondStruct};
335
336 fn main() {
337     t$0
338 }
339 "#,
340             expect![[r#""#]],
341         );
342     }
343
344     #[test]
345     fn fuzzy_completions_come_in_specific_order() {
346         cov_mark::check!(certain_fuzzy_order_test);
347         check(
348             r#"
349 //- /lib.rs crate:dep
350 pub struct FirstStruct;
351 pub mod some_module {
352     // already imported, omitted
353     pub struct SecondStruct;
354     // does not contain all letters from the query, omitted
355     pub struct UnrelatedOne;
356     // contains all letters from the query, but not in sequence, displayed last
357     pub struct ThiiiiiirdStruct;
358     // contains all letters from the query, but not in the beginning, displayed second
359     pub struct AfterThirdStruct;
360     // contains all letters from the query in the begginning, displayed first
361     pub struct ThirdStruct;
362 }
363
364 //- /main.rs crate:main deps:dep
365 use dep::{FirstStruct, some_module::SecondStruct};
366
367 fn main() {
368     hir$0
369 }
370 "#,
371             expect![[r#"
372                 st dep::some_module::ThirdStruct
373                 st dep::some_module::AfterThirdStruct
374                 st dep::some_module::ThiiiiiirdStruct
375             "#]],
376         );
377     }
378
379     #[test]
380     fn trait_function_fuzzy_completion() {
381         let fixture = r#"
382         //- /lib.rs crate:dep
383         pub mod test_mod {
384             pub trait TestTrait {
385                 const SPECIAL_CONST: u8;
386                 type HumbleType;
387                 fn weird_function();
388                 fn random_method(&self);
389             }
390             pub struct TestStruct {}
391             impl TestTrait for TestStruct {
392                 const SPECIAL_CONST: u8 = 42;
393                 type HumbleType = ();
394                 fn weird_function() {}
395                 fn random_method(&self) {}
396             }
397         }
398
399         //- /main.rs crate:main deps:dep
400         fn main() {
401             dep::test_mod::TestStruct::wei$0
402         }
403         "#;
404
405         check(
406             fixture,
407             expect![[r#"
408                 fn weird_function() (dep::test_mod::TestTrait) fn()
409             "#]],
410         );
411
412         check_edit(
413             "weird_function",
414             fixture,
415             r#"
416 use dep::test_mod::TestTrait;
417
418 fn main() {
419     dep::test_mod::TestStruct::weird_function()$0
420 }
421 "#,
422         );
423     }
424
425     #[test]
426     fn trait_const_fuzzy_completion() {
427         let fixture = r#"
428         //- /lib.rs crate:dep
429         pub mod test_mod {
430             pub trait TestTrait {
431                 const SPECIAL_CONST: u8;
432                 type HumbleType;
433                 fn weird_function();
434                 fn random_method(&self);
435             }
436             pub struct TestStruct {}
437             impl TestTrait for TestStruct {
438                 const SPECIAL_CONST: u8 = 42;
439                 type HumbleType = ();
440                 fn weird_function() {}
441                 fn random_method(&self) {}
442             }
443         }
444
445         //- /main.rs crate:main deps:dep
446         fn main() {
447             dep::test_mod::TestStruct::spe$0
448         }
449         "#;
450
451         check(
452             fixture,
453             expect![[r#"
454             ct SPECIAL_CONST (dep::test_mod::TestTrait)
455         "#]],
456         );
457
458         check_edit(
459             "SPECIAL_CONST",
460             fixture,
461             r#"
462 use dep::test_mod::TestTrait;
463
464 fn main() {
465     dep::test_mod::TestStruct::SPECIAL_CONST
466 }
467 "#,
468         );
469     }
470
471     #[test]
472     fn trait_method_fuzzy_completion() {
473         let fixture = r#"
474         //- /lib.rs crate:dep
475         pub mod test_mod {
476             pub trait TestTrait {
477                 const SPECIAL_CONST: u8;
478                 type HumbleType;
479                 fn weird_function();
480                 fn random_method(&self);
481             }
482             pub struct TestStruct {}
483             impl TestTrait for TestStruct {
484                 const SPECIAL_CONST: u8 = 42;
485                 type HumbleType = ();
486                 fn weird_function() {}
487                 fn random_method(&self) {}
488             }
489         }
490
491         //- /main.rs crate:main deps:dep
492         fn main() {
493             let test_struct = dep::test_mod::TestStruct {};
494             test_struct.ran$0
495         }
496         "#;
497
498         check(
499             fixture,
500             expect![[r#"
501                 me random_method() (dep::test_mod::TestTrait) fn(&self)
502             "#]],
503         );
504
505         check_edit(
506             "random_method",
507             fixture,
508             r#"
509 use dep::test_mod::TestTrait;
510
511 fn main() {
512     let test_struct = dep::test_mod::TestStruct {};
513     test_struct.random_method()$0
514 }
515 "#,
516         );
517     }
518
519     #[test]
520     fn no_trait_type_fuzzy_completion() {
521         check(
522             r#"
523 //- /lib.rs crate:dep
524 pub mod test_mod {
525     pub trait TestTrait {
526         const SPECIAL_CONST: u8;
527         type HumbleType;
528         fn weird_function();
529         fn random_method(&self);
530     }
531     pub struct TestStruct {}
532     impl TestTrait for TestStruct {
533         const SPECIAL_CONST: u8 = 42;
534         type HumbleType = ();
535         fn weird_function() {}
536         fn random_method(&self) {}
537     }
538 }
539
540 //- /main.rs crate:main deps:dep
541 fn main() {
542     dep::test_mod::TestStruct::hum$0
543 }
544 "#,
545             expect![[r#""#]],
546         );
547     }
548
549     #[test]
550     fn does_not_propose_names_in_scope() {
551         check(
552             r#"
553 //- /lib.rs crate:dep
554 pub mod test_mod {
555     pub trait TestTrait {
556         const SPECIAL_CONST: u8;
557         type HumbleType;
558         fn weird_function();
559         fn random_method(&self);
560     }
561     pub struct TestStruct {}
562     impl TestTrait for TestStruct {
563         const SPECIAL_CONST: u8 = 42;
564         type HumbleType = ();
565         fn weird_function() {}
566         fn random_method(&self) {}
567     }
568 }
569
570 //- /main.rs crate:main deps:dep
571 use dep::test_mod::TestStruct;
572 fn main() {
573     TestSt$0
574 }
575 "#,
576             expect![[r#""#]],
577         );
578     }
579
580     #[test]
581     fn does_not_propose_traits_in_scope() {
582         check(
583             r#"
584 //- /lib.rs crate:dep
585 pub mod test_mod {
586     pub trait TestTrait {
587         const SPECIAL_CONST: u8;
588         type HumbleType;
589         fn weird_function();
590         fn random_method(&self);
591     }
592     pub struct TestStruct {}
593     impl TestTrait for TestStruct {
594         const SPECIAL_CONST: u8 = 42;
595         type HumbleType = ();
596         fn weird_function() {}
597         fn random_method(&self) {}
598     }
599 }
600
601 //- /main.rs crate:main deps:dep
602 use dep::test_mod::{TestStruct, TestTrait};
603 fn main() {
604     dep::test_mod::TestStruct::hum$0
605 }
606 "#,
607             expect![[r#""#]],
608         );
609     }
610
611     #[test]
612     fn blanket_trait_impl_import() {
613         check_edit(
614             "another_function",
615             r#"
616 //- /lib.rs crate:dep
617 pub mod test_mod {
618     pub struct TestStruct {}
619     pub trait TestTrait {
620         fn another_function();
621     }
622     impl<T> TestTrait for T {
623         fn another_function() {}
624     }
625 }
626
627 //- /main.rs crate:main deps:dep
628 fn main() {
629     dep::test_mod::TestStruct::ano$0
630 }
631 "#,
632             r#"
633 use dep::test_mod::TestTrait;
634
635 fn main() {
636     dep::test_mod::TestStruct::another_function()$0
637 }
638 "#,
639         );
640     }
641
642     #[test]
643     fn zero_input_deprecated_assoc_item_completion() {
644         check(
645             r#"
646 //- /lib.rs crate:dep
647 pub mod test_mod {
648     #[deprecated]
649     pub trait TestTrait {
650         const SPECIAL_CONST: u8;
651         type HumbleType;
652         fn weird_function();
653         fn random_method(&self);
654     }
655     pub struct TestStruct {}
656     impl TestTrait for TestStruct {
657         const SPECIAL_CONST: u8 = 42;
658         type HumbleType = ();
659         fn weird_function() {}
660         fn random_method(&self) {}
661     }
662 }
663
664 //- /main.rs crate:main deps:dep
665 fn main() {
666     let test_struct = dep::test_mod::TestStruct {};
667     test_struct.$0
668 }
669         "#,
670             expect![[r#"
671                 me random_method() (dep::test_mod::TestTrait) fn(&self) DEPRECATED
672             "#]],
673         );
674
675         check(
676             r#"
677 //- /lib.rs crate:dep
678 pub mod test_mod {
679     #[deprecated]
680     pub trait TestTrait {
681         const SPECIAL_CONST: u8;
682         type HumbleType;
683         fn weird_function();
684         fn random_method(&self);
685     }
686     pub struct TestStruct {}
687     impl TestTrait for TestStruct {
688         const SPECIAL_CONST: u8 = 42;
689         type HumbleType = ();
690         fn weird_function() {}
691         fn random_method(&self) {}
692     }
693 }
694
695 //- /main.rs crate:main deps:dep
696 fn main() {
697     dep::test_mod::TestStruct::$0
698 }
699 "#,
700             expect![[r#"
701                 ct SPECIAL_CONST (dep::test_mod::TestTrait) DEPRECATED
702                 fn weird_function() (dep::test_mod::TestTrait) fn() DEPRECATED
703             "#]],
704         );
705     }
706
707     #[test]
708     fn no_completions_in_use_statements() {
709         check(
710             r#"
711 //- /lib.rs crate:dep
712 pub mod io {
713     pub fn stdin() {}
714 };
715
716 //- /main.rs crate:main deps:dep
717 use stdi$0
718
719 fn main() {}
720 "#,
721             expect![[]],
722         );
723     }
724
725     #[test]
726     fn prefix_config_usage() {
727         let fixture = r#"
728 mod foo {
729     pub mod bar {
730         pub struct Item;
731     }
732 }
733
734 use crate::foo::bar;
735
736 fn main() {
737     Ite$0
738 }"#;
739         let mut config = TEST_CONFIG;
740
741         config.insert_use.prefix_kind = hir::PrefixKind::ByCrate;
742         check_edit_with_config(
743             config.clone(),
744             "Item",
745             fixture,
746             r#"
747 mod foo {
748     pub mod bar {
749         pub struct Item;
750     }
751 }
752
753 use crate::foo::bar::{self, Item};
754
755 fn main() {
756     Item
757 }"#,
758         );
759
760         config.insert_use.prefix_kind = hir::PrefixKind::BySelf;
761         check_edit_with_config(
762             config.clone(),
763             "Item",
764             fixture,
765             r#"
766 mod foo {
767     pub mod bar {
768         pub struct Item;
769     }
770 }
771
772 use crate::foo::bar;
773
774 use self::foo::bar::Item;
775
776 fn main() {
777     Item
778 }"#,
779         );
780
781         config.insert_use.prefix_kind = hir::PrefixKind::Plain;
782         check_edit_with_config(
783             config,
784             "Item",
785             fixture,
786             r#"
787 mod foo {
788     pub mod bar {
789         pub struct Item;
790     }
791 }
792
793 use foo::bar::Item;
794
795 use crate::foo::bar;
796
797 fn main() {
798     Item
799 }"#,
800         );
801     }
802
803     #[test]
804     fn unresolved_qualifier() {
805         let fixture = r#"
806 mod foo {
807     pub mod bar {
808         pub mod baz {
809             pub struct Item;
810         }
811     }
812 }
813
814 fn main() {
815     bar::baz::Ite$0
816 }"#;
817
818         check(
819             fixture,
820             expect![[r#"
821         st foo::bar::baz::Item
822         "#]],
823         );
824
825         check_edit(
826             "Item",
827             fixture,
828             r#"
829         use foo::bar;
830
831         mod foo {
832             pub mod bar {
833                 pub mod baz {
834                     pub struct Item;
835                 }
836             }
837         }
838
839         fn main() {
840             bar::baz::Item
841         }"#,
842         );
843     }
844
845     #[test]
846     fn unresolved_assoc_item_container() {
847         let fixture = r#"
848 mod foo {
849     pub struct Item;
850
851     impl Item {
852         pub const TEST_ASSOC: usize = 3;
853     }
854 }
855
856 fn main() {
857     Item::TEST_A$0
858 }"#;
859
860         check(
861             fixture,
862             expect![[r#"
863         ct TEST_ASSOC (foo::Item)
864         "#]],
865         );
866
867         check_edit(
868             "TEST_ASSOC",
869             fixture,
870             r#"
871 use foo::Item;
872
873 mod foo {
874     pub struct Item;
875
876     impl Item {
877         pub const TEST_ASSOC: usize = 3;
878     }
879 }
880
881 fn main() {
882     Item::TEST_ASSOC
883 }"#,
884         );
885     }
886
887     #[test]
888     fn unresolved_assoc_item_container_with_path() {
889         let fixture = r#"
890 mod foo {
891     pub mod bar {
892         pub struct Item;
893
894         impl Item {
895             pub const TEST_ASSOC: usize = 3;
896         }
897     }
898 }
899
900 fn main() {
901     bar::Item::TEST_A$0
902 }"#;
903
904         check(
905             fixture,
906             expect![[r#"
907         ct TEST_ASSOC (foo::bar::Item)
908     "#]],
909         );
910
911         check_edit(
912             "TEST_ASSOC",
913             fixture,
914             r#"
915 use foo::bar;
916
917 mod foo {
918     pub mod bar {
919         pub struct Item;
920
921         impl Item {
922             pub const TEST_ASSOC: usize = 3;
923         }
924     }
925 }
926
927 fn main() {
928     bar::Item::TEST_ASSOC
929 }"#,
930         );
931     }
932
933     #[test]
934     fn fuzzy_unresolved_path() {
935         check(
936             r#"
937 mod foo {
938     pub mod bar {
939         pub struct Item;
940
941         impl Item {
942             pub const TEST_ASSOC: usize = 3;
943         }
944     }
945 }
946
947 fn main() {
948     bar::ASS$0
949 }"#,
950             expect![[]],
951         )
952     }
953
954     #[test]
955     fn unqualified_assoc_items_are_omitted() {
956         check(
957             r#"
958 mod something {
959     pub trait BaseTrait {
960         fn test_function() -> i32;
961     }
962
963     pub struct Item1;
964     pub struct Item2;
965
966     impl BaseTrait for Item1 {
967         fn test_function() -> i32 {
968             1
969         }
970     }
971
972     impl BaseTrait for Item2 {
973         fn test_function() -> i32 {
974             2
975         }
976     }
977 }
978
979 fn main() {
980     test_f$0
981 }"#,
982             expect![[]],
983         )
984     }
985
986     #[test]
987     fn case_matters() {
988         check(
989             r#"
990 mod foo {
991     pub const TEST_CONST: usize = 3;
992     pub fn test_function() -> i32 {
993         4
994     }
995 }
996
997 fn main() {
998     TE$0
999 }"#,
1000             expect![[r#"
1001         ct foo::TEST_CONST
1002     "#]],
1003         );
1004
1005         check(
1006             r#"
1007 mod foo {
1008     pub const TEST_CONST: usize = 3;
1009     pub fn test_function() -> i32 {
1010         4
1011     }
1012 }
1013
1014 fn main() {
1015     te$0
1016 }"#,
1017             expect![[r#"
1018         ct foo::TEST_CONST
1019         fn test_function() (foo::test_function) fn() -> i32
1020     "#]],
1021         );
1022
1023         check(
1024             r#"
1025 mod foo {
1026     pub const TEST_CONST: usize = 3;
1027     pub fn test_function() -> i32 {
1028         4
1029     }
1030 }
1031
1032 fn main() {
1033     Te$0
1034 }"#,
1035             expect![[]],
1036         );
1037     }
1038
1039     #[test]
1040     fn no_fuzzy_during_fields_of_record_lit_syntax() {
1041         check(
1042             r#"
1043 mod m {
1044     pub fn some_fn() -> i32 {
1045         42
1046     }
1047 }
1048 struct Foo {
1049     some_field: i32,
1050 }
1051 fn main() {
1052     let _ = Foo { so$0 };
1053 }
1054 "#,
1055             expect![[]],
1056         );
1057     }
1058
1059     #[test]
1060     fn fuzzy_after_fields_of_record_lit_syntax() {
1061         check(
1062             r#"
1063 mod m {
1064     pub fn some_fn() -> i32 {
1065         42
1066     }
1067 }
1068 struct Foo {
1069     some_field: i32,
1070 }
1071 fn main() {
1072     let _ = Foo { some_field: so$0 };
1073 }
1074 "#,
1075             expect![[r#"
1076                 fn some_fn() (m::some_fn) fn() -> i32
1077             "#]],
1078         );
1079     }
1080
1081     #[test]
1082     fn no_flyimports_in_traits_and_impl_declarations() {
1083         check(
1084             r#"
1085 mod m {
1086     pub fn some_fn() -> i32 {
1087         42
1088     }
1089 }
1090 trait Foo {
1091     som$0
1092 }
1093 "#,
1094             expect![[r#""#]],
1095         );
1096
1097         check(
1098             r#"
1099 mod m {
1100     pub fn some_fn() -> i32 {
1101         42
1102     }
1103 }
1104 struct Foo;
1105 impl Foo {
1106     som$0
1107 }
1108 "#,
1109             expect![[r#""#]],
1110         );
1111
1112         check(
1113             r#"
1114 mod m {
1115     pub fn some_fn() -> i32 {
1116         42
1117     }
1118 }
1119 struct Foo;
1120 trait Bar {}
1121 impl Bar for Foo {
1122     som$0
1123 }
1124 "#,
1125             expect![[r#""#]],
1126         );
1127     }
1128
1129     #[test]
1130     fn no_inherent_candidates_proposed() {
1131         check(
1132             r#"
1133 mod baz {
1134     pub trait DefDatabase {
1135         fn method1(&self);
1136     }
1137     pub trait HirDatabase: DefDatabase {
1138         fn method2(&self);
1139     }
1140 }
1141
1142 mod bar {
1143     fn test(db: &dyn crate::baz::HirDatabase) {
1144         db.metho$0
1145     }
1146 }
1147             "#,
1148             expect![[r#""#]],
1149         );
1150     }
1151 }