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