diff options
Diffstat (limited to 'crates')
33 files changed, 550 insertions, 642 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)] | ||
202 | struct FileMeta { | 206 | struct 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() { | |||
705 | fn issue_4885() { | 705 | fn 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() { | |||
796 | fn issue_4966() { | 792 | fn 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() { | |||
1917 | fn effects_smoke_test() { | 1917 | fn 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() { | |||
567 | fn infer_ops_index() { | 567 | fn infer_ops_index() { |
568 | check_types( | 568 | check_types( |
569 | r#" | 569 | r#" |
570 | //- /main.rs crate:main deps:std | 570 | //- minicore: index |
571 | struct Bar; | 571 | struct Bar; |
572 | struct Foo; | 572 | struct Foo; |
573 | 573 | ||
574 | impl std::ops::Index<u32> for Bar { | 574 | impl 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::*; | ||
586 | mod 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 { | |||
597 | fn infer_ops_index_int() { | 588 | fn infer_ops_index_int() { |
598 | check_types( | 589 | check_types( |
599 | r#" | 590 | r#" |
600 | //- /main.rs crate:main deps:std | 591 | //- minicore: index |
601 | struct Bar; | 592 | struct Bar; |
602 | struct Foo; | 593 | struct Foo; |
603 | 594 | ||
604 | impl std::ops::Index<u32> for Bar { | 595 | impl core::ops::Index<u32> for Bar { |
605 | type Output = Foo; | 596 | type Output = Foo; |
606 | } | 597 | } |
607 | 598 | ||
608 | struct Range; | 599 | struct Range; |
609 | impl std::ops::Index<Range> for Bar { | 600 | impl 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::*; | ||
622 | mod 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 { | |||
633 | fn infer_ops_index_autoderef() { | 615 | fn 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 |
637 | fn test() { | 619 | fn 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 | ||
644 | impl<T> ops::Index<u32> for [T] { | ||
645 | type Output = T; | ||
646 | } | ||
647 | |||
648 | #[prelude_import] use ops::*; | ||
649 | mod 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(); } | |||
884 | fn generic_param_env_deref() { | 853 | fn generic_param_env_deref() { |
885 | check_types( | 854 | check_types( |
886 | r#" | 855 | r#" |
887 | #[lang = "deref"] | 856 | //- minicore: deref |
888 | trait Deref { | ||
889 | type Target; | ||
890 | } | ||
891 | trait Trait {} | 857 | trait Trait {} |
892 | impl<T> Deref for T where T: Trait { | 858 | impl<T> core::ops::Deref for T where T: Trait { |
893 | type Target = i128; | 859 | type Target = i128; |
894 | } | 860 | } |
895 | fn test<T: Trait>(t: T) { (*t); } | 861 | fn test<T: Trait>(t: T) { (*t); } |
@@ -1758,20 +1724,7 @@ fn test() { | |||
1758 | fn fn_trait_deref_with_ty_default() { | 1724 | fn fn_trait_deref_with_ty_default() { |
1759 | check_infer( | 1725 | check_infer( |
1760 | r#" | 1726 | r#" |
1761 | #[lang = "deref"] | 1727 | //- minicore: deref, fn |
1762 | trait Deref { | ||
1763 | type Target; | ||
1764 | |||
1765 | fn deref(&self) -> &Self::Target; | ||
1766 | } | ||
1767 | |||
1768 | #[lang="fn_once"] | ||
1769 | trait FnOnce<Args> { | ||
1770 | type Output; | ||
1771 | |||
1772 | fn call_once(self, args: Args) -> Self::Output; | ||
1773 | } | ||
1774 | |||
1775 | struct Foo; | 1728 | struct Foo; |
1776 | 1729 | ||
1777 | impl Foo { | 1730 | impl 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 | ||
1787 | impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { | 1740 | impl<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) { | |||
2731 | fn builtin_copy() { | 2681 | fn builtin_copy() { |
2732 | check_infer_with_mismatches( | 2682 | check_infer_with_mismatches( |
2733 | r#" | 2683 | r#" |
2734 | #[lang = "copy"] | 2684 | //- minicore: copy |
2735 | trait Copy {} | ||
2736 | |||
2737 | struct IsCopy; | 2685 | struct IsCopy; |
2738 | impl Copy for IsCopy {} | 2686 | impl Copy for IsCopy {} |
2739 | struct NotCopy; | 2687 | struct 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() { | |||
2770 | fn builtin_fn_def_copy() { | 2718 | fn builtin_fn_def_copy() { |
2771 | check_infer_with_mismatches( | 2719 | check_infer_with_mismatches( |
2772 | r#" | 2720 | r#" |
2773 | #[lang = "copy"] | 2721 | //- minicore: copy |
2774 | trait Copy {} | ||
2775 | |||
2776 | fn foo() {} | 2722 | fn foo() {} |
2777 | fn bar<T: Copy>(T) -> T {} | 2723 | fn bar<T: Copy>(T) -> T {} |
2778 | struct Struct(usize); | 2724 | struct 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() { | |||
2810 | fn builtin_fn_ptr_copy() { | 2756 | fn builtin_fn_ptr_copy() { |
2811 | check_infer_with_mismatches( | 2757 | check_infer_with_mismatches( |
2812 | r#" | 2758 | r#" |
2813 | #[lang = "copy"] | 2759 | //- minicore: copy |
2814 | trait Copy {} | ||
2815 | |||
2816 | trait Test { fn test(&self) -> bool; } | 2760 | trait Test { fn test(&self) -> bool; } |
2817 | impl<T: Copy> Test for T {} | 2761 | impl<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) { | |||
2841 | fn builtin_sized() { | 2785 | fn builtin_sized() { |
2842 | check_infer_with_mismatches( | 2786 | check_infer_with_mismatches( |
2843 | r#" | 2787 | r#" |
2844 | #[lang = "sized"] | 2788 | //- minicore: sized |
2845 | trait Sized {} | ||
2846 | |||
2847 | trait Test { fn test(&self) -> bool; } | 2789 | trait Test { fn test(&self) -> bool; } |
2848 | impl<T: Sized> Test for T {} | 2790 | impl<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"] | ||
2986 | pub trait FnOnce<Args> { | ||
2987 | type Output; | ||
2988 | |||
2989 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | ||
2990 | } | ||
2991 | |||
2992 | #[lang = "deref"] | ||
2993 | pub trait Deref { | ||
2994 | type Target: ?Sized; | ||
2995 | |||
2996 | fn deref(&self) -> &Self::Target; | ||
2997 | } | ||
2998 | |||
2999 | #[lang = "owned_box"] | 2926 | #[lang = "owned_box"] |
3000 | pub struct Box<T: ?Sized> { | 2927 | pub struct Box<T: ?Sized> { |
3001 | inner: *mut T, | 2928 | inner: *mut T, |
3002 | } | 2929 | } |
3003 | 2930 | ||
3004 | impl<T: ?Sized> Deref for Box<T> { | 2931 | impl<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 | ||
3012 | enum Option<T> { | ||
3013 | None, | ||
3014 | Some(T) | ||
3015 | } | ||
3016 | |||
3017 | fn foo() { | 2939 | fn 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 | //^^^^^^^^^^^^^^^ |
241 | struct Foo$0; | 242 | struct Foo$0; |
242 | |||
243 | mod marker { | ||
244 | trait Copy {} | ||
245 | } | ||
246 | #[rustc_builtin_macro] | ||
247 | macro Copy {} | ||
248 | "#, | 243 | "#, |
249 | ); | 244 | ); |
250 | } | 245 | } |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 4705fae08..2e1359eef 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -2258,7 +2258,7 @@ pub fn fo$0o() {} | |||
2258 | case 13. collapsed link: foo | 2258 | case 13. collapsed link: foo |
2259 | case 14. shortcut link: foo | 2259 | case 14. shortcut link: foo |
2260 | case 15. inline without URL: foo | 2260 | case 15. inline without URL: foo |
2261 | case 16. just escaped text: \[foo] | 2261 | case 16. just escaped text: \[foo\] |
2262 | case 17. inline link: Foo | 2262 | case 17. inline link: Foo |
2263 | 2263 | ||
2264 | [^example]: https://www.example.com/ | 2264 | [^example]: https://www.example.com/ |
@@ -3014,8 +3014,8 @@ fn foo() { | |||
3014 | file_id: FileId( | 3014 | file_id: FileId( |
3015 | 1, | 3015 | 1, |
3016 | ), | 3016 | ), |
3017 | full_range: 250..432, | 3017 | full_range: 251..433, |
3018 | focus_range: 289..295, | 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#" |
664 | enum Option<T> { None, Some(T) } | 664 | //- minicore: option |
665 | use Option::*; | ||
666 | |||
667 | struct FileId {} | 665 | struct FileId {} |
668 | struct SmolStr {} | 666 | struct 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 | |||
876 | fn foo() -> impl Fn() { loop {} } | 873 | fn foo() -> impl Fn() { loop {} } |
877 | fn foo1() -> impl Fn(f64) { loop {} } | 874 | fn foo1() -> impl Fn(f64) { loop {} } |
878 | fn foo2() -> impl Fn(f64, f64) { loop {} } | 875 | fn 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#" |
911 | enum Result<T, E> { Ok(T), Err(E) } | 908 | //- minicore: result |
912 | use Result::*; | ||
913 | |||
914 | struct SyntheticSyntax; | 909 | struct SyntheticSyntax; |
915 | 910 | ||
916 | fn main() { | 911 | fn 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#" |
965 | enum Option<T> { None, Some(T) } | 960 | //- minicore: option |
966 | use Option::*; | ||
967 | |||
968 | struct Test { a: Option<u32>, b: u8 } | 961 | struct Test { a: Option<u32>, b: u8 } |
969 | 962 | ||
970 | fn main() { | 963 | fn 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#" |
997 | enum Option<T> { None, Some(T) } | 990 | //- minicore: option |
998 | use Option::*; | ||
999 | |||
1000 | struct Test { a: Option<u32>, b: u8 } | 991 | struct Test { a: Option<u32>, b: u8 } |
1001 | 992 | ||
1002 | fn main() { | 993 | fn 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#" |
1015 | enum Option<T> { None, Some(T) } | 1006 | //- minicore: option |
1016 | use Option::*; | ||
1017 | |||
1018 | struct Test { a: Option<u32>, b: u8 } | 1007 | struct Test { a: Option<u32>, b: u8 } |
1019 | 1008 | ||
1020 | fn main() { | 1009 | fn 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 43e83d683..ac7f0959b 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs | |||
@@ -831,7 +831,6 @@ fn path_element_of_reference( | |||
831 | })?; | 831 | })?; |
832 | stdx::always!( | 832 | stdx::always!( |
833 | matches!(path, ast::Expr::PathExpr(_) | ast::Expr::MacroCall(_)), | 833 | matches!(path, ast::Expr::PathExpr(_) | ast::Expr::MacroCall(_)), |
834 | |||
835 | "unexpected expression type for variable usage: {:?}", | 834 | "unexpected expression type for variable usage: {:?}", |
836 | path | 835 | path |
837 | ); | 836 | ); |
@@ -2991,11 +2990,7 @@ mod bar { | |||
2991 | check_assist( | 2990 | check_assist( |
2992 | extract_function, | 2991 | extract_function, |
2993 | r#" | 2992 | r#" |
2994 | enum Option<T> { | 2993 | //- minicore: option |
2995 | #[lang = "None"] None, | ||
2996 | #[lang = "Some"] Some(T), | ||
2997 | } | ||
2998 | use Option::*; | ||
2999 | fn foo() { | 2994 | fn foo() { |
3000 | loop { | 2995 | loop { |
3001 | let n = 1; | 2996 | let n = 1; |
@@ -3007,11 +3002,6 @@ fn foo() { | |||
3007 | } | 3002 | } |
3008 | "#, | 3003 | "#, |
3009 | r#" | 3004 | r#" |
3010 | enum Option<T> { | ||
3011 | #[lang = "None"] None, | ||
3012 | #[lang = "Some"] Some(T), | ||
3013 | } | ||
3014 | use Option::*; | ||
3015 | fn foo() { | 3005 | fn foo() { |
3016 | loop { | 3006 | loop { |
3017 | let n = 1; | 3007 | let n = 1; |
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#" |
484 | enum Option<T> { Some(T), None } | 484 | //- minicore: option |
485 | use Option::*; | ||
486 | |||
487 | fn main() { | 485 | fn main() { |
488 | match None$0 { | 486 | match None$0 { |
489 | None => {} | 487 | None => {} |
490 | } | 488 | } |
491 | } | 489 | } |
492 | "#, | 490 | "#, |
493 | r#" | 491 | r#" |
494 | enum Option<T> { Some(T), None } | ||
495 | use Option::*; | ||
496 | |||
497 | fn main() { | 492 | fn 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#" |
265 | enum Option<T> { Some(T), None } | 265 | //- minicore: option |
266 | use Option::*; | ||
267 | |||
268 | fn foo(x: Option<i32>) { | 266 | fn 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#" |
277 | enum Option<T> { Some(T), None } | ||
278 | use Option::*; | ||
279 | |||
280 | fn foo(x: Option<i32>) { | 275 | fn 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#" |
295 | enum Option<T> { Some(T), None } | 290 | //- minicore: option |
296 | use Option::*; | ||
297 | |||
298 | fn foo(x: Option<i32>) { | 291 | fn 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#" |
307 | enum Option<T> { Some(T), None } | ||
308 | use Option::*; | ||
309 | |||
310 | fn foo(x: Option<i32>) { | 300 | fn 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#" |
325 | enum Result<T, E> { Ok(T), Err(E) } | 315 | //- minicore: result |
326 | use Result::*; | ||
327 | |||
328 | fn foo(x: Result<i32, ()>) { | 316 | fn 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#" |
337 | enum Result<T, E> { Ok(T), Err(E) } | ||
338 | use Result::*; | ||
339 | |||
340 | fn foo(x: Result<i32, ()>) { | 325 | fn 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#" |
355 | enum Result<T, E> { Ok(T), Err(E) } | 340 | //- minicore: result |
356 | use Result::*; | ||
357 | |||
358 | fn foo(x: Result<i32, ()>) { | 341 | fn 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#" |
367 | enum Result<T, E> { Ok(T), Err(E) } | ||
368 | use Result::*; | ||
369 | |||
370 | fn foo(x: Result<i32, ()>) { | 350 | fn 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#" |
491 | enum Option<T> { Some(T), None } | 471 | //- minicore: option |
492 | use Option::*; | ||
493 | |||
494 | fn foo(x: Option<i32>) { | 472 | fn 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#" |
502 | enum Option<T> { Some(T), None } | ||
503 | use Option::*; | ||
504 | |||
505 | fn foo(x: Option<i32>) { | 480 | fn 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#" |
521 | enum Result<T, E> { Ok(T), Err(E) } | 496 | //- minicore: result |
522 | use Result::*; | ||
523 | |||
524 | fn foo(x: Result<i32, ()>) { | 497 | fn 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#" |
532 | enum Result<T, E> { Ok(T), Err(E) } | ||
533 | use Result::*; | ||
534 | |||
535 | fn foo(x: Result<i32, ()>) { | 505 | fn 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#" |
101 | enum Result<T, E> { Ok(T), Err(E) } | 100 | //- minicore: result |
102 | fn i<T>(a: T) -> T { a } | 101 | fn i<T>(a: T) -> T { a } |
103 | fn main() { | 102 | fn 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#" |
109 | enum Result<T, E> { Ok(T), Err(E) } | ||
110 | fn i<T>(a: T) -> T { a } | 108 | fn i<T>(a: T) -> T { a } |
111 | fn main() { | 109 | fn 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#" |
127 | enum Option<T> { Some(T), None } | 125 | //- minicore: option |
128 | fn i<T>(a: T) -> T { a } | 126 | fn i<T>(a: T) -> T { a } |
129 | fn main() { | 127 | fn 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#" |
135 | enum Option<T> { Some(T), None } | ||
136 | fn i<T>(a: T) -> T { a } | 133 | fn i<T>(a: T) -> T { a } |
137 | fn main() { | 134 | fn 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#" |
153 | enum Result<T, E> { Ok(T), Err(E) } | 150 | //- minicore: result |
154 | fn i<T>(a: T) -> T { a } | 151 | fn i<T>(a: T) -> T { a } |
155 | fn main() { | 152 | fn 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#" |
161 | enum Result<T, E> { Ok(T), Err(E) } | ||
162 | fn i<T>(a: T) -> T { a } | 158 | fn i<T>(a: T) -> T { a } |
163 | fn main() { | 159 | fn 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#" |
179 | enum Option<T> { Some(T), None } | 175 | //- minicore: option |
180 | fn i<T>(a: T) -> T { a } | 176 | fn i<T>(a: T) -> T { a } |
181 | fn main() { | 177 | fn 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 |
213 | pub mod convert { pub trait Into<T> { pub fn into(self) -> T; } } | ||
214 | //- /lib.rs crate:main deps:core | ||
215 | use core::convert::Into; | ||
216 | impl $0Into<Thing> for usize { | 213 | impl $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#####" |
226 | use core::convert::Into; | ||
227 | impl From<usize> for Thing { | 223 | impl 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 |
245 | pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } } | 241 | use core::iter; |
246 | pub struct SomeIter; | ||
247 | impl self::iter::traits::iterator::Iterator for SomeIter {} | ||
248 | //- /lib.rs crate:main deps:core | ||
249 | use core::SomeIter; | ||
250 | fn main() { | 242 | fn 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#####" |
258 | use core::SomeIter; | 250 | use core::iter; |
259 | fn main() { | 251 | fn 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#####" |
1522 | enum Result<T, E> { Ok(T), Err(E) } | 1514 | //- minicore: result |
1523 | fn main() { | 1515 | fn 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#####" |
1529 | enum Result<T, E> { Ok(T), Err(E) } | ||
1530 | fn main() { | 1521 | fn 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 |
502 | trait FnOnce<Args> { | ||
503 | type Output; | ||
504 | } | ||
505 | struct S; | 502 | struct S; |
506 | 503 | ||
507 | struct Foo; | 504 | struct 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#" |
439 | enum Option<T> { Some(T), None } | 439 | //- minicore: option |
440 | |||
441 | fn main() { | 440 | fn 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#" |
447 | enum Option<T> { Some(T), None } | ||
448 | |||
449 | fn main() { | 446 | fn 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#" |
464 | enum Result<T, E> { Ok(T), Err(E) } | 461 | //- minicore: result |
465 | |||
466 | fn main() { | 462 | fn 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#" |
472 | enum Result<T, E> { Ok(T), Err(E) } | ||
473 | |||
474 | fn main() { | 468 | fn 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#" |
518 | enum Option<T> { Some(T), None } | 512 | //- minicore: option |
519 | |||
520 | fn main() { | 513 | fn 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#" |
526 | enum Option<T> { Some(T), None } | ||
527 | |||
528 | fn main() { | 519 | fn 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 | ||
945 | fn foo() { | 946 | fn foo() { |
946 | bar(|| a$0); | 947 | bar(|| a$0); |
947 | } | 948 | } |
948 | 949 | ||
949 | fn bar(f: impl FnOnce() -> u32) {} | 950 | fn bar(f: impl FnOnce() -> u32) {} |
950 | #[lang = "fn_once"] | ||
951 | trait 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 |
1273 | trait Deref { | ||
1274 | type Target; | ||
1275 | fn deref(&self) -> &Self::Target; | ||
1276 | } | ||
1277 | |||
1278 | struct S; | 1273 | struct S; |
1279 | struct T(S); | 1274 | struct T(S); |
1280 | 1275 | ||
1281 | impl Deref for T { | 1276 | impl 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 {} | |||
1292 | fn main() { | 1287 | fn 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; | |||
5 | use syntax::{ | 5 | use 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 | ||
11 | use crate::{ | 11 | use 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)] |
42 | pub enum ImportScope { | 43 | pub 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 | ||
47 | impl ImportScope { | 49 | impl 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. |
156 | pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig) { | 176 | pub 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 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | use hir::PrefixKind; | 3 | use hir::PrefixKind; |
4 | use test_utils::assert_eq_text; | 4 | use test_utils::{assert_eq_text, extract_range_or_offset, CURSOR_MARKER}; |
5 | |||
6 | #[test] | ||
7 | fn respects_cfg_attr_fn() { | ||
8 | check( | ||
9 | r"bar::Bar", | ||
10 | r#" | ||
11 | #[cfg(test)] | ||
12 | fn foo() {$0} | ||
13 | "#, | ||
14 | r#" | ||
15 | #[cfg(test)] | ||
16 | fn foo() { | ||
17 | use bar::Bar; | ||
18 | } | ||
19 | "#, | ||
20 | ImportGranularity::Crate, | ||
21 | ); | ||
22 | } | ||
23 | |||
24 | #[test] | ||
25 | fn respects_cfg_attr_const() { | ||
26 | check( | ||
27 | r"bar::Bar", | ||
28 | r#" | ||
29 | #[cfg(test)] | ||
30 | const FOO: Bar = {$0}; | ||
31 | "#, | ||
32 | r#" | ||
33 | #[cfg(test)] | ||
34 | const FOO: Bar = { | ||
35 | use bar::Bar; | ||
36 | }; | ||
37 | "#, | ||
38 | ImportGranularity::Crate, | ||
39 | ); | ||
40 | } | ||
41 | |||
42 | #[test] | ||
43 | fn insert_skips_lone_glob_imports() { | ||
44 | check( | ||
45 | "use foo::baz::A", | ||
46 | r" | ||
47 | use foo::bar::*; | ||
48 | ", | ||
49 | r" | ||
50 | use foo::bar::*; | ||
51 | use foo::baz::A; | ||
52 | ", | ||
53 | ImportGranularity::Crate, | ||
54 | ); | ||
55 | } | ||
5 | 56 | ||
6 | #[test] | 57 | #[test] |
7 | fn insert_not_group() { | 58 | fn 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" |
12 | use std::bar::B; | 63 | use std::bar::B; |
@@ -21,24 +72,32 @@ use crate::bar::A; | |||
21 | use self::bar::A; | 72 | use self::bar::A; |
22 | use super::bar::A; | 73 | use super::bar::A; |
23 | use external_crate2::bar::A;", | 74 | use 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] |
31 | fn insert_not_group_empty() { | 86 | fn 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"{ | 340 | mod x {$0} |
341 | ", | ||
342 | r" | ||
343 | mod 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] |
536 | fn merge_mod_into_glob() { | 597 | fn 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] |
546 | fn merge_self_glob() { | 614 | fn 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 | ||
760 | fn check( | 839 | fn 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 | |||
869 | fn 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 | ||
794 | fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 889 | fn 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 | ||
798 | fn check_module(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 893 | fn 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 | ||
802 | fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 897 | fn 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 | ||
806 | fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior) { | 901 | fn 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 |
53 | use core::option::Option::{self, Some, None}; | ||
54 | |||
55 | fn div(x: i32, y: i32) -> Option<i32> { | 53 | fn 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 | ||
62 | pub mod result { | ||
63 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
64 | } | ||
65 | pub mod option { | ||
66 | pub enum Option<T> { Some(T), None } | ||
67 | } | ||
68 | "#, | 59 | "#, |
69 | r#" | 60 | r#" |
70 | use core::option::Option::{self, Some, None}; | ||
71 | |||
72 | fn div(x: i32, y: i32) -> Option<i32> { | 61 | fn 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 |
87 | use core::result::Result::{self, Ok, Err}; | ||
88 | |||
89 | fn div(x: i32, y: i32) -> Result<i32, ()> { | 76 | fn 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 | ||
96 | pub mod result { | ||
97 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
98 | } | ||
99 | pub mod option { | ||
100 | pub enum Option<T> { Some(T), None } | ||
101 | } | ||
102 | "#, | 82 | "#, |
103 | r#" | 83 | r#" |
104 | use core::result::Result::{self, Ok, Err}; | ||
105 | |||
106 | fn div(x: i32, y: i32) -> Result<i32, ()> { | 84 | fn 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 |
121 | use core::result::Result::{self, Ok, Err}; | ||
122 | |||
123 | fn div<T>(x: T) -> Result<T, i32> { | 99 | fn 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 | ||
130 | pub mod result { | ||
131 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
132 | } | ||
133 | pub mod option { | ||
134 | pub enum Option<T> { Some(T), None } | ||
135 | } | ||
136 | "#, | 105 | "#, |
137 | r#" | 106 | r#" |
138 | use core::result::Result::{self, Ok, Err}; | ||
139 | |||
140 | fn div<T>(x: T) -> Result<T, i32> { | 107 | fn 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 |
155 | use core::result::Result::{self, Ok, Err}; | ||
156 | |||
157 | type MyResult<T> = Result<T, ()>; | 122 | type MyResult<T> = Result<T, ()>; |
158 | 123 | ||
159 | fn div(x: i32, y: i32) -> MyResult<i32> { | 124 | fn 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 | ||
166 | pub mod result { | ||
167 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
168 | } | ||
169 | pub mod option { | ||
170 | pub enum Option<T> { Some(T), None } | ||
171 | } | ||
172 | "#, | 130 | "#, |
173 | r#" | 131 | r#" |
174 | use core::result::Result::{self, Ok, Err}; | ||
175 | |||
176 | type MyResult<T> = Result<T, ()>; | 132 | type MyResult<T> = Result<T, ()>; |
177 | 133 | ||
178 | fn div(x: i32, y: i32) -> MyResult<i32> { | 134 | fn 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 |
193 | use core::result::Result::{self, Ok, Err}; | ||
194 | |||
195 | fn foo() -> Result<(), i32> { 0 } | 149 | fn foo() -> Result<(), i32> { 0 } |
196 | |||
197 | //- /core/lib.rs crate:core | ||
198 | pub mod result { | ||
199 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
200 | } | ||
201 | pub 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 |
213 | use core::result::Result::{self, Ok, Err}; | ||
214 | |||
215 | enum SomeOtherEnum { Ok(i32), Err(String) } | 159 | enum SomeOtherEnum { Ok(i32), Err(String) } |
216 | 160 | ||
217 | fn foo() -> SomeOtherEnum { 0 } | 161 | fn foo() -> SomeOtherEnum { 0 } |
218 | |||
219 | //- /core/lib.rs crate:core | ||
220 | pub mod result { | ||
221 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
222 | } | ||
223 | pub 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)] |
57 | mod tests { | 57 | mod 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 | ||
65 | use core::iter::Iterator; | ||
66 | use core::option::Option::{self, Some, None}; | ||
67 | "#; | ||
68 | let suffix = r#" | ||
69 | //- /core/lib.rs crate:core | ||
70 | pub mod option { | ||
71 | pub enum Option<T> { Some(T), None } | ||
72 | } | ||
73 | pub 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(); | 65 | fn 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 | ||
104 | fn foo() { | 77 | fn 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 | ||
118 | fn foo() { | 91 | fn 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 | ||
133 | fn foo() { | 106 | fn 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 |
148 | use core::iter::Iterator; | ||
149 | use core::option::Option::{self, Some, None}; | ||
150 | fn foo() { | 120 | fn 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 | ||
154 | pub mod option { | ||
155 | pub enum Option<T> { Some(T), None } | ||
156 | } | ||
157 | pub 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#" |
171 | use core::iter::Iterator; | ||
172 | use core::option::Option::{self, Some, None}; | ||
173 | fn foo() { | 125 | fn 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; | |||
8 | use rowan::{GreenNodeData, GreenTokenData}; | 8 | use rowan::{GreenNodeData, GreenTokenData}; |
9 | 9 | ||
10 | use crate::{ | 10 | use 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 | ||
48 | impl 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)] |
49 | pub enum Macro { | 55 | pub 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 | |||
291 | impl 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 | |||
284 | impl ast::UseTree { | 299 | impl 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 769028580..ce6ad8541 100644 --- a/crates/test_utils/src/minicore.rs +++ b/crates/test_utils/src/minicore.rs | |||
@@ -15,13 +15,14 @@ | |||
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 |
26 | //! clone: sized | 27 | //! clone: sized |
27 | //! copy: clone | 28 | //! copy: clone |
@@ -167,6 +168,48 @@ pub mod ops { | |||
167 | }; | 168 | }; |
168 | // endregion:deref | 169 | // endregion:deref |
169 | 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 | ||
212 | |||
170 | // region:range | 213 | // region:range |
171 | mod range { | 214 | mod range { |
172 | #[lang = "RangeFull"] | 215 | #[lang = "RangeFull"] |
@@ -347,7 +390,6 @@ pub mod iter { | |||
347 | iter: I, | 390 | iter: I, |
348 | n: usize, | 391 | n: usize, |
349 | } | 392 | } |
350 | |||
351 | impl<I> Iterator for Take<I> | 393 | impl<I> Iterator for Take<I> |
352 | where | 394 | where |
353 | I: Iterator, | 395 | I: Iterator, |
@@ -358,6 +400,22 @@ pub mod iter { | |||
358 | loop {} | 400 | loop {} |
359 | } | 401 | } |
360 | } | 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 | } | ||
361 | } | 419 | } |
362 | pub use self::adapters::Take; | 420 | pub use self::adapters::Take; |
363 | 421 | ||
@@ -405,6 +463,13 @@ pub mod iter { | |||
405 | fn take(self, n: usize) -> crate::iter::Take<Self> { | 463 | fn take(self, n: usize) -> crate::iter::Take<Self> { |
406 | loop {} | 464 | loop {} |
407 | } | 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 | } | ||
408 | // endregion:iterators | 473 | // endregion:iterators |
409 | } | 474 | } |
410 | impl<I: Iterator + ?Sized> Iterator for &mut I { | 475 | impl<I: Iterator + ?Sized> Iterator for &mut I { |