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