]> git.lizzy.rs Git - rust.git/blob - crates/ide_assists/src/handlers/auto_import.rs
Refactor ide handling for paths in derive inputs
[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, AstToken, SyntaxNode};
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 = ctx.sema.original_range(&syntax_under_caret).range;
94     let group_label = group_label(import_assets.import_candidate());
95     let scope = ImportScope::find_insert_use_container_with_macros(&syntax_under_caret, &ctx.sema)?;
96
97     // we aren't interested in different namespaces
98     proposed_imports.dedup_by(|a, b| a.import_path == b.import_path);
99     for import in proposed_imports {
100         acc.add_group(
101             &group_label,
102             AssistId("auto_import", AssistKind::QuickFix),
103             format!("Import `{}`", import.import_path),
104             range,
105             |builder| {
106                 let scope = match scope.clone() {
107                     ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
108                     ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
109                     ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
110                 };
111                 insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
112             },
113         );
114     }
115     Some(())
116 }
117
118 pub(super) fn find_importable_node(ctx: &AssistContext) -> Option<(ImportAssets, SyntaxNode)> {
119     if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
120         ImportAssets::for_exact_path(&path_under_caret, &ctx.sema)
121             .zip(Some(path_under_caret.syntax().clone()))
122     } else if let Some(method_under_caret) =
123         ctx.find_node_at_offset_with_descend::<ast::MethodCallExpr>()
124     {
125         ImportAssets::for_method_call(&method_under_caret, &ctx.sema)
126             .zip(Some(method_under_caret.syntax().clone()))
127     } else if let Some(pat) = ctx
128         .find_node_at_offset_with_descend::<ast::IdentPat>()
129         .filter(ast::IdentPat::is_simple_ident)
130     {
131         ImportAssets::for_ident_pat(&ctx.sema, &pat).zip(Some(pat.syntax().clone()))
132     } else {
133         let ident = ctx.find_token_at_offset()?;
134         ImportAssets::for_derive_ident(&ctx.sema, &ident).zip(ident.syntax().parent())
135     }
136 }
137
138 fn group_label(import_candidate: &ImportCandidate) -> GroupLabel {
139     let name = match import_candidate {
140         ImportCandidate::Path(candidate) => format!("Import {}", candidate.name.text()),
141         ImportCandidate::TraitAssocItem(candidate) => {
142             format!("Import a trait for item {}", candidate.assoc_item_name.text())
143         }
144         ImportCandidate::TraitMethod(candidate) => {
145             format!("Import a trait for method {}", candidate.assoc_item_name.text())
146         }
147     };
148     GroupLabel(name)
149 }
150
151 #[cfg(test)]
152 mod tests {
153     use super::*;
154
155     use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
156
157     #[test]
158     fn applicable_when_found_an_import_partial() {
159         check_assist(
160             auto_import,
161             r"
162             mod std {
163                 pub mod fmt {
164                     pub struct Formatter;
165                 }
166             }
167
168             use std::fmt;
169
170             $0Formatter
171             ",
172             r"
173             mod std {
174                 pub mod fmt {
175                     pub struct Formatter;
176                 }
177             }
178
179             use std::fmt::{self, Formatter};
180
181             Formatter
182             ",
183         );
184     }
185
186     #[test]
187     fn applicable_when_found_an_import() {
188         check_assist(
189             auto_import,
190             r"
191             $0PubStruct
192
193             pub mod PubMod {
194                 pub struct PubStruct;
195             }
196             ",
197             r"
198             use PubMod::PubStruct;
199
200             PubStruct
201
202             pub mod PubMod {
203                 pub struct PubStruct;
204             }
205             ",
206         );
207     }
208
209     #[test]
210     fn applicable_when_found_an_import_in_macros() {
211         check_assist(
212             auto_import,
213             r"
214             macro_rules! foo {
215                 ($i:ident) => { fn foo(a: $i) {} }
216             }
217             foo!(Pub$0Struct);
218
219             pub mod PubMod {
220                 pub struct PubStruct;
221             }
222             ",
223             r"
224             use PubMod::PubStruct;
225
226             macro_rules! foo {
227                 ($i:ident) => { fn foo(a: $i) {} }
228             }
229             foo!(PubStruct);
230
231             pub mod PubMod {
232                 pub struct PubStruct;
233             }
234             ",
235         );
236     }
237
238     #[test]
239     fn applicable_when_found_multiple_imports() {
240         check_assist(
241             auto_import,
242             r"
243             PubSt$0ruct
244
245             pub mod PubMod1 {
246                 pub struct PubStruct;
247             }
248             pub mod PubMod2 {
249                 pub struct PubStruct;
250             }
251             pub mod PubMod3 {
252                 pub struct PubStruct;
253             }
254             ",
255             r"
256             use PubMod3::PubStruct;
257
258             PubStruct
259
260             pub mod PubMod1 {
261                 pub struct PubStruct;
262             }
263             pub mod PubMod2 {
264                 pub struct PubStruct;
265             }
266             pub mod PubMod3 {
267                 pub struct PubStruct;
268             }
269             ",
270         );
271     }
272
273     #[test]
274     fn not_applicable_for_already_imported_types() {
275         check_assist_not_applicable(
276             auto_import,
277             r"
278             use PubMod::PubStruct;
279
280             PubStruct$0
281
282             pub mod PubMod {
283                 pub struct PubStruct;
284             }
285             ",
286         );
287     }
288
289     #[test]
290     fn not_applicable_for_types_with_private_paths() {
291         check_assist_not_applicable(
292             auto_import,
293             r"
294             PrivateStruct$0
295
296             pub mod PubMod {
297                 struct PrivateStruct;
298             }
299             ",
300         );
301     }
302
303     #[test]
304     fn not_applicable_when_no_imports_found() {
305         check_assist_not_applicable(
306             auto_import,
307             "
308             PubStruct$0",
309         );
310     }
311
312     #[test]
313     fn not_applicable_in_import_statements() {
314         check_assist_not_applicable(
315             auto_import,
316             r"
317             use PubStruct$0;
318
319             pub mod PubMod {
320                 pub struct PubStruct;
321             }",
322         );
323     }
324
325     #[test]
326     fn function_import() {
327         check_assist(
328             auto_import,
329             r"
330             test_function$0
331
332             pub mod PubMod {
333                 pub fn test_function() {};
334             }
335             ",
336             r"
337             use PubMod::test_function;
338
339             test_function
340
341             pub mod PubMod {
342                 pub fn test_function() {};
343             }
344             ",
345         );
346     }
347
348     #[test]
349     fn macro_import() {
350         check_assist(
351             auto_import,
352             r"
353 //- /lib.rs crate:crate_with_macro
354 #[macro_export]
355 macro_rules! foo {
356     () => ()
357 }
358
359 //- /main.rs crate:main deps:crate_with_macro
360 fn main() {
361     foo$0
362 }
363 ",
364             r"use crate_with_macro::foo;
365
366 fn main() {
367     foo
368 }
369 ",
370         );
371     }
372
373     #[test]
374     fn auto_import_target() {
375         check_assist_target(
376             auto_import,
377             r"
378             struct AssistInfo {
379                 group_label: Option<$0GroupLabel>,
380             }
381
382             mod m { pub struct GroupLabel; }
383             ",
384             "GroupLabel",
385         )
386     }
387
388     #[test]
389     fn not_applicable_when_path_start_is_imported() {
390         check_assist_not_applicable(
391             auto_import,
392             r"
393             pub mod mod1 {
394                 pub mod mod2 {
395                     pub mod mod3 {
396                         pub struct TestStruct;
397                     }
398                 }
399             }
400
401             use mod1::mod2;
402             fn main() {
403                 mod2::mod3::TestStruct$0
404             }
405             ",
406         );
407     }
408
409     #[test]
410     fn not_applicable_for_imported_function() {
411         check_assist_not_applicable(
412             auto_import,
413             r"
414             pub mod test_mod {
415                 pub fn test_function() {}
416             }
417
418             use test_mod::test_function;
419             fn main() {
420                 test_function$0
421             }
422             ",
423         );
424     }
425
426     #[test]
427     fn associated_struct_function() {
428         check_assist(
429             auto_import,
430             r"
431             mod test_mod {
432                 pub struct TestStruct {}
433                 impl TestStruct {
434                     pub fn test_function() {}
435                 }
436             }
437
438             fn main() {
439                 TestStruct::test_function$0
440             }
441             ",
442             r"
443             use test_mod::TestStruct;
444
445             mod test_mod {
446                 pub struct TestStruct {}
447                 impl TestStruct {
448                     pub fn test_function() {}
449                 }
450             }
451
452             fn main() {
453                 TestStruct::test_function
454             }
455             ",
456         );
457     }
458
459     #[test]
460     fn associated_struct_const() {
461         check_assist(
462             auto_import,
463             r"
464             mod test_mod {
465                 pub struct TestStruct {}
466                 impl TestStruct {
467                     const TEST_CONST: u8 = 42;
468                 }
469             }
470
471             fn main() {
472                 TestStruct::TEST_CONST$0
473             }
474             ",
475             r"
476             use test_mod::TestStruct;
477
478             mod test_mod {
479                 pub struct TestStruct {}
480                 impl TestStruct {
481                     const TEST_CONST: u8 = 42;
482                 }
483             }
484
485             fn main() {
486                 TestStruct::TEST_CONST
487             }
488             ",
489         );
490     }
491
492     #[test]
493     fn associated_trait_function() {
494         check_assist(
495             auto_import,
496             r"
497             mod test_mod {
498                 pub trait TestTrait {
499                     fn test_function();
500                 }
501                 pub struct TestStruct {}
502                 impl TestTrait for TestStruct {
503                     fn test_function() {}
504                 }
505             }
506
507             fn main() {
508                 test_mod::TestStruct::test_function$0
509             }
510             ",
511             r"
512             use test_mod::TestTrait;
513
514             mod test_mod {
515                 pub trait TestTrait {
516                     fn test_function();
517                 }
518                 pub struct TestStruct {}
519                 impl TestTrait for TestStruct {
520                     fn test_function() {}
521                 }
522             }
523
524             fn main() {
525                 test_mod::TestStruct::test_function
526             }
527             ",
528         );
529     }
530
531     #[test]
532     fn not_applicable_for_imported_trait_for_function() {
533         check_assist_not_applicable(
534             auto_import,
535             r"
536             mod test_mod {
537                 pub trait TestTrait {
538                     fn test_function();
539                 }
540                 pub trait TestTrait2 {
541                     fn test_function();
542                 }
543                 pub enum TestEnum {
544                     One,
545                     Two,
546                 }
547                 impl TestTrait2 for TestEnum {
548                     fn test_function() {}
549                 }
550                 impl TestTrait for TestEnum {
551                     fn test_function() {}
552                 }
553             }
554
555             use test_mod::TestTrait2;
556             fn main() {
557                 test_mod::TestEnum::test_function$0;
558             }
559             ",
560         )
561     }
562
563     #[test]
564     fn associated_trait_const() {
565         check_assist(
566             auto_import,
567             r"
568             mod test_mod {
569                 pub trait TestTrait {
570                     const TEST_CONST: u8;
571                 }
572                 pub struct TestStruct {}
573                 impl TestTrait for TestStruct {
574                     const TEST_CONST: u8 = 42;
575                 }
576             }
577
578             fn main() {
579                 test_mod::TestStruct::TEST_CONST$0
580             }
581             ",
582             r"
583             use test_mod::TestTrait;
584
585             mod test_mod {
586                 pub trait TestTrait {
587                     const TEST_CONST: u8;
588                 }
589                 pub struct TestStruct {}
590                 impl TestTrait for TestStruct {
591                     const TEST_CONST: u8 = 42;
592                 }
593             }
594
595             fn main() {
596                 test_mod::TestStruct::TEST_CONST
597             }
598             ",
599         );
600     }
601
602     #[test]
603     fn not_applicable_for_imported_trait_for_const() {
604         check_assist_not_applicable(
605             auto_import,
606             r"
607             mod test_mod {
608                 pub trait TestTrait {
609                     const TEST_CONST: u8;
610                 }
611                 pub trait TestTrait2 {
612                     const TEST_CONST: f64;
613                 }
614                 pub enum TestEnum {
615                     One,
616                     Two,
617                 }
618                 impl TestTrait2 for TestEnum {
619                     const TEST_CONST: f64 = 42.0;
620                 }
621                 impl TestTrait for TestEnum {
622                     const TEST_CONST: u8 = 42;
623                 }
624             }
625
626             use test_mod::TestTrait2;
627             fn main() {
628                 test_mod::TestEnum::TEST_CONST$0;
629             }
630             ",
631         )
632     }
633
634     #[test]
635     fn trait_method() {
636         check_assist(
637             auto_import,
638             r"
639             mod test_mod {
640                 pub trait TestTrait {
641                     fn test_method(&self);
642                 }
643                 pub struct TestStruct {}
644                 impl TestTrait for TestStruct {
645                     fn test_method(&self) {}
646                 }
647             }
648
649             fn main() {
650                 let test_struct = test_mod::TestStruct {};
651                 test_struct.test_meth$0od()
652             }
653             ",
654             r"
655             use test_mod::TestTrait;
656
657             mod test_mod {
658                 pub trait TestTrait {
659                     fn test_method(&self);
660                 }
661                 pub struct TestStruct {}
662                 impl TestTrait for TestStruct {
663                     fn test_method(&self) {}
664                 }
665             }
666
667             fn main() {
668                 let test_struct = test_mod::TestStruct {};
669                 test_struct.test_method()
670             }
671             ",
672         );
673     }
674
675     #[test]
676     fn trait_method_cross_crate() {
677         check_assist(
678             auto_import,
679             r"
680             //- /main.rs crate:main deps:dep
681             fn main() {
682                 let test_struct = dep::test_mod::TestStruct {};
683                 test_struct.test_meth$0od()
684             }
685             //- /dep.rs crate:dep
686             pub mod test_mod {
687                 pub trait TestTrait {
688                     fn test_method(&self);
689                 }
690                 pub struct TestStruct {}
691                 impl TestTrait for TestStruct {
692                     fn test_method(&self) {}
693                 }
694             }
695             ",
696             r"
697             use dep::test_mod::TestTrait;
698
699             fn main() {
700                 let test_struct = dep::test_mod::TestStruct {};
701                 test_struct.test_method()
702             }
703             ",
704         );
705     }
706
707     #[test]
708     fn assoc_fn_cross_crate() {
709         check_assist(
710             auto_import,
711             r"
712             //- /main.rs crate:main deps:dep
713             fn main() {
714                 dep::test_mod::TestStruct::test_func$0tion
715             }
716             //- /dep.rs crate:dep
717             pub mod test_mod {
718                 pub trait TestTrait {
719                     fn test_function();
720                 }
721                 pub struct TestStruct {}
722                 impl TestTrait for TestStruct {
723                     fn test_function() {}
724                 }
725             }
726             ",
727             r"
728             use dep::test_mod::TestTrait;
729
730             fn main() {
731                 dep::test_mod::TestStruct::test_function
732             }
733             ",
734         );
735     }
736
737     #[test]
738     fn assoc_const_cross_crate() {
739         check_assist(
740             auto_import,
741             r"
742             //- /main.rs crate:main deps:dep
743             fn main() {
744                 dep::test_mod::TestStruct::CONST$0
745             }
746             //- /dep.rs crate:dep
747             pub mod test_mod {
748                 pub trait TestTrait {
749                     const CONST: bool;
750                 }
751                 pub struct TestStruct {}
752                 impl TestTrait for TestStruct {
753                     const CONST: bool = true;
754                 }
755             }
756             ",
757             r"
758             use dep::test_mod::TestTrait;
759
760             fn main() {
761                 dep::test_mod::TestStruct::CONST
762             }
763             ",
764         );
765     }
766
767     #[test]
768     fn assoc_fn_as_method_cross_crate() {
769         check_assist_not_applicable(
770             auto_import,
771             r"
772             //- /main.rs crate:main deps:dep
773             fn main() {
774                 let test_struct = dep::test_mod::TestStruct {};
775                 test_struct.test_func$0tion()
776             }
777             //- /dep.rs crate:dep
778             pub mod test_mod {
779                 pub trait TestTrait {
780                     fn test_function();
781                 }
782                 pub struct TestStruct {}
783                 impl TestTrait for TestStruct {
784                     fn test_function() {}
785                 }
786             }
787             ",
788         );
789     }
790
791     #[test]
792     fn private_trait_cross_crate() {
793         check_assist_not_applicable(
794             auto_import,
795             r"
796             //- /main.rs crate:main deps:dep
797             fn main() {
798                 let test_struct = dep::test_mod::TestStruct {};
799                 test_struct.test_meth$0od()
800             }
801             //- /dep.rs crate:dep
802             pub mod test_mod {
803                 trait TestTrait {
804                     fn test_method(&self);
805                 }
806                 pub struct TestStruct {}
807                 impl TestTrait for TestStruct {
808                     fn test_method(&self) {}
809                 }
810             }
811             ",
812         );
813     }
814
815     #[test]
816     fn not_applicable_for_imported_trait_for_method() {
817         check_assist_not_applicable(
818             auto_import,
819             r"
820             mod test_mod {
821                 pub trait TestTrait {
822                     fn test_method(&self);
823                 }
824                 pub trait TestTrait2 {
825                     fn test_method(&self);
826                 }
827                 pub enum TestEnum {
828                     One,
829                     Two,
830                 }
831                 impl TestTrait2 for TestEnum {
832                     fn test_method(&self) {}
833                 }
834                 impl TestTrait for TestEnum {
835                     fn test_method(&self) {}
836                 }
837             }
838
839             use test_mod::TestTrait2;
840             fn main() {
841                 let one = test_mod::TestEnum::One;
842                 one.test$0_method();
843             }
844             ",
845         )
846     }
847
848     #[test]
849     fn dep_import() {
850         check_assist(
851             auto_import,
852             r"
853 //- /lib.rs crate:dep
854 pub struct Struct;
855
856 //- /main.rs crate:main deps:dep
857 fn main() {
858     Struct$0
859 }
860 ",
861             r"use dep::Struct;
862
863 fn main() {
864     Struct
865 }
866 ",
867         );
868     }
869
870     #[test]
871     fn whole_segment() {
872         // Tests that only imports whose last segment matches the identifier get suggested.
873         check_assist(
874             auto_import,
875             r"
876 //- /lib.rs crate:dep
877 pub mod fmt {
878     pub trait Display {}
879 }
880
881 pub fn panic_fmt() {}
882
883 //- /main.rs crate:main deps:dep
884 struct S;
885
886 impl f$0mt::Display for S {}
887 ",
888             r"use dep::fmt;
889
890 struct S;
891
892 impl fmt::Display for S {}
893 ",
894         );
895     }
896
897     #[test]
898     fn macro_generated() {
899         // Tests that macro-generated items are suggested from external crates.
900         check_assist(
901             auto_import,
902             r"
903 //- /lib.rs crate:dep
904 macro_rules! mac {
905     () => {
906         pub struct Cheese;
907     };
908 }
909
910 mac!();
911
912 //- /main.rs crate:main deps:dep
913 fn main() {
914     Cheese$0;
915 }
916 ",
917             r"use dep::Cheese;
918
919 fn main() {
920     Cheese;
921 }
922 ",
923         );
924     }
925
926     #[test]
927     fn casing() {
928         // Tests that differently cased names don't interfere and we only suggest the matching one.
929         check_assist(
930             auto_import,
931             r"
932 //- /lib.rs crate:dep
933 pub struct FMT;
934 pub struct fmt;
935
936 //- /main.rs crate:main deps:dep
937 fn main() {
938     FMT$0;
939 }
940 ",
941             r"use dep::FMT;
942
943 fn main() {
944     FMT;
945 }
946 ",
947         );
948     }
949
950     #[test]
951     fn inner_items() {
952         check_assist(
953             auto_import,
954             r#"
955 mod baz {
956     pub struct Foo {}
957 }
958
959 mod bar {
960     fn bar() {
961         Foo$0;
962         println!("Hallo");
963     }
964 }
965 "#,
966             r#"
967 mod baz {
968     pub struct Foo {}
969 }
970
971 mod bar {
972     use crate::baz::Foo;
973
974     fn bar() {
975         Foo;
976         println!("Hallo");
977     }
978 }
979 "#,
980         );
981     }
982
983     #[test]
984     fn uses_abs_path_with_extern_crate_clash() {
985         cov_mark::check!(ambiguous_crate_start);
986         check_assist(
987             auto_import,
988             r#"
989 //- /main.rs crate:main deps:foo
990 mod foo {}
991
992 const _: () = {
993     Foo$0
994 };
995 //- /foo.rs crate:foo
996 pub struct Foo
997 "#,
998             r#"
999 use ::foo::Foo;
1000
1001 mod foo {}
1002
1003 const _: () = {
1004     Foo
1005 };
1006 "#,
1007         );
1008     }
1009
1010     #[test]
1011     fn works_on_ident_patterns() {
1012         check_assist(
1013             auto_import,
1014             r#"
1015 mod foo {
1016     pub struct Foo {}
1017 }
1018 fn foo() {
1019     let Foo$0;
1020 }
1021 "#,
1022             r#"
1023 use foo::Foo;
1024
1025 mod foo {
1026     pub struct Foo {}
1027 }
1028 fn foo() {
1029     let Foo;
1030 }
1031 "#,
1032         );
1033     }
1034 }