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