aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/base_db/src/fixture.rs6
-rw-r--r--crates/hir_ty/src/tests/regression.rs64
-rw-r--r--crates/hir_ty/src/tests/simple.rs8
-rw-r--r--crates/hir_ty/src/tests/traits.rs309
-rw-r--r--crates/ide/src/goto_implementation.rs7
-rw-r--r--crates/ide/src/hover.rs4
-rw-r--r--crates/ide/src/inlay_hints.rs21
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs3
-rw-r--r--crates/ide_assists/src/handlers/convert_into_to_from.rs6
-rw-r--r--crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs14
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs719
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs2
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs11
-rw-r--r--crates/ide_assists/src/handlers/replace_if_let_with_match.rs66
-rw-r--r--crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs13
-rw-r--r--crates/ide_assists/src/handlers/replace_unwrap_with_match.rs60
-rw-r--r--crates/ide_assists/src/tests.rs1
-rw-r--r--crates/ide_assists/src/tests/generated.rs27
-rw-r--r--crates/ide_completion/src/completions/dot.rs5
-rw-r--r--crates/ide_completion/src/completions/postfix.rs27
-rw-r--r--crates/ide_completion/src/context.rs3
-rw-r--r--crates/ide_completion/src/item.rs2
-rw-r--r--crates/ide_completion/src/render.rs20
-rw-r--r--crates/ide_completion/src/tests.rs1
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs78
-rw-r--r--crates/ide_db/src/helpers/insert_use/tests.rs165
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs76
-rw-r--r--crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs86
-rw-r--r--crates/rust-analyzer/src/config.rs4
-rw-r--r--crates/rust-analyzer/src/integrated_benchmarks.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs1
-rw-r--r--crates/syntax/src/ast/node_ext.rs17
-rw-r--r--crates/test_utils/src/minicore.rs126
-rw-r--r--docs/user/generated_config.adoc5
-rw-r--r--editors/code/package.json5
35 files changed, 1020 insertions, 944 deletions
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs
index d56b20b83..6ce377710 100644
--- a/crates/base_db/src/fixture.rs
+++ b/crates/base_db/src/fixture.rs
@@ -106,7 +106,7 @@ impl ChangeFixture {
106 let (range_or_offset, text) = extract_range_or_offset(&entry.text); 106 let (range_or_offset, text) = extract_range_or_offset(&entry.text);
107 assert!(file_position.is_none()); 107 assert!(file_position.is_none());
108 file_position = Some((file_id, range_or_offset)); 108 file_position = Some((file_id, range_or_offset));
109 text.to_string() 109 text
110 } 110 }
111 } else { 111 } else {
112 entry.text.clone() 112 entry.text.clone()
@@ -114,6 +114,9 @@ impl ChangeFixture {
114 114
115 let meta = FileMeta::from(entry); 115 let meta = FileMeta::from(entry);
116 assert!(meta.path.starts_with(&source_root_prefix)); 116 assert!(meta.path.starts_with(&source_root_prefix));
117 if !meta.deps.is_empty() {
118 assert!(meta.krate.is_some(), "can't specify deps without naming the crate")
119 }
117 120
118 if meta.introduce_new_source_root { 121 if meta.introduce_new_source_root {
119 roots.push(SourceRoot::new_local(mem::take(&mut file_set))); 122 roots.push(SourceRoot::new_local(mem::take(&mut file_set)));
@@ -199,6 +202,7 @@ impl ChangeFixture {
199 } 202 }
200} 203}
201 204
205#[derive(Debug)]
202struct FileMeta { 206struct FileMeta {
203 path: String, 207 path: String,
204 krate: Option<String>, 208 krate: Option<String>,
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index e0ad41fb9..0f418ea49 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -705,12 +705,8 @@ fn issue_4931() {
705fn issue_4885() { 705fn issue_4885() {
706 check_infer( 706 check_infer(
707 r#" 707 r#"
708 #[lang = "coerce_unsized"] 708 //- minicore: coerce_unsized, future
709 pub trait CoerceUnsized<T> {} 709 use core::future::Future;
710
711 trait Future {
712 type Output;
713 }
714 trait Foo<R> { 710 trait Foo<R> {
715 type Bar; 711 type Bar;
716 } 712 }
@@ -727,13 +723,13 @@ fn issue_4885() {
727 } 723 }
728 "#, 724 "#,
729 expect![[r#" 725 expect![[r#"
730 136..139 'key': &K 726 70..73 'key': &K
731 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> 727 132..148 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
732 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> 728 138..141 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
733 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> 729 138..146 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
734 208..211 'key': &K 730 142..145 'key': &K
735 228..231 'key': &K 731 162..165 'key': &K
736 290..293 '{ }': () 732 224..227 '{ }': ()
737 "#]], 733 "#]],
738 ); 734 );
739} 735}
@@ -796,6 +792,7 @@ fn issue_4800() {
796fn issue_4966() { 792fn issue_4966() {
797 check_infer( 793 check_infer(
798 r#" 794 r#"
795 //- minicore: deref
799 pub trait IntoIterator { 796 pub trait IntoIterator {
800 type Item; 797 type Item;
801 } 798 }
@@ -806,12 +803,7 @@ fn issue_4966() {
806 803
807 struct Vec<T> {} 804 struct Vec<T> {}
808 805
809 #[lang = "deref"] 806 impl<T> core::ops::Deref for Vec<T> {
810 pub trait Deref {
811 type Target;
812 }
813
814 impl<T> Deref for Vec<T> {
815 type Target = [T]; 807 type Target = [T];
816 } 808 }
817 809
@@ -828,23 +820,23 @@ fn issue_4966() {
828 } 820 }
829 "#, 821 "#,
830 expect![[r#" 822 expect![[r#"
831 270..274 'iter': T 823 225..229 'iter': T
832 289..291 '{}': () 824 244..246 '{}': ()
833 303..447 '{ ...r(); }': () 825 258..402 '{ ...r(); }': ()
834 313..318 'inner': Map<|&f64| -> f64> 826 268..273 'inner': Map<|&f64| -> f64>
835 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> 827 276..300 'Map { ... 0.0 }': Map<|&f64| -> f64>
836 330..343 '|_: &f64| 0.0': |&f64| -> f64 828 285..298 '|_: &f64| 0.0': |&f64| -> f64
837 331..332 '_': &f64 829 286..287 '_': &f64
838 340..343 '0.0': f64 830 295..298 '0.0': f64
839 356..362 'repeat': Repeat<Map<|&f64| -> f64>> 831 311..317 'repeat': Repeat<Map<|&f64| -> f64>>
840 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> 832 320..345 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
841 383..388 'inner': Map<|&f64| -> f64> 833 338..343 'inner': Map<|&f64| -> f64>
842 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 834 356..359 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
843 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 835 362..371 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
844 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 836 362..379 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
845 417..423 'repeat': Repeat<Map<|&f64| -> f64>> 837 372..378 'repeat': Repeat<Map<|&f64| -> f64>>
846 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 838 386..389 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
847 431..444 'vec.foo_bar()': {unknown} 839 386..399 'vec.foo_bar()': {unknown}
848 "#]], 840 "#]],
849 ); 841 );
850} 842}
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 68776f3c0..108ff3179 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1917,6 +1917,7 @@ fn fn_pointer_return() {
1917fn effects_smoke_test() { 1917fn effects_smoke_test() {
1918 check_infer( 1918 check_infer(
1919 r#" 1919 r#"
1920 //- minicore: future
1920 async fn main() { 1921 async fn main() {
1921 let x = unsafe { 92 }; 1922 let x = unsafe { 92 };
1922 let y = async { async { () }.await }; 1923 let y = async { async { () }.await };
@@ -1924,13 +1925,6 @@ fn effects_smoke_test() {
1924 let w = const { 92 }; 1925 let w = const { 92 };
1925 let t = 'a: { 92 }; 1926 let t = 'a: { 92 };
1926 } 1927 }
1927
1928 #[prelude_import] use future::*;
1929
1930 mod future {
1931 #[lang = "future_trait"]
1932 pub trait Future { type Output; }
1933 }
1934 "#, 1928 "#,
1935 expect![[r#" 1929 expect![[r#"
1936 16..162 '{ ...2 }; }': () 1930 16..162 '{ ...2 }; }': ()
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 22e0bfc49..279a1354a 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -567,11 +567,11 @@ fn indexing_arrays() {
567fn infer_ops_index() { 567fn infer_ops_index() {
568 check_types( 568 check_types(
569 r#" 569 r#"
570//- /main.rs crate:main deps:std 570//- minicore: index
571struct Bar; 571struct Bar;
572struct Foo; 572struct Foo;
573 573
574impl std::ops::Index<u32> for Bar { 574impl core::ops::Index<u32> for Bar {
575 type Output = Foo; 575 type Output = Foo;
576} 576}
577 577
@@ -580,15 +580,6 @@ fn test() {
580 let b = a[1u32]; 580 let b = a[1u32];
581 b; 581 b;
582} //^ Foo 582} //^ Foo
583
584//- /std.rs crate:std
585#[prelude_import] use ops::*;
586mod ops {
587 #[lang = "index"]
588 pub trait Index<Idx> {
589 type Output;
590 }
591}
592"#, 583"#,
593 ); 584 );
594} 585}
@@ -597,16 +588,16 @@ mod ops {
597fn infer_ops_index_int() { 588fn infer_ops_index_int() {
598 check_types( 589 check_types(
599 r#" 590 r#"
600//- /main.rs crate:main deps:std 591//- minicore: index
601struct Bar; 592struct Bar;
602struct Foo; 593struct Foo;
603 594
604impl std::ops::Index<u32> for Bar { 595impl core::ops::Index<u32> for Bar {
605 type Output = Foo; 596 type Output = Foo;
606} 597}
607 598
608struct Range; 599struct Range;
609impl std::ops::Index<Range> for Bar { 600impl core::ops::Index<Range> for Bar {
610 type Output = Bar; 601 type Output = Bar;
611} 602}
612 603
@@ -616,15 +607,6 @@ fn test() {
616 b; 607 b;
617 //^ Foo 608 //^ Foo
618} 609}
619
620//- /std.rs crate:std
621#[prelude_import] use ops::*;
622mod ops {
623 #[lang = "index"]
624 pub trait Index<Idx> {
625 type Output;
626 }
627}
628"#, 610"#,
629 ); 611 );
630} 612}
@@ -633,25 +615,12 @@ mod ops {
633fn infer_ops_index_autoderef() { 615fn infer_ops_index_autoderef() {
634 check_types( 616 check_types(
635 r#" 617 r#"
636//- /main.rs crate:main deps:std 618//- minicore: index, slice
637fn test() { 619fn test() {
638 let a = &[1u32, 2, 3]; 620 let a = &[1u32, 2, 3];
639 let b = a[1u32]; 621 let b = a[1];
640 b; 622 b;
641} //^ u32 623} //^ u32
642
643//- /std.rs crate:std
644impl<T> ops::Index<u32> for [T] {
645 type Output = T;
646}
647
648#[prelude_import] use ops::*;
649mod ops {
650 #[lang = "index"]
651 pub trait Index<Idx> {
652 type Output;
653 }
654}
655"#, 624"#,
656 ); 625 );
657} 626}
@@ -884,12 +853,9 @@ fn test<T>(t: T) { t.foo(); }
884fn generic_param_env_deref() { 853fn generic_param_env_deref() {
885 check_types( 854 check_types(
886 r#" 855 r#"
887#[lang = "deref"] 856//- minicore: deref
888trait Deref {
889 type Target;
890}
891trait Trait {} 857trait Trait {}
892impl<T> Deref for T where T: Trait { 858impl<T> core::ops::Deref for T where T: Trait {
893 type Target = i128; 859 type Target = i128;
894} 860}
895fn test<T: Trait>(t: T) { (*t); } 861fn test<T: Trait>(t: T) { (*t); }
@@ -1758,20 +1724,7 @@ fn test() {
1758fn fn_trait_deref_with_ty_default() { 1724fn fn_trait_deref_with_ty_default() {
1759 check_infer( 1725 check_infer(
1760 r#" 1726 r#"
1761#[lang = "deref"] 1727//- minicore: deref, fn
1762trait Deref {
1763 type Target;
1764
1765 fn deref(&self) -> &Self::Target;
1766}
1767
1768#[lang="fn_once"]
1769trait FnOnce<Args> {
1770 type Output;
1771
1772 fn call_once(self, args: Args) -> Self::Output;
1773}
1774
1775struct Foo; 1728struct Foo;
1776 1729
1777impl Foo { 1730impl Foo {
@@ -1784,7 +1737,7 @@ impl<T, F> Lazy<T, F> {
1784 pub fn new(f: F) -> Lazy<T, F> {} 1737 pub fn new(f: F) -> Lazy<T, F> {}
1785} 1738}
1786 1739
1787impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { 1740impl<T, F: FnOnce() -> T> core::ops::Deref for Lazy<T, F> {
1788 type Target = T; 1741 type Target = T;
1789} 1742}
1790 1743
@@ -1798,32 +1751,29 @@ fn test() {
1798 let r2 = lazy2.foo(); 1751 let r2 = lazy2.foo();
1799}"#, 1752}"#,
1800 expect![[r#" 1753 expect![[r#"
1801 64..68 'self': &Self 1754 36..40 'self': &Foo
1802 165..169 'self': Self 1755 51..53 '{}': ()
1803 171..175 'args': Args 1756 131..132 'f': F
1804 239..243 'self': &Foo 1757 151..153 '{}': ()
1805 254..256 '{}': () 1758 251..497 '{ ...o(); }': ()
1806 334..335 'f': F 1759 261..266 'lazy1': Lazy<Foo, || -> Foo>
1807 354..356 '{}': () 1760 283..292 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo>
1808 443..689 '{ ...o(); }': () 1761 283..300 'Lazy::...| Foo)': Lazy<Foo, || -> Foo>
1809 453..458 'lazy1': Lazy<Foo, || -> Foo> 1762 293..299 '|| Foo': || -> Foo
1810 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> 1763 296..299 'Foo': Foo
1811 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> 1764 310..312 'r1': usize
1812 485..491 '|| Foo': || -> Foo 1765 315..320 'lazy1': Lazy<Foo, || -> Foo>
1813 488..491 'Foo': Foo 1766 315..326 'lazy1.foo()': usize
1814 502..504 'r1': usize 1767 368..383 'make_foo_fn_ptr': fn() -> Foo
1815 507..512 'lazy1': Lazy<Foo, || -> Foo> 1768 399..410 'make_foo_fn': fn make_foo_fn() -> Foo
1816 507..518 'lazy1.foo()': usize 1769 420..425 'lazy2': Lazy<Foo, fn() -> Foo>
1817 560..575 'make_foo_fn_ptr': fn() -> Foo 1770 442..451 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo>
1818 591..602 'make_foo_fn': fn make_foo_fn() -> Foo 1771 442..468 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo>
1819 612..617 'lazy2': Lazy<Foo, fn() -> Foo> 1772 452..467 'make_foo_fn_ptr': fn() -> Foo
1820 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> 1773 478..480 'r2': usize
1821 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> 1774 483..488 'lazy2': Lazy<Foo, fn() -> Foo>
1822 644..659 'make_foo_fn_ptr': fn() -> Foo 1775 483..494 'lazy2.foo()': usize
1823 670..672 'r2': usize 1776 357..359 '{}': ()
1824 675..680 'lazy2': Lazy<Foo, fn() -> Foo>
1825 675..686 'lazy2.foo()': usize
1826 549..551 '{}': ()
1827 "#]], 1777 "#]],
1828 ); 1778 );
1829} 1779}
@@ -2731,9 +2681,7 @@ fn test(x: &dyn Foo) {
2731fn builtin_copy() { 2681fn builtin_copy() {
2732 check_infer_with_mismatches( 2682 check_infer_with_mismatches(
2733 r#" 2683 r#"
2734#[lang = "copy"] 2684//- minicore: copy
2735trait Copy {}
2736
2737struct IsCopy; 2685struct IsCopy;
2738impl Copy for IsCopy {} 2686impl Copy for IsCopy {}
2739struct NotCopy; 2687struct NotCopy;
@@ -2748,20 +2696,20 @@ fn test() {
2748 (IsCopy, NotCopy).test(); 2696 (IsCopy, NotCopy).test();
2749}"#, 2697}"#,
2750 expect![[r#" 2698 expect![[r#"
2751 110..114 'self': &Self 2699 78..82 'self': &Self
2752 166..267 '{ ...t(); }': () 2700 134..235 '{ ...t(); }': ()
2753 172..178 'IsCopy': IsCopy 2701 140..146 'IsCopy': IsCopy
2754 172..185 'IsCopy.test()': bool 2702 140..153 'IsCopy.test()': bool
2755 191..198 'NotCopy': NotCopy 2703 159..166 'NotCopy': NotCopy
2756 191..205 'NotCopy.test()': {unknown} 2704 159..173 'NotCopy.test()': {unknown}
2757 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) 2705 179..195 '(IsCop...sCopy)': (IsCopy, IsCopy)
2758 211..234 '(IsCop...test()': bool 2706 179..202 '(IsCop...test()': bool
2759 212..218 'IsCopy': IsCopy 2707 180..186 'IsCopy': IsCopy
2760 220..226 'IsCopy': IsCopy 2708 188..194 'IsCopy': IsCopy
2761 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) 2709 208..225 '(IsCop...tCopy)': (IsCopy, NotCopy)
2762 240..264 '(IsCop...test()': {unknown} 2710 208..232 '(IsCop...test()': {unknown}
2763 241..247 'IsCopy': IsCopy 2711 209..215 'IsCopy': IsCopy
2764 249..256 'NotCopy': NotCopy 2712 217..224 'NotCopy': NotCopy
2765 "#]], 2713 "#]],
2766 ); 2714 );
2767} 2715}
@@ -2770,9 +2718,7 @@ fn test() {
2770fn builtin_fn_def_copy() { 2718fn builtin_fn_def_copy() {
2771 check_infer_with_mismatches( 2719 check_infer_with_mismatches(
2772 r#" 2720 r#"
2773#[lang = "copy"] 2721//- minicore: copy
2774trait Copy {}
2775
2776fn foo() {} 2722fn foo() {}
2777fn bar<T: Copy>(T) -> T {} 2723fn bar<T: Copy>(T) -> T {}
2778struct Struct(usize); 2724struct Struct(usize);
@@ -2788,20 +2734,20 @@ fn test() {
2788 Enum::Variant.test(); 2734 Enum::Variant.test();
2789}"#, 2735}"#,
2790 expect![[r#" 2736 expect![[r#"
2791 41..43 '{}': () 2737 9..11 '{}': ()
2792 60..61 'T': {unknown} 2738 28..29 'T': {unknown}
2793 68..70 '{}': () 2739 36..38 '{}': ()
2794 68..70: expected T, got () 2740 36..38: expected T, got ()
2795 145..149 'self': &Self 2741 113..117 'self': &Self
2796 201..281 '{ ...t(); }': () 2742 169..249 '{ ...t(); }': ()
2797 207..210 'foo': fn foo() 2743 175..178 'foo': fn foo()
2798 207..217 'foo.test()': bool 2744 175..185 'foo.test()': bool
2799 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} 2745 191..194 'bar': fn bar<{unknown}>({unknown}) -> {unknown}
2800 223..233 'bar.test()': bool 2746 191..201 'bar.test()': bool
2801 239..245 'Struct': Struct(usize) -> Struct 2747 207..213 'Struct': Struct(usize) -> Struct
2802 239..252 'Struct.test()': bool 2748 207..220 'Struct.test()': bool
2803 258..271 'Enum::Variant': Variant(usize) -> Enum 2749 226..239 'Enum::Variant': Variant(usize) -> Enum
2804 258..278 'Enum::...test()': bool 2750 226..246 'Enum::...test()': bool
2805 "#]], 2751 "#]],
2806 ); 2752 );
2807} 2753}
@@ -2810,9 +2756,7 @@ fn test() {
2810fn builtin_fn_ptr_copy() { 2756fn builtin_fn_ptr_copy() {
2811 check_infer_with_mismatches( 2757 check_infer_with_mismatches(
2812 r#" 2758 r#"
2813#[lang = "copy"] 2759//- minicore: copy
2814trait Copy {}
2815
2816trait Test { fn test(&self) -> bool; } 2760trait Test { fn test(&self) -> bool; }
2817impl<T: Copy> Test for T {} 2761impl<T: Copy> Test for T {}
2818 2762
@@ -2822,17 +2766,17 @@ fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2822 f3.test(); 2766 f3.test();
2823}"#, 2767}"#,
2824 expect![[r#" 2768 expect![[r#"
2825 54..58 'self': &Self 2769 22..26 'self': &Self
2826 108..110 'f1': fn() 2770 76..78 'f1': fn()
2827 118..120 'f2': fn(usize) -> u8 2771 86..88 'f2': fn(usize) -> u8
2828 139..141 'f3': fn(u8, u8) -> &u8 2772 107..109 'f3': fn(u8, u8) -> &u8
2829 162..210 '{ ...t(); }': () 2773 130..178 '{ ...t(); }': ()
2830 168..170 'f1': fn() 2774 136..138 'f1': fn()
2831 168..177 'f1.test()': bool 2775 136..145 'f1.test()': bool
2832 183..185 'f2': fn(usize) -> u8 2776 151..153 'f2': fn(usize) -> u8
2833 183..192 'f2.test()': bool 2777 151..160 'f2.test()': bool
2834 198..200 'f3': fn(u8, u8) -> &u8 2778 166..168 'f3': fn(u8, u8) -> &u8
2835 198..207 'f3.test()': bool 2779 166..175 'f3.test()': bool
2836 "#]], 2780 "#]],
2837 ); 2781 );
2838} 2782}
@@ -2841,9 +2785,7 @@ fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2841fn builtin_sized() { 2785fn builtin_sized() {
2842 check_infer_with_mismatches( 2786 check_infer_with_mismatches(
2843 r#" 2787 r#"
2844#[lang = "sized"] 2788//- minicore: sized
2845trait Sized {}
2846
2847trait Test { fn test(&self) -> bool; } 2789trait Test { fn test(&self) -> bool; }
2848impl<T: Sized> Test for T {} 2790impl<T: Sized> Test for T {}
2849 2791
@@ -2854,22 +2796,22 @@ fn test() {
2854 (1u8, *"foo").test(); // not Sized 2796 (1u8, *"foo").test(); // not Sized
2855}"#, 2797}"#,
2856 expect![[r#" 2798 expect![[r#"
2857 56..60 'self': &Self 2799 22..26 'self': &Self
2858 113..228 '{ ...ized }': () 2800 79..194 '{ ...ized }': ()
2859 119..122 '1u8': u8 2801 85..88 '1u8': u8
2860 119..129 '1u8.test()': bool 2802 85..95 '1u8.test()': bool
2861 135..150 '(*"foo").test()': {unknown} 2803 101..116 '(*"foo").test()': {unknown}
2862 136..142 '*"foo"': str 2804 102..108 '*"foo"': str
2863 137..142 '"foo"': &str 2805 103..108 '"foo"': &str
2864 169..179 '(1u8, 1u8)': (u8, u8) 2806 135..145 '(1u8, 1u8)': (u8, u8)
2865 169..186 '(1u8, ...test()': bool 2807 135..152 '(1u8, ...test()': bool
2866 170..173 '1u8': u8 2808 136..139 '1u8': u8
2867 175..178 '1u8': u8 2809 141..144 '1u8': u8
2868 192..205 '(1u8, *"foo")': (u8, str) 2810 158..171 '(1u8, *"foo")': (u8, str)
2869 192..212 '(1u8, ...test()': {unknown} 2811 158..178 '(1u8, ...test()': {unknown}
2870 193..196 '1u8': u8 2812 159..162 '1u8': u8
2871 198..204 '*"foo"': str 2813 164..170 '*"foo"': str
2872 199..204 '"foo"': &str 2814 165..170 '"foo"': &str
2873 "#]], 2815 "#]],
2874 ); 2816 );
2875} 2817}
@@ -2980,28 +2922,13 @@ fn infer_box_fn_arg() {
2980 // The type mismatch is because we don't define Unsize and CoerceUnsized 2922 // The type mismatch is because we don't define Unsize and CoerceUnsized
2981 check_infer_with_mismatches( 2923 check_infer_with_mismatches(
2982 r#" 2924 r#"
2983//- /lib.rs deps:std 2925//- minicore: fn, deref, option
2984
2985#[lang = "fn_once"]
2986pub trait FnOnce<Args> {
2987 type Output;
2988
2989 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
2990}
2991
2992#[lang = "deref"]
2993pub trait Deref {
2994 type Target: ?Sized;
2995
2996 fn deref(&self) -> &Self::Target;
2997}
2998
2999#[lang = "owned_box"] 2926#[lang = "owned_box"]
3000pub struct Box<T: ?Sized> { 2927pub struct Box<T: ?Sized> {
3001 inner: *mut T, 2928 inner: *mut T,
3002} 2929}
3003 2930
3004impl<T: ?Sized> Deref for Box<T> { 2931impl<T: ?Sized> core::ops::Deref for Box<T> {
3005 type Target = T; 2932 type Target = T;
3006 2933
3007 fn deref(&self) -> &T { 2934 fn deref(&self) -> &T {
@@ -3009,38 +2936,30 @@ impl<T: ?Sized> Deref for Box<T> {
3009 } 2936 }
3010} 2937}
3011 2938
3012enum Option<T> {
3013 None,
3014 Some(T)
3015}
3016
3017fn foo() { 2939fn foo() {
3018 let s = Option::None; 2940 let s = None;
3019 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); 2941 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
3020 f(&s); 2942 f(&s);
3021}"#, 2943}"#,
3022 expect![[r#" 2944 expect![[r#"
3023 100..104 'self': Self 2945 154..158 'self': &Box<T>
3024 106..110 'args': Args 2946 166..193 '{ ... }': &T
3025 214..218 'self': &Self 2947 176..187 '&self.inner': &*mut T
3026 384..388 'self': &Box<T> 2948 177..181 'self': &Box<T>
3027 396..423 '{ ... }': &T 2949 177..187 'self.inner': *mut T
3028 406..417 '&self.inner': &*mut T 2950 206..296 '{ ...&s); }': ()
3029 407..411 'self': &Box<T> 2951 216..217 's': Option<i32>
3030 407..417 'self.inner': *mut T 2952 220..224 'None': Option<i32>
3031 478..576 '{ ...&s); }': () 2953 234..235 'f': Box<dyn FnOnce(&Option<i32>)>
3032 488..489 's': Option<i32> 2954 269..282 'box (|ps| {})': Box<|{unknown}| -> ()>
3033 492..504 'Option::None': Option<i32> 2955 274..281 '|ps| {}': |{unknown}| -> ()
3034 514..515 'f': Box<dyn FnOnce(&Option<i32>)> 2956 275..277 'ps': {unknown}
3035 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> 2957 279..281 '{}': ()
3036 554..561 '|ps| {}': |{unknown}| -> () 2958 288..289 'f': Box<dyn FnOnce(&Option<i32>)>
3037 555..557 'ps': {unknown} 2959 288..293 'f(&s)': ()
3038 559..561 '{}': () 2960 290..292 '&s': &Option<i32>
3039 568..569 'f': Box<dyn FnOnce(&Option<i32>)> 2961 291..292 's': Option<i32>
3040 568..573 'f(&s)': () 2962 269..282: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
3041 570..572 '&s': &Option<i32>
3042 571..572 's': Option<i32>
3043 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
3044 "#]], 2963 "#]],
3045 ); 2964 );
3046} 2965}
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs
index 0013820b4..07686017d 100644
--- a/crates/ide/src/goto_implementation.rs
+++ b/crates/ide/src/goto_implementation.rs
@@ -236,15 +236,10 @@ impl T for &Foo {}
236 fn goto_implementation_to_builtin_derive() { 236 fn goto_implementation_to_builtin_derive() {
237 check( 237 check(
238 r#" 238 r#"
239//- minicore: copy, derive
239 #[derive(Copy)] 240 #[derive(Copy)]
240//^^^^^^^^^^^^^^^ 241//^^^^^^^^^^^^^^^
241struct Foo$0; 242struct Foo$0;
242
243mod marker {
244 trait Copy {}
245}
246#[rustc_builtin_macro]
247macro Copy {}
248"#, 243"#,
249 ); 244 );
250 } 245 }
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 3c3de3ffd..2e1359eef 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3014,8 +3014,8 @@ fn foo() {
3014 file_id: FileId( 3014 file_id: FileId(
3015 1, 3015 1,
3016 ), 3016 ),
3017 full_range: 248..430, 3017 full_range: 251..433,
3018 focus_range: 287..293, 3018 focus_range: 290..296,
3019 name: "Future", 3019 name: "Future",
3020 kind: Trait, 3020 kind: Trait,
3021 description: "pub trait Future", 3021 description: "pub trait Future",
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 335d57a0d..95f9edce4 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -661,9 +661,7 @@ fn main() {
661 fn function_call_parameter_hint() { 661 fn function_call_parameter_hint() {
662 check_params( 662 check_params(
663 r#" 663 r#"
664enum Option<T> { None, Some(T) } 664//- minicore: option
665use Option::*;
666
667struct FileId {} 665struct FileId {}
668struct SmolStr {} 666struct SmolStr {}
669 667
@@ -872,7 +870,6 @@ fn main() {
872 check_types( 870 check_types(
873 r#" 871 r#"
874//- minicore: fn, sized 872//- minicore: fn, sized
875
876fn foo() -> impl Fn() { loop {} } 873fn foo() -> impl Fn() { loop {} }
877fn foo1() -> impl Fn(f64) { loop {} } 874fn foo1() -> impl Fn(f64) { loop {} }
878fn foo2() -> impl Fn(f64, f64) { loop {} } 875fn foo2() -> impl Fn(f64, f64) { loop {} }
@@ -908,9 +905,7 @@ fn main() {
908 fn unit_structs_have_no_type_hints() { 905 fn unit_structs_have_no_type_hints() {
909 check_types( 906 check_types(
910 r#" 907 r#"
911enum Result<T, E> { Ok(T), Err(E) } 908//- minicore: result
912use Result::*;
913
914struct SyntheticSyntax; 909struct SyntheticSyntax;
915 910
916fn main() { 911fn main() {
@@ -962,9 +957,7 @@ fn main() {
962 fn if_expr() { 957 fn if_expr() {
963 check_types( 958 check_types(
964 r#" 959 r#"
965enum Option<T> { None, Some(T) } 960//- minicore: option
966use Option::*;
967
968struct Test { a: Option<u32>, b: u8 } 961struct Test { a: Option<u32>, b: u8 }
969 962
970fn main() { 963fn main() {
@@ -994,9 +987,7 @@ fn main() {
994 fn while_expr() { 987 fn while_expr() {
995 check_types( 988 check_types(
996 r#" 989 r#"
997enum Option<T> { None, Some(T) } 990//- minicore: option
998use Option::*;
999
1000struct Test { a: Option<u32>, b: u8 } 991struct Test { a: Option<u32>, b: u8 }
1001 992
1002fn main() { 993fn main() {
@@ -1012,9 +1003,7 @@ fn main() {
1012 fn match_arm_list() { 1003 fn match_arm_list() {
1013 check_types( 1004 check_types(
1014 r#" 1005 r#"
1015enum Option<T> { None, Some(T) } 1006//- minicore: option
1016use Option::*;
1017
1018struct Test { a: Option<u32>, b: u8 } 1007struct Test { a: Option<u32>, b: u8 }
1019 1008
1020fn main() { 1009fn main() {
diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs
index d4748ef3a..accc345fc 100644
--- a/crates/ide_assists/src/handlers/auto_import.rs
+++ b/crates/ide_assists/src/handlers/auto_import.rs
@@ -103,8 +103,9 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
103 let scope = match scope.clone() { 103 let scope = match scope.clone() {
104 ImportScope::File(it) => ImportScope::File(builder.make_mut(it)), 104 ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
105 ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)), 105 ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
106 ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
106 }; 107 };
107 insert_use(&scope, mod_path_to_ast(&import.import_path), ctx.config.insert_use); 108 insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
108 }, 109 },
109 ); 110 );
110 } 111 }
diff --git a/crates/ide_assists/src/handlers/convert_into_to_from.rs b/crates/ide_assists/src/handlers/convert_into_to_from.rs
index 79a0c4879..2d8b936cd 100644
--- a/crates/ide_assists/src/handlers/convert_into_to_from.rs
+++ b/crates/ide_assists/src/handlers/convert_into_to_from.rs
@@ -13,10 +13,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
13// Converts an Into impl to an equivalent From impl. 13// Converts an Into impl to an equivalent From impl.
14// 14//
15// ``` 15// ```
16// # //- /lib.rs crate:core 16// # //- minicore: from
17// # pub mod convert { pub trait Into<T> { pub fn into(self) -> T; } }
18// # //- /lib.rs crate:main deps:core
19// # use core::convert::Into;
20// impl $0Into<Thing> for usize { 17// impl $0Into<Thing> for usize {
21// fn into(self) -> Thing { 18// fn into(self) -> Thing {
22// Thing { 19// Thing {
@@ -28,7 +25,6 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
28// ``` 25// ```
29// -> 26// ->
30// ``` 27// ```
31// # use core::convert::Into;
32// impl From<usize> for Thing { 28// impl From<usize> for Thing {
33// fn from(val: usize) -> Self { 29// fn from(val: usize) -> Self {
34// Thing { 30// Thing {
diff --git a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
index 7fd73d4c7..70754adf9 100644
--- a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
+++ b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
@@ -11,14 +11,10 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
11// Converts an Iterator::for_each function into a for loop. 11// Converts an Iterator::for_each function into a for loop.
12// 12//
13// ``` 13// ```
14// # //- /lib.rs crate:core 14// # //- minicore: iterators
15// # pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } } 15// # use core::iter;
16// # pub struct SomeIter;
17// # impl self::iter::traits::iterator::Iterator for SomeIter {}
18// # //- /lib.rs crate:main deps:core
19// # use core::SomeIter;
20// fn main() { 16// fn main() {
21// let iter = SomeIter; 17// let iter = iter::repeat((9, 2));
22// iter.for_each$0(|(x, y)| { 18// iter.for_each$0(|(x, y)| {
23// println!("x: {}, y: {}", x, y); 19// println!("x: {}, y: {}", x, y);
24// }); 20// });
@@ -26,9 +22,9 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
26// ``` 22// ```
27// -> 23// ->
28// ``` 24// ```
29// # use core::SomeIter; 25// # use core::iter;
30// fn main() { 26// fn main() {
31// let iter = SomeIter; 27// let iter = iter::repeat((9, 2));
32// for (x, y) in iter { 28// for (x, y) in iter {
33// println!("x: {}, y: {}", x, y); 29// println!("x: {}, y: {}", x, y);
34// } 30// }
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
index 7085a0c48..ac7f0959b 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -1501,7 +1501,8 @@ mod tests {
1501 r#" 1501 r#"
1502fn foo() { 1502fn foo() {
1503 foo($01 + 1$0); 1503 foo($01 + 1$0);
1504}"#, 1504}
1505"#,
1505 r#" 1506 r#"
1506fn foo() { 1507fn foo() {
1507 foo(fun_name()); 1508 foo(fun_name());
@@ -1509,7 +1510,8 @@ fn foo() {
1509 1510
1510fn $0fun_name() -> i32 { 1511fn $0fun_name() -> i32 {
1511 1 + 1 1512 1 + 1
1512}"#, 1513}
1514"#,
1513 ); 1515 );
1514 } 1516 }
1515 1517
@@ -1522,7 +1524,8 @@ mod bar {
1522 fn foo() { 1524 fn foo() {
1523 foo($01 + 1$0); 1525 foo($01 + 1$0);
1524 } 1526 }
1525}"#, 1527}
1528"#,
1526 r#" 1529 r#"
1527mod bar { 1530mod bar {
1528 fn foo() { 1531 fn foo() {
@@ -1532,7 +1535,8 @@ mod bar {
1532 fn $0fun_name() -> i32 { 1535 fn $0fun_name() -> i32 {
1533 1 + 1 1536 1 + 1
1534 } 1537 }
1535}"#, 1538}
1539"#,
1536 ); 1540 );
1537 } 1541 }
1538 1542
@@ -1543,7 +1547,8 @@ mod bar {
1543 r#" 1547 r#"
1544fn foo() { 1548fn foo() {
1545 $0{ 1 + 1 }$0; 1549 $0{ 1 + 1 }$0;
1546}"#, 1550}
1551"#,
1547 r#" 1552 r#"
1548fn foo() { 1553fn foo() {
1549 fun_name(); 1554 fun_name();
@@ -1551,7 +1556,8 @@ fn foo() {
1551 1556
1552fn $0fun_name() -> i32 { 1557fn $0fun_name() -> i32 {
1553 1 + 1 1558 1 + 1
1554}"#, 1559}
1560"#,
1555 ); 1561 );
1556 } 1562 }
1557 1563
@@ -1564,7 +1570,8 @@ fn foo() -> i32 {
1564 let k = 1; 1570 let k = 1;
1565 $0let m = 1; 1571 $0let m = 1;
1566 m + 1$0 1572 m + 1$0
1567}"#, 1573}
1574"#,
1568 r#" 1575 r#"
1569fn foo() -> i32 { 1576fn foo() -> i32 {
1570 let k = 1; 1577 let k = 1;
@@ -1574,7 +1581,8 @@ fn foo() -> i32 {
1574fn $0fun_name() -> i32 { 1581fn $0fun_name() -> i32 {
1575 let m = 1; 1582 let m = 1;
1576 m + 1 1583 m + 1
1577}"#, 1584}
1585"#,
1578 ); 1586 );
1579 } 1587 }
1580 1588
@@ -1588,7 +1596,8 @@ fn foo() {
1588 $0let m = 1; 1596 $0let m = 1;
1589 let n = m + 1;$0 1597 let n = m + 1;$0
1590 let g = 5; 1598 let g = 5;
1591}"#, 1599}
1600"#,
1592 r#" 1601 r#"
1593fn foo() { 1602fn foo() {
1594 let k = 3; 1603 let k = 3;
@@ -1599,7 +1608,8 @@ fn foo() {
1599fn $0fun_name() { 1608fn $0fun_name() {
1600 let m = 1; 1609 let m = 1;
1601 let n = m + 1; 1610 let n = m + 1;
1602}"#, 1611}
1612"#,
1603 ); 1613 );
1604 } 1614 }
1605 1615
@@ -1610,7 +1620,8 @@ fn $0fun_name() {
1610 r#" 1620 r#"
1611fn foo() { 1621fn foo() {
1612 $0if true { }$0 1622 $0if true { }$0
1613}"#, 1623}
1624"#,
1614 r#" 1625 r#"
1615fn foo() { 1626fn foo() {
1616 fun_name(); 1627 fun_name();
@@ -1618,7 +1629,8 @@ fn foo() {
1618 1629
1619fn $0fun_name() { 1630fn $0fun_name() {
1620 if true { } 1631 if true { }
1621}"#, 1632}
1633"#,
1622 ); 1634 );
1623 } 1635 }
1624 1636
@@ -1629,7 +1641,8 @@ fn $0fun_name() {
1629 r#" 1641 r#"
1630fn foo() -> i32 { 1642fn foo() -> i32 {
1631 $0if true { 1 } else { 2 }$0 1643 $0if true { 1 } else { 2 }$0
1632}"#, 1644}
1645"#,
1633 r#" 1646 r#"
1634fn foo() -> i32 { 1647fn foo() -> i32 {
1635 fun_name() 1648 fun_name()
@@ -1637,7 +1650,8 @@ fn foo() -> i32 {
1637 1650
1638fn $0fun_name() -> i32 { 1651fn $0fun_name() -> i32 {
1639 if true { 1 } else { 2 } 1652 if true { 1 } else { 2 }
1640}"#, 1653}
1654"#,
1641 ); 1655 );
1642 } 1656 }
1643 1657
@@ -1648,7 +1662,8 @@ fn $0fun_name() -> i32 {
1648 r#" 1662 r#"
1649fn foo() -> i32 { 1663fn foo() -> i32 {
1650 $0if let true = false { 1 } else { 2 }$0 1664 $0if let true = false { 1 } else { 2 }$0
1651}"#, 1665}
1666"#,
1652 r#" 1667 r#"
1653fn foo() -> i32 { 1668fn foo() -> i32 {
1654 fun_name() 1669 fun_name()
@@ -1656,7 +1671,8 @@ fn foo() -> i32 {
1656 1671
1657fn $0fun_name() -> i32 { 1672fn $0fun_name() -> i32 {
1658 if let true = false { 1 } else { 2 } 1673 if let true = false { 1 } else { 2 }
1659}"#, 1674}
1675"#,
1660 ); 1676 );
1661 } 1677 }
1662 1678
@@ -1670,7 +1686,8 @@ fn foo() -> i32 {
1670 true => 1, 1686 true => 1,
1671 false => 2, 1687 false => 2,
1672 }$0 1688 }$0
1673}"#, 1689}
1690"#,
1674 r#" 1691 r#"
1675fn foo() -> i32 { 1692fn foo() -> i32 {
1676 fun_name() 1693 fun_name()
@@ -1681,7 +1698,8 @@ fn $0fun_name() -> i32 {
1681 true => 1, 1698 true => 1,
1682 false => 2, 1699 false => 2,
1683 } 1700 }
1684}"#, 1701}
1702"#,
1685 ); 1703 );
1686 } 1704 }
1687 1705
@@ -1692,7 +1710,8 @@ fn $0fun_name() -> i32 {
1692 r#" 1710 r#"
1693fn foo() { 1711fn foo() {
1694 $0while true { }$0 1712 $0while true { }$0
1695}"#, 1713}
1714"#,
1696 r#" 1715 r#"
1697fn foo() { 1716fn foo() {
1698 fun_name(); 1717 fun_name();
@@ -1700,7 +1719,8 @@ fn foo() {
1700 1719
1701fn $0fun_name() { 1720fn $0fun_name() {
1702 while true { } 1721 while true { }
1703}"#, 1722}
1723"#,
1704 ); 1724 );
1705 } 1725 }
1706 1726
@@ -1711,7 +1731,8 @@ fn $0fun_name() {
1711 r#" 1731 r#"
1712fn foo() { 1732fn foo() {
1713 $0for v in &[0, 1] { }$0 1733 $0for v in &[0, 1] { }$0
1714}"#, 1734}
1735"#,
1715 r#" 1736 r#"
1716fn foo() { 1737fn foo() {
1717 fun_name(); 1738 fun_name();
@@ -1719,7 +1740,8 @@ fn foo() {
1719 1740
1720fn $0fun_name() { 1741fn $0fun_name() {
1721 for v in &[0, 1] { } 1742 for v in &[0, 1] { }
1722}"#, 1743}
1744"#,
1723 ); 1745 );
1724 } 1746 }
1725 1747
@@ -1732,7 +1754,8 @@ fn foo() {
1732 $0loop { 1754 $0loop {
1733 let m = 1; 1755 let m = 1;
1734 }$0 1756 }$0
1735}"#, 1757}
1758"#,
1736 r#" 1759 r#"
1737fn foo() { 1760fn foo() {
1738 fun_name() 1761 fun_name()
@@ -1742,7 +1765,8 @@ fn $0fun_name() -> ! {
1742 loop { 1765 loop {
1743 let m = 1; 1766 let m = 1;
1744 } 1767 }
1745}"#, 1768}
1769"#,
1746 ); 1770 );
1747 } 1771 }
1748 1772
@@ -1756,7 +1780,8 @@ fn foo() {
1756 let m = 1; 1780 let m = 1;
1757 break m; 1781 break m;
1758 }$0; 1782 }$0;
1759}"#, 1783}
1784"#,
1760 r#" 1785 r#"
1761fn foo() { 1786fn foo() {
1762 let v = fun_name(); 1787 let v = fun_name();
@@ -1767,7 +1792,8 @@ fn $0fun_name() -> i32 {
1767 let m = 1; 1792 let m = 1;
1768 break m; 1793 break m;
1769 } 1794 }
1770}"#, 1795}
1796"#,
1771 ); 1797 );
1772 } 1798 }
1773 1799
@@ -1781,7 +1807,8 @@ fn foo() {
1781 Some(x) => x, 1807 Some(x) => x,
1782 None => 0, 1808 None => 0,
1783 }$0; 1809 }$0;
1784}"#, 1810}
1811"#,
1785 r#" 1812 r#"
1786fn foo() { 1813fn foo() {
1787 let v: i32 = fun_name(); 1814 let v: i32 = fun_name();
@@ -1792,7 +1819,8 @@ fn $0fun_name() -> i32 {
1792 Some(x) => x, 1819 Some(x) => x,
1793 None => 0, 1820 None => 0,
1794 } 1821 }
1795}"#, 1822}
1823"#,
1796 ); 1824 );
1797 } 1825 }
1798 1826
@@ -1805,7 +1833,8 @@ fn foo() {
1805 let n = 1; 1833 let n = 1;
1806 let mut v = $0n * n;$0 1834 let mut v = $0n * n;$0
1807 v += 1; 1835 v += 1;
1808}"#, 1836}
1837"#,
1809 r#" 1838 r#"
1810fn foo() { 1839fn foo() {
1811 let n = 1; 1840 let n = 1;
@@ -1816,7 +1845,8 @@ fn foo() {
1816fn $0fun_name(n: i32) -> i32 { 1845fn $0fun_name(n: i32) -> i32 {
1817 let mut v = n * n; 1846 let mut v = n * n;
1818 v 1847 v
1819}"#, 1848}
1849"#,
1820 ); 1850 );
1821 } 1851 }
1822 1852
@@ -1832,7 +1862,8 @@ fn foo() {
1832 let mut w = 3;$0 1862 let mut w = 3;$0
1833 v += 1; 1863 v += 1;
1834 w += 1; 1864 w += 1;
1835}"#, 1865}
1866"#,
1836 r#" 1867 r#"
1837fn foo() { 1868fn foo() {
1838 let m = 2; 1869 let m = 2;
@@ -1846,7 +1877,8 @@ fn $0fun_name(m: i32, n: i32) -> (i32, i32) {
1846 let mut v = m * n; 1877 let mut v = m * n;
1847 let mut w = 3; 1878 let mut w = 3;
1848 (v, w) 1879 (v, w)
1849}"#, 1880}
1881"#,
1850 ); 1882 );
1851 } 1883 }
1852 1884
@@ -1854,12 +1886,13 @@ fn $0fun_name(m: i32, n: i32) -> (i32, i32) {
1854 fn argument_form_expr() { 1886 fn argument_form_expr() {
1855 check_assist( 1887 check_assist(
1856 extract_function, 1888 extract_function,
1857 r" 1889 r#"
1858fn foo() -> u32 { 1890fn foo() -> u32 {
1859 let n = 2; 1891 let n = 2;
1860 $0n+2$0 1892 $0n+2$0
1861}", 1893}
1862 r" 1894"#,
1895 r#"
1863fn foo() -> u32 { 1896fn foo() -> u32 {
1864 let n = 2; 1897 let n = 2;
1865 fun_name(n) 1898 fun_name(n)
@@ -1867,7 +1900,8 @@ fn foo() -> u32 {
1867 1900
1868fn $0fun_name(n: u32) -> u32 { 1901fn $0fun_name(n: u32) -> u32 {
1869 n+2 1902 n+2
1870}", 1903}
1904"#,
1871 ) 1905 )
1872 } 1906 }
1873 1907
@@ -1875,12 +1909,13 @@ fn $0fun_name(n: u32) -> u32 {
1875 fn argument_used_twice_form_expr() { 1909 fn argument_used_twice_form_expr() {
1876 check_assist( 1910 check_assist(
1877 extract_function, 1911 extract_function,
1878 r" 1912 r#"
1879fn foo() -> u32 { 1913fn foo() -> u32 {
1880 let n = 2; 1914 let n = 2;
1881 $0n+n$0 1915 $0n+n$0
1882}", 1916}
1883 r" 1917"#,
1918 r#"
1884fn foo() -> u32 { 1919fn foo() -> u32 {
1885 let n = 2; 1920 let n = 2;
1886 fun_name(n) 1921 fun_name(n)
@@ -1888,7 +1923,8 @@ fn foo() -> u32 {
1888 1923
1889fn $0fun_name(n: u32) -> u32 { 1924fn $0fun_name(n: u32) -> u32 {
1890 n+n 1925 n+n
1891}", 1926}
1927"#,
1892 ) 1928 )
1893 } 1929 }
1894 1930
@@ -1896,13 +1932,14 @@ fn $0fun_name(n: u32) -> u32 {
1896 fn two_arguments_form_expr() { 1932 fn two_arguments_form_expr() {
1897 check_assist( 1933 check_assist(
1898 extract_function, 1934 extract_function,
1899 r" 1935 r#"
1900fn foo() -> u32 { 1936fn foo() -> u32 {
1901 let n = 2; 1937 let n = 2;
1902 let m = 3; 1938 let m = 3;
1903 $0n+n*m$0 1939 $0n+n*m$0
1904}", 1940}
1905 r" 1941"#,
1942 r#"
1906fn foo() -> u32 { 1943fn foo() -> u32 {
1907 let n = 2; 1944 let n = 2;
1908 let m = 3; 1945 let m = 3;
@@ -1911,7 +1948,8 @@ fn foo() -> u32 {
1911 1948
1912fn $0fun_name(n: u32, m: u32) -> u32 { 1949fn $0fun_name(n: u32, m: u32) -> u32 {
1913 n+n*m 1950 n+n*m
1914}", 1951}
1952"#,
1915 ) 1953 )
1916 } 1954 }
1917 1955
@@ -1919,13 +1957,14 @@ fn $0fun_name(n: u32, m: u32) -> u32 {
1919 fn argument_and_locals() { 1957 fn argument_and_locals() {
1920 check_assist( 1958 check_assist(
1921 extract_function, 1959 extract_function,
1922 r" 1960 r#"
1923fn foo() -> u32 { 1961fn foo() -> u32 {
1924 let n = 2; 1962 let n = 2;
1925 $0let m = 1; 1963 $0let m = 1;
1926 n + m$0 1964 n + m$0
1927}", 1965}
1928 r" 1966"#,
1967 r#"
1929fn foo() -> u32 { 1968fn foo() -> u32 {
1930 let n = 2; 1969 let n = 2;
1931 fun_name(n) 1970 fun_name(n)
@@ -1934,7 +1973,8 @@ fn foo() -> u32 {
1934fn $0fun_name(n: u32) -> u32 { 1973fn $0fun_name(n: u32) -> u32 {
1935 let m = 1; 1974 let m = 1;
1936 n + m 1975 n + m
1937}", 1976}
1977"#,
1938 ) 1978 )
1939 } 1979 }
1940 1980
@@ -1948,18 +1988,20 @@ fn $0fun_name(n: u32) -> u32 {
1948 fn part_of_expr_stmt() { 1988 fn part_of_expr_stmt() {
1949 check_assist( 1989 check_assist(
1950 extract_function, 1990 extract_function,
1951 " 1991 r#"
1952fn foo() { 1992fn foo() {
1953 $01$0 + 1; 1993 $01$0 + 1;
1954}", 1994}
1955 " 1995"#,
1996 r#"
1956fn foo() { 1997fn foo() {
1957 fun_name() + 1; 1998 fun_name() + 1;
1958} 1999}
1959 2000
1960fn $0fun_name() -> i32 { 2001fn $0fun_name() -> i32 {
1961 1 2002 1
1962}", 2003}
2004"#,
1963 ); 2005 );
1964 } 2006 }
1965 2007
@@ -1970,7 +2012,8 @@ fn $0fun_name() -> i32 {
1970 r#" 2012 r#"
1971fn foo() { 2013fn foo() {
1972 $0bar(1 + 1)$0 2014 $0bar(1 + 1)$0
1973}"#, 2015}
2016"#,
1974 r#" 2017 r#"
1975fn foo() { 2018fn foo() {
1976 fun_name(); 2019 fun_name();
@@ -1978,7 +2021,8 @@ fn foo() {
1978 2021
1979fn $0fun_name() { 2022fn $0fun_name() {
1980 bar(1 + 1) 2023 bar(1 + 1)
1981}"#, 2024}
2025"#,
1982 ) 2026 )
1983 } 2027 }
1984 2028
@@ -1986,15 +2030,16 @@ fn $0fun_name() {
1986 fn extract_from_nested() { 2030 fn extract_from_nested() {
1987 check_assist( 2031 check_assist(
1988 extract_function, 2032 extract_function,
1989 r" 2033 r#"
1990fn main() { 2034fn main() {
1991 let x = true; 2035 let x = true;
1992 let tuple = match x { 2036 let tuple = match x {
1993 true => ($02 + 2$0, true) 2037 true => ($02 + 2$0, true)
1994 _ => (0, false) 2038 _ => (0, false)
1995 }; 2039 };
1996}", 2040}
1997 r" 2041"#,
2042 r#"
1998fn main() { 2043fn main() {
1999 let x = true; 2044 let x = true;
2000 let tuple = match x { 2045 let tuple = match x {
@@ -2005,7 +2050,8 @@ fn main() {
2005 2050
2006fn $0fun_name() -> i32 { 2051fn $0fun_name() -> i32 {
2007 2 + 2 2052 2 + 2
2008}", 2053}
2054"#,
2009 ); 2055 );
2010 } 2056 }
2011 2057
@@ -2013,18 +2059,20 @@ fn $0fun_name() -> i32 {
2013 fn param_from_closure() { 2059 fn param_from_closure() {
2014 check_assist( 2060 check_assist(
2015 extract_function, 2061 extract_function,
2016 r" 2062 r#"
2017fn main() { 2063fn main() {
2018 let lambda = |x: u32| $0x * 2$0; 2064 let lambda = |x: u32| $0x * 2$0;
2019}", 2065}
2020 r" 2066"#,
2067 r#"
2021fn main() { 2068fn main() {
2022 let lambda = |x: u32| fun_name(x); 2069 let lambda = |x: u32| fun_name(x);
2023} 2070}
2024 2071
2025fn $0fun_name(x: u32) -> u32 { 2072fn $0fun_name(x: u32) -> u32 {
2026 x * 2 2073 x * 2
2027}", 2074}
2075"#,
2028 ); 2076 );
2029 } 2077 }
2030 2078
@@ -2032,18 +2080,20 @@ fn $0fun_name(x: u32) -> u32 {
2032 fn extract_return_stmt() { 2080 fn extract_return_stmt() {
2033 check_assist( 2081 check_assist(
2034 extract_function, 2082 extract_function,
2035 r" 2083 r#"
2036fn foo() -> u32 { 2084fn foo() -> u32 {
2037 $0return 2 + 2$0; 2085 $0return 2 + 2$0;
2038}", 2086}
2039 r" 2087"#,
2088 r#"
2040fn foo() -> u32 { 2089fn foo() -> u32 {
2041 return fun_name(); 2090 return fun_name();
2042} 2091}
2043 2092
2044fn $0fun_name() -> u32 { 2093fn $0fun_name() -> u32 {
2045 2 + 2 2094 2 + 2
2046}", 2095}
2096"#,
2047 ); 2097 );
2048 } 2098 }
2049 2099
@@ -2051,13 +2101,14 @@ fn $0fun_name() -> u32 {
2051 fn does_not_add_extra_whitespace() { 2101 fn does_not_add_extra_whitespace() {
2052 check_assist( 2102 check_assist(
2053 extract_function, 2103 extract_function,
2054 r" 2104 r#"
2055fn foo() -> u32 { 2105fn foo() -> u32 {
2056 2106
2057 2107
2058 $0return 2 + 2$0; 2108 $0return 2 + 2$0;
2059}", 2109}
2060 r" 2110"#,
2111 r#"
2061fn foo() -> u32 { 2112fn foo() -> u32 {
2062 2113
2063 2114
@@ -2066,7 +2117,8 @@ fn foo() -> u32 {
2066 2117
2067fn $0fun_name() -> u32 { 2118fn $0fun_name() -> u32 {
2068 2 + 2 2119 2 + 2
2069}", 2120}
2121"#,
2070 ); 2122 );
2071 } 2123 }
2072 2124
@@ -2074,13 +2126,14 @@ fn $0fun_name() -> u32 {
2074 fn break_stmt() { 2126 fn break_stmt() {
2075 check_assist( 2127 check_assist(
2076 extract_function, 2128 extract_function,
2077 r" 2129 r#"
2078fn main() { 2130fn main() {
2079 let result = loop { 2131 let result = loop {
2080 $0break 2 + 2$0; 2132 $0break 2 + 2$0;
2081 }; 2133 };
2082}", 2134}
2083 r" 2135"#,
2136 r#"
2084fn main() { 2137fn main() {
2085 let result = loop { 2138 let result = loop {
2086 break fun_name(); 2139 break fun_name();
@@ -2089,7 +2142,8 @@ fn main() {
2089 2142
2090fn $0fun_name() -> i32 { 2143fn $0fun_name() -> i32 {
2091 2 + 2 2144 2 + 2
2092}", 2145}
2146"#,
2093 ); 2147 );
2094 } 2148 }
2095 2149
@@ -2097,18 +2151,20 @@ fn $0fun_name() -> i32 {
2097 fn extract_cast() { 2151 fn extract_cast() {
2098 check_assist( 2152 check_assist(
2099 extract_function, 2153 extract_function,
2100 r" 2154 r#"
2101fn main() { 2155fn main() {
2102 let v = $00f32 as u32$0; 2156 let v = $00f32 as u32$0;
2103}", 2157}
2104 r" 2158"#,
2159 r#"
2105fn main() { 2160fn main() {
2106 let v = fun_name(); 2161 let v = fun_name();
2107} 2162}
2108 2163
2109fn $0fun_name() -> u32 { 2164fn $0fun_name() -> u32 {
2110 0f32 as u32 2165 0f32 as u32
2111}", 2166}
2167"#,
2112 ); 2168 );
2113 } 2169 }
2114 2170
@@ -2121,15 +2177,16 @@ fn $0fun_name() -> u32 {
2121 fn method_to_freestanding() { 2177 fn method_to_freestanding() {
2122 check_assist( 2178 check_assist(
2123 extract_function, 2179 extract_function,
2124 r" 2180 r#"
2125struct S; 2181struct S;
2126 2182
2127impl S { 2183impl S {
2128 fn foo(&self) -> i32 { 2184 fn foo(&self) -> i32 {
2129 $01+1$0 2185 $01+1$0
2130 } 2186 }
2131}", 2187}
2132 r" 2188"#,
2189 r#"
2133struct S; 2190struct S;
2134 2191
2135impl S { 2192impl S {
@@ -2140,7 +2197,8 @@ impl S {
2140 2197
2141fn $0fun_name() -> i32 { 2198fn $0fun_name() -> i32 {
2142 1+1 2199 1+1
2143}", 2200}
2201"#,
2144 ); 2202 );
2145 } 2203 }
2146 2204
@@ -2148,15 +2206,16 @@ fn $0fun_name() -> i32 {
2148 fn method_with_reference() { 2206 fn method_with_reference() {
2149 check_assist( 2207 check_assist(
2150 extract_function, 2208 extract_function,
2151 r" 2209 r#"
2152struct S { f: i32 }; 2210struct S { f: i32 };
2153 2211
2154impl S { 2212impl S {
2155 fn foo(&self) -> i32 { 2213 fn foo(&self) -> i32 {
2156 $01+self.f$0 2214 $01+self.f$0
2157 } 2215 }
2158}", 2216}
2159 r" 2217"#,
2218 r#"
2160struct S { f: i32 }; 2219struct S { f: i32 };
2161 2220
2162impl S { 2221impl S {
@@ -2167,7 +2226,8 @@ impl S {
2167 fn $0fun_name(&self) -> i32 { 2226 fn $0fun_name(&self) -> i32 {
2168 1+self.f 2227 1+self.f
2169 } 2228 }
2170}", 2229}
2230"#,
2171 ); 2231 );
2172 } 2232 }
2173 2233
@@ -2175,15 +2235,16 @@ impl S {
2175 fn method_with_mut() { 2235 fn method_with_mut() {
2176 check_assist( 2236 check_assist(
2177 extract_function, 2237 extract_function,
2178 r" 2238 r#"
2179struct S { f: i32 }; 2239struct S { f: i32 };
2180 2240
2181impl S { 2241impl S {
2182 fn foo(&mut self) { 2242 fn foo(&mut self) {
2183 $0self.f += 1;$0 2243 $0self.f += 1;$0
2184 } 2244 }
2185}", 2245}
2186 r" 2246"#,
2247 r#"
2187struct S { f: i32 }; 2248struct S { f: i32 };
2188 2249
2189impl S { 2250impl S {
@@ -2194,7 +2255,8 @@ impl S {
2194 fn $0fun_name(&mut self) { 2255 fn $0fun_name(&mut self) {
2195 self.f += 1; 2256 self.f += 1;
2196 } 2257 }
2197}", 2258}
2259"#,
2198 ); 2260 );
2199 } 2261 }
2200 2262
@@ -2202,13 +2264,14 @@ impl S {
2202 fn variable_defined_inside_and_used_after_no_ret() { 2264 fn variable_defined_inside_and_used_after_no_ret() {
2203 check_assist( 2265 check_assist(
2204 extract_function, 2266 extract_function,
2205 r" 2267 r#"
2206fn foo() { 2268fn foo() {
2207 let n = 1; 2269 let n = 1;
2208 $0let k = n * n;$0 2270 $0let k = n * n;$0
2209 let m = k + 1; 2271 let m = k + 1;
2210}", 2272}
2211 r" 2273"#,
2274 r#"
2212fn foo() { 2275fn foo() {
2213 let n = 1; 2276 let n = 1;
2214 let k = fun_name(n); 2277 let k = fun_name(n);
@@ -2218,7 +2281,8 @@ fn foo() {
2218fn $0fun_name(n: i32) -> i32 { 2281fn $0fun_name(n: i32) -> i32 {
2219 let k = n * n; 2282 let k = n * n;
2220 k 2283 k
2221}", 2284}
2285"#,
2222 ); 2286 );
2223 } 2287 }
2224 2288
@@ -2226,13 +2290,14 @@ fn $0fun_name(n: i32) -> i32 {
2226 fn variable_defined_inside_and_used_after_mutably_no_ret() { 2290 fn variable_defined_inside_and_used_after_mutably_no_ret() {
2227 check_assist( 2291 check_assist(
2228 extract_function, 2292 extract_function,
2229 r" 2293 r#"
2230fn foo() { 2294fn foo() {
2231 let n = 1; 2295 let n = 1;
2232 $0let mut k = n * n;$0 2296 $0let mut k = n * n;$0
2233 k += 1; 2297 k += 1;
2234}", 2298}
2235 r" 2299"#,
2300 r#"
2236fn foo() { 2301fn foo() {
2237 let n = 1; 2302 let n = 1;
2238 let mut k = fun_name(n); 2303 let mut k = fun_name(n);
@@ -2242,7 +2307,8 @@ fn foo() {
2242fn $0fun_name(n: i32) -> i32 { 2307fn $0fun_name(n: i32) -> i32 {
2243 let mut k = n * n; 2308 let mut k = n * n;
2244 k 2309 k
2245}", 2310}
2311"#,
2246 ); 2312 );
2247 } 2313 }
2248 2314
@@ -2250,14 +2316,15 @@ fn $0fun_name(n: i32) -> i32 {
2250 fn two_variables_defined_inside_and_used_after_no_ret() { 2316 fn two_variables_defined_inside_and_used_after_no_ret() {
2251 check_assist( 2317 check_assist(
2252 extract_function, 2318 extract_function,
2253 r" 2319 r#"
2254fn foo() { 2320fn foo() {
2255 let n = 1; 2321 let n = 1;
2256 $0let k = n * n; 2322 $0let k = n * n;
2257 let m = k + 2;$0 2323 let m = k + 2;$0
2258 let h = k + m; 2324 let h = k + m;
2259}", 2325}
2260 r" 2326"#,
2327 r#"
2261fn foo() { 2328fn foo() {
2262 let n = 1; 2329 let n = 1;
2263 let (k, m) = fun_name(n); 2330 let (k, m) = fun_name(n);
@@ -2268,7 +2335,8 @@ fn $0fun_name(n: i32) -> (i32, i32) {
2268 let k = n * n; 2335 let k = n * n;
2269 let m = k + 2; 2336 let m = k + 2;
2270 (k, m) 2337 (k, m)
2271}", 2338}
2339"#,
2272 ); 2340 );
2273 } 2341 }
2274 2342
@@ -2276,7 +2344,7 @@ fn $0fun_name(n: i32) -> (i32, i32) {
2276 fn multi_variables_defined_inside_and_used_after_mutably_no_ret() { 2344 fn multi_variables_defined_inside_and_used_after_mutably_no_ret() {
2277 check_assist( 2345 check_assist(
2278 extract_function, 2346 extract_function,
2279 r" 2347 r#"
2280fn foo() { 2348fn foo() {
2281 let n = 1; 2349 let n = 1;
2282 $0let mut k = n * n; 2350 $0let mut k = n * n;
@@ -2285,8 +2353,9 @@ fn foo() {
2285 o += 1;$0 2353 o += 1;$0
2286 k += o; 2354 k += o;
2287 m = 1; 2355 m = 1;
2288}", 2356}
2289 r" 2357"#,
2358 r#"
2290fn foo() { 2359fn foo() {
2291 let n = 1; 2360 let n = 1;
2292 let (mut k, mut m, o) = fun_name(n); 2361 let (mut k, mut m, o) = fun_name(n);
@@ -2300,7 +2369,8 @@ fn $0fun_name(n: i32) -> (i32, i32, i32) {
2300 let mut o = m + 3; 2369 let mut o = m + 3;
2301 o += 1; 2370 o += 1;
2302 (k, m, o) 2371 (k, m, o)
2303}", 2372}
2373"#,
2304 ); 2374 );
2305 } 2375 }
2306 2376
@@ -2308,13 +2378,14 @@ fn $0fun_name(n: i32) -> (i32, i32, i32) {
2308 fn nontrivial_patterns_define_variables() { 2378 fn nontrivial_patterns_define_variables() {
2309 check_assist( 2379 check_assist(
2310 extract_function, 2380 extract_function,
2311 r" 2381 r#"
2312struct Counter(i32); 2382struct Counter(i32);
2313fn foo() { 2383fn foo() {
2314 $0let Counter(n) = Counter(0);$0 2384 $0let Counter(n) = Counter(0);$0
2315 let m = n; 2385 let m = n;
2316}", 2386}
2317 r" 2387"#,
2388 r#"
2318struct Counter(i32); 2389struct Counter(i32);
2319fn foo() { 2390fn foo() {
2320 let n = fun_name(); 2391 let n = fun_name();
@@ -2324,7 +2395,8 @@ fn foo() {
2324fn $0fun_name() -> i32 { 2395fn $0fun_name() -> i32 {
2325 let Counter(n) = Counter(0); 2396 let Counter(n) = Counter(0);
2326 n 2397 n
2327}", 2398}
2399"#,
2328 ); 2400 );
2329 } 2401 }
2330 2402
@@ -2332,13 +2404,14 @@ fn $0fun_name() -> i32 {
2332 fn struct_with_two_fields_pattern_define_variables() { 2404 fn struct_with_two_fields_pattern_define_variables() {
2333 check_assist( 2405 check_assist(
2334 extract_function, 2406 extract_function,
2335 r" 2407 r#"
2336struct Counter { n: i32, m: i32 }; 2408struct Counter { n: i32, m: i32 };
2337fn foo() { 2409fn foo() {
2338 $0let Counter { n, m: k } = Counter { n: 1, m: 2 };$0 2410 $0let Counter { n, m: k } = Counter { n: 1, m: 2 };$0
2339 let h = n + k; 2411 let h = n + k;
2340}", 2412}
2341 r" 2413"#,
2414 r#"
2342struct Counter { n: i32, m: i32 }; 2415struct Counter { n: i32, m: i32 };
2343fn foo() { 2416fn foo() {
2344 let (n, k) = fun_name(); 2417 let (n, k) = fun_name();
@@ -2348,7 +2421,8 @@ fn foo() {
2348fn $0fun_name() -> (i32, i32) { 2421fn $0fun_name() -> (i32, i32) {
2349 let Counter { n, m: k } = Counter { n: 1, m: 2 }; 2422 let Counter { n, m: k } = Counter { n: 1, m: 2 };
2350 (n, k) 2423 (n, k)
2351}", 2424}
2425"#,
2352 ); 2426 );
2353 } 2427 }
2354 2428
@@ -2356,13 +2430,14 @@ fn $0fun_name() -> (i32, i32) {
2356 fn mut_var_from_outer_scope() { 2430 fn mut_var_from_outer_scope() {
2357 check_assist( 2431 check_assist(
2358 extract_function, 2432 extract_function,
2359 r" 2433 r#"
2360fn foo() { 2434fn foo() {
2361 let mut n = 1; 2435 let mut n = 1;
2362 $0n += 1;$0 2436 $0n += 1;$0
2363 let m = n + 1; 2437 let m = n + 1;
2364}", 2438}
2365 r" 2439"#,
2440 r#"
2366fn foo() { 2441fn foo() {
2367 let mut n = 1; 2442 let mut n = 1;
2368 fun_name(&mut n); 2443 fun_name(&mut n);
@@ -2371,7 +2446,8 @@ fn foo() {
2371 2446
2372fn $0fun_name(n: &mut i32) { 2447fn $0fun_name(n: &mut i32) {
2373 *n += 1; 2448 *n += 1;
2374}", 2449}
2450"#,
2375 ); 2451 );
2376 } 2452 }
2377 2453
@@ -2379,14 +2455,15 @@ fn $0fun_name(n: &mut i32) {
2379 fn mut_field_from_outer_scope() { 2455 fn mut_field_from_outer_scope() {
2380 check_assist( 2456 check_assist(
2381 extract_function, 2457 extract_function,
2382 r" 2458 r#"
2383struct C { n: i32 } 2459struct C { n: i32 }
2384fn foo() { 2460fn foo() {
2385 let mut c = C { n: 0 }; 2461 let mut c = C { n: 0 };
2386 $0c.n += 1;$0 2462 $0c.n += 1;$0
2387 let m = c.n + 1; 2463 let m = c.n + 1;
2388}", 2464}
2389 r" 2465"#,
2466 r#"
2390struct C { n: i32 } 2467struct C { n: i32 }
2391fn foo() { 2468fn foo() {
2392 let mut c = C { n: 0 }; 2469 let mut c = C { n: 0 };
@@ -2396,7 +2473,8 @@ fn foo() {
2396 2473
2397fn $0fun_name(c: &mut C) { 2474fn $0fun_name(c: &mut C) {
2398 c.n += 1; 2475 c.n += 1;
2399}", 2476}
2477"#,
2400 ); 2478 );
2401 } 2479 }
2402 2480
@@ -2404,7 +2482,7 @@ fn $0fun_name(c: &mut C) {
2404 fn mut_nested_field_from_outer_scope() { 2482 fn mut_nested_field_from_outer_scope() {
2405 check_assist( 2483 check_assist(
2406 extract_function, 2484 extract_function,
2407 r" 2485 r#"
2408struct P { n: i32} 2486struct P { n: i32}
2409struct C { p: P } 2487struct C { p: P }
2410fn foo() { 2488fn foo() {
@@ -2414,8 +2492,9 @@ fn foo() {
2414 $0c.p.n += u.p.n; 2492 $0c.p.n += u.p.n;
2415 let r = &mut v.p.n;$0 2493 let r = &mut v.p.n;$0
2416 let m = c.p.n + v.p.n + u.p.n; 2494 let m = c.p.n + v.p.n + u.p.n;
2417}", 2495}
2418 r" 2496"#,
2497 r#"
2419struct P { n: i32} 2498struct P { n: i32}
2420struct C { p: P } 2499struct C { p: P }
2421fn foo() { 2500fn foo() {
@@ -2429,7 +2508,8 @@ fn foo() {
2429fn $0fun_name(c: &mut C, u: &C, v: &mut C) { 2508fn $0fun_name(c: &mut C, u: &C, v: &mut C) {
2430 c.p.n += u.p.n; 2509 c.p.n += u.p.n;
2431 let r = &mut v.p.n; 2510 let r = &mut v.p.n;
2432}", 2511}
2512"#,
2433 ); 2513 );
2434 } 2514 }
2435 2515
@@ -2437,7 +2517,7 @@ fn $0fun_name(c: &mut C, u: &C, v: &mut C) {
2437 fn mut_param_many_usages_stmt() { 2517 fn mut_param_many_usages_stmt() {
2438 check_assist( 2518 check_assist(
2439 extract_function, 2519 extract_function,
2440 r" 2520 r#"
2441fn bar(k: i32) {} 2521fn bar(k: i32) {}
2442trait I: Copy { 2522trait I: Copy {
2443 fn succ(&self) -> Self; 2523 fn succ(&self) -> Self;
@@ -2458,8 +2538,9 @@ fn foo() {
2458 *v = v.succ(); 2538 *v = v.succ();
2459 n.succ();$0 2539 n.succ();$0
2460 let m = n + 1; 2540 let m = n + 1;
2461}", 2541}
2462 r" 2542"#,
2543 r#"
2463fn bar(k: i32) {} 2544fn bar(k: i32) {}
2464trait I: Copy { 2545trait I: Copy {
2465 fn succ(&self) -> Self; 2546 fn succ(&self) -> Self;
@@ -2484,7 +2565,8 @@ fn $0fun_name(n: &mut i32) {
2484 let v = n; 2565 let v = n;
2485 *v = v.succ(); 2566 *v = v.succ();
2486 n.succ(); 2567 n.succ();
2487}", 2568}
2569"#,
2488 ); 2570 );
2489 } 2571 }
2490 2572
@@ -2492,7 +2574,7 @@ fn $0fun_name(n: &mut i32) {
2492 fn mut_param_many_usages_expr() { 2574 fn mut_param_many_usages_expr() {
2493 check_assist( 2575 check_assist(
2494 extract_function, 2576 extract_function,
2495 r" 2577 r#"
2496fn bar(k: i32) {} 2578fn bar(k: i32) {}
2497trait I: Copy { 2579trait I: Copy {
2498 fn succ(&self) -> Self; 2580 fn succ(&self) -> Self;
@@ -2515,8 +2597,9 @@ fn foo() {
2515 n.succ(); 2597 n.succ();
2516 }$0 2598 }$0
2517 let m = n + 1; 2599 let m = n + 1;
2518}", 2600}
2519 r" 2601"#,
2602 r#"
2520fn bar(k: i32) {} 2603fn bar(k: i32) {}
2521trait I: Copy { 2604trait I: Copy {
2522 fn succ(&self) -> Self; 2605 fn succ(&self) -> Self;
@@ -2541,7 +2624,8 @@ fn $0fun_name(n: &mut i32) {
2541 let v = n; 2624 let v = n;
2542 *v = v.succ(); 2625 *v = v.succ();
2543 n.succ(); 2626 n.succ();
2544}", 2627}
2628"#,
2545 ); 2629 );
2546 } 2630 }
2547 2631
@@ -2549,11 +2633,12 @@ fn $0fun_name(n: &mut i32) {
2549 fn mut_param_by_value() { 2633 fn mut_param_by_value() {
2550 check_assist( 2634 check_assist(
2551 extract_function, 2635 extract_function,
2552 r" 2636 r#"
2553fn foo() { 2637fn foo() {
2554 let mut n = 1; 2638 let mut n = 1;
2555 $0n += 1;$0 2639 $0n += 1;$0
2556}", 2640}
2641"#,
2557 r" 2642 r"
2558fn foo() { 2643fn foo() {
2559 let mut n = 1; 2644 let mut n = 1;
@@ -2562,7 +2647,8 @@ fn foo() {
2562 2647
2563fn $0fun_name(mut n: i32) { 2648fn $0fun_name(mut n: i32) {
2564 n += 1; 2649 n += 1;
2565}", 2650}
2651",
2566 ); 2652 );
2567 } 2653 }
2568 2654
@@ -2570,14 +2656,15 @@ fn $0fun_name(mut n: i32) {
2570 fn mut_param_because_of_mut_ref() { 2656 fn mut_param_because_of_mut_ref() {
2571 check_assist( 2657 check_assist(
2572 extract_function, 2658 extract_function,
2573 r" 2659 r#"
2574fn foo() { 2660fn foo() {
2575 let mut n = 1; 2661 let mut n = 1;
2576 $0let v = &mut n; 2662 $0let v = &mut n;
2577 *v += 1;$0 2663 *v += 1;$0
2578 let k = n; 2664 let k = n;
2579}", 2665}
2580 r" 2666"#,
2667 r#"
2581fn foo() { 2668fn foo() {
2582 let mut n = 1; 2669 let mut n = 1;
2583 fun_name(&mut n); 2670 fun_name(&mut n);
@@ -2587,7 +2674,8 @@ fn foo() {
2587fn $0fun_name(n: &mut i32) { 2674fn $0fun_name(n: &mut i32) {
2588 let v = n; 2675 let v = n;
2589 *v += 1; 2676 *v += 1;
2590}", 2677}
2678"#,
2591 ); 2679 );
2592 } 2680 }
2593 2681
@@ -2600,8 +2688,9 @@ fn foo() {
2600 let mut n = 1; 2688 let mut n = 1;
2601 $0let v = &mut n; 2689 $0let v = &mut n;
2602 *v += 1;$0 2690 *v += 1;$0
2603}", 2691}
2604 r" 2692",
2693 r#"
2605fn foo() { 2694fn foo() {
2606 let mut n = 1; 2695 let mut n = 1;
2607 fun_name(n); 2696 fun_name(n);
@@ -2610,7 +2699,8 @@ fn foo() {
2610fn $0fun_name(mut n: i32) { 2699fn $0fun_name(mut n: i32) {
2611 let v = &mut n; 2700 let v = &mut n;
2612 *v += 1; 2701 *v += 1;
2613}", 2702}
2703"#,
2614 ); 2704 );
2615 } 2705 }
2616 2706
@@ -2618,7 +2708,7 @@ fn $0fun_name(mut n: i32) {
2618 fn mut_method_call() { 2708 fn mut_method_call() {
2619 check_assist( 2709 check_assist(
2620 extract_function, 2710 extract_function,
2621 r" 2711 r#"
2622trait I { 2712trait I {
2623 fn inc(&mut self); 2713 fn inc(&mut self);
2624} 2714}
@@ -2628,8 +2718,9 @@ impl I for i32 {
2628fn foo() { 2718fn foo() {
2629 let mut n = 1; 2719 let mut n = 1;
2630 $0n.inc();$0 2720 $0n.inc();$0
2631}", 2721}
2632 r" 2722"#,
2723 r#"
2633trait I { 2724trait I {
2634 fn inc(&mut self); 2725 fn inc(&mut self);
2635} 2726}
@@ -2643,7 +2734,8 @@ fn foo() {
2643 2734
2644fn $0fun_name(mut n: i32) { 2735fn $0fun_name(mut n: i32) {
2645 n.inc(); 2736 n.inc();
2646}", 2737}
2738"#,
2647 ); 2739 );
2648 } 2740 }
2649 2741
@@ -2651,7 +2743,7 @@ fn $0fun_name(mut n: i32) {
2651 fn shared_method_call() { 2743 fn shared_method_call() {
2652 check_assist( 2744 check_assist(
2653 extract_function, 2745 extract_function,
2654 r" 2746 r#"
2655trait I { 2747trait I {
2656 fn succ(&self); 2748 fn succ(&self);
2657} 2749}
@@ -2661,7 +2753,8 @@ impl I for i32 {
2661fn foo() { 2753fn foo() {
2662 let mut n = 1; 2754 let mut n = 1;
2663 $0n.succ();$0 2755 $0n.succ();$0
2664}", 2756}
2757"#,
2665 r" 2758 r"
2666trait I { 2759trait I {
2667 fn succ(&self); 2760 fn succ(&self);
@@ -2676,7 +2769,8 @@ fn foo() {
2676 2769
2677fn $0fun_name(n: i32) { 2770fn $0fun_name(n: i32) {
2678 n.succ(); 2771 n.succ();
2679}", 2772}
2773",
2680 ); 2774 );
2681 } 2775 }
2682 2776
@@ -2684,7 +2778,7 @@ fn $0fun_name(n: i32) {
2684 fn mut_method_call_with_other_receiver() { 2778 fn mut_method_call_with_other_receiver() {
2685 check_assist( 2779 check_assist(
2686 extract_function, 2780 extract_function,
2687 r" 2781 r#"
2688trait I { 2782trait I {
2689 fn inc(&mut self, n: i32); 2783 fn inc(&mut self, n: i32);
2690} 2784}
@@ -2695,7 +2789,8 @@ fn foo() {
2695 let mut n = 1; 2789 let mut n = 1;
2696 $0let mut m = 2; 2790 $0let mut m = 2;
2697 m.inc(n);$0 2791 m.inc(n);$0
2698}", 2792}
2793"#,
2699 r" 2794 r"
2700trait I { 2795trait I {
2701 fn inc(&mut self, n: i32); 2796 fn inc(&mut self, n: i32);
@@ -2711,7 +2806,8 @@ fn foo() {
2711fn $0fun_name(n: i32) { 2806fn $0fun_name(n: i32) {
2712 let mut m = 2; 2807 let mut m = 2;
2713 m.inc(n); 2808 m.inc(n);
2714}", 2809}
2810",
2715 ); 2811 );
2716 } 2812 }
2717 2813
@@ -2719,12 +2815,13 @@ fn $0fun_name(n: i32) {
2719 fn non_copy_without_usages_after() { 2815 fn non_copy_without_usages_after() {
2720 check_assist( 2816 check_assist(
2721 extract_function, 2817 extract_function,
2722 r" 2818 r#"
2723struct Counter(i32); 2819struct Counter(i32);
2724fn foo() { 2820fn foo() {
2725 let c = Counter(0); 2821 let c = Counter(0);
2726 $0let n = c.0;$0 2822 $0let n = c.0;$0
2727}", 2823}
2824"#,
2728 r" 2825 r"
2729struct Counter(i32); 2826struct Counter(i32);
2730fn foo() { 2827fn foo() {
@@ -2734,7 +2831,8 @@ fn foo() {
2734 2831
2735fn $0fun_name(c: Counter) { 2832fn $0fun_name(c: Counter) {
2736 let n = c.0; 2833 let n = c.0;
2737}", 2834}
2835",
2738 ); 2836 );
2739 } 2837 }
2740 2838
@@ -2748,8 +2846,9 @@ fn foo() {
2748 let c = Counter(0); 2846 let c = Counter(0);
2749 $0let n = c.0;$0 2847 $0let n = c.0;$0
2750 let m = c.0; 2848 let m = c.0;
2751}", 2849}
2752 r" 2850",
2851 r#"
2753struct Counter(i32); 2852struct Counter(i32);
2754fn foo() { 2853fn foo() {
2755 let c = Counter(0); 2854 let c = Counter(0);
@@ -2759,7 +2858,8 @@ fn foo() {
2759 2858
2760fn $0fun_name(c: &Counter) { 2859fn $0fun_name(c: &Counter) {
2761 let n = c.0; 2860 let n = c.0;
2762}", 2861}
2862"#,
2763 ); 2863 );
2764 } 2864 }
2765 2865
@@ -2767,19 +2867,15 @@ fn $0fun_name(c: &Counter) {
2767 fn copy_used_after() { 2867 fn copy_used_after() {
2768 check_assist( 2868 check_assist(
2769 extract_function, 2869 extract_function,
2770 r##" 2870 r#"
2771#[lang = "copy"] 2871//- minicore: copy
2772pub trait Copy {}
2773impl Copy for i32 {}
2774fn foo() { 2872fn foo() {
2775 let n = 0; 2873 let n = 0;
2776 $0let m = n;$0 2874 $0let m = n;$0
2777 let k = n; 2875 let k = n;
2778}"##, 2876}
2779 r##" 2877"#,
2780#[lang = "copy"] 2878 r#"
2781pub trait Copy {}
2782impl Copy for i32 {}
2783fn foo() { 2879fn foo() {
2784 let n = 0; 2880 let n = 0;
2785 fun_name(n); 2881 fun_name(n);
@@ -2788,7 +2884,8 @@ fn foo() {
2788 2884
2789fn $0fun_name(n: i32) { 2885fn $0fun_name(n: i32) {
2790 let m = n; 2886 let m = n;
2791}"##, 2887}
2888"#,
2792 ) 2889 )
2793 } 2890 }
2794 2891
@@ -2796,21 +2893,19 @@ fn $0fun_name(n: i32) {
2796 fn copy_custom_used_after() { 2893 fn copy_custom_used_after() {
2797 check_assist( 2894 check_assist(
2798 extract_function, 2895 extract_function,
2799 r##" 2896 r#"
2800#[lang = "copy"] 2897//- minicore: copy, derive
2801pub trait Copy {} 2898#[derive(Clone, Copy)]
2802struct Counter(i32); 2899struct Counter(i32);
2803impl Copy for Counter {}
2804fn foo() { 2900fn foo() {
2805 let c = Counter(0); 2901 let c = Counter(0);
2806 $0let n = c.0;$0 2902 $0let n = c.0;$0
2807 let m = c.0; 2903 let m = c.0;
2808}"##, 2904}
2809 r##" 2905"#,
2810#[lang = "copy"] 2906 r#"
2811pub trait Copy {} 2907#[derive(Clone, Copy)]
2812struct Counter(i32); 2908struct Counter(i32);
2813impl Copy for Counter {}
2814fn foo() { 2909fn foo() {
2815 let c = Counter(0); 2910 let c = Counter(0);
2816 fun_name(c); 2911 fun_name(c);
@@ -2819,7 +2914,8 @@ fn foo() {
2819 2914
2820fn $0fun_name(c: Counter) { 2915fn $0fun_name(c: Counter) {
2821 let n = c.0; 2916 let n = c.0;
2822}"##, 2917}
2918"#,
2823 ); 2919 );
2824 } 2920 }
2825 2921
@@ -2827,7 +2923,7 @@ fn $0fun_name(c: Counter) {
2827 fn indented_stmts() { 2923 fn indented_stmts() {
2828 check_assist( 2924 check_assist(
2829 extract_function, 2925 extract_function,
2830 r" 2926 r#"
2831fn foo() { 2927fn foo() {
2832 if true { 2928 if true {
2833 loop { 2929 loop {
@@ -2835,8 +2931,9 @@ fn foo() {
2835 let m = 2;$0 2931 let m = 2;$0
2836 } 2932 }
2837 } 2933 }
2838}", 2934}
2839 r" 2935"#,
2936 r#"
2840fn foo() { 2937fn foo() {
2841 if true { 2938 if true {
2842 loop { 2939 loop {
@@ -2848,7 +2945,8 @@ fn foo() {
2848fn $0fun_name() { 2945fn $0fun_name() {
2849 let n = 1; 2946 let n = 1;
2850 let m = 2; 2947 let m = 2;
2851}", 2948}
2949"#,
2852 ); 2950 );
2853 } 2951 }
2854 2952
@@ -2856,7 +2954,7 @@ fn $0fun_name() {
2856 fn indented_stmts_inside_mod() { 2954 fn indented_stmts_inside_mod() {
2857 check_assist( 2955 check_assist(
2858 extract_function, 2956 extract_function,
2859 r" 2957 r#"
2860mod bar { 2958mod bar {
2861 fn foo() { 2959 fn foo() {
2862 if true { 2960 if true {
@@ -2866,8 +2964,9 @@ mod bar {
2866 } 2964 }
2867 } 2965 }
2868 } 2966 }
2869}", 2967}
2870 r" 2968"#,
2969 r#"
2871mod bar { 2970mod bar {
2872 fn foo() { 2971 fn foo() {
2873 if true { 2972 if true {
@@ -2881,7 +2980,8 @@ mod bar {
2881 let n = 1; 2980 let n = 1;
2882 let m = 2; 2981 let m = 2;
2883 } 2982 }
2884}", 2983}
2984"#,
2885 ); 2985 );
2886 } 2986 }
2887 2987
@@ -2889,12 +2989,8 @@ mod bar {
2889 fn break_loop() { 2989 fn break_loop() {
2890 check_assist( 2990 check_assist(
2891 extract_function, 2991 extract_function,
2892 r##" 2992 r#"
2893enum Option<T> { 2993//- minicore: option
2894 #[lang = "None"] None,
2895 #[lang = "Some"] Some(T),
2896}
2897use Option::*;
2898fn foo() { 2994fn foo() {
2899 loop { 2995 loop {
2900 let n = 1; 2996 let n = 1;
@@ -2903,13 +2999,9 @@ fn foo() {
2903 let k = 2;$0 2999 let k = 2;$0
2904 let h = 1 + k; 3000 let h = 1 + k;
2905 } 3001 }
2906}"##,
2907 r##"
2908enum Option<T> {
2909 #[lang = "None"] None,
2910 #[lang = "Some"] Some(T),
2911} 3002}
2912use Option::*; 3003"#,
3004 r#"
2913fn foo() { 3005fn foo() {
2914 loop { 3006 loop {
2915 let n = 1; 3007 let n = 1;
@@ -2926,7 +3018,8 @@ fn $0fun_name(n: i32) -> Option<i32> {
2926 return None; 3018 return None;
2927 let k = 2; 3019 let k = 2;
2928 Some(k) 3020 Some(k)
2929}"##, 3021}
3022"#,
2930 ); 3023 );
2931 } 3024 }
2932 3025
@@ -2934,31 +3027,17 @@ fn $0fun_name(n: i32) -> Option<i32> {
2934 fn return_to_parent() { 3027 fn return_to_parent() {
2935 check_assist( 3028 check_assist(
2936 extract_function, 3029 extract_function,
2937 r##" 3030 r#"
2938#[lang = "copy"] 3031//- minicore: copy, result
2939pub trait Copy {}
2940impl Copy for i32 {}
2941enum Result<T, E> {
2942 #[lang = "Ok"] Ok(T),
2943 #[lang = "Err"] Err(E),
2944}
2945use Result::*;
2946fn foo() -> i64 { 3032fn foo() -> i64 {
2947 let n = 1; 3033 let n = 1;
2948 $0let m = n + 1; 3034 $0let m = n + 1;
2949 return 1; 3035 return 1;
2950 let k = 2;$0 3036 let k = 2;$0
2951 (n + k) as i64 3037 (n + k) as i64
2952}"##, 3038}
2953 r##" 3039"#,
2954#[lang = "copy"] 3040 r#"
2955pub trait Copy {}
2956impl Copy for i32 {}
2957enum Result<T, E> {
2958 #[lang = "Ok"] Ok(T),
2959 #[lang = "Err"] Err(E),
2960}
2961use Result::*;
2962fn foo() -> i64 { 3041fn foo() -> i64 {
2963 let n = 1; 3042 let n = 1;
2964 let k = match fun_name(n) { 3043 let k = match fun_name(n) {
@@ -2973,7 +3052,8 @@ fn $0fun_name(n: i32) -> Result<i32, i64> {
2973 return Err(1); 3052 return Err(1);
2974 let k = 2; 3053 let k = 2;
2975 Ok(k) 3054 Ok(k)
2976}"##, 3055}
3056"#,
2977 ); 3057 );
2978 } 3058 }
2979 3059
@@ -2982,7 +3062,7 @@ fn $0fun_name(n: i32) -> Result<i32, i64> {
2982 cov_mark::check!(external_control_flow_break_and_continue); 3062 cov_mark::check!(external_control_flow_break_and_continue);
2983 check_assist_not_applicable( 3063 check_assist_not_applicable(
2984 extract_function, 3064 extract_function,
2985 r##" 3065 r#"
2986fn foo() { 3066fn foo() {
2987 loop { 3067 loop {
2988 let n = 1; 3068 let n = 1;
@@ -2993,7 +3073,8 @@ fn foo() {
2993 let k = k + 1;$0 3073 let k = k + 1;$0
2994 let r = n + k; 3074 let r = n + k;
2995 } 3075 }
2996}"##, 3076}
3077"#,
2997 ); 3078 );
2998 } 3079 }
2999 3080
@@ -3002,7 +3083,7 @@ fn foo() {
3002 cov_mark::check!(external_control_flow_return_and_bc); 3083 cov_mark::check!(external_control_flow_return_and_bc);
3003 check_assist_not_applicable( 3084 check_assist_not_applicable(
3004 extract_function, 3085 extract_function,
3005 r##" 3086 r#"
3006fn foo() { 3087fn foo() {
3007 loop { 3088 loop {
3008 let n = 1; 3089 let n = 1;
@@ -3013,7 +3094,8 @@ fn foo() {
3013 let k = k + 1;$0 3094 let k = k + 1;$0
3014 let r = n + k; 3095 let r = n + k;
3015 } 3096 }
3016}"##, 3097}
3098"#,
3017 ); 3099 );
3018 } 3100 }
3019 3101
@@ -3021,7 +3103,7 @@ fn foo() {
3021 fn break_loop_with_if() { 3103 fn break_loop_with_if() {
3022 check_assist( 3104 check_assist(
3023 extract_function, 3105 extract_function,
3024 r##" 3106 r#"
3025fn foo() { 3107fn foo() {
3026 loop { 3108 loop {
3027 let mut n = 1; 3109 let mut n = 1;
@@ -3030,8 +3112,9 @@ fn foo() {
3030 n += m;$0 3112 n += m;$0
3031 let h = 1 + n; 3113 let h = 1 + n;
3032 } 3114 }
3033}"##, 3115}
3034 r##" 3116"#,
3117 r#"
3035fn foo() { 3118fn foo() {
3036 loop { 3119 loop {
3037 let mut n = 1; 3120 let mut n = 1;
@@ -3047,7 +3130,8 @@ fn $0fun_name(n: &mut i32) -> bool {
3047 return true; 3130 return true;
3048 *n += m; 3131 *n += m;
3049 false 3132 false
3050}"##, 3133}
3134"#,
3051 ); 3135 );
3052 } 3136 }
3053 3137
@@ -3055,7 +3139,7 @@ fn $0fun_name(n: &mut i32) -> bool {
3055 fn break_loop_nested() { 3139 fn break_loop_nested() {
3056 check_assist( 3140 check_assist(
3057 extract_function, 3141 extract_function,
3058 r##" 3142 r#"
3059fn foo() { 3143fn foo() {
3060 loop { 3144 loop {
3061 let mut n = 1; 3145 let mut n = 1;
@@ -3065,8 +3149,9 @@ fn foo() {
3065 }$0 3149 }$0
3066 let h = 1; 3150 let h = 1;
3067 } 3151 }
3068}"##, 3152}
3069 r##" 3153"#,
3154 r#"
3070fn foo() { 3155fn foo() {
3071 loop { 3156 loop {
3072 let mut n = 1; 3157 let mut n = 1;
@@ -3083,7 +3168,8 @@ fn $0fun_name(n: i32) -> bool {
3083 return true; 3168 return true;
3084 } 3169 }
3085 false 3170 false
3086}"##, 3171}
3172"#,
3087 ); 3173 );
3088 } 3174 }
3089 3175
@@ -3091,7 +3177,7 @@ fn $0fun_name(n: i32) -> bool {
3091 fn return_from_nested_loop() { 3177 fn return_from_nested_loop() {
3092 check_assist( 3178 check_assist(
3093 extract_function, 3179 extract_function,
3094 r##" 3180 r#"
3095fn foo() { 3181fn foo() {
3096 loop { 3182 loop {
3097 let n = 1; 3183 let n = 1;
@@ -3103,8 +3189,9 @@ fn foo() {
3103 let m = k + 1;$0 3189 let m = k + 1;$0
3104 let h = 1 + m; 3190 let h = 1 + m;
3105 } 3191 }
3106}"##, 3192}
3107 r##" 3193"#,
3194 r#"
3108fn foo() { 3195fn foo() {
3109 loop { 3196 loop {
3110 let n = 1; 3197 let n = 1;
@@ -3123,7 +3210,8 @@ fn $0fun_name() -> Option<i32> {
3123 } 3210 }
3124 let m = k + 1; 3211 let m = k + 1;
3125 Some(m) 3212 Some(m)
3126}"##, 3213}
3214"#,
3127 ); 3215 );
3128 } 3216 }
3129 3217
@@ -3131,7 +3219,7 @@ fn $0fun_name() -> Option<i32> {
3131 fn break_from_nested_loop() { 3219 fn break_from_nested_loop() {
3132 check_assist( 3220 check_assist(
3133 extract_function, 3221 extract_function,
3134 r##" 3222 r#"
3135fn foo() { 3223fn foo() {
3136 loop { 3224 loop {
3137 let n = 1; 3225 let n = 1;
@@ -3142,8 +3230,9 @@ fn foo() {
3142 let m = k + 1;$0 3230 let m = k + 1;$0
3143 let h = 1 + m; 3231 let h = 1 + m;
3144 } 3232 }
3145}"##, 3233}
3146 r##" 3234"#,
3235 r#"
3147fn foo() { 3236fn foo() {
3148 loop { 3237 loop {
3149 let n = 1; 3238 let n = 1;
@@ -3159,7 +3248,8 @@ fn $0fun_name() -> i32 {
3159 } 3248 }
3160 let m = k + 1; 3249 let m = k + 1;
3161 m 3250 m
3162}"##, 3251}
3252"#,
3163 ); 3253 );
3164 } 3254 }
3165 3255
@@ -3167,7 +3257,7 @@ fn $0fun_name() -> i32 {
3167 fn break_from_nested_and_outer_loops() { 3257 fn break_from_nested_and_outer_loops() {
3168 check_assist( 3258 check_assist(
3169 extract_function, 3259 extract_function,
3170 r##" 3260 r#"
3171fn foo() { 3261fn foo() {
3172 loop { 3262 loop {
3173 let n = 1; 3263 let n = 1;
@@ -3181,8 +3271,9 @@ fn foo() {
3181 let m = k + 1;$0 3271 let m = k + 1;$0
3182 let h = 1 + m; 3272 let h = 1 + m;
3183 } 3273 }
3184}"##, 3274}
3185 r##" 3275"#,
3276 r#"
3186fn foo() { 3277fn foo() {
3187 loop { 3278 loop {
3188 let n = 1; 3279 let n = 1;
@@ -3204,7 +3295,8 @@ fn $0fun_name() -> Option<i32> {
3204 } 3295 }
3205 let m = k + 1; 3296 let m = k + 1;
3206 Some(m) 3297 Some(m)
3207}"##, 3298}
3299"#,
3208 ); 3300 );
3209 } 3301 }
3210 3302
@@ -3212,7 +3304,7 @@ fn $0fun_name() -> Option<i32> {
3212 fn return_from_nested_fn() { 3304 fn return_from_nested_fn() {
3213 check_assist( 3305 check_assist(
3214 extract_function, 3306 extract_function,
3215 r##" 3307 r#"
3216fn foo() { 3308fn foo() {
3217 loop { 3309 loop {
3218 let n = 1; 3310 let n = 1;
@@ -3223,8 +3315,9 @@ fn foo() {
3223 let m = k + 1;$0 3315 let m = k + 1;$0
3224 let h = 1 + m; 3316 let h = 1 + m;
3225 } 3317 }
3226}"##, 3318}
3227 r##" 3319"#,
3320 r#"
3228fn foo() { 3321fn foo() {
3229 loop { 3322 loop {
3230 let n = 1; 3323 let n = 1;
@@ -3240,7 +3333,8 @@ fn $0fun_name() -> i32 {
3240 } 3333 }
3241 let m = k + 1; 3334 let m = k + 1;
3242 m 3335 m
3243}"##, 3336}
3337"#,
3244 ); 3338 );
3245 } 3339 }
3246 3340
@@ -3248,7 +3342,7 @@ fn $0fun_name() -> i32 {
3248 fn break_with_value() { 3342 fn break_with_value() {
3249 check_assist( 3343 check_assist(
3250 extract_function, 3344 extract_function,
3251 r##" 3345 r#"
3252fn foo() -> i32 { 3346fn foo() -> i32 {
3253 loop { 3347 loop {
3254 let n = 1; 3348 let n = 1;
@@ -3259,8 +3353,9 @@ fn foo() -> i32 {
3259 let m = k + 1;$0 3353 let m = k + 1;$0
3260 let h = 1; 3354 let h = 1;
3261 } 3355 }
3262}"##, 3356}
3263 r##" 3357"#,
3358 r#"
3264fn foo() -> i32 { 3359fn foo() -> i32 {
3265 loop { 3360 loop {
3266 let n = 1; 3361 let n = 1;
@@ -3278,7 +3373,8 @@ fn $0fun_name() -> Option<i32> {
3278 } 3373 }
3279 let m = k + 1; 3374 let m = k + 1;
3280 None 3375 None
3281}"##, 3376}
3377"#,
3282 ); 3378 );
3283 } 3379 }
3284 3380
@@ -3286,7 +3382,7 @@ fn $0fun_name() -> Option<i32> {
3286 fn break_with_value_and_return() { 3382 fn break_with_value_and_return() {
3287 check_assist( 3383 check_assist(
3288 extract_function, 3384 extract_function,
3289 r##" 3385 r#"
3290fn foo() -> i64 { 3386fn foo() -> i64 {
3291 loop { 3387 loop {
3292 let n = 1; 3388 let n = 1;
@@ -3298,8 +3394,9 @@ fn foo() -> i64 {
3298 let m = k + 1;$0 3394 let m = k + 1;$0
3299 let h = 1 + m; 3395 let h = 1 + m;
3300 } 3396 }
3301}"##, 3397}
3302 r##" 3398"#,
3399 r#"
3303fn foo() -> i64 { 3400fn foo() -> i64 {
3304 loop { 3401 loop {
3305 let n = 1; 3402 let n = 1;
@@ -3318,7 +3415,8 @@ fn $0fun_name() -> Result<i32, i64> {
3318 } 3415 }
3319 let m = k + 1; 3416 let m = k + 1;
3320 Ok(m) 3417 Ok(m)
3321}"##, 3418}
3419"#,
3322 ); 3420 );
3323 } 3421 }
3324 3422
@@ -3326,9 +3424,8 @@ fn $0fun_name() -> Result<i32, i64> {
3326 fn try_option() { 3424 fn try_option() {
3327 check_assist( 3425 check_assist(
3328 extract_function, 3426 extract_function,
3329 r##" 3427 r#"
3330enum Option<T> { None, Some(T), } 3428//- minicore: option
3331use Option::*;
3332fn bar() -> Option<i32> { None } 3429fn bar() -> Option<i32> { None }
3333fn foo() -> Option<()> { 3430fn foo() -> Option<()> {
3334 let n = bar()?; 3431 let n = bar()?;
@@ -3336,10 +3433,9 @@ fn foo() -> Option<()> {
3336 let m = k + 1;$0 3433 let m = k + 1;$0
3337 let h = 1 + m; 3434 let h = 1 + m;
3338 Some(()) 3435 Some(())
3339}"##, 3436}
3340 r##" 3437"#,
3341enum Option<T> { None, Some(T), } 3438 r#"
3342use Option::*;
3343fn bar() -> Option<i32> { None } 3439fn bar() -> Option<i32> { None }
3344fn foo() -> Option<()> { 3440fn foo() -> Option<()> {
3345 let n = bar()?; 3441 let n = bar()?;
@@ -3352,7 +3448,8 @@ fn $0fun_name() -> Option<i32> {
3352 let k = foo()?; 3448 let k = foo()?;
3353 let m = k + 1; 3449 let m = k + 1;
3354 Some(m) 3450 Some(m)
3355}"##, 3451}
3452"#,
3356 ); 3453 );
3357 } 3454 }
3358 3455
@@ -3360,19 +3457,17 @@ fn $0fun_name() -> Option<i32> {
3360 fn try_option_unit() { 3457 fn try_option_unit() {
3361 check_assist( 3458 check_assist(
3362 extract_function, 3459 extract_function,
3363 r##" 3460 r#"
3364enum Option<T> { None, Some(T), } 3461//- minicore: option
3365use Option::*;
3366fn foo() -> Option<()> { 3462fn foo() -> Option<()> {
3367 let n = 1; 3463 let n = 1;
3368 $0let k = foo()?; 3464 $0let k = foo()?;
3369 let m = k + 1;$0 3465 let m = k + 1;$0
3370 let h = 1 + n; 3466 let h = 1 + n;
3371 Some(()) 3467 Some(())
3372}"##, 3468}
3373 r##" 3469"#,
3374enum Option<T> { None, Some(T), } 3470 r#"
3375use Option::*;
3376fn foo() -> Option<()> { 3471fn foo() -> Option<()> {
3377 let n = 1; 3472 let n = 1;
3378 fun_name()?; 3473 fun_name()?;
@@ -3384,7 +3479,8 @@ fn $0fun_name() -> Option<()> {
3384 let k = foo()?; 3479 let k = foo()?;
3385 let m = k + 1; 3480 let m = k + 1;
3386 Some(()) 3481 Some(())
3387}"##, 3482}
3483"#,
3388 ); 3484 );
3389 } 3485 }
3390 3486
@@ -3392,19 +3488,17 @@ fn $0fun_name() -> Option<()> {
3392 fn try_result() { 3488 fn try_result() {
3393 check_assist( 3489 check_assist(
3394 extract_function, 3490 extract_function,
3395 r##" 3491 r#"
3396enum Result<T, E> { Ok(T), Err(E), } 3492//- minicore: result
3397use Result::*;
3398fn foo() -> Result<(), i64> { 3493fn foo() -> Result<(), i64> {
3399 let n = 1; 3494 let n = 1;
3400 $0let k = foo()?; 3495 $0let k = foo()?;
3401 let m = k + 1;$0 3496 let m = k + 1;$0
3402 let h = 1 + m; 3497 let h = 1 + m;
3403 Ok(()) 3498 Ok(())
3404}"##, 3499}
3405 r##" 3500"#,
3406enum Result<T, E> { Ok(T), Err(E), } 3501 r#"
3407use Result::*;
3408fn foo() -> Result<(), i64> { 3502fn foo() -> Result<(), i64> {
3409 let n = 1; 3503 let n = 1;
3410 let m = fun_name()?; 3504 let m = fun_name()?;
@@ -3416,7 +3510,8 @@ fn $0fun_name() -> Result<i32, i64> {
3416 let k = foo()?; 3510 let k = foo()?;
3417 let m = k + 1; 3511 let m = k + 1;
3418 Ok(m) 3512 Ok(m)
3419}"##, 3513}
3514"#,
3420 ); 3515 );
3421 } 3516 }
3422 3517
@@ -3424,9 +3519,8 @@ fn $0fun_name() -> Result<i32, i64> {
3424 fn try_option_with_return() { 3519 fn try_option_with_return() {
3425 check_assist( 3520 check_assist(
3426 extract_function, 3521 extract_function,
3427 r##" 3522 r#"
3428enum Option<T> { None, Some(T) } 3523//- minicore: option
3429use Option::*;
3430fn foo() -> Option<()> { 3524fn foo() -> Option<()> {
3431 let n = 1; 3525 let n = 1;
3432 $0let k = foo()?; 3526 $0let k = foo()?;
@@ -3436,10 +3530,9 @@ fn foo() -> Option<()> {
3436 let m = k + 1;$0 3530 let m = k + 1;$0
3437 let h = 1 + m; 3531 let h = 1 + m;
3438 Some(()) 3532 Some(())
3439}"##, 3533}
3440 r##" 3534"#,
3441enum Option<T> { None, Some(T) } 3535 r#"
3442use Option::*;
3443fn foo() -> Option<()> { 3536fn foo() -> Option<()> {
3444 let n = 1; 3537 let n = 1;
3445 let m = fun_name()?; 3538 let m = fun_name()?;
@@ -3454,7 +3547,8 @@ fn $0fun_name() -> Option<i32> {
3454 } 3547 }
3455 let m = k + 1; 3548 let m = k + 1;
3456 Some(m) 3549 Some(m)
3457}"##, 3550}
3551"#,
3458 ); 3552 );
3459 } 3553 }
3460 3554
@@ -3462,9 +3556,8 @@ fn $0fun_name() -> Option<i32> {
3462 fn try_result_with_return() { 3556 fn try_result_with_return() {
3463 check_assist( 3557 check_assist(
3464 extract_function, 3558 extract_function,
3465 r##" 3559 r#"
3466enum Result<T, E> { Ok(T), Err(E), } 3560//- minicore: result
3467use Result::*;
3468fn foo() -> Result<(), i64> { 3561fn foo() -> Result<(), i64> {
3469 let n = 1; 3562 let n = 1;
3470 $0let k = foo()?; 3563 $0let k = foo()?;
@@ -3474,10 +3567,9 @@ fn foo() -> Result<(), i64> {
3474 let m = k + 1;$0 3567 let m = k + 1;$0
3475 let h = 1 + m; 3568 let h = 1 + m;
3476 Ok(()) 3569 Ok(())
3477}"##, 3570}
3478 r##" 3571"#,
3479enum Result<T, E> { Ok(T), Err(E), } 3572 r#"
3480use Result::*;
3481fn foo() -> Result<(), i64> { 3573fn foo() -> Result<(), i64> {
3482 let n = 1; 3574 let n = 1;
3483 let m = fun_name()?; 3575 let m = fun_name()?;
@@ -3492,7 +3584,8 @@ fn $0fun_name() -> Result<i32, i64> {
3492 } 3584 }
3493 let m = k + 1; 3585 let m = k + 1;
3494 Ok(m) 3586 Ok(m)
3495}"##, 3587}
3588"#,
3496 ); 3589 );
3497 } 3590 }
3498 3591
@@ -3501,9 +3594,8 @@ fn $0fun_name() -> Result<i32, i64> {
3501 cov_mark::check!(external_control_flow_try_and_bc); 3594 cov_mark::check!(external_control_flow_try_and_bc);
3502 check_assist_not_applicable( 3595 check_assist_not_applicable(
3503 extract_function, 3596 extract_function,
3504 r##" 3597 r#"
3505enum Option<T> { None, Some(T) } 3598//- minicore: option
3506use Option::*;
3507fn foo() -> Option<()> { 3599fn foo() -> Option<()> {
3508 loop { 3600 loop {
3509 let n = Some(1); 3601 let n = Some(1);
@@ -3514,7 +3606,8 @@ fn foo() -> Option<()> {
3514 let r = n + k; 3606 let r = n + k;
3515 } 3607 }
3516 Some(()) 3608 Some(())
3517}"##, 3609}
3610"#,
3518 ); 3611 );
3519 } 3612 }
3520 3613
@@ -3523,9 +3616,8 @@ fn foo() -> Option<()> {
3523 cov_mark::check!(external_control_flow_try_and_return_non_err); 3616 cov_mark::check!(external_control_flow_try_and_return_non_err);
3524 check_assist_not_applicable( 3617 check_assist_not_applicable(
3525 extract_function, 3618 extract_function,
3526 r##" 3619 r#"
3527enum Result<T, E> { Ok(T), Err(E), } 3620//- minicore: result
3528use Result::*;
3529fn foo() -> Result<(), i64> { 3621fn foo() -> Result<(), i64> {
3530 let n = 1; 3622 let n = 1;
3531 $0let k = foo()?; 3623 $0let k = foo()?;
@@ -3535,7 +3627,8 @@ fn foo() -> Result<(), i64> {
3535 let m = k + 1;$0 3627 let m = k + 1;$0
3536 let h = 1 + m; 3628 let h = 1 + m;
3537 Ok(()) 3629 Ok(())
3538}"##, 3630}
3631"#,
3539 ); 3632 );
3540 } 3633 }
3541 3634
@@ -3543,7 +3636,7 @@ fn foo() -> Result<(), i64> {
3543 fn param_usage_in_macro() { 3636 fn param_usage_in_macro() {
3544 check_assist( 3637 check_assist(
3545 extract_function, 3638 extract_function,
3546 r" 3639 r#"
3547macro_rules! m { 3640macro_rules! m {
3548 ($val:expr) => { $val }; 3641 ($val:expr) => { $val };
3549} 3642}
@@ -3552,8 +3645,9 @@ fn foo() {
3552 let n = 1; 3645 let n = 1;
3553 $0let k = n * m!(n);$0 3646 $0let k = n * m!(n);$0
3554 let m = k + 1; 3647 let m = k + 1;
3555}", 3648}
3556 r" 3649"#,
3650 r#"
3557macro_rules! m { 3651macro_rules! m {
3558 ($val:expr) => { $val }; 3652 ($val:expr) => { $val };
3559} 3653}
@@ -3567,7 +3661,8 @@ fn foo() {
3567fn $0fun_name(n: i32) -> i32 { 3661fn $0fun_name(n: i32) -> i32 {
3568 let k = n * m!(n); 3662 let k = n * m!(n);
3569 k 3663 k
3570}", 3664}
3665"#,
3571 ); 3666 );
3572 } 3667 }
3573 3668
@@ -3575,7 +3670,8 @@ fn $0fun_name(n: i32) -> i32 {
3575 fn extract_with_await() { 3670 fn extract_with_await() {
3576 check_assist( 3671 check_assist(
3577 extract_function, 3672 extract_function,
3578 r#"fn main() { 3673 r#"
3674fn main() {
3579 $0some_function().await;$0 3675 $0some_function().await;$0
3580} 3676}
3581 3677
@@ -3603,7 +3699,8 @@ async fn some_function() {
3603 fn extract_with_await_in_args() { 3699 fn extract_with_await_in_args() {
3604 check_assist( 3700 check_assist(
3605 extract_function, 3701 extract_function,
3606 r#"fn main() { 3702 r#"
3703fn main() {
3607 $0function_call("a", some_function().await);$0 3704 $0function_call("a", some_function().await);$0
3608} 3705}
3609 3706
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
index 6c6ff16c2..430710448 100644
--- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -236,7 +236,7 @@ fn apply_references(
236 import: Option<(ImportScope, hir::ModPath)>, 236 import: Option<(ImportScope, hir::ModPath)>,
237) { 237) {
238 if let Some((scope, path)) = import { 238 if let Some((scope, path)) = import {
239 insert_use(&scope, mod_path_to_ast(&path), insert_use_cfg); 239 insert_use(&scope, mod_path_to_ast(&path), &insert_use_cfg);
240 } 240 }
241 // deep clone to prevent cycle 241 // deep clone to prevent cycle
242 let path = make::path_from_segments(iter::once(segment.clone_subtree()), false); 242 let path = make::path_from_segments(iter::once(segment.clone_subtree()), false);
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs
index cd0f6dba9..318faa0fc 100644
--- a/crates/ide_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ide_assists/src/handlers/fill_match_arms.rs
@@ -481,26 +481,21 @@ fn main() {
481 check_assist( 481 check_assist(
482 fill_match_arms, 482 fill_match_arms,
483 r#" 483 r#"
484enum Option<T> { Some(T), None } 484//- minicore: option
485use Option::*;
486
487fn main() { 485fn main() {
488 match None$0 { 486 match None$0 {
489 None => {} 487 None => {}
490 } 488 }
491} 489}
492 "#, 490"#,
493 r#" 491 r#"
494enum Option<T> { Some(T), None }
495use Option::*;
496
497fn main() { 492fn main() {
498 match None { 493 match None {
499 None => {} 494 None => {}
500 Some(${0:_}) => todo!(), 495 Some(${0:_}) => todo!(),
501 } 496 }
502} 497}
503 "#, 498"#,
504 ); 499 );
505 } 500 }
506 501
diff --git a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
index 9404aa26d..f37aa0d53 100644
--- a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
@@ -262,9 +262,7 @@ impl VariantData {
262 check_assist( 262 check_assist(
263 replace_if_let_with_match, 263 replace_if_let_with_match,
264 r#" 264 r#"
265enum Option<T> { Some(T), None } 265//- minicore: option
266use Option::*;
267
268fn foo(x: Option<i32>) { 266fn foo(x: Option<i32>) {
269 $0if let Some(x) = x { 267 $0if let Some(x) = x {
270 println!("{}", x) 268 println!("{}", x)
@@ -272,18 +270,15 @@ fn foo(x: Option<i32>) {
272 println!("none") 270 println!("none")
273 } 271 }
274} 272}
275 "#, 273"#,
276 r#" 274 r#"
277enum Option<T> { Some(T), None }
278use Option::*;
279
280fn foo(x: Option<i32>) { 275fn foo(x: Option<i32>) {
281 match x { 276 match x {
282 Some(x) => println!("{}", x), 277 Some(x) => println!("{}", x),
283 None => println!("none"), 278 None => println!("none"),
284 } 279 }
285} 280}
286 "#, 281"#,
287 ); 282 );
288 } 283 }
289 284
@@ -292,9 +287,7 @@ fn foo(x: Option<i32>) {
292 check_assist( 287 check_assist(
293 replace_if_let_with_match, 288 replace_if_let_with_match,
294 r#" 289 r#"
295enum Option<T> { Some(T), None } 290//- minicore: option
296use Option::*;
297
298fn foo(x: Option<i32>) { 291fn foo(x: Option<i32>) {
299 $0if let None = x { 292 $0if let None = x {
300 println!("none") 293 println!("none")
@@ -302,18 +295,15 @@ fn foo(x: Option<i32>) {
302 println!("some") 295 println!("some")
303 } 296 }
304} 297}
305 "#, 298"#,
306 r#" 299 r#"
307enum Option<T> { Some(T), None }
308use Option::*;
309
310fn foo(x: Option<i32>) { 300fn foo(x: Option<i32>) {
311 match x { 301 match x {
312 None => println!("none"), 302 None => println!("none"),
313 Some(_) => println!("some"), 303 Some(_) => println!("some"),
314 } 304 }
315} 305}
316 "#, 306"#,
317 ); 307 );
318 } 308 }
319 309
@@ -322,9 +312,7 @@ fn foo(x: Option<i32>) {
322 check_assist( 312 check_assist(
323 replace_if_let_with_match, 313 replace_if_let_with_match,
324 r#" 314 r#"
325enum Result<T, E> { Ok(T), Err(E) } 315//- minicore: result
326use Result::*;
327
328fn foo(x: Result<i32, ()>) { 316fn foo(x: Result<i32, ()>) {
329 $0if let Ok(x) = x { 317 $0if let Ok(x) = x {
330 println!("{}", x) 318 println!("{}", x)
@@ -332,18 +320,15 @@ fn foo(x: Result<i32, ()>) {
332 println!("none") 320 println!("none")
333 } 321 }
334} 322}
335 "#, 323"#,
336 r#" 324 r#"
337enum Result<T, E> { Ok(T), Err(E) }
338use Result::*;
339
340fn foo(x: Result<i32, ()>) { 325fn foo(x: Result<i32, ()>) {
341 match x { 326 match x {
342 Ok(x) => println!("{}", x), 327 Ok(x) => println!("{}", x),
343 Err(_) => println!("none"), 328 Err(_) => println!("none"),
344 } 329 }
345} 330}
346 "#, 331"#,
347 ); 332 );
348 } 333 }
349 334
@@ -352,9 +337,7 @@ fn foo(x: Result<i32, ()>) {
352 check_assist( 337 check_assist(
353 replace_if_let_with_match, 338 replace_if_let_with_match,
354 r#" 339 r#"
355enum Result<T, E> { Ok(T), Err(E) } 340//- minicore: result
356use Result::*;
357
358fn foo(x: Result<i32, ()>) { 341fn foo(x: Result<i32, ()>) {
359 $0if let Err(x) = x { 342 $0if let Err(x) = x {
360 println!("{}", x) 343 println!("{}", x)
@@ -362,18 +345,15 @@ fn foo(x: Result<i32, ()>) {
362 println!("ok") 345 println!("ok")
363 } 346 }
364} 347}
365 "#, 348"#,
366 r#" 349 r#"
367enum Result<T, E> { Ok(T), Err(E) }
368use Result::*;
369
370fn foo(x: Result<i32, ()>) { 350fn foo(x: Result<i32, ()>) {
371 match x { 351 match x {
372 Err(x) => println!("{}", x), 352 Err(x) => println!("{}", x),
373 Ok(_) => println!("ok"), 353 Ok(_) => println!("ok"),
374 } 354 }
375} 355}
376 "#, 356"#,
377 ); 357 );
378 } 358 }
379 359
@@ -488,20 +468,15 @@ impl VariantData {
488 check_assist( 468 check_assist(
489 replace_match_with_if_let, 469 replace_match_with_if_let,
490 r#" 470 r#"
491enum Option<T> { Some(T), None } 471//- minicore: option
492use Option::*;
493
494fn foo(x: Option<i32>) { 472fn foo(x: Option<i32>) {
495 $0match x { 473 $0match x {
496 Some(x) => println!("{}", x), 474 Some(x) => println!("{}", x),
497 None => println!("none"), 475 None => println!("none"),
498 } 476 }
499} 477}
500 "#, 478"#,
501 r#" 479 r#"
502enum Option<T> { Some(T), None }
503use Option::*;
504
505fn foo(x: Option<i32>) { 480fn foo(x: Option<i32>) {
506 if let Some(x) = x { 481 if let Some(x) = x {
507 println!("{}", x) 482 println!("{}", x)
@@ -509,7 +484,7 @@ fn foo(x: Option<i32>) {
509 println!("none") 484 println!("none")
510 } 485 }
511} 486}
512 "#, 487"#,
513 ); 488 );
514 } 489 }
515 490
@@ -518,20 +493,15 @@ fn foo(x: Option<i32>) {
518 check_assist( 493 check_assist(
519 replace_match_with_if_let, 494 replace_match_with_if_let,
520 r#" 495 r#"
521enum Result<T, E> { Ok(T), Err(E) } 496//- minicore: result
522use Result::*;
523
524fn foo(x: Result<i32, ()>) { 497fn foo(x: Result<i32, ()>) {
525 $0match x { 498 $0match x {
526 Ok(x) => println!("{}", x), 499 Ok(x) => println!("{}", x),
527 Err(_) => println!("none"), 500 Err(_) => println!("none"),
528 } 501 }
529} 502}
530 "#, 503"#,
531 r#" 504 r#"
532enum Result<T, E> { Ok(T), Err(E) }
533use Result::*;
534
535fn foo(x: Result<i32, ()>) { 505fn foo(x: Result<i32, ()>) {
536 if let Ok(x) = x { 506 if let Ok(x) = x {
537 println!("{}", x) 507 println!("{}", x)
@@ -539,7 +509,7 @@ fn foo(x: Result<i32, ()>) {
539 println!("none") 509 println!("none")
540 } 510 }
541} 511}
542 "#, 512"#,
543 ); 513 );
544 } 514 }
545 515
diff --git a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
index 39f5eb4ff..26778ee74 100644
--- a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -32,7 +32,6 @@ pub(crate) fn replace_qualified_name_with_use(
32 32
33 let target = path.syntax().text_range(); 33 let target = path.syntax().text_range();
34 let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?; 34 let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?;
35 let syntax = scope.as_syntax_node();
36 acc.add( 35 acc.add(
37 AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite), 36 AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite),
38 "Replace qualified path with use", 37 "Replace qualified path with use",
@@ -40,11 +39,13 @@ pub(crate) fn replace_qualified_name_with_use(
40 |builder| { 39 |builder| {
41 // Now that we've brought the name into scope, re-qualify all paths that could be 40 // Now that we've brought the name into scope, re-qualify all paths that could be
42 // affected (that is, all paths inside the node we added the `use` to). 41 // affected (that is, all paths inside the node we added the `use` to).
43 let syntax = builder.make_syntax_mut(syntax.clone()); 42 let scope = match scope {
44 if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { 43 ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
45 shorten_paths(&syntax, &path.clone_for_update()); 44 ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
46 insert_use(import_scope, path, ctx.config.insert_use); 45 ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
47 } 46 };
47 shorten_paths(scope.as_syntax_node(), &path.clone_for_update());
48 insert_use(&scope, path, &ctx.config.insert_use);
48 }, 49 },
49 ) 50 )
50} 51}
diff --git a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
index a3bfa221c..f39c48d8f 100644
--- a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
@@ -20,17 +20,16 @@ use ide_db::ty_filter::TryEnum;
20// Replaces `unwrap` with a `match` expression. Works for Result and Option. 20// Replaces `unwrap` with a `match` expression. Works for Result and Option.
21// 21//
22// ``` 22// ```
23// enum Result<T, E> { Ok(T), Err(E) } 23// # //- minicore: result
24// fn main() { 24// fn main() {
25// let x: Result<i32, i32> = Result::Ok(92); 25// let x: Result<i32, i32> = Ok(92);
26// let y = x.$0unwrap(); 26// let y = x.$0unwrap();
27// } 27// }
28// ``` 28// ```
29// -> 29// ->
30// ``` 30// ```
31// enum Result<T, E> { Ok(T), Err(E) }
32// fn main() { 31// fn main() {
33// let x: Result<i32, i32> = Result::Ok(92); 32// let x: Result<i32, i32> = Ok(92);
34// let y = match x { 33// let y = match x {
35// Ok(it) => it, 34// Ok(it) => it,
36// $0_ => unreachable!(), 35// $0_ => unreachable!(),
@@ -97,25 +96,24 @@ mod tests {
97 fn test_replace_result_unwrap_with_match() { 96 fn test_replace_result_unwrap_with_match() {
98 check_assist( 97 check_assist(
99 replace_unwrap_with_match, 98 replace_unwrap_with_match,
100 r" 99 r#"
101enum Result<T, E> { Ok(T), Err(E) } 100//- minicore: result
102fn i<T>(a: T) -> T { a } 101fn i<T>(a: T) -> T { a }
103fn main() { 102fn main() {
104 let x: Result<i32, i32> = Result::Ok(92); 103 let x: Result<i32, i32> = Ok(92);
105 let y = i(x).$0unwrap(); 104 let y = i(x).$0unwrap();
106} 105}
107 ", 106"#,
108 r" 107 r#"
109enum Result<T, E> { Ok(T), Err(E) }
110fn i<T>(a: T) -> T { a } 108fn i<T>(a: T) -> T { a }
111fn main() { 109fn main() {
112 let x: Result<i32, i32> = Result::Ok(92); 110 let x: Result<i32, i32> = Ok(92);
113 let y = match i(x) { 111 let y = match i(x) {
114 Ok(it) => it, 112 Ok(it) => it,
115 $0_ => unreachable!(), 113 $0_ => unreachable!(),
116 }; 114 };
117} 115}
118 ", 116"#,
119 ) 117 )
120 } 118 }
121 119
@@ -123,25 +121,24 @@ fn main() {
123 fn test_replace_option_unwrap_with_match() { 121 fn test_replace_option_unwrap_with_match() {
124 check_assist( 122 check_assist(
125 replace_unwrap_with_match, 123 replace_unwrap_with_match,
126 r" 124 r#"
127enum Option<T> { Some(T), None } 125//- minicore: option
128fn i<T>(a: T) -> T { a } 126fn i<T>(a: T) -> T { a }
129fn main() { 127fn main() {
130 let x = Option::Some(92); 128 let x = Some(92);
131 let y = i(x).$0unwrap(); 129 let y = i(x).$0unwrap();
132} 130}
133 ", 131"#,
134 r" 132 r#"
135enum Option<T> { Some(T), None }
136fn i<T>(a: T) -> T { a } 133fn i<T>(a: T) -> T { a }
137fn main() { 134fn main() {
138 let x = Option::Some(92); 135 let x = Some(92);
139 let y = match i(x) { 136 let y = match i(x) {
140 Some(it) => it, 137 Some(it) => it,
141 $0_ => unreachable!(), 138 $0_ => unreachable!(),
142 }; 139 };
143} 140}
144 ", 141"#,
145 ); 142 );
146 } 143 }
147 144
@@ -149,25 +146,24 @@ fn main() {
149 fn test_replace_result_unwrap_with_match_chaining() { 146 fn test_replace_result_unwrap_with_match_chaining() {
150 check_assist( 147 check_assist(
151 replace_unwrap_with_match, 148 replace_unwrap_with_match,
152 r" 149 r#"
153enum Result<T, E> { Ok(T), Err(E) } 150//- minicore: result
154fn i<T>(a: T) -> T { a } 151fn i<T>(a: T) -> T { a }
155fn main() { 152fn main() {
156 let x: Result<i32, i32> = Result::Ok(92); 153 let x: Result<i32, i32> = Ok(92);
157 let y = i(x).$0unwrap().count_zeroes(); 154 let y = i(x).$0unwrap().count_zeroes();
158} 155}
159 ", 156"#,
160 r" 157 r#"
161enum Result<T, E> { Ok(T), Err(E) }
162fn i<T>(a: T) -> T { a } 158fn i<T>(a: T) -> T { a }
163fn main() { 159fn main() {
164 let x: Result<i32, i32> = Result::Ok(92); 160 let x: Result<i32, i32> = Ok(92);
165 let y = match i(x) { 161 let y = match i(x) {
166 Ok(it) => it, 162 Ok(it) => it,
167 $0_ => unreachable!(), 163 $0_ => unreachable!(),
168 }.count_zeroes(); 164 }.count_zeroes();
169} 165}
170 ", 166"#,
171 ) 167 )
172 } 168 }
173 169
@@ -175,14 +171,14 @@ fn main() {
175 fn replace_unwrap_with_match_target() { 171 fn replace_unwrap_with_match_target() {
176 check_assist_target( 172 check_assist_target(
177 replace_unwrap_with_match, 173 replace_unwrap_with_match,
178 r" 174 r#"
179enum Option<T> { Some(T), None } 175//- minicore: option
180fn i<T>(a: T) -> T { a } 176fn i<T>(a: T) -> T { a }
181fn main() { 177fn main() {
182 let x = Option::Some(92); 178 let x = Some(92);
183 let y = i(x).$0unwrap(); 179 let y = i(x).$0unwrap();
184} 180}
185 ", 181"#,
186 r"i(x).unwrap()", 182 r"i(x).unwrap()",
187 ); 183 );
188 } 184 }
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index 4e96ff1ec..841537c77 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -28,6 +28,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
28 prefix_kind: hir::PrefixKind::Plain, 28 prefix_kind: hir::PrefixKind::Plain,
29 enforce_granularity: true, 29 enforce_granularity: true,
30 group: true, 30 group: true,
31 skip_glob_imports: true,
31 }, 32 },
32}; 33};
33 34
diff --git a/crates/ide_assists/src/tests/generated.rs b/crates/ide_assists/src/tests/generated.rs
index de5d9e55a..1509c3c63 100644
--- a/crates/ide_assists/src/tests/generated.rs
+++ b/crates/ide_assists/src/tests/generated.rs
@@ -209,10 +209,7 @@ fn doctest_convert_into_to_from() {
209 check_doc_test( 209 check_doc_test(
210 "convert_into_to_from", 210 "convert_into_to_from",
211 r#####" 211 r#####"
212//- /lib.rs crate:core 212//- minicore: from
213pub mod convert { pub trait Into<T> { pub fn into(self) -> T; } }
214//- /lib.rs crate:main deps:core
215use core::convert::Into;
216impl $0Into<Thing> for usize { 213impl $0Into<Thing> for usize {
217 fn into(self) -> Thing { 214 fn into(self) -> Thing {
218 Thing { 215 Thing {
@@ -223,7 +220,6 @@ impl $0Into<Thing> for usize {
223} 220}
224"#####, 221"#####,
225 r#####" 222 r#####"
226use core::convert::Into;
227impl From<usize> for Thing { 223impl From<usize> for Thing {
228 fn from(val: usize) -> Self { 224 fn from(val: usize) -> Self {
229 Thing { 225 Thing {
@@ -241,23 +237,19 @@ fn doctest_convert_iter_for_each_to_for() {
241 check_doc_test( 237 check_doc_test(
242 "convert_iter_for_each_to_for", 238 "convert_iter_for_each_to_for",
243 r#####" 239 r#####"
244//- /lib.rs crate:core 240//- minicore: iterators
245pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } } 241use core::iter;
246pub struct SomeIter;
247impl self::iter::traits::iterator::Iterator for SomeIter {}
248//- /lib.rs crate:main deps:core
249use core::SomeIter;
250fn main() { 242fn main() {
251 let iter = SomeIter; 243 let iter = iter::repeat((9, 2));
252 iter.for_each$0(|(x, y)| { 244 iter.for_each$0(|(x, y)| {
253 println!("x: {}, y: {}", x, y); 245 println!("x: {}, y: {}", x, y);
254 }); 246 });
255} 247}
256"#####, 248"#####,
257 r#####" 249 r#####"
258use core::SomeIter; 250use core::iter;
259fn main() { 251fn main() {
260 let iter = SomeIter; 252 let iter = iter::repeat((9, 2));
261 for (x, y) in iter { 253 for (x, y) in iter {
262 println!("x: {}, y: {}", x, y); 254 println!("x: {}, y: {}", x, y);
263 } 255 }
@@ -1519,16 +1511,15 @@ fn doctest_replace_unwrap_with_match() {
1519 check_doc_test( 1511 check_doc_test(
1520 "replace_unwrap_with_match", 1512 "replace_unwrap_with_match",
1521 r#####" 1513 r#####"
1522enum Result<T, E> { Ok(T), Err(E) } 1514//- minicore: result
1523fn main() { 1515fn main() {
1524 let x: Result<i32, i32> = Result::Ok(92); 1516 let x: Result<i32, i32> = Ok(92);
1525 let y = x.$0unwrap(); 1517 let y = x.$0unwrap();
1526} 1518}
1527"#####, 1519"#####,
1528 r#####" 1520 r#####"
1529enum Result<T, E> { Ok(T), Err(E) }
1530fn main() { 1521fn main() {
1531 let x: Result<i32, i32> = Result::Ok(92); 1522 let x: Result<i32, i32> = Ok(92);
1532 let y = match x { 1523 let y = match x {
1533 Ok(it) => it, 1524 Ok(it) => it,
1534 $0_ => unreachable!(), 1525 $0_ => unreachable!(),
diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs
index 7f75d4298..286d7cb67 100644
--- a/crates/ide_completion/src/completions/dot.rs
+++ b/crates/ide_completion/src/completions/dot.rs
@@ -498,10 +498,7 @@ mod foo {
498 fn issue_8931() { 498 fn issue_8931() {
499 check( 499 check(
500 r#" 500 r#"
501#[lang = "fn_once"] 501//- minicore: fn
502trait FnOnce<Args> {
503 type Output;
504}
505struct S; 502struct S;
506 503
507struct Foo; 504struct Foo;
diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs
index c3c7e4589..4e20ec003 100644
--- a/crates/ide_completion/src/completions/postfix.rs
+++ b/crates/ide_completion/src/completions/postfix.rs
@@ -436,18 +436,15 @@ fn main() {
436 check_edit( 436 check_edit(
437 "ifl", 437 "ifl",
438 r#" 438 r#"
439enum Option<T> { Some(T), None } 439//- minicore: option
440
441fn main() { 440fn main() {
442 let bar = Option::Some(true); 441 let bar = Some(true);
443 bar.$0 442 bar.$0
444} 443}
445"#, 444"#,
446 r#" 445 r#"
447enum Option<T> { Some(T), None }
448
449fn main() { 446fn main() {
450 let bar = Option::Some(true); 447 let bar = Some(true);
451 if let Some($1) = bar { 448 if let Some($1) = bar {
452 $0 449 $0
453} 450}
@@ -461,18 +458,15 @@ fn main() {
461 check_edit( 458 check_edit(
462 "match", 459 "match",
463 r#" 460 r#"
464enum Result<T, E> { Ok(T), Err(E) } 461//- minicore: result
465
466fn main() { 462fn main() {
467 let bar = Result::Ok(true); 463 let bar = Ok(true);
468 bar.$0 464 bar.$0
469} 465}
470"#, 466"#,
471 r#" 467 r#"
472enum Result<T, E> { Ok(T), Err(E) }
473
474fn main() { 468fn main() {
475 let bar = Result::Ok(true); 469 let bar = Ok(true);
476 match bar { 470 match bar {
477 Ok(${1:_}) => {$2}, 471 Ok(${1:_}) => {$2},
478 Err(${3:_}) => {$0}, 472 Err(${3:_}) => {$0},
@@ -515,18 +509,15 @@ fn main() {
515 check_edit( 509 check_edit(
516 "ifl", 510 "ifl",
517 r#" 511 r#"
518enum Option<T> { Some(T), None } 512//- minicore: option
519
520fn main() { 513fn main() {
521 let bar = &Option::Some(true); 514 let bar = &Some(true);
522 bar.$0 515 bar.$0
523} 516}
524"#, 517"#,
525 r#" 518 r#"
526enum Option<T> { Some(T), None }
527
528fn main() { 519fn main() {
529 let bar = &Option::Some(true); 520 let bar = &Some(true);
530 if let Some($1) = bar { 521 if let Some($1) = bar {
531 $0 522 $0
532} 523}
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 98fb36042..e49e434fa 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -942,13 +942,12 @@ fn foo() -> u32 {
942 // FIXME: make this work with `|| $0` 942 // FIXME: make this work with `|| $0`
943 check_expected_type_and_name( 943 check_expected_type_and_name(
944 r#" 944 r#"
945//- minicore: fn
945fn foo() { 946fn foo() {
946 bar(|| a$0); 947 bar(|| a$0);
947} 948}
948 949
949fn bar(f: impl FnOnce() -> u32) {} 950fn bar(f: impl FnOnce() -> u32) {}
950#[lang = "fn_once"]
951trait FnOnce { type Output; }
952"#, 951"#,
953 expect![[r#"ty: u32, name: ?"#]], 952 expect![[r#"ty: u32, name: ?"#]],
954 ); 953 );
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index 99edb9499..ae63d132e 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -378,7 +378,7 @@ impl ImportEdit {
378 let _p = profile::span("ImportEdit::to_text_edit"); 378 let _p = profile::span("ImportEdit::to_text_edit");
379 379
380 let new_ast = self.scope.clone_for_update(); 380 let new_ast = self.scope.clone_for_update();
381 insert_use::insert_use(&new_ast, mod_path_to_ast(&self.import.import_path), cfg); 381 insert_use::insert_use(&new_ast, mod_path_to_ast(&self.import.import_path), &cfg);
382 let mut import_insert = TextEdit::builder(); 382 let mut import_insert = TextEdit::builder();
383 algo::diff(self.scope.as_syntax_node(), new_ast.as_syntax_node()) 383 algo::diff(self.scope.as_syntax_node(), new_ast.as_syntax_node())
384 .into_text_edit(&mut import_insert); 384 .into_text_edit(&mut import_insert);
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 4b55f7504..9bec03e17 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -1269,16 +1269,11 @@ fn bar(t: &Foo) {}
1269 fn suggest_deref_fn_ret() { 1269 fn suggest_deref_fn_ret() {
1270 check_relevance( 1270 check_relevance(
1271 r#" 1271 r#"
1272#[lang = "deref"] 1272//- minicore: deref
1273trait Deref {
1274 type Target;
1275 fn deref(&self) -> &Self::Target;
1276}
1277
1278struct S; 1273struct S;
1279struct T(S); 1274struct T(S);
1280 1275
1281impl Deref for T { 1276impl core::ops::Deref for T {
1282 type Target = S; 1277 type Target = S;
1283 1278
1284 fn deref(&self) -> &Self::Target { 1279 fn deref(&self) -> &Self::Target {
@@ -1292,15 +1287,16 @@ fn bar() -> T {}
1292fn main() { 1287fn main() {
1293 foo($0); 1288 foo($0);
1294} 1289}
1295 "#, 1290"#,
1296 expect![[r#" 1291 expect![[r#"
1297 tt Deref []
1298 fn bar() []
1299 fn &bar() [type]
1300 fn foo(…) []
1301 st T [] 1292 st T []
1302 st S [] 1293 st S []
1303 fn main() [] 1294 fn main() []
1295 fn bar() []
1296 fn &bar() [type]
1297 fn foo(…) []
1298 md core []
1299 tt Sized []
1304 "#]], 1300 "#]],
1305 ) 1301 )
1306 } 1302 }
diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs
index 1ea6017ce..211c89c40 100644
--- a/crates/ide_completion/src/tests.rs
+++ b/crates/ide_completion/src/tests.rs
@@ -36,6 +36,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
36 prefix_kind: PrefixKind::Plain, 36 prefix_kind: PrefixKind::Plain,
37 enforce_granularity: true, 37 enforce_granularity: true,
38 group: true, 38 group: true,
39 skip_glob_imports: true,
39 }, 40 },
40}; 41};
41 42
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index 10bbafe77..e6b4832e7 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -5,7 +5,7 @@ use hir::Semantics;
5use syntax::{ 5use syntax::{
6 algo, 6 algo,
7 ast::{self, make, AstNode, AttrsOwner, ModuleItemOwner, PathSegmentKind, VisibilityOwner}, 7 ast::{self, make, AstNode, AttrsOwner, ModuleItemOwner, PathSegmentKind, VisibilityOwner},
8 ted, AstToken, Direction, NodeOrToken, SyntaxNode, SyntaxToken, 8 match_ast, ted, AstToken, Direction, NodeOrToken, SyntaxNode, SyntaxToken,
9}; 9};
10 10
11use crate::{ 11use crate::{
@@ -36,22 +36,39 @@ pub struct InsertUseConfig {
36 pub enforce_granularity: bool, 36 pub enforce_granularity: bool,
37 pub prefix_kind: PrefixKind, 37 pub prefix_kind: PrefixKind,
38 pub group: bool, 38 pub group: bool,
39 pub skip_glob_imports: bool,
39} 40}
40 41
41#[derive(Debug, Clone)] 42#[derive(Debug, Clone)]
42pub enum ImportScope { 43pub enum ImportScope {
43 File(ast::SourceFile), 44 File(ast::SourceFile),
44 Module(ast::ItemList), 45 Module(ast::ItemList),
46 Block(ast::BlockExpr),
45} 47}
46 48
47impl ImportScope { 49impl ImportScope {
48 pub fn from(syntax: SyntaxNode) -> Option<Self> { 50 fn from(syntax: SyntaxNode) -> Option<Self> {
49 if let Some(module) = ast::Module::cast(syntax.clone()) { 51 fn contains_cfg_attr(attrs: &dyn AttrsOwner) -> bool {
50 module.item_list().map(ImportScope::Module) 52 attrs
51 } else if let this @ Some(_) = ast::SourceFile::cast(syntax.clone()) { 53 .attrs()
52 this.map(ImportScope::File) 54 .any(|attr| attr.as_simple_call().map_or(false, |(ident, _)| ident == "cfg"))
53 } else { 55 }
54 ast::ItemList::cast(syntax).map(ImportScope::Module) 56 match_ast! {
57 match syntax {
58 ast::Module(module) => module.item_list().map(ImportScope::Module),
59 ast::SourceFile(file) => Some(ImportScope::File(file)),
60 ast::Fn(func) => contains_cfg_attr(&func).then(|| func.body().map(ImportScope::Block)).flatten(),
61 ast::Const(konst) => contains_cfg_attr(&konst).then(|| match konst.body()? {
62 ast::Expr::BlockExpr(block) => Some(block),
63 _ => None,
64 }).flatten().map(ImportScope::Block),
65 ast::Static(statik) => contains_cfg_attr(&statik).then(|| match statik.body()? {
66 ast::Expr::BlockExpr(block) => Some(block),
67 _ => None,
68 }).flatten().map(ImportScope::Block),
69 _ => None,
70
71 }
55 } 72 }
56 } 73 }
57 74
@@ -72,6 +89,7 @@ impl ImportScope {
72 match self { 89 match self {
73 ImportScope::File(file) => file.syntax(), 90 ImportScope::File(file) => file.syntax(),
74 ImportScope::Module(item_list) => item_list.syntax(), 91 ImportScope::Module(item_list) => item_list.syntax(),
92 ImportScope::Block(block) => block.syntax(),
75 } 93 }
76 } 94 }
77 95
@@ -79,6 +97,7 @@ impl ImportScope {
79 match self { 97 match self {
80 ImportScope::File(file) => ImportScope::File(file.clone_for_update()), 98 ImportScope::File(file) => ImportScope::File(file.clone_for_update()),
81 ImportScope::Module(item_list) => ImportScope::Module(item_list.clone_for_update()), 99 ImportScope::Module(item_list) => ImportScope::Module(item_list.clone_for_update()),
100 ImportScope::Block(block) => ImportScope::Block(block.clone_for_update()),
82 } 101 }
83 } 102 }
84 103
@@ -95,6 +114,7 @@ impl ImportScope {
95 let mut use_stmts = match self { 114 let mut use_stmts = match self {
96 ImportScope::File(f) => f.items(), 115 ImportScope::File(f) => f.items(),
97 ImportScope::Module(m) => m.items(), 116 ImportScope::Module(m) => m.items(),
117 ImportScope::Block(b) => b.items(),
98 } 118 }
99 .filter_map(use_stmt); 119 .filter_map(use_stmt);
100 let mut res = ImportGranularityGuess::Unknown; 120 let mut res = ImportGranularityGuess::Unknown;
@@ -153,7 +173,7 @@ enum ImportGranularityGuess {
153} 173}
154 174
155/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur. 175/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
156pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig) { 176pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
157 let _p = profile::span("insert_use"); 177 let _p = profile::span("insert_use");
158 let mut mb = match cfg.granularity { 178 let mut mb = match cfg.granularity {
159 ImportGranularity::Crate => Some(MergeBehavior::Crate), 179 ImportGranularity::Crate => Some(MergeBehavior::Crate),
@@ -175,7 +195,10 @@ pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig
175 make::use_(None, make::use_tree(path.clone(), None, None, false)).clone_for_update(); 195 make::use_(None, make::use_tree(path.clone(), None, None, false)).clone_for_update();
176 // merge into existing imports if possible 196 // merge into existing imports if possible
177 if let Some(mb) = mb { 197 if let Some(mb) = mb {
178 for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) { 198 let filter = |it: &_| !(cfg.skip_glob_imports && ast::Use::is_simple_glob(it));
199 for existing_use in
200 scope.as_syntax_node().children().filter_map(ast::Use::cast).filter(filter)
201 {
179 if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { 202 if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) {
180 ted::replace(existing_use.syntax(), merged.syntax()); 203 ted::replace(existing_use.syntax(), merged.syntax());
181 return; 204 return;
@@ -315,28 +338,29 @@ fn insert_use_(
315 ted::insert(ted::Position::after(last_inner_element), make::tokens::single_newline()); 338 ted::insert(ted::Position::after(last_inner_element), make::tokens::single_newline());
316 return; 339 return;
317 } 340 }
318 match scope { 341 let l_curly = match scope {
319 ImportScope::File(_) => { 342 ImportScope::File(_) => {
320 cov_mark::hit!(insert_group_empty_file); 343 cov_mark::hit!(insert_group_empty_file);
321 ted::insert(ted::Position::first_child_of(scope_syntax), make::tokens::blank_line()); 344 ted::insert(ted::Position::first_child_of(scope_syntax), make::tokens::blank_line());
322 ted::insert(ted::Position::first_child_of(scope_syntax), use_item.syntax()) 345 ted::insert(ted::Position::first_child_of(scope_syntax), use_item.syntax());
346 return;
323 } 347 }
348 // don't insert the imports before the item list/block expr's opening curly brace
349 ImportScope::Module(item_list) => item_list.l_curly_token(),
324 // don't insert the imports before the item list's opening curly brace 350 // don't insert the imports before the item list's opening curly brace
325 ImportScope::Module(item_list) => match item_list.l_curly_token() { 351 ImportScope::Block(block) => block.l_curly_token(),
326 Some(b) => { 352 };
327 cov_mark::hit!(insert_group_empty_module); 353 match l_curly {
328 ted::insert(ted::Position::after(&b), make::tokens::single_newline()); 354 Some(b) => {
329 ted::insert(ted::Position::after(&b), use_item.syntax()); 355 cov_mark::hit!(insert_group_empty_module);
330 } 356 ted::insert(ted::Position::after(&b), make::tokens::single_newline());
331 None => { 357 ted::insert(ted::Position::after(&b), use_item.syntax());
332 // This should never happens, broken module syntax node 358 }
333 ted::insert( 359 None => {
334 ted::Position::first_child_of(scope_syntax), 360 // This should never happens, broken module syntax node
335 make::tokens::blank_line(), 361 ted::insert(ted::Position::first_child_of(scope_syntax), make::tokens::blank_line());
336 ); 362 ted::insert(ted::Position::first_child_of(scope_syntax), use_item.syntax());
337 ted::insert(ted::Position::first_child_of(scope_syntax), use_item.syntax()); 363 }
338 }
339 },
340 } 364 }
341} 365}
342 366
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs
index 5a88ec742..01894630a 100644
--- a/crates/ide_db/src/helpers/insert_use/tests.rs
+++ b/crates/ide_db/src/helpers/insert_use/tests.rs
@@ -1,12 +1,63 @@
1use super::*; 1use super::*;
2 2
3use hir::PrefixKind; 3use hir::PrefixKind;
4use test_utils::assert_eq_text; 4use test_utils::{assert_eq_text, extract_range_or_offset, CURSOR_MARKER};
5
6#[test]
7fn respects_cfg_attr_fn() {
8 check(
9 r"bar::Bar",
10 r#"
11#[cfg(test)]
12fn foo() {$0}
13"#,
14 r#"
15#[cfg(test)]
16fn foo() {
17use bar::Bar;
18}
19"#,
20 ImportGranularity::Crate,
21 );
22}
23
24#[test]
25fn respects_cfg_attr_const() {
26 check(
27 r"bar::Bar",
28 r#"
29#[cfg(test)]
30const FOO: Bar = {$0};
31"#,
32 r#"
33#[cfg(test)]
34const FOO: Bar = {
35use bar::Bar;
36};
37"#,
38 ImportGranularity::Crate,
39 );
40}
41
42#[test]
43fn insert_skips_lone_glob_imports() {
44 check(
45 "use foo::baz::A",
46 r"
47use foo::bar::*;
48",
49 r"
50use foo::bar::*;
51use foo::baz::A;
52",
53 ImportGranularity::Crate,
54 );
55}
5 56
6#[test] 57#[test]
7fn insert_not_group() { 58fn insert_not_group() {
8 cov_mark::check!(insert_no_grouping_last); 59 cov_mark::check!(insert_no_grouping_last);
9 check( 60 check_with_config(
10 "use external_crate2::bar::A", 61 "use external_crate2::bar::A",
11 r" 62 r"
12use std::bar::B; 63use std::bar::B;
@@ -21,24 +72,32 @@ use crate::bar::A;
21use self::bar::A; 72use self::bar::A;
22use super::bar::A; 73use super::bar::A;
23use external_crate2::bar::A;", 74use external_crate2::bar::A;",
24 ImportGranularity::Item, 75 &InsertUseConfig {
25 false, 76 granularity: ImportGranularity::Item,
26 false, 77 enforce_granularity: true,
78 prefix_kind: PrefixKind::Plain,
79 group: false,
80 skip_glob_imports: true,
81 },
27 ); 82 );
28} 83}
29 84
30#[test] 85#[test]
31fn insert_not_group_empty() { 86fn insert_not_group_empty() {
32 cov_mark::check!(insert_no_grouping_last2); 87 cov_mark::check!(insert_no_grouping_last2);
33 check( 88 check_with_config(
34 "use external_crate2::bar::A", 89 "use external_crate2::bar::A",
35 r"", 90 r"",
36 r"use external_crate2::bar::A; 91 r"use external_crate2::bar::A;
37 92
38", 93",
39 ImportGranularity::Item, 94 &InsertUseConfig {
40 false, 95 granularity: ImportGranularity::Item,
41 false, 96 enforce_granularity: true,
97 prefix_kind: PrefixKind::Plain,
98 group: false,
99 skip_glob_imports: true,
100 },
42 ); 101 );
43} 102}
44 103
@@ -277,13 +336,15 @@ fn insert_empty_module() {
277 cov_mark::check!(insert_group_empty_module); 336 cov_mark::check!(insert_group_empty_module);
278 check( 337 check(
279 "foo::bar", 338 "foo::bar",
280 "mod x {}", 339 r"
281 r"{ 340mod x {$0}
341",
342 r"
343mod x {
282 use foo::bar; 344 use foo::bar;
283}", 345}
346",
284 ImportGranularity::Item, 347 ImportGranularity::Item,
285 true,
286 true,
287 ) 348 )
288} 349}
289 350
@@ -534,17 +595,35 @@ fn merge_groups_self() {
534 595
535#[test] 596#[test]
536fn merge_mod_into_glob() { 597fn merge_mod_into_glob() {
537 check_crate( 598 check_with_config(
538 "token::TokenKind", 599 "token::TokenKind",
539 r"use token::TokenKind::*;", 600 r"use token::TokenKind::*;",
540 r"use token::TokenKind::{*, self};", 601 r"use token::TokenKind::{*, self};",
602 &InsertUseConfig {
603 granularity: ImportGranularity::Crate,
604 enforce_granularity: true,
605 prefix_kind: PrefixKind::Plain,
606 group: false,
607 skip_glob_imports: false,
608 },
541 ) 609 )
542 // FIXME: have it emit `use token::TokenKind::{self, *}`? 610 // FIXME: have it emit `use token::TokenKind::{self, *}`?
543} 611}
544 612
545#[test] 613#[test]
546fn merge_self_glob() { 614fn merge_self_glob() {
547 check_crate("self", r"use self::*;", r"use self::{*, self};") 615 check_with_config(
616 "self",
617 r"use self::*;",
618 r"use self::{*, self};",
619 &InsertUseConfig {
620 granularity: ImportGranularity::Crate,
621 enforce_granularity: true,
622 prefix_kind: PrefixKind::Plain,
623 group: false,
624 skip_glob_imports: false,
625 },
626 )
548 // FIXME: have it emit `use {self, *}`? 627 // FIXME: have it emit `use {self, *}`?
549} 628}
550 629
@@ -757,19 +836,24 @@ use foo::bar::qux;
757 ); 836 );
758} 837}
759 838
760fn check( 839fn check_with_config(
761 path: &str, 840 path: &str,
762 ra_fixture_before: &str, 841 ra_fixture_before: &str,
763 ra_fixture_after: &str, 842 ra_fixture_after: &str,
764 granularity: ImportGranularity, 843 config: &InsertUseConfig,
765 module: bool,
766 group: bool,
767) { 844) {
768 let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone(); 845 let (text, pos) = if ra_fixture_before.contains(CURSOR_MARKER) {
769 if module { 846 let (range_or_offset, text) = extract_range_or_offset(ra_fixture_before);
770 syntax = syntax.descendants().find_map(ast::Module::cast).unwrap().syntax().clone(); 847 (text, Some(range_or_offset))
771 } 848 } else {
772 let file = super::ImportScope::from(syntax.clone_for_update()).unwrap(); 849 (ra_fixture_before.to_owned(), None)
850 };
851 let syntax = ast::SourceFile::parse(&text).tree().syntax().clone_for_update();
852 let file = pos
853 .and_then(|pos| syntax.token_at_offset(pos.expect_offset()).next()?.parent())
854 .and_then(|it| super::ImportScope::find_insert_use_container(&it))
855 .or_else(|| super::ImportScope::from(syntax))
856 .unwrap();
773 let path = ast::SourceFile::parse(&format!("use {};", path)) 857 let path = ast::SourceFile::parse(&format!("use {};", path))
774 .tree() 858 .tree()
775 .syntax() 859 .syntax()
@@ -777,30 +861,41 @@ fn check(
777 .find_map(ast::Path::cast) 861 .find_map(ast::Path::cast)
778 .unwrap(); 862 .unwrap();
779 863
780 insert_use( 864 insert_use(&file, path, config);
781 &file, 865 let result = file.as_syntax_node().ancestors().last().unwrap().to_string();
866 assert_eq_text!(ra_fixture_after, &result);
867}
868
869fn check(
870 path: &str,
871 ra_fixture_before: &str,
872 ra_fixture_after: &str,
873 granularity: ImportGranularity,
874) {
875 check_with_config(
782 path, 876 path,
783 InsertUseConfig { 877 ra_fixture_before,
878 ra_fixture_after,
879 &InsertUseConfig {
784 granularity, 880 granularity,
785 enforce_granularity: true, 881 enforce_granularity: true,
786 prefix_kind: PrefixKind::Plain, 882 prefix_kind: PrefixKind::Plain,
787 group, 883 group: true,
884 skip_glob_imports: true,
788 }, 885 },
789 ); 886 )
790 let result = file.as_syntax_node().to_string();
791 assert_eq_text!(ra_fixture_after, &result);
792} 887}
793 888
794fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 889fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
795 check(path, ra_fixture_before, ra_fixture_after, ImportGranularity::Crate, false, true) 890 check(path, ra_fixture_before, ra_fixture_after, ImportGranularity::Crate)
796} 891}
797 892
798fn check_module(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 893fn check_module(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
799 check(path, ra_fixture_before, ra_fixture_after, ImportGranularity::Module, false, true) 894 check(path, ra_fixture_before, ra_fixture_after, ImportGranularity::Module)
800} 895}
801 896
802fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 897fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
803 check(path, ra_fixture_before, ra_fixture_after, ImportGranularity::Item, false, true) 898 check(path, ra_fixture_before, ra_fixture_after, ImportGranularity::Item)
804} 899}
805 900
806fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior) { 901fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior) {
diff --git a/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs b/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
index 63de54570..c0edcd7d3 100644
--- a/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
+++ b/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
@@ -49,26 +49,15 @@ mod tests {
49 fn test_wrap_return_type_option() { 49 fn test_wrap_return_type_option() {
50 check_fix( 50 check_fix(
51 r#" 51 r#"
52//- /main.rs crate:main deps:core 52//- minicore: option, result
53use core::option::Option::{self, Some, None};
54
55fn div(x: i32, y: i32) -> Option<i32> { 53fn div(x: i32, y: i32) -> Option<i32> {
56 if y == 0 { 54 if y == 0 {
57 return None; 55 return None;
58 } 56 }
59 x / y$0 57 x / y$0
60} 58}
61//- /core/lib.rs crate:core
62pub mod result {
63 pub enum Result<T, E> { Ok(T), Err(E) }
64}
65pub mod option {
66 pub enum Option<T> { Some(T), None }
67}
68"#, 59"#,
69 r#" 60 r#"
70use core::option::Option::{self, Some, None};
71
72fn div(x: i32, y: i32) -> Option<i32> { 61fn div(x: i32, y: i32) -> Option<i32> {
73 if y == 0 { 62 if y == 0 {
74 return None; 63 return None;
@@ -83,26 +72,15 @@ fn div(x: i32, y: i32) -> Option<i32> {
83 fn test_wrap_return_type() { 72 fn test_wrap_return_type() {
84 check_fix( 73 check_fix(
85 r#" 74 r#"
86//- /main.rs crate:main deps:core 75//- minicore: option, result
87use core::result::Result::{self, Ok, Err};
88
89fn div(x: i32, y: i32) -> Result<i32, ()> { 76fn div(x: i32, y: i32) -> Result<i32, ()> {
90 if y == 0 { 77 if y == 0 {
91 return Err(()); 78 return Err(());
92 } 79 }
93 x / y$0 80 x / y$0
94} 81}
95//- /core/lib.rs crate:core
96pub mod result {
97 pub enum Result<T, E> { Ok(T), Err(E) }
98}
99pub mod option {
100 pub enum Option<T> { Some(T), None }
101}
102"#, 82"#,
103 r#" 83 r#"
104use core::result::Result::{self, Ok, Err};
105
106fn div(x: i32, y: i32) -> Result<i32, ()> { 84fn div(x: i32, y: i32) -> Result<i32, ()> {
107 if y == 0 { 85 if y == 0 {
108 return Err(()); 86 return Err(());
@@ -117,26 +95,15 @@ fn div(x: i32, y: i32) -> Result<i32, ()> {
117 fn test_wrap_return_type_handles_generic_functions() { 95 fn test_wrap_return_type_handles_generic_functions() {
118 check_fix( 96 check_fix(
119 r#" 97 r#"
120//- /main.rs crate:main deps:core 98//- minicore: option, result
121use core::result::Result::{self, Ok, Err};
122
123fn div<T>(x: T) -> Result<T, i32> { 99fn div<T>(x: T) -> Result<T, i32> {
124 if x == 0 { 100 if x == 0 {
125 return Err(7); 101 return Err(7);
126 } 102 }
127 $0x 103 $0x
128} 104}
129//- /core/lib.rs crate:core
130pub mod result {
131 pub enum Result<T, E> { Ok(T), Err(E) }
132}
133pub mod option {
134 pub enum Option<T> { Some(T), None }
135}
136"#, 105"#,
137 r#" 106 r#"
138use core::result::Result::{self, Ok, Err};
139
140fn div<T>(x: T) -> Result<T, i32> { 107fn div<T>(x: T) -> Result<T, i32> {
141 if x == 0 { 108 if x == 0 {
142 return Err(7); 109 return Err(7);
@@ -151,9 +118,7 @@ fn div<T>(x: T) -> Result<T, i32> {
151 fn test_wrap_return_type_handles_type_aliases() { 118 fn test_wrap_return_type_handles_type_aliases() {
152 check_fix( 119 check_fix(
153 r#" 120 r#"
154//- /main.rs crate:main deps:core 121//- minicore: option, result
155use core::result::Result::{self, Ok, Err};
156
157type MyResult<T> = Result<T, ()>; 122type MyResult<T> = Result<T, ()>;
158 123
159fn div(x: i32, y: i32) -> MyResult<i32> { 124fn div(x: i32, y: i32) -> MyResult<i32> {
@@ -162,17 +127,8 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
162 } 127 }
163 x $0/ y 128 x $0/ y
164} 129}
165//- /core/lib.rs crate:core
166pub mod result {
167 pub enum Result<T, E> { Ok(T), Err(E) }
168}
169pub mod option {
170 pub enum Option<T> { Some(T), None }
171}
172"#, 130"#,
173 r#" 131 r#"
174use core::result::Result::{self, Ok, Err};
175
176type MyResult<T> = Result<T, ()>; 132type MyResult<T> = Result<T, ()>;
177 133
178fn div(x: i32, y: i32) -> MyResult<i32> { 134fn div(x: i32, y: i32) -> MyResult<i32> {
@@ -189,18 +145,8 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
189 fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() { 145 fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() {
190 check_diagnostics( 146 check_diagnostics(
191 r#" 147 r#"
192//- /main.rs crate:main deps:core 148//- minicore: option, result
193use core::result::Result::{self, Ok, Err};
194
195fn foo() -> Result<(), i32> { 0 } 149fn foo() -> Result<(), i32> { 0 }
196
197//- /core/lib.rs crate:core
198pub mod result {
199 pub enum Result<T, E> { Ok(T), Err(E) }
200}
201pub mod option {
202 pub enum Option<T> { Some(T), None }
203}
204"#, 150"#,
205 ); 151 );
206 } 152 }
@@ -209,20 +155,10 @@ pub mod option {
209 fn test_wrap_return_type_not_applicable_when_return_type_is_not_result_or_option() { 155 fn test_wrap_return_type_not_applicable_when_return_type_is_not_result_or_option() {
210 check_diagnostics( 156 check_diagnostics(
211 r#" 157 r#"
212//- /main.rs crate:main deps:core 158//- minicore: option, result
213use core::result::Result::{self, Ok, Err};
214
215enum SomeOtherEnum { Ok(i32), Err(String) } 159enum SomeOtherEnum { Ok(i32), Err(String) }
216 160
217fn foo() -> SomeOtherEnum { 0 } 161fn foo() -> SomeOtherEnum { 0 }
218
219//- /core/lib.rs crate:core
220pub mod result {
221 pub enum Result<T, E> { Ok(T), Err(E) }
222}
223pub mod option {
224 pub enum Option<T> { Some(T), None }
225}
226"#, 162"#,
227 ); 163 );
228 } 164 }
diff --git a/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs b/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
index cd87a10bb..839ceac03 100644
--- a/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
+++ b/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
@@ -55,44 +55,16 @@ fn fixes(
55 55
56#[cfg(test)] 56#[cfg(test)]
57mod tests { 57mod tests {
58 use crate::tests::check_fix; 58 use crate::tests::{check_diagnostics, check_fix};
59
60 // Register the required standard library types to make the tests work
61 #[track_caller]
62 fn check_diagnostics(ra_fixture: &str) {
63 let prefix = r#"
64//- /main.rs crate:main deps:core
65use core::iter::Iterator;
66use core::option::Option::{self, Some, None};
67"#;
68 let suffix = r#"
69//- /core/lib.rs crate:core
70pub mod option {
71 pub enum Option<T> { Some(T), None }
72}
73pub mod iter {
74 pub trait Iterator {
75 type Item;
76 fn filter_map<B, F>(self, f: F) -> FilterMap where F: FnMut(Self::Item) -> Option<B> { FilterMap }
77 fn next(&mut self) -> Option<Self::Item>;
78 }
79 pub struct FilterMap {}
80 impl Iterator for FilterMap {
81 type Item = i32;
82 fn next(&mut self) -> i32 { 7 }
83 }
84}
85"#;
86 crate::tests::check_diagnostics(&format!("{}{}{}", prefix, ra_fixture, suffix))
87 }
88 59
89 #[test] 60 #[test]
90 fn replace_filter_map_next_with_find_map2() { 61 fn replace_filter_map_next_with_find_map2() {
91 check_diagnostics( 62 check_diagnostics(
92 r#" 63 r#"
93 fn foo() { 64//- minicore: iterators
94 let m = [1, 2, 3].iter().filter_map(|x| Some(92)).next(); 65fn foo() {
95 } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 💡 weak: replace filter_map(..).next() with find_map(..) 66 let m = core::iter::repeat(()).filter_map(|()| Some(92)).next();
67} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 💡 weak: replace filter_map(..).next() with find_map(..)
96"#, 68"#,
97 ); 69 );
98 } 70 }
@@ -101,11 +73,11 @@ pub mod iter {
101 fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() { 73 fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() {
102 check_diagnostics( 74 check_diagnostics(
103 r#" 75 r#"
76//- minicore: iterators
104fn foo() { 77fn foo() {
105 let m = [1, 2, 3] 78 let m = core::iter::repeat(())
106 .iter() 79 .filter_map(|()| Some(92))
107 .filter_map(|x| Some(92)) 80 .count();
108 .len();
109} 81}
110"#, 82"#,
111 ); 83 );
@@ -115,12 +87,12 @@ fn foo() {
115 fn replace_filter_map_next_with_find_map_no_diagnostic_with_intervening_methods() { 87 fn replace_filter_map_next_with_find_map_no_diagnostic_with_intervening_methods() {
116 check_diagnostics( 88 check_diagnostics(
117 r#" 89 r#"
90//- minicore: iterators
118fn foo() { 91fn foo() {
119 let m = [1, 2, 3] 92 let m = core::iter::repeat(())
120 .iter() 93 .filter_map(|()| Some(92))
121 .filter_map(|x| Some(92))
122 .map(|x| x + 2) 94 .map(|x| x + 2)
123 .len(); 95 .next();
124} 96}
125"#, 97"#,
126 ); 98 );
@@ -130,10 +102,10 @@ fn foo() {
130 fn replace_filter_map_next_with_find_map_no_diagnostic_if_not_in_chain() { 102 fn replace_filter_map_next_with_find_map_no_diagnostic_if_not_in_chain() {
131 check_diagnostics( 103 check_diagnostics(
132 r#" 104 r#"
105//- minicore: iterators
133fn foo() { 106fn foo() {
134 let m = [1, 2, 3] 107 let m = core::iter::repeat(())
135 .iter() 108 .filter_map(|()| Some(92));
136 .filter_map(|x| Some(92));
137 let n = m.next(); 109 let n = m.next();
138} 110}
139"#, 111"#,
@@ -144,34 +116,14 @@ fn foo() {
144 fn replace_with_wind_map() { 116 fn replace_with_wind_map() {
145 check_fix( 117 check_fix(
146 r#" 118 r#"
147//- /main.rs crate:main deps:core 119//- minicore: iterators
148use core::iter::Iterator;
149use core::option::Option::{self, Some, None};
150fn foo() { 120fn foo() {
151 let m = [1, 2, 3].iter().$0filter_map(|x| Some(92)).next(); 121 let m = core::iter::repeat(()).$0filter_map(|()| Some(92)).next();
152}
153//- /core/lib.rs crate:core
154pub mod option {
155 pub enum Option<T> { Some(T), None }
156}
157pub mod iter {
158 pub trait Iterator {
159 type Item;
160 fn filter_map<B, F>(self, f: F) -> FilterMap where F: FnMut(Self::Item) -> Option<B> { FilterMap }
161 fn next(&mut self) -> Option<Self::Item>;
162 }
163 pub struct FilterMap {}
164 impl Iterator for FilterMap {
165 type Item = i32;
166 fn next(&mut self) -> i32 { 7 }
167 }
168} 122}
169"#, 123"#,
170 r#" 124 r#"
171use core::iter::Iterator;
172use core::option::Option::{self, Some, None};
173fn foo() { 125fn foo() {
174 let m = [1, 2, 3].iter().find_map(|x| Some(92)); 126 let m = core::iter::repeat(()).find_map(|()| Some(92));
175} 127}
176"#, 128"#,
177 ) 129 )
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index c4757a1cb..16c295639 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -44,6 +44,9 @@ config_data! {
44 assist_importPrefix: ImportPrefixDef = "\"plain\"", 44 assist_importPrefix: ImportPrefixDef = "\"plain\"",
45 /// Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines. 45 /// Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
46 assist_importGroup: bool = "true", 46 assist_importGroup: bool = "true",
47 /// Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
48 assist_allowMergingIntoGlobImports: bool = "true",
49
47 /// Show function name and docs in parameter hints. 50 /// Show function name and docs in parameter hints.
48 callInfo_full: bool = "true", 51 callInfo_full: bool = "true",
49 52
@@ -672,6 +675,7 @@ impl Config {
672 ImportPrefixDef::BySelf => PrefixKind::BySelf, 675 ImportPrefixDef::BySelf => PrefixKind::BySelf,
673 }, 676 },
674 group: self.data.assist_importGroup, 677 group: self.data.assist_importGroup,
678 skip_glob_imports: !self.data.assist_allowMergingIntoGlobImports,
675 } 679 }
676 } 680 }
677 pub fn completion(&self) -> CompletionConfig { 681 pub fn completion(&self) -> CompletionConfig {
diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs
index 8ddeb59f7..f8afc930a 100644
--- a/crates/rust-analyzer/src/integrated_benchmarks.rs
+++ b/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -143,6 +143,7 @@ fn integrated_completion_benchmark() {
143 prefix_kind: hir::PrefixKind::ByCrate, 143 prefix_kind: hir::PrefixKind::ByCrate,
144 enforce_granularity: true, 144 enforce_granularity: true,
145 group: true, 145 group: true,
146 skip_glob_imports: true,
146 }, 147 },
147 }; 148 };
148 let position = 149 let position =
@@ -178,6 +179,7 @@ fn integrated_completion_benchmark() {
178 prefix_kind: hir::PrefixKind::ByCrate, 179 prefix_kind: hir::PrefixKind::ByCrate,
179 enforce_granularity: true, 180 enforce_granularity: true,
180 group: true, 181 group: true,
182 skip_glob_imports: true,
181 }, 183 },
182 }; 184 };
183 let position = 185 let position =
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index e53cd3c7b..310d8c6d2 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -1187,6 +1187,7 @@ mod tests {
1187 prefix_kind: PrefixKind::Plain, 1187 prefix_kind: PrefixKind::Plain,
1188 enforce_granularity: true, 1188 enforce_granularity: true,
1189 group: true, 1189 group: true,
1190 skip_glob_imports: true,
1190 }, 1191 },
1191 }, 1192 },
1192 ide_db::base_db::FilePosition { file_id, offset }, 1193 ide_db::base_db::FilePosition { file_id, offset },
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index b057e6624..e33e5bb03 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -8,7 +8,7 @@ use parser::SyntaxKind;
8use rowan::{GreenNodeData, GreenTokenData}; 8use rowan::{GreenNodeData, GreenTokenData};
9 9
10use crate::{ 10use crate::{
11 ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode}, 11 ast::{self, support, AstChildren, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode},
12 NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T, 12 NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
13}; 13};
14 14
@@ -45,6 +45,12 @@ fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> {
45 } 45 }
46} 46}
47 47
48impl ast::BlockExpr {
49 pub fn items(&self) -> AstChildren<ast::Item> {
50 support::children(self.syntax())
51 }
52}
53
48#[derive(Debug, PartialEq, Eq, Clone)] 54#[derive(Debug, PartialEq, Eq, Clone)]
49pub enum Macro { 55pub enum Macro {
50 MacroRules(ast::MacroRules), 56 MacroRules(ast::MacroRules),
@@ -281,6 +287,15 @@ impl ast::Path {
281 successors(self.qualifier(), |p| p.qualifier()) 287 successors(self.qualifier(), |p| p.qualifier())
282 } 288 }
283} 289}
290
291impl ast::Use {
292 pub fn is_simple_glob(&self) -> bool {
293 self.use_tree()
294 .map(|use_tree| use_tree.use_tree_list().is_none() && use_tree.star_token().is_some())
295 .unwrap_or(false)
296 }
297}
298
284impl ast::UseTree { 299impl ast::UseTree {
285 pub fn is_simple_path(&self) -> bool { 300 pub fn is_simple_path(&self) -> bool {
286 self.use_tree_list().is_none() && self.star_token().is_none() 301 self.use_tree_list().is_none() && self.star_token().is_none()
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
index 9ec541c57..ce6ad8541 100644
--- a/crates/test_utils/src/minicore.rs
+++ b/crates/test_utils/src/minicore.rs
@@ -15,14 +15,17 @@
15//! range: 15//! range:
16//! deref: sized 16//! deref: sized
17//! deref_mut: deref 17//! deref_mut: deref
18//! index: sized
18//! fn: 19//! fn:
19//! pin: 20//! pin:
20//! future: pin 21//! future: pin
21//! option: 22//! option:
22//! result: 23//! result:
23//! iterator: option 24//! iterator: option
24//! iterators: iterator 25//! iterators: iterator, fn
25//! default: sized 26//! default: sized
27//! clone: sized
28//! copy: clone
26//! from: sized 29//! from: sized
27//! eq: sized 30//! eq: sized
28//! ord: eq, option 31//! ord: eq, option
@@ -40,6 +43,38 @@ pub mod marker {
40 #[lang = "unsize"] 43 #[lang = "unsize"]
41 pub trait Unsize<T: ?Sized> {} 44 pub trait Unsize<T: ?Sized> {}
42 // endregion:unsize 45 // endregion:unsize
46
47 // region:copy
48 #[lang = "copy"]
49 pub trait Copy: Clone {}
50 // region:derive
51 #[rustc_builtin_macro]
52 pub macro Copy($item:item) {}
53 // endregion:derive
54
55 mod copy_impls {
56 use super::Copy;
57
58 macro_rules! impl_copy {
59 ($($t:ty)*) => {
60 $(
61 impl Copy for $t {}
62 )*
63 }
64 }
65
66 impl_copy! {
67 usize u8 u16 u32 u64 u128
68 isize i8 i16 i32 i64 i128
69 f32 f64
70 bool char
71 }
72
73 impl<T: ?Sized> Copy for *const T {}
74 impl<T: ?Sized> Copy for *mut T {}
75 impl<T: ?Sized> Copy for &T {}
76 }
77 // endregion:copy
43} 78}
44 79
45// region:default 80// region:default
@@ -50,6 +85,19 @@ pub mod default {
50} 85}
51// endregion:default 86// endregion:default
52 87
88// region:clone
89pub mod clone {
90 #[lang = "clone"]
91 pub trait Clone: Sized {
92 fn clone(&self) -> Self;
93 }
94 // region:derive
95 #[rustc_builtin_macro]
96 pub macro Clone($item:item) {}
97 // endregion:derive
98}
99// endregion:clone
100
53// region:from 101// region:from
54pub mod convert { 102pub mod convert {
55 pub trait From<T>: Sized { 103 pub trait From<T>: Sized {
@@ -114,9 +162,53 @@ pub mod ops {
114 } 162 }
115 // endregion:deref_mut 163 // endregion:deref_mut
116 } 164 }
117 pub use self::deref::Deref; 165 pub use self::deref::{
118 pub use self::deref::DerefMut; //:deref_mut 166 Deref,
119 // endregion:deref 167 DerefMut, // :deref_mut
168 };
169 // endregion:deref
170
171 // region:index
172 mod index {
173 #[lang = "index"]
174 pub trait Index<Idx: ?Sized> {
175 type Output: ?Sized;
176 fn index(&self, index: Idx) -> &Self::Output;
177 }
178 #[lang = "index_mut"]
179 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
180 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
181 }
182
183 // region:slice
184 impl<T, I> Index<I> for [T]
185 where
186 I: SliceIndex<[T]>,
187 {
188 type Output = I::Output;
189 fn index(&self, index: I) -> &I::Output {
190 loop {}
191 }
192 }
193 impl<T, I> IndexMut<I> for [T]
194 where
195 I: SliceIndex<[T]>,
196 {
197 fn index_mut(&mut self, index: I) -> &mut I::Output {
198 loop {}
199 }
200 }
201
202 pub unsafe trait SliceIndex<T: ?Sized> {
203 type Output: ?Sized;
204 }
205 unsafe impl<T> SliceIndex<[T]> for usize {
206 type Output = T;
207 }
208 // endregion:slice
209 }
210 pub use self::index::{Index, IndexMut};
211 // endregion:index
120 212
121 // region:range 213 // region:range
122 mod range { 214 mod range {
@@ -298,7 +390,6 @@ pub mod iter {
298 iter: I, 390 iter: I,
299 n: usize, 391 n: usize,
300 } 392 }
301
302 impl<I> Iterator for Take<I> 393 impl<I> Iterator for Take<I>
303 where 394 where
304 I: Iterator, 395 I: Iterator,
@@ -309,6 +400,22 @@ pub mod iter {
309 loop {} 400 loop {}
310 } 401 }
311 } 402 }
403
404 pub struct FilterMap<I, F> {
405 iter: I,
406 f: F,
407 }
408 impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
409 where
410 F: FnMut(I::Item) -> Option<B>,
411 {
412 type Item = B;
413
414 #[inline]
415 fn next(&mut self) -> Option<B> {
416 loop {}
417 }
418 }
312 } 419 }
313 pub use self::adapters::Take; 420 pub use self::adapters::Take;
314 421
@@ -356,6 +463,13 @@ pub mod iter {
356 fn take(self, n: usize) -> crate::iter::Take<Self> { 463 fn take(self, n: usize) -> crate::iter::Take<Self> {
357 loop {} 464 loop {}
358 } 465 }
466 fn filter_map<B, F>(self, f: F) -> crate::iter::FilterMap<Self, F>
467 where
468 Self: Sized,
469 F: FnMut(Self::Item) -> Option<B>,
470 {
471 loop {}
472 }
359 // endregion:iterators 473 // endregion:iterators
360 } 474 }
361 impl<I: Iterator + ?Sized> Iterator for &mut I { 475 impl<I: Iterator + ?Sized> Iterator for &mut I {
@@ -402,12 +516,14 @@ mod macros {
402pub mod prelude { 516pub mod prelude {
403 pub mod v1 { 517 pub mod v1 {
404 pub use crate::{ 518 pub use crate::{
519 clone::Clone, // :clone
405 cmp::{Eq, PartialEq}, // :eq 520 cmp::{Eq, PartialEq}, // :eq
406 cmp::{Ord, PartialOrd}, // :ord 521 cmp::{Ord, PartialOrd}, // :ord
407 convert::{From, Into}, // :from 522 convert::{From, Into}, // :from
408 default::Default, // :default 523 default::Default, // :default
409 iter::{IntoIterator, Iterator}, // :iterator 524 iter::{IntoIterator, Iterator}, // :iterator
410 macros::builtin::derive, // :derive 525 macros::builtin::derive, // :derive
526 marker::Copy, // :copy
411 marker::Sized, // :sized 527 marker::Sized, // :sized
412 ops::{Fn, FnMut, FnOnce}, // :fn 528 ops::{Fn, FnMut, FnOnce}, // :fn
413 option::Option::{self, None, Some}, // :option 529 option::Option::{self, None, Some}, // :option
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index 34a91486b..18ea77266 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -18,6 +18,11 @@ The path structure for newly inserted paths to use.
18-- 18--
19Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines. 19Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
20-- 20--
21[[rust-analyzer.assist.allowMergingIntoGlobImports]]rust-analyzer.assist.allowMergingIntoGlobImports (default: `true`)::
22+
23--
24Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
25--
21[[rust-analyzer.callInfo.full]]rust-analyzer.callInfo.full (default: `true`):: 26[[rust-analyzer.callInfo.full]]rust-analyzer.callInfo.full (default: `true`)::
22+ 27+
23-- 28--
diff --git a/editors/code/package.json b/editors/code/package.json
index 1fac700be..c077bd2c0 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -432,6 +432,11 @@
432 "default": true, 432 "default": true,
433 "type": "boolean" 433 "type": "boolean"
434 }, 434 },
435 "rust-analyzer.assist.allowMergingIntoGlobImports": {
436 "markdownDescription": "Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.",
437 "default": true,
438 "type": "boolean"
439 },
435 "rust-analyzer.callInfo.full": { 440 "rust-analyzer.callInfo.full": {
436 "markdownDescription": "Show function name and docs in parameter hints.", 441 "markdownDescription": "Show function name and docs in parameter hints.",
437 "default": true, 442 "default": true,