]> git.lizzy.rs Git - rust.git/blob - crates/ide_assists/src/handlers/qualify_path.rs
Work towards better import labels
[rust.git] / crates / ide_assists / src / handlers / qualify_path.rs
1 use std::iter;
2
3 use hir::AsAssocItem;
4 use ide_db::helpers::{
5     import_assets::{ImportCandidate, LocatedImport, Qualifier},
6     mod_path_to_ast,
7 };
8 use ide_db::RootDatabase;
9 use syntax::{
10     ast,
11     ast::{make, ArgListOwner},
12     AstNode,
13 };
14
15 use crate::{
16     assist_context::{AssistContext, Assists},
17     AssistId, AssistKind, GroupLabel,
18 };
19
20 use super::auto_import::find_importable_node;
21
22 // Assist: qualify_path
23 //
24 // If the name is unresolved, provides all possible qualified paths for it.
25 //
26 // ```
27 // fn main() {
28 //     let map = HashMap$0::new();
29 // }
30 // # pub mod std { pub mod collections { pub struct HashMap { } } }
31 // ```
32 // ->
33 // ```
34 // fn main() {
35 //     let map = std::collections::HashMap::new();
36 // }
37 // # pub mod std { pub mod collections { pub struct HashMap { } } }
38 // ```
39 pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
40     let (import_assets, syntax_under_caret) = find_importable_node(ctx)?;
41     let proposed_imports = import_assets.search_for_relative_paths(&ctx.sema);
42     if proposed_imports.is_empty() {
43         return None;
44     }
45
46     let candidate = import_assets.import_candidate();
47     let range = ctx.sema.original_range(&syntax_under_caret).range;
48
49     let qualify_candidate = match candidate {
50         ImportCandidate::Path(candidate) => {
51             if !matches!(candidate.qualifier, Qualifier::Absent) {
52                 cov_mark::hit!(qualify_path_qualifier_start);
53                 let path = ast::Path::cast(syntax_under_caret)?;
54                 let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?);
55                 QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list())
56             } else {
57                 cov_mark::hit!(qualify_path_unqualified_name);
58                 let path = ast::Path::cast(syntax_under_caret)?;
59                 let generics = path.segment()?.generic_arg_list();
60                 QualifyCandidate::UnqualifiedName(generics)
61             }
62         }
63         ImportCandidate::TraitAssocItem(_) => {
64             cov_mark::hit!(qualify_path_trait_assoc_item);
65             let path = ast::Path::cast(syntax_under_caret)?;
66             let (qualifier, segment) = (path.qualifier()?, path.segment()?);
67             QualifyCandidate::TraitAssocItem(qualifier, segment)
68         }
69         ImportCandidate::TraitMethod(_) => {
70             cov_mark::hit!(qualify_path_trait_method);
71             let mcall_expr = ast::MethodCallExpr::cast(syntax_under_caret)?;
72             QualifyCandidate::TraitMethod(ctx.sema.db, mcall_expr)
73         }
74     };
75
76     let group_label = group_label(candidate);
77     for import in proposed_imports {
78         acc.add_group(
79             &group_label,
80             AssistId("qualify_path", AssistKind::QuickFix),
81             label(ctx.db(), candidate, &import),
82             range,
83             |builder| {
84                 qualify_candidate.qualify(
85                     |replace_with: String| builder.replace(range, replace_with),
86                     &import.import_path,
87                     import.item_to_import,
88                 )
89             },
90         );
91     }
92     Some(())
93 }
94
95 enum QualifyCandidate<'db> {
96     QualifierStart(ast::PathSegment, Option<ast::GenericArgList>),
97     UnqualifiedName(Option<ast::GenericArgList>),
98     TraitAssocItem(ast::Path, ast::PathSegment),
99     TraitMethod(&'db RootDatabase, ast::MethodCallExpr),
100 }
101
102 impl QualifyCandidate<'_> {
103     fn qualify(
104         &self,
105         mut replacer: impl FnMut(String),
106         import: &hir::ModPath,
107         item: hir::ItemInNs,
108     ) {
109         let import = mod_path_to_ast(import);
110         match self {
111             QualifyCandidate::QualifierStart(segment, generics) => {
112                 let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
113                 replacer(format!("{}{}::{}", import, generics, segment));
114             }
115             QualifyCandidate::UnqualifiedName(generics) => {
116                 let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
117                 replacer(format!("{}{}", import.to_string(), generics));
118             }
119             QualifyCandidate::TraitAssocItem(qualifier, segment) => {
120                 replacer(format!("<{} as {}>::{}", qualifier, import, segment));
121             }
122             &QualifyCandidate::TraitMethod(db, ref mcall_expr) => {
123                 Self::qualify_trait_method(db, mcall_expr, replacer, import, item);
124             }
125         }
126     }
127
128     fn qualify_trait_method(
129         db: &RootDatabase,
130         mcall_expr: &ast::MethodCallExpr,
131         mut replacer: impl FnMut(String),
132         import: ast::Path,
133         item: hir::ItemInNs,
134     ) -> Option<()> {
135         let receiver = mcall_expr.receiver()?;
136         let trait_method_name = mcall_expr.name_ref()?;
137         let generics =
138             mcall_expr.generic_arg_list().as_ref().map_or_else(String::new, ToString::to_string);
139         let arg_list = mcall_expr.arg_list().map(|arg_list| arg_list.args());
140         let trait_ = item_as_trait(db, item)?;
141         let method = find_trait_method(db, trait_, &trait_method_name)?;
142         if let Some(self_access) = method.self_param(db).map(|sp| sp.access(db)) {
143             let receiver = match self_access {
144                 hir::Access::Shared => make::expr_ref(receiver, false),
145                 hir::Access::Exclusive => make::expr_ref(receiver, true),
146                 hir::Access::Owned => receiver,
147             };
148             replacer(format!(
149                 "{}::{}{}{}",
150                 import,
151                 trait_method_name,
152                 generics,
153                 match arg_list {
154                     Some(args) => make::arg_list(iter::once(receiver).chain(args)),
155                     None => make::arg_list(iter::once(receiver)),
156                 }
157             ));
158         }
159         Some(())
160     }
161 }
162
163 fn find_trait_method(
164     db: &RootDatabase,
165     trait_: hir::Trait,
166     trait_method_name: &ast::NameRef,
167 ) -> Option<hir::Function> {
168     if let Some(hir::AssocItem::Function(method)) =
169         trait_.items(db).into_iter().find(|item: &hir::AssocItem| {
170             item.name(db)
171                 .map(|name| name.to_string() == trait_method_name.to_string())
172                 .unwrap_or(false)
173         })
174     {
175         Some(method)
176     } else {
177         None
178     }
179 }
180
181 fn item_as_trait(db: &RootDatabase, item: hir::ItemInNs) -> Option<hir::Trait> {
182     let item_module_def = hir::ModuleDef::from(item.as_module_def_id()?);
183
184     if let hir::ModuleDef::Trait(trait_) = item_module_def {
185         Some(trait_)
186     } else {
187         item_module_def.as_assoc_item(db)?.containing_trait(db)
188     }
189 }
190
191 fn group_label(candidate: &ImportCandidate) -> GroupLabel {
192     let name = match candidate {
193         ImportCandidate::Path(it) => &it.name,
194         ImportCandidate::TraitAssocItem(it) | ImportCandidate::TraitMethod(it) => &it.name,
195     }
196     .text();
197     GroupLabel(format!("Qualify {}", name))
198 }
199
200 fn label(db: &RootDatabase, candidate: &ImportCandidate, import: &LocatedImport) -> String {
201     let display_path = match import.original_item_name(db) {
202         Some(display_path) => display_path.to_string(),
203         None => "{unknown}".to_string(),
204     };
205     match candidate {
206         ImportCandidate::Path(candidate) => {
207             if !matches!(candidate.qualifier, Qualifier::Absent) {
208                 format!("Qualify with `{}`", display_path)
209             } else {
210                 format!("Qualify as `{}`", display_path)
211             }
212         }
213         ImportCandidate::TraitAssocItem(_) => format!("Qualify `{}`", display_path),
214         ImportCandidate::TraitMethod(_) => format!("Qualify with cast as `{}`", display_path),
215     }
216 }
217
218 #[cfg(test)]
219 mod tests {
220     use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
221
222     use super::*;
223
224     #[test]
225     fn applicable_when_found_an_import_partial() {
226         cov_mark::check!(qualify_path_unqualified_name);
227         check_assist(
228             qualify_path,
229             r"
230             mod std {
231                 pub mod fmt {
232                     pub struct Formatter;
233                 }
234             }
235
236             use std::fmt;
237
238             $0Formatter
239             ",
240             r"
241             mod std {
242                 pub mod fmt {
243                     pub struct Formatter;
244                 }
245             }
246
247             use std::fmt;
248
249             fmt::Formatter
250             ",
251         );
252     }
253
254     #[test]
255     fn applicable_when_found_an_import() {
256         check_assist(
257             qualify_path,
258             r"
259             $0PubStruct
260
261             pub mod PubMod {
262                 pub struct PubStruct;
263             }
264             ",
265             r"
266             PubMod::PubStruct
267
268             pub mod PubMod {
269                 pub struct PubStruct;
270             }
271             ",
272         );
273     }
274
275     #[test]
276     fn applicable_in_macros() {
277         check_assist(
278             qualify_path,
279             r"
280             macro_rules! foo {
281                 ($i:ident) => { fn foo(a: $i) {} }
282             }
283             foo!(Pub$0Struct);
284
285             pub mod PubMod {
286                 pub struct PubStruct;
287             }
288             ",
289             r"
290             macro_rules! foo {
291                 ($i:ident) => { fn foo(a: $i) {} }
292             }
293             foo!(PubMod::PubStruct);
294
295             pub mod PubMod {
296                 pub struct PubStruct;
297             }
298             ",
299         );
300     }
301
302     #[test]
303     fn applicable_when_found_multiple_imports() {
304         check_assist(
305             qualify_path,
306             r"
307             PubSt$0ruct
308
309             pub mod PubMod1 {
310                 pub struct PubStruct;
311             }
312             pub mod PubMod2 {
313                 pub struct PubStruct;
314             }
315             pub mod PubMod3 {
316                 pub struct PubStruct;
317             }
318             ",
319             r"
320             PubMod1::PubStruct
321
322             pub mod PubMod1 {
323                 pub struct PubStruct;
324             }
325             pub mod PubMod2 {
326                 pub struct PubStruct;
327             }
328             pub mod PubMod3 {
329                 pub struct PubStruct;
330             }
331             ",
332         );
333     }
334
335     #[test]
336     fn not_applicable_for_already_imported_types() {
337         check_assist_not_applicable(
338             qualify_path,
339             r"
340             use PubMod::PubStruct;
341
342             PubStruct$0
343
344             pub mod PubMod {
345                 pub struct PubStruct;
346             }
347             ",
348         );
349     }
350
351     #[test]
352     fn not_applicable_for_types_with_private_paths() {
353         check_assist_not_applicable(
354             qualify_path,
355             r"
356             PrivateStruct$0
357
358             pub mod PubMod {
359                 struct PrivateStruct;
360             }
361             ",
362         );
363     }
364
365     #[test]
366     fn not_applicable_when_no_imports_found() {
367         check_assist_not_applicable(
368             qualify_path,
369             "
370             PubStruct$0",
371         );
372     }
373
374     #[test]
375     fn not_applicable_in_import_statements() {
376         check_assist_not_applicable(
377             qualify_path,
378             r"
379             use PubStruct$0;
380
381             pub mod PubMod {
382                 pub struct PubStruct;
383             }",
384         );
385     }
386
387     #[test]
388     fn qualify_function() {
389         check_assist(
390             qualify_path,
391             r"
392             test_function$0
393
394             pub mod PubMod {
395                 pub fn test_function() {};
396             }
397             ",
398             r"
399             PubMod::test_function
400
401             pub mod PubMod {
402                 pub fn test_function() {};
403             }
404             ",
405         );
406     }
407
408     #[test]
409     fn qualify_macro() {
410         check_assist(
411             qualify_path,
412             r"
413 //- /lib.rs crate:crate_with_macro
414 #[macro_export]
415 macro_rules! foo {
416     () => ()
417 }
418
419 //- /main.rs crate:main deps:crate_with_macro
420 fn main() {
421     foo$0
422 }
423 ",
424             r"
425 fn main() {
426     crate_with_macro::foo
427 }
428 ",
429         );
430     }
431
432     #[test]
433     fn qualify_path_target() {
434         check_assist_target(
435             qualify_path,
436             r"
437             struct AssistInfo {
438                 group_label: Option<$0GroupLabel>,
439             }
440
441             mod m { pub struct GroupLabel; }
442             ",
443             "GroupLabel",
444         )
445     }
446
447     #[test]
448     fn not_applicable_when_path_start_is_imported() {
449         check_assist_not_applicable(
450             qualify_path,
451             r"
452             pub mod mod1 {
453                 pub mod mod2 {
454                     pub mod mod3 {
455                         pub struct TestStruct;
456                     }
457                 }
458             }
459
460             use mod1::mod2;
461             fn main() {
462                 mod2::mod3::TestStruct$0
463             }
464             ",
465         );
466     }
467
468     #[test]
469     fn not_applicable_for_imported_function() {
470         check_assist_not_applicable(
471             qualify_path,
472             r"
473             pub mod test_mod {
474                 pub fn test_function() {}
475             }
476
477             use test_mod::test_function;
478             fn main() {
479                 test_function$0
480             }
481             ",
482         );
483     }
484
485     #[test]
486     fn associated_struct_function() {
487         check_assist(
488             qualify_path,
489             r"
490             mod test_mod {
491                 pub struct TestStruct {}
492                 impl TestStruct {
493                     pub fn test_function() {}
494                 }
495             }
496
497             fn main() {
498                 TestStruct::test_function$0
499             }
500             ",
501             r"
502             mod test_mod {
503                 pub struct TestStruct {}
504                 impl TestStruct {
505                     pub fn test_function() {}
506                 }
507             }
508
509             fn main() {
510                 test_mod::TestStruct::test_function
511             }
512             ",
513         );
514     }
515
516     #[test]
517     fn associated_struct_const() {
518         cov_mark::check!(qualify_path_qualifier_start);
519         check_assist(
520             qualify_path,
521             r"
522             mod test_mod {
523                 pub struct TestStruct {}
524                 impl TestStruct {
525                     const TEST_CONST: u8 = 42;
526                 }
527             }
528
529             fn main() {
530                 TestStruct::TEST_CONST$0
531             }
532             ",
533             r"
534             mod test_mod {
535                 pub struct TestStruct {}
536                 impl TestStruct {
537                     const TEST_CONST: u8 = 42;
538                 }
539             }
540
541             fn main() {
542                 test_mod::TestStruct::TEST_CONST
543             }
544             ",
545         );
546     }
547
548     #[test]
549     fn associated_trait_function() {
550         check_assist(
551             qualify_path,
552             r"
553             mod test_mod {
554                 pub trait TestTrait {
555                     fn test_function();
556                 }
557                 pub struct TestStruct {}
558                 impl TestTrait for TestStruct {
559                     fn test_function() {}
560                 }
561             }
562
563             fn main() {
564                 test_mod::TestStruct::test_function$0
565             }
566             ",
567             r"
568             mod test_mod {
569                 pub trait TestTrait {
570                     fn test_function();
571                 }
572                 pub struct TestStruct {}
573                 impl TestTrait for TestStruct {
574                     fn test_function() {}
575                 }
576             }
577
578             fn main() {
579                 <test_mod::TestStruct as test_mod::TestTrait>::test_function
580             }
581             ",
582         );
583     }
584
585     #[test]
586     fn not_applicable_for_imported_trait_for_function() {
587         check_assist_not_applicable(
588             qualify_path,
589             r"
590             mod test_mod {
591                 pub trait TestTrait {
592                     fn test_function();
593                 }
594                 pub trait TestTrait2 {
595                     fn test_function();
596                 }
597                 pub enum TestEnum {
598                     One,
599                     Two,
600                 }
601                 impl TestTrait2 for TestEnum {
602                     fn test_function() {}
603                 }
604                 impl TestTrait for TestEnum {
605                     fn test_function() {}
606                 }
607             }
608
609             use test_mod::TestTrait2;
610             fn main() {
611                 test_mod::TestEnum::test_function$0;
612             }
613             ",
614         )
615     }
616
617     #[test]
618     fn associated_trait_const() {
619         cov_mark::check!(qualify_path_trait_assoc_item);
620         check_assist(
621             qualify_path,
622             r"
623             mod test_mod {
624                 pub trait TestTrait {
625                     const TEST_CONST: u8;
626                 }
627                 pub struct TestStruct {}
628                 impl TestTrait for TestStruct {
629                     const TEST_CONST: u8 = 42;
630                 }
631             }
632
633             fn main() {
634                 test_mod::TestStruct::TEST_CONST$0
635             }
636             ",
637             r"
638             mod test_mod {
639                 pub trait TestTrait {
640                     const TEST_CONST: u8;
641                 }
642                 pub struct TestStruct {}
643                 impl TestTrait for TestStruct {
644                     const TEST_CONST: u8 = 42;
645                 }
646             }
647
648             fn main() {
649                 <test_mod::TestStruct as test_mod::TestTrait>::TEST_CONST
650             }
651             ",
652         );
653     }
654
655     #[test]
656     fn not_applicable_for_imported_trait_for_const() {
657         check_assist_not_applicable(
658             qualify_path,
659             r"
660             mod test_mod {
661                 pub trait TestTrait {
662                     const TEST_CONST: u8;
663                 }
664                 pub trait TestTrait2 {
665                     const TEST_CONST: f64;
666                 }
667                 pub enum TestEnum {
668                     One,
669                     Two,
670                 }
671                 impl TestTrait2 for TestEnum {
672                     const TEST_CONST: f64 = 42.0;
673                 }
674                 impl TestTrait for TestEnum {
675                     const TEST_CONST: u8 = 42;
676                 }
677             }
678
679             use test_mod::TestTrait2;
680             fn main() {
681                 test_mod::TestEnum::TEST_CONST$0;
682             }
683             ",
684         )
685     }
686
687     #[test]
688     fn trait_method() {
689         cov_mark::check!(qualify_path_trait_method);
690         check_assist(
691             qualify_path,
692             r"
693             mod test_mod {
694                 pub trait TestTrait {
695                     fn test_method(&self);
696                 }
697                 pub struct TestStruct {}
698                 impl TestTrait for TestStruct {
699                     fn test_method(&self) {}
700                 }
701             }
702
703             fn main() {
704                 let test_struct = test_mod::TestStruct {};
705                 test_struct.test_meth$0od()
706             }
707             ",
708             r"
709             mod test_mod {
710                 pub trait TestTrait {
711                     fn test_method(&self);
712                 }
713                 pub struct TestStruct {}
714                 impl TestTrait for TestStruct {
715                     fn test_method(&self) {}
716                 }
717             }
718
719             fn main() {
720                 let test_struct = test_mod::TestStruct {};
721                 test_mod::TestTrait::test_method(&test_struct)
722             }
723             ",
724         );
725     }
726
727     #[test]
728     fn trait_method_multi_params() {
729         check_assist(
730             qualify_path,
731             r"
732             mod test_mod {
733                 pub trait TestTrait {
734                     fn test_method(&self, test: i32);
735                 }
736                 pub struct TestStruct {}
737                 impl TestTrait for TestStruct {
738                     fn test_method(&self, test: i32) {}
739                 }
740             }
741
742             fn main() {
743                 let test_struct = test_mod::TestStruct {};
744                 test_struct.test_meth$0od(42)
745             }
746             ",
747             r"
748             mod test_mod {
749                 pub trait TestTrait {
750                     fn test_method(&self, test: i32);
751                 }
752                 pub struct TestStruct {}
753                 impl TestTrait for TestStruct {
754                     fn test_method(&self, test: i32) {}
755                 }
756             }
757
758             fn main() {
759                 let test_struct = test_mod::TestStruct {};
760                 test_mod::TestTrait::test_method(&test_struct, 42)
761             }
762             ",
763         );
764     }
765
766     #[test]
767     fn trait_method_consume() {
768         check_assist(
769             qualify_path,
770             r"
771             mod test_mod {
772                 pub trait TestTrait {
773                     fn test_method(self);
774                 }
775                 pub struct TestStruct {}
776                 impl TestTrait for TestStruct {
777                     fn test_method(self) {}
778                 }
779             }
780
781             fn main() {
782                 let test_struct = test_mod::TestStruct {};
783                 test_struct.test_meth$0od()
784             }
785             ",
786             r"
787             mod test_mod {
788                 pub trait TestTrait {
789                     fn test_method(self);
790                 }
791                 pub struct TestStruct {}
792                 impl TestTrait for TestStruct {
793                     fn test_method(self) {}
794                 }
795             }
796
797             fn main() {
798                 let test_struct = test_mod::TestStruct {};
799                 test_mod::TestTrait::test_method(test_struct)
800             }
801             ",
802         );
803     }
804
805     #[test]
806     fn trait_method_cross_crate() {
807         check_assist(
808             qualify_path,
809             r"
810             //- /main.rs crate:main deps:dep
811             fn main() {
812                 let test_struct = dep::test_mod::TestStruct {};
813                 test_struct.test_meth$0od()
814             }
815             //- /dep.rs crate:dep
816             pub mod test_mod {
817                 pub trait TestTrait {
818                     fn test_method(&self);
819                 }
820                 pub struct TestStruct {}
821                 impl TestTrait for TestStruct {
822                     fn test_method(&self) {}
823                 }
824             }
825             ",
826             r"
827             fn main() {
828                 let test_struct = dep::test_mod::TestStruct {};
829                 dep::test_mod::TestTrait::test_method(&test_struct)
830             }
831             ",
832         );
833     }
834
835     #[test]
836     fn assoc_fn_cross_crate() {
837         check_assist(
838             qualify_path,
839             r"
840             //- /main.rs crate:main deps:dep
841             fn main() {
842                 dep::test_mod::TestStruct::test_func$0tion
843             }
844             //- /dep.rs crate:dep
845             pub mod test_mod {
846                 pub trait TestTrait {
847                     fn test_function();
848                 }
849                 pub struct TestStruct {}
850                 impl TestTrait for TestStruct {
851                     fn test_function() {}
852                 }
853             }
854             ",
855             r"
856             fn main() {
857                 <dep::test_mod::TestStruct as dep::test_mod::TestTrait>::test_function
858             }
859             ",
860         );
861     }
862
863     #[test]
864     fn assoc_const_cross_crate() {
865         check_assist(
866             qualify_path,
867             r"
868             //- /main.rs crate:main deps:dep
869             fn main() {
870                 dep::test_mod::TestStruct::CONST$0
871             }
872             //- /dep.rs crate:dep
873             pub mod test_mod {
874                 pub trait TestTrait {
875                     const CONST: bool;
876                 }
877                 pub struct TestStruct {}
878                 impl TestTrait for TestStruct {
879                     const CONST: bool = true;
880                 }
881             }
882             ",
883             r"
884             fn main() {
885                 <dep::test_mod::TestStruct as dep::test_mod::TestTrait>::CONST
886             }
887             ",
888         );
889     }
890
891     #[test]
892     fn assoc_fn_as_method_cross_crate() {
893         check_assist_not_applicable(
894             qualify_path,
895             r"
896             //- /main.rs crate:main deps:dep
897             fn main() {
898                 let test_struct = dep::test_mod::TestStruct {};
899                 test_struct.test_func$0tion()
900             }
901             //- /dep.rs crate:dep
902             pub mod test_mod {
903                 pub trait TestTrait {
904                     fn test_function();
905                 }
906                 pub struct TestStruct {}
907                 impl TestTrait for TestStruct {
908                     fn test_function() {}
909                 }
910             }
911             ",
912         );
913     }
914
915     #[test]
916     fn private_trait_cross_crate() {
917         check_assist_not_applicable(
918             qualify_path,
919             r"
920             //- /main.rs crate:main deps:dep
921             fn main() {
922                 let test_struct = dep::test_mod::TestStruct {};
923                 test_struct.test_meth$0od()
924             }
925             //- /dep.rs crate:dep
926             pub mod test_mod {
927                 trait TestTrait {
928                     fn test_method(&self);
929                 }
930                 pub struct TestStruct {}
931                 impl TestTrait for TestStruct {
932                     fn test_method(&self) {}
933                 }
934             }
935             ",
936         );
937     }
938
939     #[test]
940     fn not_applicable_for_imported_trait_for_method() {
941         check_assist_not_applicable(
942             qualify_path,
943             r"
944             mod test_mod {
945                 pub trait TestTrait {
946                     fn test_method(&self);
947                 }
948                 pub trait TestTrait2 {
949                     fn test_method(&self);
950                 }
951                 pub enum TestEnum {
952                     One,
953                     Two,
954                 }
955                 impl TestTrait2 for TestEnum {
956                     fn test_method(&self) {}
957                 }
958                 impl TestTrait for TestEnum {
959                     fn test_method(&self) {}
960                 }
961             }
962
963             use test_mod::TestTrait2;
964             fn main() {
965                 let one = test_mod::TestEnum::One;
966                 one.test$0_method();
967             }
968             ",
969         )
970     }
971
972     #[test]
973     fn dep_import() {
974         check_assist(
975             qualify_path,
976             r"
977 //- /lib.rs crate:dep
978 pub struct Struct;
979
980 //- /main.rs crate:main deps:dep
981 fn main() {
982     Struct$0
983 }
984 ",
985             r"
986 fn main() {
987     dep::Struct
988 }
989 ",
990         );
991     }
992
993     #[test]
994     fn whole_segment() {
995         // Tests that only imports whose last segment matches the identifier get suggested.
996         check_assist(
997             qualify_path,
998             r"
999 //- /lib.rs crate:dep
1000 pub mod fmt {
1001     pub trait Display {}
1002 }
1003
1004 pub fn panic_fmt() {}
1005
1006 //- /main.rs crate:main deps:dep
1007 struct S;
1008
1009 impl f$0mt::Display for S {}
1010 ",
1011             r"
1012 struct S;
1013
1014 impl dep::fmt::Display for S {}
1015 ",
1016         );
1017     }
1018
1019     #[test]
1020     fn macro_generated() {
1021         // Tests that macro-generated items are suggested from external crates.
1022         check_assist(
1023             qualify_path,
1024             r"
1025 //- /lib.rs crate:dep
1026 macro_rules! mac {
1027     () => {
1028         pub struct Cheese;
1029     };
1030 }
1031
1032 mac!();
1033
1034 //- /main.rs crate:main deps:dep
1035 fn main() {
1036     Cheese$0;
1037 }
1038 ",
1039             r"
1040 fn main() {
1041     dep::Cheese;
1042 }
1043 ",
1044         );
1045     }
1046
1047     #[test]
1048     fn casing() {
1049         // Tests that differently cased names don't interfere and we only suggest the matching one.
1050         check_assist(
1051             qualify_path,
1052             r"
1053 //- /lib.rs crate:dep
1054 pub struct FMT;
1055 pub struct fmt;
1056
1057 //- /main.rs crate:main deps:dep
1058 fn main() {
1059     FMT$0;
1060 }
1061 ",
1062             r"
1063 fn main() {
1064     dep::FMT;
1065 }
1066 ",
1067         );
1068     }
1069
1070     #[test]
1071     fn keep_generic_annotations() {
1072         check_assist(
1073             qualify_path,
1074             r"
1075 //- /lib.rs crate:dep
1076 pub mod generic { pub struct Thing<'a, T>(&'a T); }
1077
1078 //- /main.rs crate:main deps:dep
1079 fn foo() -> Thin$0g<'static, ()> {}
1080
1081 fn main() {}
1082 ",
1083             r"
1084 fn foo() -> dep::generic::Thing<'static, ()> {}
1085
1086 fn main() {}
1087 ",
1088         );
1089     }
1090
1091     #[test]
1092     fn keep_generic_annotations_leading_colon() {
1093         check_assist(
1094             qualify_path,
1095             r"
1096 //- /lib.rs crate:dep
1097 pub mod generic { pub struct Thing<'a, T>(&'a T); }
1098
1099 //- /main.rs crate:main deps:dep
1100 fn foo() -> Thin$0g::<'static, ()> {}
1101
1102 fn main() {}
1103 ",
1104             r"
1105 fn foo() -> dep::generic::Thing::<'static, ()> {}
1106
1107 fn main() {}
1108 ",
1109         );
1110     }
1111
1112     #[test]
1113     fn associated_struct_const_generic() {
1114         check_assist(
1115             qualify_path,
1116             r"
1117             mod test_mod {
1118                 pub struct TestStruct<T> {}
1119                 impl<T> TestStruct<T> {
1120                     const TEST_CONST: u8 = 42;
1121                 }
1122             }
1123
1124             fn main() {
1125                 TestStruct::<()>::TEST_CONST$0
1126             }
1127             ",
1128             r"
1129             mod test_mod {
1130                 pub struct TestStruct<T> {}
1131                 impl<T> TestStruct<T> {
1132                     const TEST_CONST: u8 = 42;
1133                 }
1134             }
1135
1136             fn main() {
1137                 test_mod::TestStruct::<()>::TEST_CONST
1138             }
1139             ",
1140         );
1141     }
1142
1143     #[test]
1144     fn associated_trait_const_generic() {
1145         check_assist(
1146             qualify_path,
1147             r"
1148             mod test_mod {
1149                 pub trait TestTrait {
1150                     const TEST_CONST: u8;
1151                 }
1152                 pub struct TestStruct<T> {}
1153                 impl<T> TestTrait for TestStruct<T> {
1154                     const TEST_CONST: u8 = 42;
1155                 }
1156             }
1157
1158             fn main() {
1159                 test_mod::TestStruct::<()>::TEST_CONST$0
1160             }
1161             ",
1162             r"
1163             mod test_mod {
1164                 pub trait TestTrait {
1165                     const TEST_CONST: u8;
1166                 }
1167                 pub struct TestStruct<T> {}
1168                 impl<T> TestTrait for TestStruct<T> {
1169                     const TEST_CONST: u8 = 42;
1170                 }
1171             }
1172
1173             fn main() {
1174                 <test_mod::TestStruct::<()> as test_mod::TestTrait>::TEST_CONST
1175             }
1176             ",
1177         );
1178     }
1179
1180     #[test]
1181     fn trait_method_generic() {
1182         check_assist(
1183             qualify_path,
1184             r"
1185             mod test_mod {
1186                 pub trait TestTrait {
1187                     fn test_method<T>(&self);
1188                 }
1189                 pub struct TestStruct {}
1190                 impl TestTrait for TestStruct {
1191                     fn test_method<T>(&self) {}
1192                 }
1193             }
1194
1195             fn main() {
1196                 let test_struct = test_mod::TestStruct {};
1197                 test_struct.test_meth$0od::<()>()
1198             }
1199             ",
1200             r"
1201             mod test_mod {
1202                 pub trait TestTrait {
1203                     fn test_method<T>(&self);
1204                 }
1205                 pub struct TestStruct {}
1206                 impl TestTrait for TestStruct {
1207                     fn test_method<T>(&self) {}
1208                 }
1209             }
1210
1211             fn main() {
1212                 let test_struct = test_mod::TestStruct {};
1213                 test_mod::TestTrait::test_method::<()>(&test_struct)
1214             }
1215             ",
1216         );
1217     }
1218 }