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