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