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