]> git.lizzy.rs Git - rust.git/blob - crates/ide_assists/src/handlers/auto_import.rs
Merge #11461
[rust.git] / crates / ide_assists / src / handlers / auto_import.rs
1 use ide_db::helpers::{
2     import_assets::{ImportAssets, ImportCandidate},
3     insert_use::{insert_use, ImportScope},
4     mod_path_to_ast,
5 };
6 use syntax::{ast, AstNode, NodeOrToken, SyntaxElement};
7
8 use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel};
9
10 // Feature: Auto Import
11 //
12 // Using the `auto-import` assist it is possible to insert missing imports for unresolved items.
13 // When inserting an import it will do so in a structured manner by keeping imports grouped,
14 // separated by a newline in the following order:
15 //
16 // - `std` and `core`
17 // - External Crates
18 // - Current Crate, paths prefixed by `crate`
19 // - Current Module, paths prefixed by `self`
20 // - Super Module, paths prefixed by `super`
21 //
22 // Example:
23 // ```rust
24 // use std::fs::File;
25 //
26 // use itertools::Itertools;
27 // use syntax::ast;
28 //
29 // use crate::utils::insert_use;
30 //
31 // use self::auto_import;
32 //
33 // use super::AssistContext;
34 // ```
35 //
36 // .Import Granularity
37 //
38 // It is possible to configure how use-trees are merged with the `importGranularity` setting.
39 // It has the following configurations:
40 //
41 // - `crate`: Merge imports from the same crate into a single use statement. This kind of
42 //  nesting is only supported in Rust versions later than 1.24.
43 // - `module`: Merge imports from the same module into a single use statement.
44 // - `item`: Don't merge imports at all, creating one import per item.
45 // - `preserve`: Do not change the granularity of any imports. For auto-import this has the same
46 //  effect as `item`.
47 //
48 // In `VS Code` the configuration for this is `rust-analyzer.assist.importGranularity`.
49 //
50 // .Import Prefix
51 //
52 // The style of imports in the same crate is configurable through the `importPrefix` setting.
53 // It has the following configurations:
54 //
55 // - `by_crate`: This setting will force paths to be always absolute, starting with the `crate`
56 //  prefix, unless the item is defined outside of the current crate.
57 // - `by_self`: This setting will force paths that are relative to the current module to always
58 //  start with `self`. This will result in paths that always start with either `crate`, `self`,
59 //  `super` or an extern crate identifier.
60 // - `plain`: This setting does not impose any restrictions in imports.
61 //
62 // In `VS Code` the configuration for this is `rust-analyzer.assist.importPrefix`.
63 //
64 // image::https://user-images.githubusercontent.com/48062697/113020673-b85be580-917a-11eb-9022-59585f35d4f8.gif[]
65
66 // Assist: auto_import
67 //
68 // If the name is unresolved, provides all possible imports for it.
69 //
70 // ```
71 // fn main() {
72 //     let map = HashMap$0::new();
73 // }
74 // # pub mod std { pub mod collections { pub struct HashMap { } } }
75 // ```
76 // ->
77 // ```
78 // use std::collections::HashMap;
79 //
80 // fn main() {
81 //     let map = HashMap::new();
82 // }
83 // # pub mod std { pub mod collections { pub struct HashMap { } } }
84 // ```
85 pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
86     let (import_assets, syntax_under_caret) = find_importable_node(ctx)?;
87     let mut proposed_imports =
88         import_assets.search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind);
89     if proposed_imports.is_empty() {
90         return None;
91     }
92
93     let range = match &syntax_under_caret {
94         NodeOrToken::Node(node) => ctx.sema.original_range(node).range,
95         NodeOrToken::Token(token) => token.text_range(),
96     };
97     let group_label = group_label(import_assets.import_candidate());
98     let scope = ImportScope::find_insert_use_container(
99         &match syntax_under_caret {
100             NodeOrToken::Node(it) => it,
101             NodeOrToken::Token(it) => it.parent()?,
102         },
103         &ctx.sema,
104     )?;
105
106     // we aren't interested in different namespaces
107     proposed_imports.dedup_by(|a, b| a.import_path == b.import_path);
108     for import in proposed_imports {
109         acc.add_group(
110             &group_label,
111             AssistId("auto_import", AssistKind::QuickFix),
112             format!("Import `{}`", import.import_path),
113             range,
114             |builder| {
115                 let scope = match scope.clone() {
116                     ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
117                     ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
118                     ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
119                 };
120                 insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
121             },
122         );
123     }
124     Some(())
125 }
126
127 pub(super) fn find_importable_node(ctx: &AssistContext) -> Option<(ImportAssets, SyntaxElement)> {
128     if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
129         ImportAssets::for_exact_path(&path_under_caret, &ctx.sema)
130             .zip(Some(path_under_caret.syntax().clone().into()))
131     } else if let Some(method_under_caret) =
132         ctx.find_node_at_offset_with_descend::<ast::MethodCallExpr>()
133     {
134         ImportAssets::for_method_call(&method_under_caret, &ctx.sema)
135             .zip(Some(method_under_caret.syntax().clone().into()))
136     } else if let Some(pat) = ctx
137         .find_node_at_offset_with_descend::<ast::IdentPat>()
138         .filter(ast::IdentPat::is_simple_ident)
139     {
140         ImportAssets::for_ident_pat(&ctx.sema, &pat).zip(Some(pat.syntax().clone().into()))
141     } else {
142         None
143     }
144 }
145
146 fn group_label(import_candidate: &ImportCandidate) -> GroupLabel {
147     let name = match import_candidate {
148         ImportCandidate::Path(candidate) => format!("Import {}", candidate.name.text()),
149         ImportCandidate::TraitAssocItem(candidate) => {
150             format!("Import a trait for item {}", candidate.assoc_item_name.text())
151         }
152         ImportCandidate::TraitMethod(candidate) => {
153             format!("Import a trait for method {}", candidate.assoc_item_name.text())
154         }
155     };
156     GroupLabel(name)
157 }
158
159 #[cfg(test)]
160 mod tests {
161     use super::*;
162
163     use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
164
165     #[test]
166     fn not_applicable_if_scope_inside_macro() {
167         check_assist_not_applicable(
168             auto_import,
169             r"
170 mod bar {
171     pub struct Baz;
172 }
173 macro_rules! foo {
174     ($it:ident) => {
175         mod __ {
176             fn __(x: $it) {}
177         }
178     };
179 }
180 foo! {
181     Baz$0
182 }
183 ",
184         );
185     }
186
187     #[test]
188     fn applicable_in_attributes() {
189         check_assist(
190             auto_import,
191             r"
192 //- proc_macros: identity
193 #[proc_macros::identity]
194 mod foo {
195     mod bar {
196         const _: Baz$0 = ();
197     }
198 }
199 mod baz {
200     pub struct Baz;
201 }
202 ",
203             r"
204 #[proc_macros::identity]
205 mod foo {
206     mod bar {
207         use crate::baz::Baz;
208
209         const _: Baz = ();
210     }
211 }
212 mod baz {
213     pub struct Baz;
214 }
215 ",
216         );
217     }
218
219     #[test]
220     fn applicable_when_found_an_import_partial() {
221         check_assist(
222             auto_import,
223             r"
224             mod std {
225                 pub mod fmt {
226                     pub struct Formatter;
227                 }
228             }
229
230             use std::fmt;
231
232             $0Formatter
233             ",
234             r"
235             mod std {
236                 pub mod fmt {
237                     pub struct Formatter;
238                 }
239             }
240
241             use std::fmt::{self, Formatter};
242
243             Formatter
244             ",
245         );
246     }
247
248     #[test]
249     fn applicable_when_found_an_import() {
250         check_assist(
251             auto_import,
252             r"
253             $0PubStruct
254
255             pub mod PubMod {
256                 pub struct PubStruct;
257             }
258             ",
259             r"
260             use PubMod::PubStruct;
261
262             PubStruct
263
264             pub mod PubMod {
265                 pub struct PubStruct;
266             }
267             ",
268         );
269     }
270
271     #[test]
272     fn applicable_when_found_an_import_in_macros() {
273         check_assist(
274             auto_import,
275             r"
276             macro_rules! foo {
277                 ($i:ident) => { fn foo(a: $i) {} }
278             }
279             foo!(Pub$0Struct);
280
281             pub mod PubMod {
282                 pub struct PubStruct;
283             }
284             ",
285             r"
286             use PubMod::PubStruct;
287
288             macro_rules! foo {
289                 ($i:ident) => { fn foo(a: $i) {} }
290             }
291             foo!(PubStruct);
292
293             pub mod PubMod {
294                 pub struct PubStruct;
295             }
296             ",
297         );
298     }
299
300     #[test]
301     fn applicable_when_found_multiple_imports() {
302         check_assist(
303             auto_import,
304             r"
305             PubSt$0ruct
306
307             pub mod PubMod1 {
308                 pub struct PubStruct;
309             }
310             pub mod PubMod2 {
311                 pub struct PubStruct;
312             }
313             pub mod PubMod3 {
314                 pub struct PubStruct;
315             }
316             ",
317             r"
318             use PubMod3::PubStruct;
319
320             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             auto_import,
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             auto_import,
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             auto_import,
369             "
370             PubStruct$0",
371         );
372     }
373
374     #[test]
375     fn not_applicable_in_import_statements() {
376         check_assist_not_applicable(
377             auto_import,
378             r"
379             use PubStruct$0;
380
381             pub mod PubMod {
382                 pub struct PubStruct;
383             }",
384         );
385     }
386
387     #[test]
388     fn function_import() {
389         check_assist(
390             auto_import,
391             r"
392             test_function$0
393
394             pub mod PubMod {
395                 pub fn test_function() {};
396             }
397             ",
398             r"
399             use PubMod::test_function;
400
401             test_function
402
403             pub mod PubMod {
404                 pub fn test_function() {};
405             }
406             ",
407         );
408     }
409
410     #[test]
411     fn macro_import() {
412         check_assist(
413             auto_import,
414             r"
415 //- /lib.rs crate:crate_with_macro
416 #[macro_export]
417 macro_rules! foo {
418     () => ()
419 }
420
421 //- /main.rs crate:main deps:crate_with_macro
422 fn main() {
423     foo$0
424 }
425 ",
426             r"use crate_with_macro::foo;
427
428 fn main() {
429     foo
430 }
431 ",
432         );
433     }
434
435     #[test]
436     fn auto_import_target() {
437         check_assist_target(
438             auto_import,
439             r"
440             struct AssistInfo {
441                 group_label: Option<$0GroupLabel>,
442             }
443
444             mod m { pub struct GroupLabel; }
445             ",
446             "GroupLabel",
447         )
448     }
449
450     #[test]
451     fn not_applicable_when_path_start_is_imported() {
452         check_assist_not_applicable(
453             auto_import,
454             r"
455             pub mod mod1 {
456                 pub mod mod2 {
457                     pub mod mod3 {
458                         pub struct TestStruct;
459                     }
460                 }
461             }
462
463             use mod1::mod2;
464             fn main() {
465                 mod2::mod3::TestStruct$0
466             }
467             ",
468         );
469     }
470
471     #[test]
472     fn not_applicable_for_imported_function() {
473         check_assist_not_applicable(
474             auto_import,
475             r"
476             pub mod test_mod {
477                 pub fn test_function() {}
478             }
479
480             use test_mod::test_function;
481             fn main() {
482                 test_function$0
483             }
484             ",
485         );
486     }
487
488     #[test]
489     fn associated_struct_function() {
490         check_assist(
491             auto_import,
492             r"
493             mod test_mod {
494                 pub struct TestStruct {}
495                 impl TestStruct {
496                     pub fn test_function() {}
497                 }
498             }
499
500             fn main() {
501                 TestStruct::test_function$0
502             }
503             ",
504             r"
505             use test_mod::TestStruct;
506
507             mod test_mod {
508                 pub struct TestStruct {}
509                 impl TestStruct {
510                     pub fn test_function() {}
511                 }
512             }
513
514             fn main() {
515                 TestStruct::test_function
516             }
517             ",
518         );
519     }
520
521     #[test]
522     fn associated_struct_const() {
523         check_assist(
524             auto_import,
525             r"
526             mod test_mod {
527                 pub struct TestStruct {}
528                 impl TestStruct {
529                     const TEST_CONST: u8 = 42;
530                 }
531             }
532
533             fn main() {
534                 TestStruct::TEST_CONST$0
535             }
536             ",
537             r"
538             use test_mod::TestStruct;
539
540             mod test_mod {
541                 pub struct TestStruct {}
542                 impl TestStruct {
543                     const TEST_CONST: u8 = 42;
544                 }
545             }
546
547             fn main() {
548                 TestStruct::TEST_CONST
549             }
550             ",
551         );
552     }
553
554     #[test]
555     fn associated_trait_function() {
556         check_assist(
557             auto_import,
558             r"
559             mod test_mod {
560                 pub trait TestTrait {
561                     fn test_function();
562                 }
563                 pub struct TestStruct {}
564                 impl TestTrait for TestStruct {
565                     fn test_function() {}
566                 }
567             }
568
569             fn main() {
570                 test_mod::TestStruct::test_function$0
571             }
572             ",
573             r"
574             use test_mod::TestTrait;
575
576             mod test_mod {
577                 pub trait TestTrait {
578                     fn test_function();
579                 }
580                 pub struct TestStruct {}
581                 impl TestTrait for TestStruct {
582                     fn test_function() {}
583                 }
584             }
585
586             fn main() {
587                 test_mod::TestStruct::test_function
588             }
589             ",
590         );
591     }
592
593     #[test]
594     fn not_applicable_for_imported_trait_for_function() {
595         check_assist_not_applicable(
596             auto_import,
597             r"
598             mod test_mod {
599                 pub trait TestTrait {
600                     fn test_function();
601                 }
602                 pub trait TestTrait2 {
603                     fn test_function();
604                 }
605                 pub enum TestEnum {
606                     One,
607                     Two,
608                 }
609                 impl TestTrait2 for TestEnum {
610                     fn test_function() {}
611                 }
612                 impl TestTrait for TestEnum {
613                     fn test_function() {}
614                 }
615             }
616
617             use test_mod::TestTrait2;
618             fn main() {
619                 test_mod::TestEnum::test_function$0;
620             }
621             ",
622         )
623     }
624
625     #[test]
626     fn associated_trait_const() {
627         check_assist(
628             auto_import,
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             use test_mod::TestTrait;
646
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::TEST_CONST
659             }
660             ",
661         );
662     }
663
664     #[test]
665     fn not_applicable_for_imported_trait_for_const() {
666         check_assist_not_applicable(
667             auto_import,
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         check_assist(
699             auto_import,
700             r"
701             mod test_mod {
702                 pub trait TestTrait {
703                     fn test_method(&self);
704                 }
705                 pub struct TestStruct {}
706                 impl TestTrait for TestStruct {
707                     fn test_method(&self) {}
708                 }
709             }
710
711             fn main() {
712                 let test_struct = test_mod::TestStruct {};
713                 test_struct.test_meth$0od()
714             }
715             ",
716             r"
717             use test_mod::TestTrait;
718
719             mod test_mod {
720                 pub trait TestTrait {
721                     fn test_method(&self);
722                 }
723                 pub struct TestStruct {}
724                 impl TestTrait for TestStruct {
725                     fn test_method(&self) {}
726                 }
727             }
728
729             fn main() {
730                 let test_struct = test_mod::TestStruct {};
731                 test_struct.test_method()
732             }
733             ",
734         );
735     }
736
737     #[test]
738     fn trait_method_cross_crate() {
739         check_assist(
740             auto_import,
741             r"
742             //- /main.rs crate:main deps:dep
743             fn main() {
744                 let test_struct = dep::test_mod::TestStruct {};
745                 test_struct.test_meth$0od()
746             }
747             //- /dep.rs crate:dep
748             pub mod test_mod {
749                 pub trait TestTrait {
750                     fn test_method(&self);
751                 }
752                 pub struct TestStruct {}
753                 impl TestTrait for TestStruct {
754                     fn test_method(&self) {}
755                 }
756             }
757             ",
758             r"
759             use dep::test_mod::TestTrait;
760
761             fn main() {
762                 let test_struct = dep::test_mod::TestStruct {};
763                 test_struct.test_method()
764             }
765             ",
766         );
767     }
768
769     #[test]
770     fn assoc_fn_cross_crate() {
771         check_assist(
772             auto_import,
773             r"
774             //- /main.rs crate:main deps:dep
775             fn main() {
776                 dep::test_mod::TestStruct::test_func$0tion
777             }
778             //- /dep.rs crate:dep
779             pub mod test_mod {
780                 pub trait TestTrait {
781                     fn test_function();
782                 }
783                 pub struct TestStruct {}
784                 impl TestTrait for TestStruct {
785                     fn test_function() {}
786                 }
787             }
788             ",
789             r"
790             use dep::test_mod::TestTrait;
791
792             fn main() {
793                 dep::test_mod::TestStruct::test_function
794             }
795             ",
796         );
797     }
798
799     #[test]
800     fn assoc_const_cross_crate() {
801         check_assist(
802             auto_import,
803             r"
804             //- /main.rs crate:main deps:dep
805             fn main() {
806                 dep::test_mod::TestStruct::CONST$0
807             }
808             //- /dep.rs crate:dep
809             pub mod test_mod {
810                 pub trait TestTrait {
811                     const CONST: bool;
812                 }
813                 pub struct TestStruct {}
814                 impl TestTrait for TestStruct {
815                     const CONST: bool = true;
816                 }
817             }
818             ",
819             r"
820             use dep::test_mod::TestTrait;
821
822             fn main() {
823                 dep::test_mod::TestStruct::CONST
824             }
825             ",
826         );
827     }
828
829     #[test]
830     fn assoc_fn_as_method_cross_crate() {
831         check_assist_not_applicable(
832             auto_import,
833             r"
834             //- /main.rs crate:main deps:dep
835             fn main() {
836                 let test_struct = dep::test_mod::TestStruct {};
837                 test_struct.test_func$0tion()
838             }
839             //- /dep.rs crate:dep
840             pub mod test_mod {
841                 pub trait TestTrait {
842                     fn test_function();
843                 }
844                 pub struct TestStruct {}
845                 impl TestTrait for TestStruct {
846                     fn test_function() {}
847                 }
848             }
849             ",
850         );
851     }
852
853     #[test]
854     fn private_trait_cross_crate() {
855         check_assist_not_applicable(
856             auto_import,
857             r"
858             //- /main.rs crate:main deps:dep
859             fn main() {
860                 let test_struct = dep::test_mod::TestStruct {};
861                 test_struct.test_meth$0od()
862             }
863             //- /dep.rs crate:dep
864             pub mod test_mod {
865                 trait TestTrait {
866                     fn test_method(&self);
867                 }
868                 pub struct TestStruct {}
869                 impl TestTrait for TestStruct {
870                     fn test_method(&self) {}
871                 }
872             }
873             ",
874         );
875     }
876
877     #[test]
878     fn not_applicable_for_imported_trait_for_method() {
879         check_assist_not_applicable(
880             auto_import,
881             r"
882             mod test_mod {
883                 pub trait TestTrait {
884                     fn test_method(&self);
885                 }
886                 pub trait TestTrait2 {
887                     fn test_method(&self);
888                 }
889                 pub enum TestEnum {
890                     One,
891                     Two,
892                 }
893                 impl TestTrait2 for TestEnum {
894                     fn test_method(&self) {}
895                 }
896                 impl TestTrait for TestEnum {
897                     fn test_method(&self) {}
898                 }
899             }
900
901             use test_mod::TestTrait2;
902             fn main() {
903                 let one = test_mod::TestEnum::One;
904                 one.test$0_method();
905             }
906             ",
907         )
908     }
909
910     #[test]
911     fn dep_import() {
912         check_assist(
913             auto_import,
914             r"
915 //- /lib.rs crate:dep
916 pub struct Struct;
917
918 //- /main.rs crate:main deps:dep
919 fn main() {
920     Struct$0
921 }
922 ",
923             r"use dep::Struct;
924
925 fn main() {
926     Struct
927 }
928 ",
929         );
930     }
931
932     #[test]
933     fn whole_segment() {
934         // Tests that only imports whose last segment matches the identifier get suggested.
935         check_assist(
936             auto_import,
937             r"
938 //- /lib.rs crate:dep
939 pub mod fmt {
940     pub trait Display {}
941 }
942
943 pub fn panic_fmt() {}
944
945 //- /main.rs crate:main deps:dep
946 struct S;
947
948 impl f$0mt::Display for S {}
949 ",
950             r"use dep::fmt;
951
952 struct S;
953
954 impl fmt::Display for S {}
955 ",
956         );
957     }
958
959     #[test]
960     fn macro_generated() {
961         // Tests that macro-generated items are suggested from external crates.
962         check_assist(
963             auto_import,
964             r"
965 //- /lib.rs crate:dep
966 macro_rules! mac {
967     () => {
968         pub struct Cheese;
969     };
970 }
971
972 mac!();
973
974 //- /main.rs crate:main deps:dep
975 fn main() {
976     Cheese$0;
977 }
978 ",
979             r"use dep::Cheese;
980
981 fn main() {
982     Cheese;
983 }
984 ",
985         );
986     }
987
988     #[test]
989     fn casing() {
990         // Tests that differently cased names don't interfere and we only suggest the matching one.
991         check_assist(
992             auto_import,
993             r"
994 //- /lib.rs crate:dep
995 pub struct FMT;
996 pub struct fmt;
997
998 //- /main.rs crate:main deps:dep
999 fn main() {
1000     FMT$0;
1001 }
1002 ",
1003             r"use dep::FMT;
1004
1005 fn main() {
1006     FMT;
1007 }
1008 ",
1009         );
1010     }
1011
1012     #[test]
1013     fn inner_items() {
1014         check_assist(
1015             auto_import,
1016             r#"
1017 mod baz {
1018     pub struct Foo {}
1019 }
1020
1021 mod bar {
1022     fn bar() {
1023         Foo$0;
1024         println!("Hallo");
1025     }
1026 }
1027 "#,
1028             r#"
1029 mod baz {
1030     pub struct Foo {}
1031 }
1032
1033 mod bar {
1034     use crate::baz::Foo;
1035
1036     fn bar() {
1037         Foo;
1038         println!("Hallo");
1039     }
1040 }
1041 "#,
1042         );
1043     }
1044
1045     #[test]
1046     fn uses_abs_path_with_extern_crate_clash() {
1047         cov_mark::check!(ambiguous_crate_start);
1048         check_assist(
1049             auto_import,
1050             r#"
1051 //- /main.rs crate:main deps:foo
1052 mod foo {}
1053
1054 const _: () = {
1055     Foo$0
1056 };
1057 //- /foo.rs crate:foo
1058 pub struct Foo
1059 "#,
1060             r#"
1061 use ::foo::Foo;
1062
1063 mod foo {}
1064
1065 const _: () = {
1066     Foo
1067 };
1068 "#,
1069         );
1070     }
1071
1072     #[test]
1073     fn works_on_ident_patterns() {
1074         check_assist(
1075             auto_import,
1076             r#"
1077 mod foo {
1078     pub struct Foo {}
1079 }
1080 fn foo() {
1081     let Foo$0;
1082 }
1083 "#,
1084             r#"
1085 use foo::Foo;
1086
1087 mod foo {
1088     pub struct Foo {}
1089 }
1090 fn foo() {
1091     let Foo;
1092 }
1093 "#,
1094         );
1095     }
1096
1097     #[test]
1098     fn works_in_derives() {
1099         check_assist(
1100             auto_import,
1101             r#"
1102 //- minicore:derive
1103 mod foo {
1104     #[rustc_builtin_macro]
1105     pub macro Copy {}
1106 }
1107 #[derive(Copy$0)]
1108 struct Foo;
1109 "#,
1110             r#"
1111 use foo::Copy;
1112
1113 mod foo {
1114     #[rustc_builtin_macro]
1115     pub macro Copy {}
1116 }
1117 #[derive(Copy)]
1118 struct Foo;
1119 "#,
1120         );
1121     }
1122 }