aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/base_db/src/fixture.rs4
-rw-r--r--crates/hir_def/src/resolver.rs3
-rw-r--r--crates/hir_expand/src/builtin_macro.rs4
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs2
-rw-r--r--crates/hir_ty/src/infer/expr.rs10
-rw-r--r--crates/hir_ty/src/infer/pat.rs2
-rw-r--r--crates/hir_ty/src/lower.rs2
-rw-r--r--crates/hir_ty/src/tests/regression.rs64
-rw-r--r--crates/hir_ty/src/tests/simple.rs8
-rw-r--r--crates/hir_ty/src/tests/traits.rs309
-rw-r--r--crates/ide/src/goto_type_definition.rs2
-rw-r--r--crates/ide/src/hover.rs29
-rw-r--r--crates/ide/src/inlay_hints.rs21
-rw-r--r--crates/ide_assists/src/handlers/apply_demorgan.rs114
-rw-r--r--crates/ide_assists/src/handlers/convert_into_to_from.rs6
-rw-r--r--crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs14
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs719
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs27
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs11
-rw-r--r--crates/ide_assists/src/handlers/remove_dbg.rs4
-rw-r--r--crates/ide_assists/src/handlers/replace_if_let_with_match.rs66
-rw-r--r--crates/ide_assists/src/handlers/replace_unwrap_with_match.rs60
-rw-r--r--crates/ide_assists/src/lib.rs1
-rw-r--r--crates/ide_assists/src/tests.rs1
-rw-r--r--crates/ide_assists/src/tests/generated.rs27
-rw-r--r--crates/ide_assists/src/utils.rs6
-rw-r--r--crates/ide_completion/src/completions/attribute.rs5
-rw-r--r--crates/ide_completion/src/completions/attribute/repr.rs199
-rw-r--r--crates/ide_completion/src/completions/dot.rs5
-rw-r--r--crates/ide_completion/src/completions/keyword.rs4
-rw-r--r--crates/ide_completion/src/completions/postfix.rs27
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs309
-rw-r--r--crates/ide_completion/src/context.rs3
-rw-r--r--crates/ide_completion/src/render.rs20
-rw-r--r--crates/ide_db/src/helpers.rs11
-rw-r--r--crates/ide_db/src/helpers/famous_defs_fixture.rs36
-rw-r--r--crates/ide_db/src/lib.rs1
-rw-r--r--crates/ide_db/src/path_transform.rs (renamed from crates/ide_assists/src/path_transform.rs)12
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs76
-rw-r--r--crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs86
-rw-r--r--crates/parser/src/grammar/params.rs3
-rw-r--r--crates/proc_macro_api/src/version.rs10
-rw-r--r--crates/project_model/src/build_data.rs4
-rw-r--r--crates/test_utils/src/fixture.rs2
-rw-r--r--crates/test_utils/src/minicore.rs188
-rw-r--r--editors/code/package-lock.json12
-rw-r--r--xtask/src/tidy.rs2
47 files changed, 1467 insertions, 1064 deletions
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs
index d56b20b83..d0c946d83 100644
--- a/crates/base_db/src/fixture.rs
+++ b/crates/base_db/src/fixture.rs
@@ -114,6 +114,9 @@ impl ChangeFixture {
114 114
115 let meta = FileMeta::from(entry); 115 let meta = FileMeta::from(entry);
116 assert!(meta.path.starts_with(&source_root_prefix)); 116 assert!(meta.path.starts_with(&source_root_prefix));
117 if !meta.deps.is_empty() {
118 assert!(meta.krate.is_some(), "can't specify deps without naming the crate")
119 }
117 120
118 if meta.introduce_new_source_root { 121 if meta.introduce_new_source_root {
119 roots.push(SourceRoot::new_local(mem::take(&mut file_set))); 122 roots.push(SourceRoot::new_local(mem::take(&mut file_set)));
@@ -199,6 +202,7 @@ impl ChangeFixture {
199 } 202 }
200} 203}
201 204
205#[derive(Debug)]
202struct FileMeta { 206struct FileMeta {
203 path: String, 207 path: String,
204 krate: Option<String>, 208 krate: Option<String>,
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index 47e56259f..49c573087 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -640,8 +640,7 @@ pub trait HasResolver: Copy {
640impl HasResolver for ModuleId { 640impl HasResolver for ModuleId {
641 fn resolver(self, db: &dyn DefDatabase) -> Resolver { 641 fn resolver(self, db: &dyn DefDatabase) -> Resolver {
642 let mut def_map = self.def_map(db); 642 let mut def_map = self.def_map(db);
643 let mut modules = Vec::new(); 643 let mut modules = vec![(def_map.clone(), self.local_id)];
644 modules.push((def_map.clone(), self.local_id));
645 while let Some(parent) = def_map.parent() { 644 while let Some(parent) = def_map.parent() {
646 def_map = parent.def_map(db); 645 def_map = parent.def_map(db);
647 modules.push((def_map.clone(), parent.local_id)); 646 modules.push((def_map.clone(), parent.local_id));
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index f24d1d919..4c83a2efe 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -202,7 +202,7 @@ fn assert_expand(
202 202
203 let arg_tts = args.into_iter().flat_map(|arg| { 203 let arg_tts = args.into_iter().flat_map(|arg| {
204 quote! { &(#arg), } 204 quote! { &(#arg), }
205 }.token_trees).collect::<Vec<_>>(); 205 }.token_trees);
206 206
207 let expanded = quote! { 207 let expanded = quote! {
208 { { (##arg_tts); } } 208 { { (##arg_tts); } }
@@ -254,7 +254,7 @@ fn format_args_expand(
254 let _format_string = args.remove(0); 254 let _format_string = args.remove(0);
255 let arg_tts = args.into_iter().flat_map(|arg| { 255 let arg_tts = args.into_iter().flat_map(|arg| {
256 quote! { std::fmt::ArgumentV1::new(&(#arg), std::fmt::Display::fmt), } 256 quote! { std::fmt::ArgumentV1::new(&(#arg), std::fmt::Display::fmt), }
257 }.token_trees).collect::<Vec<_>>(); 257 }.token_trees);
258 let expanded = quote! { 258 let expanded = quote! {
259 std::fmt::Arguments::new_v1(&[], &[##arg_tts]) 259 std::fmt::Arguments::new_v1(&[], &[##arg_tts])
260 }; 260 };
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index b809b96a0..dc8f20138 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -56,7 +56,7 @@ impl BodyValidationDiagnostic {
56 pub fn collect(db: &dyn HirDatabase, owner: DefWithBodyId) -> Vec<BodyValidationDiagnostic> { 56 pub fn collect(db: &dyn HirDatabase, owner: DefWithBodyId) -> Vec<BodyValidationDiagnostic> {
57 let _p = profile::span("BodyValidationDiagnostic::collect"); 57 let _p = profile::span("BodyValidationDiagnostic::collect");
58 let infer = db.infer(owner); 58 let infer = db.infer(owner);
59 let mut validator = ExprValidator::new(owner, infer.clone()); 59 let mut validator = ExprValidator::new(owner, infer);
60 validator.validate_body(db); 60 validator.validate_body(db);
61 validator.diagnostics 61 validator.diagnostics
62 } 62 }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 4e4f6e5a4..c3a5b979f 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -367,7 +367,7 @@ impl<'a> InferenceContext<'a> {
367 Expr::Path(p) => { 367 Expr::Path(p) => {
368 // FIXME this could be more efficient... 368 // FIXME this could be more efficient...
369 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 369 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
370 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty()) 370 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or_else(|| self.err_ty())
371 } 371 }
372 Expr::Continue { .. } => TyKind::Never.intern(&Interner), 372 Expr::Continue { .. } => TyKind::Never.intern(&Interner),
373 Expr::Break { expr, label } => { 373 Expr::Break { expr, label } => {
@@ -511,7 +511,7 @@ impl<'a> InferenceContext<'a> {
511 _ => None, 511 _ => None,
512 } 512 }
513 }) 513 })
514 .unwrap_or(self.err_ty()); 514 .unwrap_or_else(|| self.err_ty());
515 let ty = self.insert_type_vars(ty); 515 let ty = self.insert_type_vars(ty);
516 self.normalize_associated_types_in(ty) 516 self.normalize_associated_types_in(ty)
517 } 517 }
@@ -818,8 +818,10 @@ impl<'a> InferenceContext<'a> {
818 for stmt in statements { 818 for stmt in statements {
819 match stmt { 819 match stmt {
820 Statement::Let { pat, type_ref, initializer } => { 820 Statement::Let { pat, type_ref, initializer } => {
821 let decl_ty = 821 let decl_ty = type_ref
822 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty()); 822 .as_ref()
823 .map(|tr| self.make_ty(tr))
824 .unwrap_or_else(|| self.err_ty());
823 825
824 // Always use the declared type when specified 826 // Always use the declared type when specified
825 let mut ty = decl_ty.clone(); 827 let mut ty = decl_ty.clone();
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 58cb23e9d..c79ed91ea 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -192,7 +192,7 @@ impl<'a> InferenceContext<'a> {
192 Pat::Path(path) => { 192 Pat::Path(path) => {
193 // FIXME use correct resolver for the surrounding expression 193 // FIXME use correct resolver for the surrounding expression
194 let resolver = self.resolver.clone(); 194 let resolver = self.resolver.clone();
195 self.infer_path(&resolver, path, pat.into()).unwrap_or(self.err_ty()) 195 self.infer_path(&resolver, path, pat.into()).unwrap_or_else(|| self.err_ty())
196 } 196 }
197 Pat::Bind { mode, name: _, subpat } => { 197 Pat::Bind { mode, name: _, subpat } => {
198 let mode = if mode == &BindingAnnotation::Unannotated { 198 let mode = if mode == &BindingAnnotation::Unannotated {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 817a65c20..ea03b6a6c 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -562,7 +562,7 @@ impl<'a> TyLoweringContext<'a> {
562 }, 562 },
563 ); 563 );
564 564
565 ty.unwrap_or(TyKind::Error.intern(&Interner)) 565 ty.unwrap_or_else(|| TyKind::Error.intern(&Interner))
566 } else { 566 } else {
567 TyKind::Error.intern(&Interner) 567 TyKind::Error.intern(&Interner)
568 } 568 }
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index e0ad41fb9..0f418ea49 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -705,12 +705,8 @@ fn issue_4931() {
705fn issue_4885() { 705fn issue_4885() {
706 check_infer( 706 check_infer(
707 r#" 707 r#"
708 #[lang = "coerce_unsized"] 708 //- minicore: coerce_unsized, future
709 pub trait CoerceUnsized<T> {} 709 use core::future::Future;
710
711 trait Future {
712 type Output;
713 }
714 trait Foo<R> { 710 trait Foo<R> {
715 type Bar; 711 type Bar;
716 } 712 }
@@ -727,13 +723,13 @@ fn issue_4885() {
727 } 723 }
728 "#, 724 "#,
729 expect![[r#" 725 expect![[r#"
730 136..139 'key': &K 726 70..73 'key': &K
731 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> 727 132..148 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
732 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> 728 138..141 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
733 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> 729 138..146 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
734 208..211 'key': &K 730 142..145 'key': &K
735 228..231 'key': &K 731 162..165 'key': &K
736 290..293 '{ }': () 732 224..227 '{ }': ()
737 "#]], 733 "#]],
738 ); 734 );
739} 735}
@@ -796,6 +792,7 @@ fn issue_4800() {
796fn issue_4966() { 792fn issue_4966() {
797 check_infer( 793 check_infer(
798 r#" 794 r#"
795 //- minicore: deref
799 pub trait IntoIterator { 796 pub trait IntoIterator {
800 type Item; 797 type Item;
801 } 798 }
@@ -806,12 +803,7 @@ fn issue_4966() {
806 803
807 struct Vec<T> {} 804 struct Vec<T> {}
808 805
809 #[lang = "deref"] 806 impl<T> core::ops::Deref for Vec<T> {
810 pub trait Deref {
811 type Target;
812 }
813
814 impl<T> Deref for Vec<T> {
815 type Target = [T]; 807 type Target = [T];
816 } 808 }
817 809
@@ -828,23 +820,23 @@ fn issue_4966() {
828 } 820 }
829 "#, 821 "#,
830 expect![[r#" 822 expect![[r#"
831 270..274 'iter': T 823 225..229 'iter': T
832 289..291 '{}': () 824 244..246 '{}': ()
833 303..447 '{ ...r(); }': () 825 258..402 '{ ...r(); }': ()
834 313..318 'inner': Map<|&f64| -> f64> 826 268..273 'inner': Map<|&f64| -> f64>
835 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> 827 276..300 'Map { ... 0.0 }': Map<|&f64| -> f64>
836 330..343 '|_: &f64| 0.0': |&f64| -> f64 828 285..298 '|_: &f64| 0.0': |&f64| -> f64
837 331..332 '_': &f64 829 286..287 '_': &f64
838 340..343 '0.0': f64 830 295..298 '0.0': f64
839 356..362 'repeat': Repeat<Map<|&f64| -> f64>> 831 311..317 'repeat': Repeat<Map<|&f64| -> f64>>
840 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> 832 320..345 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
841 383..388 'inner': Map<|&f64| -> f64> 833 338..343 'inner': Map<|&f64| -> f64>
842 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 834 356..359 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
843 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 835 362..371 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
844 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 836 362..379 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
845 417..423 'repeat': Repeat<Map<|&f64| -> f64>> 837 372..378 'repeat': Repeat<Map<|&f64| -> f64>>
846 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 838 386..389 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
847 431..444 'vec.foo_bar()': {unknown} 839 386..399 'vec.foo_bar()': {unknown}
848 "#]], 840 "#]],
849 ); 841 );
850} 842}
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 68776f3c0..108ff3179 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1917,6 +1917,7 @@ fn fn_pointer_return() {
1917fn effects_smoke_test() { 1917fn effects_smoke_test() {
1918 check_infer( 1918 check_infer(
1919 r#" 1919 r#"
1920 //- minicore: future
1920 async fn main() { 1921 async fn main() {
1921 let x = unsafe { 92 }; 1922 let x = unsafe { 92 };
1922 let y = async { async { () }.await }; 1923 let y = async { async { () }.await };
@@ -1924,13 +1925,6 @@ fn effects_smoke_test() {
1924 let w = const { 92 }; 1925 let w = const { 92 };
1925 let t = 'a: { 92 }; 1926 let t = 'a: { 92 };
1926 } 1927 }
1927
1928 #[prelude_import] use future::*;
1929
1930 mod future {
1931 #[lang = "future_trait"]
1932 pub trait Future { type Output; }
1933 }
1934 "#, 1928 "#,
1935 expect![[r#" 1929 expect![[r#"
1936 16..162 '{ ...2 }; }': () 1930 16..162 '{ ...2 }; }': ()
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 22e0bfc49..279a1354a 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -567,11 +567,11 @@ fn indexing_arrays() {
567fn infer_ops_index() { 567fn infer_ops_index() {
568 check_types( 568 check_types(
569 r#" 569 r#"
570//- /main.rs crate:main deps:std 570//- minicore: index
571struct Bar; 571struct Bar;
572struct Foo; 572struct Foo;
573 573
574impl std::ops::Index<u32> for Bar { 574impl core::ops::Index<u32> for Bar {
575 type Output = Foo; 575 type Output = Foo;
576} 576}
577 577
@@ -580,15 +580,6 @@ fn test() {
580 let b = a[1u32]; 580 let b = a[1u32];
581 b; 581 b;
582} //^ Foo 582} //^ Foo
583
584//- /std.rs crate:std
585#[prelude_import] use ops::*;
586mod ops {
587 #[lang = "index"]
588 pub trait Index<Idx> {
589 type Output;
590 }
591}
592"#, 583"#,
593 ); 584 );
594} 585}
@@ -597,16 +588,16 @@ mod ops {
597fn infer_ops_index_int() { 588fn infer_ops_index_int() {
598 check_types( 589 check_types(
599 r#" 590 r#"
600//- /main.rs crate:main deps:std 591//- minicore: index
601struct Bar; 592struct Bar;
602struct Foo; 593struct Foo;
603 594
604impl std::ops::Index<u32> for Bar { 595impl core::ops::Index<u32> for Bar {
605 type Output = Foo; 596 type Output = Foo;
606} 597}
607 598
608struct Range; 599struct Range;
609impl std::ops::Index<Range> for Bar { 600impl core::ops::Index<Range> for Bar {
610 type Output = Bar; 601 type Output = Bar;
611} 602}
612 603
@@ -616,15 +607,6 @@ fn test() {
616 b; 607 b;
617 //^ Foo 608 //^ Foo
618} 609}
619
620//- /std.rs crate:std
621#[prelude_import] use ops::*;
622mod ops {
623 #[lang = "index"]
624 pub trait Index<Idx> {
625 type Output;
626 }
627}
628"#, 610"#,
629 ); 611 );
630} 612}
@@ -633,25 +615,12 @@ mod ops {
633fn infer_ops_index_autoderef() { 615fn infer_ops_index_autoderef() {
634 check_types( 616 check_types(
635 r#" 617 r#"
636//- /main.rs crate:main deps:std 618//- minicore: index, slice
637fn test() { 619fn test() {
638 let a = &[1u32, 2, 3]; 620 let a = &[1u32, 2, 3];
639 let b = a[1u32]; 621 let b = a[1];
640 b; 622 b;
641} //^ u32 623} //^ u32
642
643//- /std.rs crate:std
644impl<T> ops::Index<u32> for [T] {
645 type Output = T;
646}
647
648#[prelude_import] use ops::*;
649mod ops {
650 #[lang = "index"]
651 pub trait Index<Idx> {
652 type Output;
653 }
654}
655"#, 624"#,
656 ); 625 );
657} 626}
@@ -884,12 +853,9 @@ fn test<T>(t: T) { t.foo(); }
884fn generic_param_env_deref() { 853fn generic_param_env_deref() {
885 check_types( 854 check_types(
886 r#" 855 r#"
887#[lang = "deref"] 856//- minicore: deref
888trait Deref {
889 type Target;
890}
891trait Trait {} 857trait Trait {}
892impl<T> Deref for T where T: Trait { 858impl<T> core::ops::Deref for T where T: Trait {
893 type Target = i128; 859 type Target = i128;
894} 860}
895fn test<T: Trait>(t: T) { (*t); } 861fn test<T: Trait>(t: T) { (*t); }
@@ -1758,20 +1724,7 @@ fn test() {
1758fn fn_trait_deref_with_ty_default() { 1724fn fn_trait_deref_with_ty_default() {
1759 check_infer( 1725 check_infer(
1760 r#" 1726 r#"
1761#[lang = "deref"] 1727//- minicore: deref, fn
1762trait Deref {
1763 type Target;
1764
1765 fn deref(&self) -> &Self::Target;
1766}
1767
1768#[lang="fn_once"]
1769trait FnOnce<Args> {
1770 type Output;
1771
1772 fn call_once(self, args: Args) -> Self::Output;
1773}
1774
1775struct Foo; 1728struct Foo;
1776 1729
1777impl Foo { 1730impl Foo {
@@ -1784,7 +1737,7 @@ impl<T, F> Lazy<T, F> {
1784 pub fn new(f: F) -> Lazy<T, F> {} 1737 pub fn new(f: F) -> Lazy<T, F> {}
1785} 1738}
1786 1739
1787impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { 1740impl<T, F: FnOnce() -> T> core::ops::Deref for Lazy<T, F> {
1788 type Target = T; 1741 type Target = T;
1789} 1742}
1790 1743
@@ -1798,32 +1751,29 @@ fn test() {
1798 let r2 = lazy2.foo(); 1751 let r2 = lazy2.foo();
1799}"#, 1752}"#,
1800 expect![[r#" 1753 expect![[r#"
1801 64..68 'self': &Self 1754 36..40 'self': &Foo
1802 165..169 'self': Self 1755 51..53 '{}': ()
1803 171..175 'args': Args 1756 131..132 'f': F
1804 239..243 'self': &Foo 1757 151..153 '{}': ()
1805 254..256 '{}': () 1758 251..497 '{ ...o(); }': ()
1806 334..335 'f': F 1759 261..266 'lazy1': Lazy<Foo, || -> Foo>
1807 354..356 '{}': () 1760 283..292 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo>
1808 443..689 '{ ...o(); }': () 1761 283..300 'Lazy::...| Foo)': Lazy<Foo, || -> Foo>
1809 453..458 'lazy1': Lazy<Foo, || -> Foo> 1762 293..299 '|| Foo': || -> Foo
1810 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> 1763 296..299 'Foo': Foo
1811 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> 1764 310..312 'r1': usize
1812 485..491 '|| Foo': || -> Foo 1765 315..320 'lazy1': Lazy<Foo, || -> Foo>
1813 488..491 'Foo': Foo 1766 315..326 'lazy1.foo()': usize
1814 502..504 'r1': usize 1767 368..383 'make_foo_fn_ptr': fn() -> Foo
1815 507..512 'lazy1': Lazy<Foo, || -> Foo> 1768 399..410 'make_foo_fn': fn make_foo_fn() -> Foo
1816 507..518 'lazy1.foo()': usize 1769 420..425 'lazy2': Lazy<Foo, fn() -> Foo>
1817 560..575 'make_foo_fn_ptr': fn() -> Foo 1770 442..451 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo>
1818 591..602 'make_foo_fn': fn make_foo_fn() -> Foo 1771 442..468 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo>
1819 612..617 'lazy2': Lazy<Foo, fn() -> Foo> 1772 452..467 'make_foo_fn_ptr': fn() -> Foo
1820 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> 1773 478..480 'r2': usize
1821 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> 1774 483..488 'lazy2': Lazy<Foo, fn() -> Foo>
1822 644..659 'make_foo_fn_ptr': fn() -> Foo 1775 483..494 'lazy2.foo()': usize
1823 670..672 'r2': usize 1776 357..359 '{}': ()
1824 675..680 'lazy2': Lazy<Foo, fn() -> Foo>
1825 675..686 'lazy2.foo()': usize
1826 549..551 '{}': ()
1827 "#]], 1777 "#]],
1828 ); 1778 );
1829} 1779}
@@ -2731,9 +2681,7 @@ fn test(x: &dyn Foo) {
2731fn builtin_copy() { 2681fn builtin_copy() {
2732 check_infer_with_mismatches( 2682 check_infer_with_mismatches(
2733 r#" 2683 r#"
2734#[lang = "copy"] 2684//- minicore: copy
2735trait Copy {}
2736
2737struct IsCopy; 2685struct IsCopy;
2738impl Copy for IsCopy {} 2686impl Copy for IsCopy {}
2739struct NotCopy; 2687struct NotCopy;
@@ -2748,20 +2696,20 @@ fn test() {
2748 (IsCopy, NotCopy).test(); 2696 (IsCopy, NotCopy).test();
2749}"#, 2697}"#,
2750 expect![[r#" 2698 expect![[r#"
2751 110..114 'self': &Self 2699 78..82 'self': &Self
2752 166..267 '{ ...t(); }': () 2700 134..235 '{ ...t(); }': ()
2753 172..178 'IsCopy': IsCopy 2701 140..146 'IsCopy': IsCopy
2754 172..185 'IsCopy.test()': bool 2702 140..153 'IsCopy.test()': bool
2755 191..198 'NotCopy': NotCopy 2703 159..166 'NotCopy': NotCopy
2756 191..205 'NotCopy.test()': {unknown} 2704 159..173 'NotCopy.test()': {unknown}
2757 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) 2705 179..195 '(IsCop...sCopy)': (IsCopy, IsCopy)
2758 211..234 '(IsCop...test()': bool 2706 179..202 '(IsCop...test()': bool
2759 212..218 'IsCopy': IsCopy 2707 180..186 'IsCopy': IsCopy
2760 220..226 'IsCopy': IsCopy 2708 188..194 'IsCopy': IsCopy
2761 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) 2709 208..225 '(IsCop...tCopy)': (IsCopy, NotCopy)
2762 240..264 '(IsCop...test()': {unknown} 2710 208..232 '(IsCop...test()': {unknown}
2763 241..247 'IsCopy': IsCopy 2711 209..215 'IsCopy': IsCopy
2764 249..256 'NotCopy': NotCopy 2712 217..224 'NotCopy': NotCopy
2765 "#]], 2713 "#]],
2766 ); 2714 );
2767} 2715}
@@ -2770,9 +2718,7 @@ fn test() {
2770fn builtin_fn_def_copy() { 2718fn builtin_fn_def_copy() {
2771 check_infer_with_mismatches( 2719 check_infer_with_mismatches(
2772 r#" 2720 r#"
2773#[lang = "copy"] 2721//- minicore: copy
2774trait Copy {}
2775
2776fn foo() {} 2722fn foo() {}
2777fn bar<T: Copy>(T) -> T {} 2723fn bar<T: Copy>(T) -> T {}
2778struct Struct(usize); 2724struct Struct(usize);
@@ -2788,20 +2734,20 @@ fn test() {
2788 Enum::Variant.test(); 2734 Enum::Variant.test();
2789}"#, 2735}"#,
2790 expect![[r#" 2736 expect![[r#"
2791 41..43 '{}': () 2737 9..11 '{}': ()
2792 60..61 'T': {unknown} 2738 28..29 'T': {unknown}
2793 68..70 '{}': () 2739 36..38 '{}': ()
2794 68..70: expected T, got () 2740 36..38: expected T, got ()
2795 145..149 'self': &Self 2741 113..117 'self': &Self
2796 201..281 '{ ...t(); }': () 2742 169..249 '{ ...t(); }': ()
2797 207..210 'foo': fn foo() 2743 175..178 'foo': fn foo()
2798 207..217 'foo.test()': bool 2744 175..185 'foo.test()': bool
2799 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} 2745 191..194 'bar': fn bar<{unknown}>({unknown}) -> {unknown}
2800 223..233 'bar.test()': bool 2746 191..201 'bar.test()': bool
2801 239..245 'Struct': Struct(usize) -> Struct 2747 207..213 'Struct': Struct(usize) -> Struct
2802 239..252 'Struct.test()': bool 2748 207..220 'Struct.test()': bool
2803 258..271 'Enum::Variant': Variant(usize) -> Enum 2749 226..239 'Enum::Variant': Variant(usize) -> Enum
2804 258..278 'Enum::...test()': bool 2750 226..246 'Enum::...test()': bool
2805 "#]], 2751 "#]],
2806 ); 2752 );
2807} 2753}
@@ -2810,9 +2756,7 @@ fn test() {
2810fn builtin_fn_ptr_copy() { 2756fn builtin_fn_ptr_copy() {
2811 check_infer_with_mismatches( 2757 check_infer_with_mismatches(
2812 r#" 2758 r#"
2813#[lang = "copy"] 2759//- minicore: copy
2814trait Copy {}
2815
2816trait Test { fn test(&self) -> bool; } 2760trait Test { fn test(&self) -> bool; }
2817impl<T: Copy> Test for T {} 2761impl<T: Copy> Test for T {}
2818 2762
@@ -2822,17 +2766,17 @@ fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2822 f3.test(); 2766 f3.test();
2823}"#, 2767}"#,
2824 expect![[r#" 2768 expect![[r#"
2825 54..58 'self': &Self 2769 22..26 'self': &Self
2826 108..110 'f1': fn() 2770 76..78 'f1': fn()
2827 118..120 'f2': fn(usize) -> u8 2771 86..88 'f2': fn(usize) -> u8
2828 139..141 'f3': fn(u8, u8) -> &u8 2772 107..109 'f3': fn(u8, u8) -> &u8
2829 162..210 '{ ...t(); }': () 2773 130..178 '{ ...t(); }': ()
2830 168..170 'f1': fn() 2774 136..138 'f1': fn()
2831 168..177 'f1.test()': bool 2775 136..145 'f1.test()': bool
2832 183..185 'f2': fn(usize) -> u8 2776 151..153 'f2': fn(usize) -> u8
2833 183..192 'f2.test()': bool 2777 151..160 'f2.test()': bool
2834 198..200 'f3': fn(u8, u8) -> &u8 2778 166..168 'f3': fn(u8, u8) -> &u8
2835 198..207 'f3.test()': bool 2779 166..175 'f3.test()': bool
2836 "#]], 2780 "#]],
2837 ); 2781 );
2838} 2782}
@@ -2841,9 +2785,7 @@ fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2841fn builtin_sized() { 2785fn builtin_sized() {
2842 check_infer_with_mismatches( 2786 check_infer_with_mismatches(
2843 r#" 2787 r#"
2844#[lang = "sized"] 2788//- minicore: sized
2845trait Sized {}
2846
2847trait Test { fn test(&self) -> bool; } 2789trait Test { fn test(&self) -> bool; }
2848impl<T: Sized> Test for T {} 2790impl<T: Sized> Test for T {}
2849 2791
@@ -2854,22 +2796,22 @@ fn test() {
2854 (1u8, *"foo").test(); // not Sized 2796 (1u8, *"foo").test(); // not Sized
2855}"#, 2797}"#,
2856 expect![[r#" 2798 expect![[r#"
2857 56..60 'self': &Self 2799 22..26 'self': &Self
2858 113..228 '{ ...ized }': () 2800 79..194 '{ ...ized }': ()
2859 119..122 '1u8': u8 2801 85..88 '1u8': u8
2860 119..129 '1u8.test()': bool 2802 85..95 '1u8.test()': bool
2861 135..150 '(*"foo").test()': {unknown} 2803 101..116 '(*"foo").test()': {unknown}
2862 136..142 '*"foo"': str 2804 102..108 '*"foo"': str
2863 137..142 '"foo"': &str 2805 103..108 '"foo"': &str
2864 169..179 '(1u8, 1u8)': (u8, u8) 2806 135..145 '(1u8, 1u8)': (u8, u8)
2865 169..186 '(1u8, ...test()': bool 2807 135..152 '(1u8, ...test()': bool
2866 170..173 '1u8': u8 2808 136..139 '1u8': u8
2867 175..178 '1u8': u8 2809 141..144 '1u8': u8
2868 192..205 '(1u8, *"foo")': (u8, str) 2810 158..171 '(1u8, *"foo")': (u8, str)
2869 192..212 '(1u8, ...test()': {unknown} 2811 158..178 '(1u8, ...test()': {unknown}
2870 193..196 '1u8': u8 2812 159..162 '1u8': u8
2871 198..204 '*"foo"': str 2813 164..170 '*"foo"': str
2872 199..204 '"foo"': &str 2814 165..170 '"foo"': &str
2873 "#]], 2815 "#]],
2874 ); 2816 );
2875} 2817}
@@ -2980,28 +2922,13 @@ fn infer_box_fn_arg() {
2980 // The type mismatch is because we don't define Unsize and CoerceUnsized 2922 // The type mismatch is because we don't define Unsize and CoerceUnsized
2981 check_infer_with_mismatches( 2923 check_infer_with_mismatches(
2982 r#" 2924 r#"
2983//- /lib.rs deps:std 2925//- minicore: fn, deref, option
2984
2985#[lang = "fn_once"]
2986pub trait FnOnce<Args> {
2987 type Output;
2988
2989 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
2990}
2991
2992#[lang = "deref"]
2993pub trait Deref {
2994 type Target: ?Sized;
2995
2996 fn deref(&self) -> &Self::Target;
2997}
2998
2999#[lang = "owned_box"] 2926#[lang = "owned_box"]
3000pub struct Box<T: ?Sized> { 2927pub struct Box<T: ?Sized> {
3001 inner: *mut T, 2928 inner: *mut T,
3002} 2929}
3003 2930
3004impl<T: ?Sized> Deref for Box<T> { 2931impl<T: ?Sized> core::ops::Deref for Box<T> {
3005 type Target = T; 2932 type Target = T;
3006 2933
3007 fn deref(&self) -> &T { 2934 fn deref(&self) -> &T {
@@ -3009,38 +2936,30 @@ impl<T: ?Sized> Deref for Box<T> {
3009 } 2936 }
3010} 2937}
3011 2938
3012enum Option<T> {
3013 None,
3014 Some(T)
3015}
3016
3017fn foo() { 2939fn foo() {
3018 let s = Option::None; 2940 let s = None;
3019 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); 2941 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
3020 f(&s); 2942 f(&s);
3021}"#, 2943}"#,
3022 expect![[r#" 2944 expect![[r#"
3023 100..104 'self': Self 2945 154..158 'self': &Box<T>
3024 106..110 'args': Args 2946 166..193 '{ ... }': &T
3025 214..218 'self': &Self 2947 176..187 '&self.inner': &*mut T
3026 384..388 'self': &Box<T> 2948 177..181 'self': &Box<T>
3027 396..423 '{ ... }': &T 2949 177..187 'self.inner': *mut T
3028 406..417 '&self.inner': &*mut T 2950 206..296 '{ ...&s); }': ()
3029 407..411 'self': &Box<T> 2951 216..217 's': Option<i32>
3030 407..417 'self.inner': *mut T 2952 220..224 'None': Option<i32>
3031 478..576 '{ ...&s); }': () 2953 234..235 'f': Box<dyn FnOnce(&Option<i32>)>
3032 488..489 's': Option<i32> 2954 269..282 'box (|ps| {})': Box<|{unknown}| -> ()>
3033 492..504 'Option::None': Option<i32> 2955 274..281 '|ps| {}': |{unknown}| -> ()
3034 514..515 'f': Box<dyn FnOnce(&Option<i32>)> 2956 275..277 'ps': {unknown}
3035 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> 2957 279..281 '{}': ()
3036 554..561 '|ps| {}': |{unknown}| -> () 2958 288..289 'f': Box<dyn FnOnce(&Option<i32>)>
3037 555..557 'ps': {unknown} 2959 288..293 'f(&s)': ()
3038 559..561 '{}': () 2960 290..292 '&s': &Option<i32>
3039 568..569 'f': Box<dyn FnOnce(&Option<i32>)> 2961 291..292 's': Option<i32>
3040 568..573 'f(&s)': () 2962 269..282: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
3041 570..572 '&s': &Option<i32>
3042 571..572 's': Option<i32>
3043 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
3044 "#]], 2963 "#]],
3045 ); 2964 );
3046} 2965}
diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs
index ca3c02bf6..43cffefe5 100644
--- a/crates/ide/src/goto_type_definition.rs
+++ b/crates/ide/src/goto_type_definition.rs
@@ -25,7 +25,7 @@ pub(crate) fn goto_type_definition(
25 let token: SyntaxToken = pick_best(file.syntax().token_at_offset(position.offset))?; 25 let token: SyntaxToken = pick_best(file.syntax().token_at_offset(position.offset))?;
26 let token: SyntaxToken = sema.descend_into_macros(token); 26 let token: SyntaxToken = sema.descend_into_macros(token);
27 27
28 let (ty, node) = sema.token_ancestors_with_macros(token.clone()).find_map(|node| { 28 let (ty, node) = sema.token_ancestors_with_macros(token).find_map(|node| {
29 let ty = match_ast! { 29 let ty = match_ast! {
30 match node { 30 match node {
31 ast::Expr(it) => sema.type_of_expr(&it)?, 31 ast::Expr(it) => sema.type_of_expr(&it)?,
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 01dd0c0da..05a2b1293 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -568,8 +568,6 @@ mod tests {
568 568
569 use crate::fixture; 569 use crate::fixture;
570 570
571 use super::*;
572
573 fn check_hover_no_result(ra_fixture: &str) { 571 fn check_hover_no_result(ra_fixture: &str) {
574 let (analysis, position) = fixture::position(ra_fixture); 572 let (analysis, position) = fixture::position(ra_fixture);
575 assert!(analysis.hover(position, true, true).unwrap().is_none()); 573 assert!(analysis.hover(position, true, true).unwrap().is_none());
@@ -3016,8 +3014,8 @@ fn foo() {
3016 file_id: FileId( 3014 file_id: FileId(
3017 1, 3015 1,
3018 ), 3016 ),
3019 full_range: 247..429, 3017 full_range: 251..433,
3020 focus_range: 286..292, 3018 focus_range: 290..296,
3021 name: "Future", 3019 name: "Future",
3022 kind: Trait, 3020 kind: Trait,
3023 description: "pub trait Future", 3021 description: "pub trait Future",
@@ -3813,11 +3811,14 @@ use foo::bar::{self$0};
3813 3811
3814 #[test] 3812 #[test]
3815 fn hover_keyword() { 3813 fn hover_keyword() {
3816 let ra_fixture = r#"//- /main.rs crate:main deps:std
3817fn f() { retur$0n; }"#;
3818 let fixture = format!("{}\n{}", ra_fixture, FamousDefs::FIXTURE);
3819 check( 3814 check(
3820 &fixture, 3815 r#"
3816//- /main.rs crate:main deps:std
3817fn f() { retur$0n; }
3818//- /libstd.rs crate:std
3819/// Docs for return_keyword
3820mod return_keyword {}
3821"#,
3821 expect![[r#" 3822 expect![[r#"
3822 *return* 3823 *return*
3823 3824
@@ -3834,11 +3835,15 @@ fn f() { retur$0n; }"#;
3834 3835
3835 #[test] 3836 #[test]
3836 fn hover_builtin() { 3837 fn hover_builtin() {
3837 let ra_fixture = r#"//- /main.rs crate:main deps:std
3838cosnt _: &str$0 = ""; }"#;
3839 let fixture = format!("{}\n{}", ra_fixture, FamousDefs::FIXTURE);
3840 check( 3838 check(
3841 &fixture, 3839 r#"
3840//- /main.rs crate:main deps:std
3841cosnt _: &str$0 = ""; }
3842
3843//- /libstd.rs crate:std
3844/// Docs for prim_str
3845mod prim_str {}
3846"#,
3842 expect![[r#" 3847 expect![[r#"
3843 *str* 3848 *str*
3844 3849
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 335d57a0d..95f9edce4 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -661,9 +661,7 @@ fn main() {
661 fn function_call_parameter_hint() { 661 fn function_call_parameter_hint() {
662 check_params( 662 check_params(
663 r#" 663 r#"
664enum Option<T> { None, Some(T) } 664//- minicore: option
665use Option::*;
666
667struct FileId {} 665struct FileId {}
668struct SmolStr {} 666struct SmolStr {}
669 667
@@ -872,7 +870,6 @@ fn main() {
872 check_types( 870 check_types(
873 r#" 871 r#"
874//- minicore: fn, sized 872//- minicore: fn, sized
875
876fn foo() -> impl Fn() { loop {} } 873fn foo() -> impl Fn() { loop {} }
877fn foo1() -> impl Fn(f64) { loop {} } 874fn foo1() -> impl Fn(f64) { loop {} }
878fn foo2() -> impl Fn(f64, f64) { loop {} } 875fn foo2() -> impl Fn(f64, f64) { loop {} }
@@ -908,9 +905,7 @@ fn main() {
908 fn unit_structs_have_no_type_hints() { 905 fn unit_structs_have_no_type_hints() {
909 check_types( 906 check_types(
910 r#" 907 r#"
911enum Result<T, E> { Ok(T), Err(E) } 908//- minicore: result
912use Result::*;
913
914struct SyntheticSyntax; 909struct SyntheticSyntax;
915 910
916fn main() { 911fn main() {
@@ -962,9 +957,7 @@ fn main() {
962 fn if_expr() { 957 fn if_expr() {
963 check_types( 958 check_types(
964 r#" 959 r#"
965enum Option<T> { None, Some(T) } 960//- minicore: option
966use Option::*;
967
968struct Test { a: Option<u32>, b: u8 } 961struct Test { a: Option<u32>, b: u8 }
969 962
970fn main() { 963fn main() {
@@ -994,9 +987,7 @@ fn main() {
994 fn while_expr() { 987 fn while_expr() {
995 check_types( 988 check_types(
996 r#" 989 r#"
997enum Option<T> { None, Some(T) } 990//- minicore: option
998use Option::*;
999
1000struct Test { a: Option<u32>, b: u8 } 991struct Test { a: Option<u32>, b: u8 }
1001 992
1002fn main() { 993fn main() {
@@ -1012,9 +1003,7 @@ fn main() {
1012 fn match_arm_list() { 1003 fn match_arm_list() {
1013 check_types( 1004 check_types(
1014 r#" 1005 r#"
1015enum Option<T> { None, Some(T) } 1006//- minicore: option
1016use Option::*;
1017
1018struct Test { a: Option<u32>, b: u8 } 1007struct Test { a: Option<u32>, b: u8 }
1019 1008
1020fn main() { 1009fn main() {
diff --git a/crates/ide_assists/src/handlers/apply_demorgan.rs b/crates/ide_assists/src/handlers/apply_demorgan.rs
index c93959e66..e2bd6e456 100644
--- a/crates/ide_assists/src/handlers/apply_demorgan.rs
+++ b/crates/ide_assists/src/handlers/apply_demorgan.rs
@@ -147,74 +147,92 @@ fn opposite_logic_op(kind: ast::BinOp) -> Option<&'static str> {
147 147
148#[cfg(test)] 148#[cfg(test)]
149mod tests { 149mod tests {
150 use ide_db::helpers::FamousDefs;
151
152 use super::*;
153
154 use crate::tests::{check_assist, check_assist_not_applicable}; 150 use crate::tests::{check_assist, check_assist_not_applicable};
155 151
156 const ORDABLE_FIXTURE: &'static str = r" 152 use super::*;
157//- /lib.rs deps:core crate:ordable
158struct NonOrderable;
159struct Orderable;
160impl core::cmp::Ord for Orderable {}
161";
162
163 fn check(ra_fixture_before: &str, ra_fixture_after: &str) {
164 let before = &format!(
165 "//- /main.rs crate:main deps:core,ordable\n{}\n{}{}",
166 ra_fixture_before,
167 FamousDefs::FIXTURE,
168 ORDABLE_FIXTURE
169 );
170 check_assist(apply_demorgan, before, &format!("{}\n", ra_fixture_after));
171 }
172 153
173 #[test] 154 #[test]
174 fn demorgan_handles_leq() { 155 fn demorgan_handles_leq() {
175 check( 156 check_assist(
176 r"use ordable::Orderable; 157 apply_demorgan,
158 r#"
159//- minicore: ord, derive
160#[derive(PartialEq, Eq, PartialOrd, Ord)]
161struct S;
162
177fn f() { 163fn f() {
178 Orderable < Orderable &&$0 Orderable <= Orderable 164 S < S &&$0 S <= S
179}", 165}
180 r"use ordable::Orderable; 166"#,
167 r#"
168#[derive(PartialEq, Eq, PartialOrd, Ord)]
169struct S;
170
181fn f() { 171fn f() {
182 !(Orderable >= Orderable || Orderable > Orderable) 172 !(S >= S || S > S)
183}", 173}
174"#,
184 ); 175 );
185 check( 176
186 r"use ordable::NonOrderable; 177 check_assist(
178 apply_demorgan,
179 r#"
180//- minicore: ord, derive
181struct S;
182
187fn f() { 183fn f() {
188 NonOrderable < NonOrderable &&$0 NonOrderable <= NonOrderable 184 S < S &&$0 S <= S
189}", 185}
190 r"use ordable::NonOrderable; 186"#,
187 r#"
188struct S;
189
191fn f() { 190fn f() {
192 !(!(NonOrderable < NonOrderable) || !(NonOrderable <= NonOrderable)) 191 !(!(S < S) || !(S <= S))
193}", 192}
193"#,
194 ); 194 );
195 } 195 }
196 196
197 #[test] 197 #[test]
198 fn demorgan_handles_geq() { 198 fn demorgan_handles_geq() {
199 check( 199 check_assist(
200 r"use ordable::Orderable; 200 apply_demorgan,
201 r#"
202//- minicore: ord, derive
203#[derive(PartialEq, Eq, PartialOrd, Ord)]
204struct S;
205
201fn f() { 206fn f() {
202 Orderable > Orderable &&$0 Orderable >= Orderable 207 S > S &&$0 S >= S
203}", 208}
204 r"use ordable::Orderable; 209"#,
210 r#"
211#[derive(PartialEq, Eq, PartialOrd, Ord)]
212struct S;
213
205fn f() { 214fn f() {
206 !(Orderable <= Orderable || Orderable < Orderable) 215 !(S <= S || S < S)
207}", 216}
217"#,
208 ); 218 );
209 check( 219 check_assist(
210 r"use ordable::NonOrderable; 220 apply_demorgan,
221 r#"
222//- minicore: ord, derive
223struct S;
224
211fn f() { 225fn f() {
212 Orderable > Orderable &&$0 Orderable >= Orderable 226 S > S &&$0 S >= S
213}", 227}
214 r"use ordable::NonOrderable; 228"#,
229 r#"
230struct S;
231
215fn f() { 232fn f() {
216 !(!(Orderable > Orderable) || !(Orderable >= Orderable)) 233 !(!(S > S) || !(S >= S))
217}", 234}
235"#,
218 ); 236 );
219 } 237 }
220 238
diff --git a/crates/ide_assists/src/handlers/convert_into_to_from.rs b/crates/ide_assists/src/handlers/convert_into_to_from.rs
index 79a0c4879..2d8b936cd 100644
--- a/crates/ide_assists/src/handlers/convert_into_to_from.rs
+++ b/crates/ide_assists/src/handlers/convert_into_to_from.rs
@@ -13,10 +13,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
13// Converts an Into impl to an equivalent From impl. 13// Converts an Into impl to an equivalent From impl.
14// 14//
15// ``` 15// ```
16// # //- /lib.rs crate:core 16// # //- minicore: from
17// # pub mod convert { pub trait Into<T> { pub fn into(self) -> T; } }
18// # //- /lib.rs crate:main deps:core
19// # use core::convert::Into;
20// impl $0Into<Thing> for usize { 17// impl $0Into<Thing> for usize {
21// fn into(self) -> Thing { 18// fn into(self) -> Thing {
22// Thing { 19// Thing {
@@ -28,7 +25,6 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
28// ``` 25// ```
29// -> 26// ->
30// ``` 27// ```
31// # use core::convert::Into;
32// impl From<usize> for Thing { 28// impl From<usize> for Thing {
33// fn from(val: usize) -> Self { 29// fn from(val: usize) -> Self {
34// Thing { 30// Thing {
diff --git a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
index 7fd73d4c7..70754adf9 100644
--- a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
+++ b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
@@ -11,14 +11,10 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
11// Converts an Iterator::for_each function into a for loop. 11// Converts an Iterator::for_each function into a for loop.
12// 12//
13// ``` 13// ```
14// # //- /lib.rs crate:core 14// # //- minicore: iterators
15// # pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } } 15// # use core::iter;
16// # pub struct SomeIter;
17// # impl self::iter::traits::iterator::Iterator for SomeIter {}
18// # //- /lib.rs crate:main deps:core
19// # use core::SomeIter;
20// fn main() { 16// fn main() {
21// let iter = SomeIter; 17// let iter = iter::repeat((9, 2));
22// iter.for_each$0(|(x, y)| { 18// iter.for_each$0(|(x, y)| {
23// println!("x: {}, y: {}", x, y); 19// println!("x: {}, y: {}", x, y);
24// }); 20// });
@@ -26,9 +22,9 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
26// ``` 22// ```
27// -> 23// ->
28// ``` 24// ```
29// # use core::SomeIter; 25// # use core::iter;
30// fn main() { 26// fn main() {
31// let iter = SomeIter; 27// let iter = iter::repeat((9, 2));
32// for (x, y) in iter { 28// for (x, y) in iter {
33// println!("x: {}, y: {}", x, y); 29// println!("x: {}, y: {}", x, y);
34// } 30// }
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
index 7085a0c48..ac7f0959b 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -1501,7 +1501,8 @@ mod tests {
1501 r#" 1501 r#"
1502fn foo() { 1502fn foo() {
1503 foo($01 + 1$0); 1503 foo($01 + 1$0);
1504}"#, 1504}
1505"#,
1505 r#" 1506 r#"
1506fn foo() { 1507fn foo() {
1507 foo(fun_name()); 1508 foo(fun_name());
@@ -1509,7 +1510,8 @@ fn foo() {
1509 1510
1510fn $0fun_name() -> i32 { 1511fn $0fun_name() -> i32 {
1511 1 + 1 1512 1 + 1
1512}"#, 1513}
1514"#,
1513 ); 1515 );
1514 } 1516 }
1515 1517
@@ -1522,7 +1524,8 @@ mod bar {
1522 fn foo() { 1524 fn foo() {
1523 foo($01 + 1$0); 1525 foo($01 + 1$0);
1524 } 1526 }
1525}"#, 1527}
1528"#,
1526 r#" 1529 r#"
1527mod bar { 1530mod bar {
1528 fn foo() { 1531 fn foo() {
@@ -1532,7 +1535,8 @@ mod bar {
1532 fn $0fun_name() -> i32 { 1535 fn $0fun_name() -> i32 {
1533 1 + 1 1536 1 + 1
1534 } 1537 }
1535}"#, 1538}
1539"#,
1536 ); 1540 );
1537 } 1541 }
1538 1542
@@ -1543,7 +1547,8 @@ mod bar {
1543 r#" 1547 r#"
1544fn foo() { 1548fn foo() {
1545 $0{ 1 + 1 }$0; 1549 $0{ 1 + 1 }$0;
1546}"#, 1550}
1551"#,
1547 r#" 1552 r#"
1548fn foo() { 1553fn foo() {
1549 fun_name(); 1554 fun_name();
@@ -1551,7 +1556,8 @@ fn foo() {
1551 1556
1552fn $0fun_name() -> i32 { 1557fn $0fun_name() -> i32 {
1553 1 + 1 1558 1 + 1
1554}"#, 1559}
1560"#,
1555 ); 1561 );
1556 } 1562 }
1557 1563
@@ -1564,7 +1570,8 @@ fn foo() -> i32 {
1564 let k = 1; 1570 let k = 1;
1565 $0let m = 1; 1571 $0let m = 1;
1566 m + 1$0 1572 m + 1$0
1567}"#, 1573}
1574"#,
1568 r#" 1575 r#"
1569fn foo() -> i32 { 1576fn foo() -> i32 {
1570 let k = 1; 1577 let k = 1;
@@ -1574,7 +1581,8 @@ fn foo() -> i32 {
1574fn $0fun_name() -> i32 { 1581fn $0fun_name() -> i32 {
1575 let m = 1; 1582 let m = 1;
1576 m + 1 1583 m + 1
1577}"#, 1584}
1585"#,
1578 ); 1586 );
1579 } 1587 }
1580 1588
@@ -1588,7 +1596,8 @@ fn foo() {
1588 $0let m = 1; 1596 $0let m = 1;
1589 let n = m + 1;$0 1597 let n = m + 1;$0
1590 let g = 5; 1598 let g = 5;
1591}"#, 1599}
1600"#,
1592 r#" 1601 r#"
1593fn foo() { 1602fn foo() {
1594 let k = 3; 1603 let k = 3;
@@ -1599,7 +1608,8 @@ fn foo() {
1599fn $0fun_name() { 1608fn $0fun_name() {
1600 let m = 1; 1609 let m = 1;
1601 let n = m + 1; 1610 let n = m + 1;
1602}"#, 1611}
1612"#,
1603 ); 1613 );
1604 } 1614 }
1605 1615
@@ -1610,7 +1620,8 @@ fn $0fun_name() {
1610 r#" 1620 r#"
1611fn foo() { 1621fn foo() {
1612 $0if true { }$0 1622 $0if true { }$0
1613}"#, 1623}
1624"#,
1614 r#" 1625 r#"
1615fn foo() { 1626fn foo() {
1616 fun_name(); 1627 fun_name();
@@ -1618,7 +1629,8 @@ fn foo() {
1618 1629
1619fn $0fun_name() { 1630fn $0fun_name() {
1620 if true { } 1631 if true { }
1621}"#, 1632}
1633"#,
1622 ); 1634 );
1623 } 1635 }
1624 1636
@@ -1629,7 +1641,8 @@ fn $0fun_name() {
1629 r#" 1641 r#"
1630fn foo() -> i32 { 1642fn foo() -> i32 {
1631 $0if true { 1 } else { 2 }$0 1643 $0if true { 1 } else { 2 }$0
1632}"#, 1644}
1645"#,
1633 r#" 1646 r#"
1634fn foo() -> i32 { 1647fn foo() -> i32 {
1635 fun_name() 1648 fun_name()
@@ -1637,7 +1650,8 @@ fn foo() -> i32 {
1637 1650
1638fn $0fun_name() -> i32 { 1651fn $0fun_name() -> i32 {
1639 if true { 1 } else { 2 } 1652 if true { 1 } else { 2 }
1640}"#, 1653}
1654"#,
1641 ); 1655 );
1642 } 1656 }
1643 1657
@@ -1648,7 +1662,8 @@ fn $0fun_name() -> i32 {
1648 r#" 1662 r#"
1649fn foo() -> i32 { 1663fn foo() -> i32 {
1650 $0if let true = false { 1 } else { 2 }$0 1664 $0if let true = false { 1 } else { 2 }$0
1651}"#, 1665}
1666"#,
1652 r#" 1667 r#"
1653fn foo() -> i32 { 1668fn foo() -> i32 {
1654 fun_name() 1669 fun_name()
@@ -1656,7 +1671,8 @@ fn foo() -> i32 {
1656 1671
1657fn $0fun_name() -> i32 { 1672fn $0fun_name() -> i32 {
1658 if let true = false { 1 } else { 2 } 1673 if let true = false { 1 } else { 2 }
1659}"#, 1674}
1675"#,
1660 ); 1676 );
1661 } 1677 }
1662 1678
@@ -1670,7 +1686,8 @@ fn foo() -> i32 {
1670 true => 1, 1686 true => 1,
1671 false => 2, 1687 false => 2,
1672 }$0 1688 }$0
1673}"#, 1689}
1690"#,
1674 r#" 1691 r#"
1675fn foo() -> i32 { 1692fn foo() -> i32 {
1676 fun_name() 1693 fun_name()
@@ -1681,7 +1698,8 @@ fn $0fun_name() -> i32 {
1681 true => 1, 1698 true => 1,
1682 false => 2, 1699 false => 2,
1683 } 1700 }
1684}"#, 1701}
1702"#,
1685 ); 1703 );
1686 } 1704 }
1687 1705
@@ -1692,7 +1710,8 @@ fn $0fun_name() -> i32 {
1692 r#" 1710 r#"
1693fn foo() { 1711fn foo() {
1694 $0while true { }$0 1712 $0while true { }$0
1695}"#, 1713}
1714"#,
1696 r#" 1715 r#"
1697fn foo() { 1716fn foo() {
1698 fun_name(); 1717 fun_name();
@@ -1700,7 +1719,8 @@ fn foo() {
1700 1719
1701fn $0fun_name() { 1720fn $0fun_name() {
1702 while true { } 1721 while true { }
1703}"#, 1722}
1723"#,
1704 ); 1724 );
1705 } 1725 }
1706 1726
@@ -1711,7 +1731,8 @@ fn $0fun_name() {
1711 r#" 1731 r#"
1712fn foo() { 1732fn foo() {
1713 $0for v in &[0, 1] { }$0 1733 $0for v in &[0, 1] { }$0
1714}"#, 1734}
1735"#,
1715 r#" 1736 r#"
1716fn foo() { 1737fn foo() {
1717 fun_name(); 1738 fun_name();
@@ -1719,7 +1740,8 @@ fn foo() {
1719 1740
1720fn $0fun_name() { 1741fn $0fun_name() {
1721 for v in &[0, 1] { } 1742 for v in &[0, 1] { }
1722}"#, 1743}
1744"#,
1723 ); 1745 );
1724 } 1746 }
1725 1747
@@ -1732,7 +1754,8 @@ fn foo() {
1732 $0loop { 1754 $0loop {
1733 let m = 1; 1755 let m = 1;
1734 }$0 1756 }$0
1735}"#, 1757}
1758"#,
1736 r#" 1759 r#"
1737fn foo() { 1760fn foo() {
1738 fun_name() 1761 fun_name()
@@ -1742,7 +1765,8 @@ fn $0fun_name() -> ! {
1742 loop { 1765 loop {
1743 let m = 1; 1766 let m = 1;
1744 } 1767 }
1745}"#, 1768}
1769"#,
1746 ); 1770 );
1747 } 1771 }
1748 1772
@@ -1756,7 +1780,8 @@ fn foo() {
1756 let m = 1; 1780 let m = 1;
1757 break m; 1781 break m;
1758 }$0; 1782 }$0;
1759}"#, 1783}
1784"#,
1760 r#" 1785 r#"
1761fn foo() { 1786fn foo() {
1762 let v = fun_name(); 1787 let v = fun_name();
@@ -1767,7 +1792,8 @@ fn $0fun_name() -> i32 {
1767 let m = 1; 1792 let m = 1;
1768 break m; 1793 break m;
1769 } 1794 }
1770}"#, 1795}
1796"#,
1771 ); 1797 );
1772 } 1798 }
1773 1799
@@ -1781,7 +1807,8 @@ fn foo() {
1781 Some(x) => x, 1807 Some(x) => x,
1782 None => 0, 1808 None => 0,
1783 }$0; 1809 }$0;
1784}"#, 1810}
1811"#,
1785 r#" 1812 r#"
1786fn foo() { 1813fn foo() {
1787 let v: i32 = fun_name(); 1814 let v: i32 = fun_name();
@@ -1792,7 +1819,8 @@ fn $0fun_name() -> i32 {
1792 Some(x) => x, 1819 Some(x) => x,
1793 None => 0, 1820 None => 0,
1794 } 1821 }
1795}"#, 1822}
1823"#,
1796 ); 1824 );
1797 } 1825 }
1798 1826
@@ -1805,7 +1833,8 @@ fn foo() {
1805 let n = 1; 1833 let n = 1;
1806 let mut v = $0n * n;$0 1834 let mut v = $0n * n;$0
1807 v += 1; 1835 v += 1;
1808}"#, 1836}
1837"#,
1809 r#" 1838 r#"
1810fn foo() { 1839fn foo() {
1811 let n = 1; 1840 let n = 1;
@@ -1816,7 +1845,8 @@ fn foo() {
1816fn $0fun_name(n: i32) -> i32 { 1845fn $0fun_name(n: i32) -> i32 {
1817 let mut v = n * n; 1846 let mut v = n * n;
1818 v 1847 v
1819}"#, 1848}
1849"#,
1820 ); 1850 );
1821 } 1851 }
1822 1852
@@ -1832,7 +1862,8 @@ fn foo() {
1832 let mut w = 3;$0 1862 let mut w = 3;$0
1833 v += 1; 1863 v += 1;
1834 w += 1; 1864 w += 1;
1835}"#, 1865}
1866"#,
1836 r#" 1867 r#"
1837fn foo() { 1868fn foo() {
1838 let m = 2; 1869 let m = 2;
@@ -1846,7 +1877,8 @@ fn $0fun_name(m: i32, n: i32) -> (i32, i32) {
1846 let mut v = m * n; 1877 let mut v = m * n;
1847 let mut w = 3; 1878 let mut w = 3;
1848 (v, w) 1879 (v, w)
1849}"#, 1880}
1881"#,
1850 ); 1882 );
1851 } 1883 }
1852 1884
@@ -1854,12 +1886,13 @@ fn $0fun_name(m: i32, n: i32) -> (i32, i32) {
1854 fn argument_form_expr() { 1886 fn argument_form_expr() {
1855 check_assist( 1887 check_assist(
1856 extract_function, 1888 extract_function,
1857 r" 1889 r#"
1858fn foo() -> u32 { 1890fn foo() -> u32 {
1859 let n = 2; 1891 let n = 2;
1860 $0n+2$0 1892 $0n+2$0
1861}", 1893}
1862 r" 1894"#,
1895 r#"
1863fn foo() -> u32 { 1896fn foo() -> u32 {
1864 let n = 2; 1897 let n = 2;
1865 fun_name(n) 1898 fun_name(n)
@@ -1867,7 +1900,8 @@ fn foo() -> u32 {
1867 1900
1868fn $0fun_name(n: u32) -> u32 { 1901fn $0fun_name(n: u32) -> u32 {
1869 n+2 1902 n+2
1870}", 1903}
1904"#,
1871 ) 1905 )
1872 } 1906 }
1873 1907
@@ -1875,12 +1909,13 @@ fn $0fun_name(n: u32) -> u32 {
1875 fn argument_used_twice_form_expr() { 1909 fn argument_used_twice_form_expr() {
1876 check_assist( 1910 check_assist(
1877 extract_function, 1911 extract_function,
1878 r" 1912 r#"
1879fn foo() -> u32 { 1913fn foo() -> u32 {
1880 let n = 2; 1914 let n = 2;
1881 $0n+n$0 1915 $0n+n$0
1882}", 1916}
1883 r" 1917"#,
1918 r#"
1884fn foo() -> u32 { 1919fn foo() -> u32 {
1885 let n = 2; 1920 let n = 2;
1886 fun_name(n) 1921 fun_name(n)
@@ -1888,7 +1923,8 @@ fn foo() -> u32 {
1888 1923
1889fn $0fun_name(n: u32) -> u32 { 1924fn $0fun_name(n: u32) -> u32 {
1890 n+n 1925 n+n
1891}", 1926}
1927"#,
1892 ) 1928 )
1893 } 1929 }
1894 1930
@@ -1896,13 +1932,14 @@ fn $0fun_name(n: u32) -> u32 {
1896 fn two_arguments_form_expr() { 1932 fn two_arguments_form_expr() {
1897 check_assist( 1933 check_assist(
1898 extract_function, 1934 extract_function,
1899 r" 1935 r#"
1900fn foo() -> u32 { 1936fn foo() -> u32 {
1901 let n = 2; 1937 let n = 2;
1902 let m = 3; 1938 let m = 3;
1903 $0n+n*m$0 1939 $0n+n*m$0
1904}", 1940}
1905 r" 1941"#,
1942 r#"
1906fn foo() -> u32 { 1943fn foo() -> u32 {
1907 let n = 2; 1944 let n = 2;
1908 let m = 3; 1945 let m = 3;
@@ -1911,7 +1948,8 @@ fn foo() -> u32 {
1911 1948
1912fn $0fun_name(n: u32, m: u32) -> u32 { 1949fn $0fun_name(n: u32, m: u32) -> u32 {
1913 n+n*m 1950 n+n*m
1914}", 1951}
1952"#,
1915 ) 1953 )
1916 } 1954 }
1917 1955
@@ -1919,13 +1957,14 @@ fn $0fun_name(n: u32, m: u32) -> u32 {
1919 fn argument_and_locals() { 1957 fn argument_and_locals() {
1920 check_assist( 1958 check_assist(
1921 extract_function, 1959 extract_function,
1922 r" 1960 r#"
1923fn foo() -> u32 { 1961fn foo() -> u32 {
1924 let n = 2; 1962 let n = 2;
1925 $0let m = 1; 1963 $0let m = 1;
1926 n + m$0 1964 n + m$0
1927}", 1965}
1928 r" 1966"#,
1967 r#"
1929fn foo() -> u32 { 1968fn foo() -> u32 {
1930 let n = 2; 1969 let n = 2;
1931 fun_name(n) 1970 fun_name(n)
@@ -1934,7 +1973,8 @@ fn foo() -> u32 {
1934fn $0fun_name(n: u32) -> u32 { 1973fn $0fun_name(n: u32) -> u32 {
1935 let m = 1; 1974 let m = 1;
1936 n + m 1975 n + m
1937}", 1976}
1977"#,
1938 ) 1978 )
1939 } 1979 }
1940 1980
@@ -1948,18 +1988,20 @@ fn $0fun_name(n: u32) -> u32 {
1948 fn part_of_expr_stmt() { 1988 fn part_of_expr_stmt() {
1949 check_assist( 1989 check_assist(
1950 extract_function, 1990 extract_function,
1951 " 1991 r#"
1952fn foo() { 1992fn foo() {
1953 $01$0 + 1; 1993 $01$0 + 1;
1954}", 1994}
1955 " 1995"#,
1996 r#"
1956fn foo() { 1997fn foo() {
1957 fun_name() + 1; 1998 fun_name() + 1;
1958} 1999}
1959 2000
1960fn $0fun_name() -> i32 { 2001fn $0fun_name() -> i32 {
1961 1 2002 1
1962}", 2003}
2004"#,
1963 ); 2005 );
1964 } 2006 }
1965 2007
@@ -1970,7 +2012,8 @@ fn $0fun_name() -> i32 {
1970 r#" 2012 r#"
1971fn foo() { 2013fn foo() {
1972 $0bar(1 + 1)$0 2014 $0bar(1 + 1)$0
1973}"#, 2015}
2016"#,
1974 r#" 2017 r#"
1975fn foo() { 2018fn foo() {
1976 fun_name(); 2019 fun_name();
@@ -1978,7 +2021,8 @@ fn foo() {
1978 2021
1979fn $0fun_name() { 2022fn $0fun_name() {
1980 bar(1 + 1) 2023 bar(1 + 1)
1981}"#, 2024}
2025"#,
1982 ) 2026 )
1983 } 2027 }
1984 2028
@@ -1986,15 +2030,16 @@ fn $0fun_name() {
1986 fn extract_from_nested() { 2030 fn extract_from_nested() {
1987 check_assist( 2031 check_assist(
1988 extract_function, 2032 extract_function,
1989 r" 2033 r#"
1990fn main() { 2034fn main() {
1991 let x = true; 2035 let x = true;
1992 let tuple = match x { 2036 let tuple = match x {
1993 true => ($02 + 2$0, true) 2037 true => ($02 + 2$0, true)
1994 _ => (0, false) 2038 _ => (0, false)
1995 }; 2039 };
1996}", 2040}
1997 r" 2041"#,
2042 r#"
1998fn main() { 2043fn main() {
1999 let x = true; 2044 let x = true;
2000 let tuple = match x { 2045 let tuple = match x {
@@ -2005,7 +2050,8 @@ fn main() {
2005 2050
2006fn $0fun_name() -> i32 { 2051fn $0fun_name() -> i32 {
2007 2 + 2 2052 2 + 2
2008}", 2053}
2054"#,
2009 ); 2055 );
2010 } 2056 }
2011 2057
@@ -2013,18 +2059,20 @@ fn $0fun_name() -> i32 {
2013 fn param_from_closure() { 2059 fn param_from_closure() {
2014 check_assist( 2060 check_assist(
2015 extract_function, 2061 extract_function,
2016 r" 2062 r#"
2017fn main() { 2063fn main() {
2018 let lambda = |x: u32| $0x * 2$0; 2064 let lambda = |x: u32| $0x * 2$0;
2019}", 2065}
2020 r" 2066"#,
2067 r#"
2021fn main() { 2068fn main() {
2022 let lambda = |x: u32| fun_name(x); 2069 let lambda = |x: u32| fun_name(x);
2023} 2070}
2024 2071
2025fn $0fun_name(x: u32) -> u32 { 2072fn $0fun_name(x: u32) -> u32 {
2026 x * 2 2073 x * 2
2027}", 2074}
2075"#,
2028 ); 2076 );
2029 } 2077 }
2030 2078
@@ -2032,18 +2080,20 @@ fn $0fun_name(x: u32) -> u32 {
2032 fn extract_return_stmt() { 2080 fn extract_return_stmt() {
2033 check_assist( 2081 check_assist(
2034 extract_function, 2082 extract_function,
2035 r" 2083 r#"
2036fn foo() -> u32 { 2084fn foo() -> u32 {
2037 $0return 2 + 2$0; 2085 $0return 2 + 2$0;
2038}", 2086}
2039 r" 2087"#,
2088 r#"
2040fn foo() -> u32 { 2089fn foo() -> u32 {
2041 return fun_name(); 2090 return fun_name();
2042} 2091}
2043 2092
2044fn $0fun_name() -> u32 { 2093fn $0fun_name() -> u32 {
2045 2 + 2 2094 2 + 2
2046}", 2095}
2096"#,
2047 ); 2097 );
2048 } 2098 }
2049 2099
@@ -2051,13 +2101,14 @@ fn $0fun_name() -> u32 {
2051 fn does_not_add_extra_whitespace() { 2101 fn does_not_add_extra_whitespace() {
2052 check_assist( 2102 check_assist(
2053 extract_function, 2103 extract_function,
2054 r" 2104 r#"
2055fn foo() -> u32 { 2105fn foo() -> u32 {
2056 2106
2057 2107
2058 $0return 2 + 2$0; 2108 $0return 2 + 2$0;
2059}", 2109}
2060 r" 2110"#,
2111 r#"
2061fn foo() -> u32 { 2112fn foo() -> u32 {
2062 2113
2063 2114
@@ -2066,7 +2117,8 @@ fn foo() -> u32 {
2066 2117
2067fn $0fun_name() -> u32 { 2118fn $0fun_name() -> u32 {
2068 2 + 2 2119 2 + 2
2069}", 2120}
2121"#,
2070 ); 2122 );
2071 } 2123 }
2072 2124
@@ -2074,13 +2126,14 @@ fn $0fun_name() -> u32 {
2074 fn break_stmt() { 2126 fn break_stmt() {
2075 check_assist( 2127 check_assist(
2076 extract_function, 2128 extract_function,
2077 r" 2129 r#"
2078fn main() { 2130fn main() {
2079 let result = loop { 2131 let result = loop {
2080 $0break 2 + 2$0; 2132 $0break 2 + 2$0;
2081 }; 2133 };
2082}", 2134}
2083 r" 2135"#,
2136 r#"
2084fn main() { 2137fn main() {
2085 let result = loop { 2138 let result = loop {
2086 break fun_name(); 2139 break fun_name();
@@ -2089,7 +2142,8 @@ fn main() {
2089 2142
2090fn $0fun_name() -> i32 { 2143fn $0fun_name() -> i32 {
2091 2 + 2 2144 2 + 2
2092}", 2145}
2146"#,
2093 ); 2147 );
2094 } 2148 }
2095 2149
@@ -2097,18 +2151,20 @@ fn $0fun_name() -> i32 {
2097 fn extract_cast() { 2151 fn extract_cast() {
2098 check_assist( 2152 check_assist(
2099 extract_function, 2153 extract_function,
2100 r" 2154 r#"
2101fn main() { 2155fn main() {
2102 let v = $00f32 as u32$0; 2156 let v = $00f32 as u32$0;
2103}", 2157}
2104 r" 2158"#,
2159 r#"
2105fn main() { 2160fn main() {
2106 let v = fun_name(); 2161 let v = fun_name();
2107} 2162}
2108 2163
2109fn $0fun_name() -> u32 { 2164fn $0fun_name() -> u32 {
2110 0f32 as u32 2165 0f32 as u32
2111}", 2166}
2167"#,
2112 ); 2168 );
2113 } 2169 }
2114 2170
@@ -2121,15 +2177,16 @@ fn $0fun_name() -> u32 {
2121 fn method_to_freestanding() { 2177 fn method_to_freestanding() {
2122 check_assist( 2178 check_assist(
2123 extract_function, 2179 extract_function,
2124 r" 2180 r#"
2125struct S; 2181struct S;
2126 2182
2127impl S { 2183impl S {
2128 fn foo(&self) -> i32 { 2184 fn foo(&self) -> i32 {
2129 $01+1$0 2185 $01+1$0
2130 } 2186 }
2131}", 2187}
2132 r" 2188"#,
2189 r#"
2133struct S; 2190struct S;
2134 2191
2135impl S { 2192impl S {
@@ -2140,7 +2197,8 @@ impl S {
2140 2197
2141fn $0fun_name() -> i32 { 2198fn $0fun_name() -> i32 {
2142 1+1 2199 1+1
2143}", 2200}
2201"#,
2144 ); 2202 );
2145 } 2203 }
2146 2204
@@ -2148,15 +2206,16 @@ fn $0fun_name() -> i32 {
2148 fn method_with_reference() { 2206 fn method_with_reference() {
2149 check_assist( 2207 check_assist(
2150 extract_function, 2208 extract_function,
2151 r" 2209 r#"
2152struct S { f: i32 }; 2210struct S { f: i32 };
2153 2211
2154impl S { 2212impl S {
2155 fn foo(&self) -> i32 { 2213 fn foo(&self) -> i32 {
2156 $01+self.f$0 2214 $01+self.f$0
2157 } 2215 }
2158}", 2216}
2159 r" 2217"#,
2218 r#"
2160struct S { f: i32 }; 2219struct S { f: i32 };
2161 2220
2162impl S { 2221impl S {
@@ -2167,7 +2226,8 @@ impl S {
2167 fn $0fun_name(&self) -> i32 { 2226 fn $0fun_name(&self) -> i32 {
2168 1+self.f 2227 1+self.f
2169 } 2228 }
2170}", 2229}
2230"#,
2171 ); 2231 );
2172 } 2232 }
2173 2233
@@ -2175,15 +2235,16 @@ impl S {
2175 fn method_with_mut() { 2235 fn method_with_mut() {
2176 check_assist( 2236 check_assist(
2177 extract_function, 2237 extract_function,
2178 r" 2238 r#"
2179struct S { f: i32 }; 2239struct S { f: i32 };
2180 2240
2181impl S { 2241impl S {
2182 fn foo(&mut self) { 2242 fn foo(&mut self) {
2183 $0self.f += 1;$0 2243 $0self.f += 1;$0
2184 } 2244 }
2185}", 2245}
2186 r" 2246"#,
2247 r#"
2187struct S { f: i32 }; 2248struct S { f: i32 };
2188 2249
2189impl S { 2250impl S {
@@ -2194,7 +2255,8 @@ impl S {
2194 fn $0fun_name(&mut self) { 2255 fn $0fun_name(&mut self) {
2195 self.f += 1; 2256 self.f += 1;
2196 } 2257 }
2197}", 2258}
2259"#,
2198 ); 2260 );
2199 } 2261 }
2200 2262
@@ -2202,13 +2264,14 @@ impl S {
2202 fn variable_defined_inside_and_used_after_no_ret() { 2264 fn variable_defined_inside_and_used_after_no_ret() {
2203 check_assist( 2265 check_assist(
2204 extract_function, 2266 extract_function,
2205 r" 2267 r#"
2206fn foo() { 2268fn foo() {
2207 let n = 1; 2269 let n = 1;
2208 $0let k = n * n;$0 2270 $0let k = n * n;$0
2209 let m = k + 1; 2271 let m = k + 1;
2210}", 2272}
2211 r" 2273"#,
2274 r#"
2212fn foo() { 2275fn foo() {
2213 let n = 1; 2276 let n = 1;
2214 let k = fun_name(n); 2277 let k = fun_name(n);
@@ -2218,7 +2281,8 @@ fn foo() {
2218fn $0fun_name(n: i32) -> i32 { 2281fn $0fun_name(n: i32) -> i32 {
2219 let k = n * n; 2282 let k = n * n;
2220 k 2283 k
2221}", 2284}
2285"#,
2222 ); 2286 );
2223 } 2287 }
2224 2288
@@ -2226,13 +2290,14 @@ fn $0fun_name(n: i32) -> i32 {
2226 fn variable_defined_inside_and_used_after_mutably_no_ret() { 2290 fn variable_defined_inside_and_used_after_mutably_no_ret() {
2227 check_assist( 2291 check_assist(
2228 extract_function, 2292 extract_function,
2229 r" 2293 r#"
2230fn foo() { 2294fn foo() {
2231 let n = 1; 2295 let n = 1;
2232 $0let mut k = n * n;$0 2296 $0let mut k = n * n;$0
2233 k += 1; 2297 k += 1;
2234}", 2298}
2235 r" 2299"#,
2300 r#"
2236fn foo() { 2301fn foo() {
2237 let n = 1; 2302 let n = 1;
2238 let mut k = fun_name(n); 2303 let mut k = fun_name(n);
@@ -2242,7 +2307,8 @@ fn foo() {
2242fn $0fun_name(n: i32) -> i32 { 2307fn $0fun_name(n: i32) -> i32 {
2243 let mut k = n * n; 2308 let mut k = n * n;
2244 k 2309 k
2245}", 2310}
2311"#,
2246 ); 2312 );
2247 } 2313 }
2248 2314
@@ -2250,14 +2316,15 @@ fn $0fun_name(n: i32) -> i32 {
2250 fn two_variables_defined_inside_and_used_after_no_ret() { 2316 fn two_variables_defined_inside_and_used_after_no_ret() {
2251 check_assist( 2317 check_assist(
2252 extract_function, 2318 extract_function,
2253 r" 2319 r#"
2254fn foo() { 2320fn foo() {
2255 let n = 1; 2321 let n = 1;
2256 $0let k = n * n; 2322 $0let k = n * n;
2257 let m = k + 2;$0 2323 let m = k + 2;$0
2258 let h = k + m; 2324 let h = k + m;
2259}", 2325}
2260 r" 2326"#,
2327 r#"
2261fn foo() { 2328fn foo() {
2262 let n = 1; 2329 let n = 1;
2263 let (k, m) = fun_name(n); 2330 let (k, m) = fun_name(n);
@@ -2268,7 +2335,8 @@ fn $0fun_name(n: i32) -> (i32, i32) {
2268 let k = n * n; 2335 let k = n * n;
2269 let m = k + 2; 2336 let m = k + 2;
2270 (k, m) 2337 (k, m)
2271}", 2338}
2339"#,
2272 ); 2340 );
2273 } 2341 }
2274 2342
@@ -2276,7 +2344,7 @@ fn $0fun_name(n: i32) -> (i32, i32) {
2276 fn multi_variables_defined_inside_and_used_after_mutably_no_ret() { 2344 fn multi_variables_defined_inside_and_used_after_mutably_no_ret() {
2277 check_assist( 2345 check_assist(
2278 extract_function, 2346 extract_function,
2279 r" 2347 r#"
2280fn foo() { 2348fn foo() {
2281 let n = 1; 2349 let n = 1;
2282 $0let mut k = n * n; 2350 $0let mut k = n * n;
@@ -2285,8 +2353,9 @@ fn foo() {
2285 o += 1;$0 2353 o += 1;$0
2286 k += o; 2354 k += o;
2287 m = 1; 2355 m = 1;
2288}", 2356}
2289 r" 2357"#,
2358 r#"
2290fn foo() { 2359fn foo() {
2291 let n = 1; 2360 let n = 1;
2292 let (mut k, mut m, o) = fun_name(n); 2361 let (mut k, mut m, o) = fun_name(n);
@@ -2300,7 +2369,8 @@ fn $0fun_name(n: i32) -> (i32, i32, i32) {
2300 let mut o = m + 3; 2369 let mut o = m + 3;
2301 o += 1; 2370 o += 1;
2302 (k, m, o) 2371 (k, m, o)
2303}", 2372}
2373"#,
2304 ); 2374 );
2305 } 2375 }
2306 2376
@@ -2308,13 +2378,14 @@ fn $0fun_name(n: i32) -> (i32, i32, i32) {
2308 fn nontrivial_patterns_define_variables() { 2378 fn nontrivial_patterns_define_variables() {
2309 check_assist( 2379 check_assist(
2310 extract_function, 2380 extract_function,
2311 r" 2381 r#"
2312struct Counter(i32); 2382struct Counter(i32);
2313fn foo() { 2383fn foo() {
2314 $0let Counter(n) = Counter(0);$0 2384 $0let Counter(n) = Counter(0);$0
2315 let m = n; 2385 let m = n;
2316}", 2386}
2317 r" 2387"#,
2388 r#"
2318struct Counter(i32); 2389struct Counter(i32);
2319fn foo() { 2390fn foo() {
2320 let n = fun_name(); 2391 let n = fun_name();
@@ -2324,7 +2395,8 @@ fn foo() {
2324fn $0fun_name() -> i32 { 2395fn $0fun_name() -> i32 {
2325 let Counter(n) = Counter(0); 2396 let Counter(n) = Counter(0);
2326 n 2397 n
2327}", 2398}
2399"#,
2328 ); 2400 );
2329 } 2401 }
2330 2402
@@ -2332,13 +2404,14 @@ fn $0fun_name() -> i32 {
2332 fn struct_with_two_fields_pattern_define_variables() { 2404 fn struct_with_two_fields_pattern_define_variables() {
2333 check_assist( 2405 check_assist(
2334 extract_function, 2406 extract_function,
2335 r" 2407 r#"
2336struct Counter { n: i32, m: i32 }; 2408struct Counter { n: i32, m: i32 };
2337fn foo() { 2409fn foo() {
2338 $0let Counter { n, m: k } = Counter { n: 1, m: 2 };$0 2410 $0let Counter { n, m: k } = Counter { n: 1, m: 2 };$0
2339 let h = n + k; 2411 let h = n + k;
2340}", 2412}
2341 r" 2413"#,
2414 r#"
2342struct Counter { n: i32, m: i32 }; 2415struct Counter { n: i32, m: i32 };
2343fn foo() { 2416fn foo() {
2344 let (n, k) = fun_name(); 2417 let (n, k) = fun_name();
@@ -2348,7 +2421,8 @@ fn foo() {
2348fn $0fun_name() -> (i32, i32) { 2421fn $0fun_name() -> (i32, i32) {
2349 let Counter { n, m: k } = Counter { n: 1, m: 2 }; 2422 let Counter { n, m: k } = Counter { n: 1, m: 2 };
2350 (n, k) 2423 (n, k)
2351}", 2424}
2425"#,
2352 ); 2426 );
2353 } 2427 }
2354 2428
@@ -2356,13 +2430,14 @@ fn $0fun_name() -> (i32, i32) {
2356 fn mut_var_from_outer_scope() { 2430 fn mut_var_from_outer_scope() {
2357 check_assist( 2431 check_assist(
2358 extract_function, 2432 extract_function,
2359 r" 2433 r#"
2360fn foo() { 2434fn foo() {
2361 let mut n = 1; 2435 let mut n = 1;
2362 $0n += 1;$0 2436 $0n += 1;$0
2363 let m = n + 1; 2437 let m = n + 1;
2364}", 2438}
2365 r" 2439"#,
2440 r#"
2366fn foo() { 2441fn foo() {
2367 let mut n = 1; 2442 let mut n = 1;
2368 fun_name(&mut n); 2443 fun_name(&mut n);
@@ -2371,7 +2446,8 @@ fn foo() {
2371 2446
2372fn $0fun_name(n: &mut i32) { 2447fn $0fun_name(n: &mut i32) {
2373 *n += 1; 2448 *n += 1;
2374}", 2449}
2450"#,
2375 ); 2451 );
2376 } 2452 }
2377 2453
@@ -2379,14 +2455,15 @@ fn $0fun_name(n: &mut i32) {
2379 fn mut_field_from_outer_scope() { 2455 fn mut_field_from_outer_scope() {
2380 check_assist( 2456 check_assist(
2381 extract_function, 2457 extract_function,
2382 r" 2458 r#"
2383struct C { n: i32 } 2459struct C { n: i32 }
2384fn foo() { 2460fn foo() {
2385 let mut c = C { n: 0 }; 2461 let mut c = C { n: 0 };
2386 $0c.n += 1;$0 2462 $0c.n += 1;$0
2387 let m = c.n + 1; 2463 let m = c.n + 1;
2388}", 2464}
2389 r" 2465"#,
2466 r#"
2390struct C { n: i32 } 2467struct C { n: i32 }
2391fn foo() { 2468fn foo() {
2392 let mut c = C { n: 0 }; 2469 let mut c = C { n: 0 };
@@ -2396,7 +2473,8 @@ fn foo() {
2396 2473
2397fn $0fun_name(c: &mut C) { 2474fn $0fun_name(c: &mut C) {
2398 c.n += 1; 2475 c.n += 1;
2399}", 2476}
2477"#,
2400 ); 2478 );
2401 } 2479 }
2402 2480
@@ -2404,7 +2482,7 @@ fn $0fun_name(c: &mut C) {
2404 fn mut_nested_field_from_outer_scope() { 2482 fn mut_nested_field_from_outer_scope() {
2405 check_assist( 2483 check_assist(
2406 extract_function, 2484 extract_function,
2407 r" 2485 r#"
2408struct P { n: i32} 2486struct P { n: i32}
2409struct C { p: P } 2487struct C { p: P }
2410fn foo() { 2488fn foo() {
@@ -2414,8 +2492,9 @@ fn foo() {
2414 $0c.p.n += u.p.n; 2492 $0c.p.n += u.p.n;
2415 let r = &mut v.p.n;$0 2493 let r = &mut v.p.n;$0
2416 let m = c.p.n + v.p.n + u.p.n; 2494 let m = c.p.n + v.p.n + u.p.n;
2417}", 2495}
2418 r" 2496"#,
2497 r#"
2419struct P { n: i32} 2498struct P { n: i32}
2420struct C { p: P } 2499struct C { p: P }
2421fn foo() { 2500fn foo() {
@@ -2429,7 +2508,8 @@ fn foo() {
2429fn $0fun_name(c: &mut C, u: &C, v: &mut C) { 2508fn $0fun_name(c: &mut C, u: &C, v: &mut C) {
2430 c.p.n += u.p.n; 2509 c.p.n += u.p.n;
2431 let r = &mut v.p.n; 2510 let r = &mut v.p.n;
2432}", 2511}
2512"#,
2433 ); 2513 );
2434 } 2514 }
2435 2515
@@ -2437,7 +2517,7 @@ fn $0fun_name(c: &mut C, u: &C, v: &mut C) {
2437 fn mut_param_many_usages_stmt() { 2517 fn mut_param_many_usages_stmt() {
2438 check_assist( 2518 check_assist(
2439 extract_function, 2519 extract_function,
2440 r" 2520 r#"
2441fn bar(k: i32) {} 2521fn bar(k: i32) {}
2442trait I: Copy { 2522trait I: Copy {
2443 fn succ(&self) -> Self; 2523 fn succ(&self) -> Self;
@@ -2458,8 +2538,9 @@ fn foo() {
2458 *v = v.succ(); 2538 *v = v.succ();
2459 n.succ();$0 2539 n.succ();$0
2460 let m = n + 1; 2540 let m = n + 1;
2461}", 2541}
2462 r" 2542"#,
2543 r#"
2463fn bar(k: i32) {} 2544fn bar(k: i32) {}
2464trait I: Copy { 2545trait I: Copy {
2465 fn succ(&self) -> Self; 2546 fn succ(&self) -> Self;
@@ -2484,7 +2565,8 @@ fn $0fun_name(n: &mut i32) {
2484 let v = n; 2565 let v = n;
2485 *v = v.succ(); 2566 *v = v.succ();
2486 n.succ(); 2567 n.succ();
2487}", 2568}
2569"#,
2488 ); 2570 );
2489 } 2571 }
2490 2572
@@ -2492,7 +2574,7 @@ fn $0fun_name(n: &mut i32) {
2492 fn mut_param_many_usages_expr() { 2574 fn mut_param_many_usages_expr() {
2493 check_assist( 2575 check_assist(
2494 extract_function, 2576 extract_function,
2495 r" 2577 r#"
2496fn bar(k: i32) {} 2578fn bar(k: i32) {}
2497trait I: Copy { 2579trait I: Copy {
2498 fn succ(&self) -> Self; 2580 fn succ(&self) -> Self;
@@ -2515,8 +2597,9 @@ fn foo() {
2515 n.succ(); 2597 n.succ();
2516 }$0 2598 }$0
2517 let m = n + 1; 2599 let m = n + 1;
2518}", 2600}
2519 r" 2601"#,
2602 r#"
2520fn bar(k: i32) {} 2603fn bar(k: i32) {}
2521trait I: Copy { 2604trait I: Copy {
2522 fn succ(&self) -> Self; 2605 fn succ(&self) -> Self;
@@ -2541,7 +2624,8 @@ fn $0fun_name(n: &mut i32) {
2541 let v = n; 2624 let v = n;
2542 *v = v.succ(); 2625 *v = v.succ();
2543 n.succ(); 2626 n.succ();
2544}", 2627}
2628"#,
2545 ); 2629 );
2546 } 2630 }
2547 2631
@@ -2549,11 +2633,12 @@ fn $0fun_name(n: &mut i32) {
2549 fn mut_param_by_value() { 2633 fn mut_param_by_value() {
2550 check_assist( 2634 check_assist(
2551 extract_function, 2635 extract_function,
2552 r" 2636 r#"
2553fn foo() { 2637fn foo() {
2554 let mut n = 1; 2638 let mut n = 1;
2555 $0n += 1;$0 2639 $0n += 1;$0
2556}", 2640}
2641"#,
2557 r" 2642 r"
2558fn foo() { 2643fn foo() {
2559 let mut n = 1; 2644 let mut n = 1;
@@ -2562,7 +2647,8 @@ fn foo() {
2562 2647
2563fn $0fun_name(mut n: i32) { 2648fn $0fun_name(mut n: i32) {
2564 n += 1; 2649 n += 1;
2565}", 2650}
2651",
2566 ); 2652 );
2567 } 2653 }
2568 2654
@@ -2570,14 +2656,15 @@ fn $0fun_name(mut n: i32) {
2570 fn mut_param_because_of_mut_ref() { 2656 fn mut_param_because_of_mut_ref() {
2571 check_assist( 2657 check_assist(
2572 extract_function, 2658 extract_function,
2573 r" 2659 r#"
2574fn foo() { 2660fn foo() {
2575 let mut n = 1; 2661 let mut n = 1;
2576 $0let v = &mut n; 2662 $0let v = &mut n;
2577 *v += 1;$0 2663 *v += 1;$0
2578 let k = n; 2664 let k = n;
2579}", 2665}
2580 r" 2666"#,
2667 r#"
2581fn foo() { 2668fn foo() {
2582 let mut n = 1; 2669 let mut n = 1;
2583 fun_name(&mut n); 2670 fun_name(&mut n);
@@ -2587,7 +2674,8 @@ fn foo() {
2587fn $0fun_name(n: &mut i32) { 2674fn $0fun_name(n: &mut i32) {
2588 let v = n; 2675 let v = n;
2589 *v += 1; 2676 *v += 1;
2590}", 2677}
2678"#,
2591 ); 2679 );
2592 } 2680 }
2593 2681
@@ -2600,8 +2688,9 @@ fn foo() {
2600 let mut n = 1; 2688 let mut n = 1;
2601 $0let v = &mut n; 2689 $0let v = &mut n;
2602 *v += 1;$0 2690 *v += 1;$0
2603}", 2691}
2604 r" 2692",
2693 r#"
2605fn foo() { 2694fn foo() {
2606 let mut n = 1; 2695 let mut n = 1;
2607 fun_name(n); 2696 fun_name(n);
@@ -2610,7 +2699,8 @@ fn foo() {
2610fn $0fun_name(mut n: i32) { 2699fn $0fun_name(mut n: i32) {
2611 let v = &mut n; 2700 let v = &mut n;
2612 *v += 1; 2701 *v += 1;
2613}", 2702}
2703"#,
2614 ); 2704 );
2615 } 2705 }
2616 2706
@@ -2618,7 +2708,7 @@ fn $0fun_name(mut n: i32) {
2618 fn mut_method_call() { 2708 fn mut_method_call() {
2619 check_assist( 2709 check_assist(
2620 extract_function, 2710 extract_function,
2621 r" 2711 r#"
2622trait I { 2712trait I {
2623 fn inc(&mut self); 2713 fn inc(&mut self);
2624} 2714}
@@ -2628,8 +2718,9 @@ impl I for i32 {
2628fn foo() { 2718fn foo() {
2629 let mut n = 1; 2719 let mut n = 1;
2630 $0n.inc();$0 2720 $0n.inc();$0
2631}", 2721}
2632 r" 2722"#,
2723 r#"
2633trait I { 2724trait I {
2634 fn inc(&mut self); 2725 fn inc(&mut self);
2635} 2726}
@@ -2643,7 +2734,8 @@ fn foo() {
2643 2734
2644fn $0fun_name(mut n: i32) { 2735fn $0fun_name(mut n: i32) {
2645 n.inc(); 2736 n.inc();
2646}", 2737}
2738"#,
2647 ); 2739 );
2648 } 2740 }
2649 2741
@@ -2651,7 +2743,7 @@ fn $0fun_name(mut n: i32) {
2651 fn shared_method_call() { 2743 fn shared_method_call() {
2652 check_assist( 2744 check_assist(
2653 extract_function, 2745 extract_function,
2654 r" 2746 r#"
2655trait I { 2747trait I {
2656 fn succ(&self); 2748 fn succ(&self);
2657} 2749}
@@ -2661,7 +2753,8 @@ impl I for i32 {
2661fn foo() { 2753fn foo() {
2662 let mut n = 1; 2754 let mut n = 1;
2663 $0n.succ();$0 2755 $0n.succ();$0
2664}", 2756}
2757"#,
2665 r" 2758 r"
2666trait I { 2759trait I {
2667 fn succ(&self); 2760 fn succ(&self);
@@ -2676,7 +2769,8 @@ fn foo() {
2676 2769
2677fn $0fun_name(n: i32) { 2770fn $0fun_name(n: i32) {
2678 n.succ(); 2771 n.succ();
2679}", 2772}
2773",
2680 ); 2774 );
2681 } 2775 }
2682 2776
@@ -2684,7 +2778,7 @@ fn $0fun_name(n: i32) {
2684 fn mut_method_call_with_other_receiver() { 2778 fn mut_method_call_with_other_receiver() {
2685 check_assist( 2779 check_assist(
2686 extract_function, 2780 extract_function,
2687 r" 2781 r#"
2688trait I { 2782trait I {
2689 fn inc(&mut self, n: i32); 2783 fn inc(&mut self, n: i32);
2690} 2784}
@@ -2695,7 +2789,8 @@ fn foo() {
2695 let mut n = 1; 2789 let mut n = 1;
2696 $0let mut m = 2; 2790 $0let mut m = 2;
2697 m.inc(n);$0 2791 m.inc(n);$0
2698}", 2792}
2793"#,
2699 r" 2794 r"
2700trait I { 2795trait I {
2701 fn inc(&mut self, n: i32); 2796 fn inc(&mut self, n: i32);
@@ -2711,7 +2806,8 @@ fn foo() {
2711fn $0fun_name(n: i32) { 2806fn $0fun_name(n: i32) {
2712 let mut m = 2; 2807 let mut m = 2;
2713 m.inc(n); 2808 m.inc(n);
2714}", 2809}
2810",
2715 ); 2811 );
2716 } 2812 }
2717 2813
@@ -2719,12 +2815,13 @@ fn $0fun_name(n: i32) {
2719 fn non_copy_without_usages_after() { 2815 fn non_copy_without_usages_after() {
2720 check_assist( 2816 check_assist(
2721 extract_function, 2817 extract_function,
2722 r" 2818 r#"
2723struct Counter(i32); 2819struct Counter(i32);
2724fn foo() { 2820fn foo() {
2725 let c = Counter(0); 2821 let c = Counter(0);
2726 $0let n = c.0;$0 2822 $0let n = c.0;$0
2727}", 2823}
2824"#,
2728 r" 2825 r"
2729struct Counter(i32); 2826struct Counter(i32);
2730fn foo() { 2827fn foo() {
@@ -2734,7 +2831,8 @@ fn foo() {
2734 2831
2735fn $0fun_name(c: Counter) { 2832fn $0fun_name(c: Counter) {
2736 let n = c.0; 2833 let n = c.0;
2737}", 2834}
2835",
2738 ); 2836 );
2739 } 2837 }
2740 2838
@@ -2748,8 +2846,9 @@ fn foo() {
2748 let c = Counter(0); 2846 let c = Counter(0);
2749 $0let n = c.0;$0 2847 $0let n = c.0;$0
2750 let m = c.0; 2848 let m = c.0;
2751}", 2849}
2752 r" 2850",
2851 r#"
2753struct Counter(i32); 2852struct Counter(i32);
2754fn foo() { 2853fn foo() {
2755 let c = Counter(0); 2854 let c = Counter(0);
@@ -2759,7 +2858,8 @@ fn foo() {
2759 2858
2760fn $0fun_name(c: &Counter) { 2859fn $0fun_name(c: &Counter) {
2761 let n = c.0; 2860 let n = c.0;
2762}", 2861}
2862"#,
2763 ); 2863 );
2764 } 2864 }
2765 2865
@@ -2767,19 +2867,15 @@ fn $0fun_name(c: &Counter) {
2767 fn copy_used_after() { 2867 fn copy_used_after() {
2768 check_assist( 2868 check_assist(
2769 extract_function, 2869 extract_function,
2770 r##" 2870 r#"
2771#[lang = "copy"] 2871//- minicore: copy
2772pub trait Copy {}
2773impl Copy for i32 {}
2774fn foo() { 2872fn foo() {
2775 let n = 0; 2873 let n = 0;
2776 $0let m = n;$0 2874 $0let m = n;$0
2777 let k = n; 2875 let k = n;
2778}"##, 2876}
2779 r##" 2877"#,
2780#[lang = "copy"] 2878 r#"
2781pub trait Copy {}
2782impl Copy for i32 {}
2783fn foo() { 2879fn foo() {
2784 let n = 0; 2880 let n = 0;
2785 fun_name(n); 2881 fun_name(n);
@@ -2788,7 +2884,8 @@ fn foo() {
2788 2884
2789fn $0fun_name(n: i32) { 2885fn $0fun_name(n: i32) {
2790 let m = n; 2886 let m = n;
2791}"##, 2887}
2888"#,
2792 ) 2889 )
2793 } 2890 }
2794 2891
@@ -2796,21 +2893,19 @@ fn $0fun_name(n: i32) {
2796 fn copy_custom_used_after() { 2893 fn copy_custom_used_after() {
2797 check_assist( 2894 check_assist(
2798 extract_function, 2895 extract_function,
2799 r##" 2896 r#"
2800#[lang = "copy"] 2897//- minicore: copy, derive
2801pub trait Copy {} 2898#[derive(Clone, Copy)]
2802struct Counter(i32); 2899struct Counter(i32);
2803impl Copy for Counter {}
2804fn foo() { 2900fn foo() {
2805 let c = Counter(0); 2901 let c = Counter(0);
2806 $0let n = c.0;$0 2902 $0let n = c.0;$0
2807 let m = c.0; 2903 let m = c.0;
2808}"##, 2904}
2809 r##" 2905"#,
2810#[lang = "copy"] 2906 r#"
2811pub trait Copy {} 2907#[derive(Clone, Copy)]
2812struct Counter(i32); 2908struct Counter(i32);
2813impl Copy for Counter {}
2814fn foo() { 2909fn foo() {
2815 let c = Counter(0); 2910 let c = Counter(0);
2816 fun_name(c); 2911 fun_name(c);
@@ -2819,7 +2914,8 @@ fn foo() {
2819 2914
2820fn $0fun_name(c: Counter) { 2915fn $0fun_name(c: Counter) {
2821 let n = c.0; 2916 let n = c.0;
2822}"##, 2917}
2918"#,
2823 ); 2919 );
2824 } 2920 }
2825 2921
@@ -2827,7 +2923,7 @@ fn $0fun_name(c: Counter) {
2827 fn indented_stmts() { 2923 fn indented_stmts() {
2828 check_assist( 2924 check_assist(
2829 extract_function, 2925 extract_function,
2830 r" 2926 r#"
2831fn foo() { 2927fn foo() {
2832 if true { 2928 if true {
2833 loop { 2929 loop {
@@ -2835,8 +2931,9 @@ fn foo() {
2835 let m = 2;$0 2931 let m = 2;$0
2836 } 2932 }
2837 } 2933 }
2838}", 2934}
2839 r" 2935"#,
2936 r#"
2840fn foo() { 2937fn foo() {
2841 if true { 2938 if true {
2842 loop { 2939 loop {
@@ -2848,7 +2945,8 @@ fn foo() {
2848fn $0fun_name() { 2945fn $0fun_name() {
2849 let n = 1; 2946 let n = 1;
2850 let m = 2; 2947 let m = 2;
2851}", 2948}
2949"#,
2852 ); 2950 );
2853 } 2951 }
2854 2952
@@ -2856,7 +2954,7 @@ fn $0fun_name() {
2856 fn indented_stmts_inside_mod() { 2954 fn indented_stmts_inside_mod() {
2857 check_assist( 2955 check_assist(
2858 extract_function, 2956 extract_function,
2859 r" 2957 r#"
2860mod bar { 2958mod bar {
2861 fn foo() { 2959 fn foo() {
2862 if true { 2960 if true {
@@ -2866,8 +2964,9 @@ mod bar {
2866 } 2964 }
2867 } 2965 }
2868 } 2966 }
2869}", 2967}
2870 r" 2968"#,
2969 r#"
2871mod bar { 2970mod bar {
2872 fn foo() { 2971 fn foo() {
2873 if true { 2972 if true {
@@ -2881,7 +2980,8 @@ mod bar {
2881 let n = 1; 2980 let n = 1;
2882 let m = 2; 2981 let m = 2;
2883 } 2982 }
2884}", 2983}
2984"#,
2885 ); 2985 );
2886 } 2986 }
2887 2987
@@ -2889,12 +2989,8 @@ mod bar {
2889 fn break_loop() { 2989 fn break_loop() {
2890 check_assist( 2990 check_assist(
2891 extract_function, 2991 extract_function,
2892 r##" 2992 r#"
2893enum Option<T> { 2993//- minicore: option
2894 #[lang = "None"] None,
2895 #[lang = "Some"] Some(T),
2896}
2897use Option::*;
2898fn foo() { 2994fn foo() {
2899 loop { 2995 loop {
2900 let n = 1; 2996 let n = 1;
@@ -2903,13 +2999,9 @@ fn foo() {
2903 let k = 2;$0 2999 let k = 2;$0
2904 let h = 1 + k; 3000 let h = 1 + k;
2905 } 3001 }
2906}"##,
2907 r##"
2908enum Option<T> {
2909 #[lang = "None"] None,
2910 #[lang = "Some"] Some(T),
2911} 3002}
2912use Option::*; 3003"#,
3004 r#"
2913fn foo() { 3005fn foo() {
2914 loop { 3006 loop {
2915 let n = 1; 3007 let n = 1;
@@ -2926,7 +3018,8 @@ fn $0fun_name(n: i32) -> Option<i32> {
2926 return None; 3018 return None;
2927 let k = 2; 3019 let k = 2;
2928 Some(k) 3020 Some(k)
2929}"##, 3021}
3022"#,
2930 ); 3023 );
2931 } 3024 }
2932 3025
@@ -2934,31 +3027,17 @@ fn $0fun_name(n: i32) -> Option<i32> {
2934 fn return_to_parent() { 3027 fn return_to_parent() {
2935 check_assist( 3028 check_assist(
2936 extract_function, 3029 extract_function,
2937 r##" 3030 r#"
2938#[lang = "copy"] 3031//- minicore: copy, result
2939pub trait Copy {}
2940impl Copy for i32 {}
2941enum Result<T, E> {
2942 #[lang = "Ok"] Ok(T),
2943 #[lang = "Err"] Err(E),
2944}
2945use Result::*;
2946fn foo() -> i64 { 3032fn foo() -> i64 {
2947 let n = 1; 3033 let n = 1;
2948 $0let m = n + 1; 3034 $0let m = n + 1;
2949 return 1; 3035 return 1;
2950 let k = 2;$0 3036 let k = 2;$0
2951 (n + k) as i64 3037 (n + k) as i64
2952}"##, 3038}
2953 r##" 3039"#,
2954#[lang = "copy"] 3040 r#"
2955pub trait Copy {}
2956impl Copy for i32 {}
2957enum Result<T, E> {
2958 #[lang = "Ok"] Ok(T),
2959 #[lang = "Err"] Err(E),
2960}
2961use Result::*;
2962fn foo() -> i64 { 3041fn foo() -> i64 {
2963 let n = 1; 3042 let n = 1;
2964 let k = match fun_name(n) { 3043 let k = match fun_name(n) {
@@ -2973,7 +3052,8 @@ fn $0fun_name(n: i32) -> Result<i32, i64> {
2973 return Err(1); 3052 return Err(1);
2974 let k = 2; 3053 let k = 2;
2975 Ok(k) 3054 Ok(k)
2976}"##, 3055}
3056"#,
2977 ); 3057 );
2978 } 3058 }
2979 3059
@@ -2982,7 +3062,7 @@ fn $0fun_name(n: i32) -> Result<i32, i64> {
2982 cov_mark::check!(external_control_flow_break_and_continue); 3062 cov_mark::check!(external_control_flow_break_and_continue);
2983 check_assist_not_applicable( 3063 check_assist_not_applicable(
2984 extract_function, 3064 extract_function,
2985 r##" 3065 r#"
2986fn foo() { 3066fn foo() {
2987 loop { 3067 loop {
2988 let n = 1; 3068 let n = 1;
@@ -2993,7 +3073,8 @@ fn foo() {
2993 let k = k + 1;$0 3073 let k = k + 1;$0
2994 let r = n + k; 3074 let r = n + k;
2995 } 3075 }
2996}"##, 3076}
3077"#,
2997 ); 3078 );
2998 } 3079 }
2999 3080
@@ -3002,7 +3083,7 @@ fn foo() {
3002 cov_mark::check!(external_control_flow_return_and_bc); 3083 cov_mark::check!(external_control_flow_return_and_bc);
3003 check_assist_not_applicable( 3084 check_assist_not_applicable(
3004 extract_function, 3085 extract_function,
3005 r##" 3086 r#"
3006fn foo() { 3087fn foo() {
3007 loop { 3088 loop {
3008 let n = 1; 3089 let n = 1;
@@ -3013,7 +3094,8 @@ fn foo() {
3013 let k = k + 1;$0 3094 let k = k + 1;$0
3014 let r = n + k; 3095 let r = n + k;
3015 } 3096 }
3016}"##, 3097}
3098"#,
3017 ); 3099 );
3018 } 3100 }
3019 3101
@@ -3021,7 +3103,7 @@ fn foo() {
3021 fn break_loop_with_if() { 3103 fn break_loop_with_if() {
3022 check_assist( 3104 check_assist(
3023 extract_function, 3105 extract_function,
3024 r##" 3106 r#"
3025fn foo() { 3107fn foo() {
3026 loop { 3108 loop {
3027 let mut n = 1; 3109 let mut n = 1;
@@ -3030,8 +3112,9 @@ fn foo() {
3030 n += m;$0 3112 n += m;$0
3031 let h = 1 + n; 3113 let h = 1 + n;
3032 } 3114 }
3033}"##, 3115}
3034 r##" 3116"#,
3117 r#"
3035fn foo() { 3118fn foo() {
3036 loop { 3119 loop {
3037 let mut n = 1; 3120 let mut n = 1;
@@ -3047,7 +3130,8 @@ fn $0fun_name(n: &mut i32) -> bool {
3047 return true; 3130 return true;
3048 *n += m; 3131 *n += m;
3049 false 3132 false
3050}"##, 3133}
3134"#,
3051 ); 3135 );
3052 } 3136 }
3053 3137
@@ -3055,7 +3139,7 @@ fn $0fun_name(n: &mut i32) -> bool {
3055 fn break_loop_nested() { 3139 fn break_loop_nested() {
3056 check_assist( 3140 check_assist(
3057 extract_function, 3141 extract_function,
3058 r##" 3142 r#"
3059fn foo() { 3143fn foo() {
3060 loop { 3144 loop {
3061 let mut n = 1; 3145 let mut n = 1;
@@ -3065,8 +3149,9 @@ fn foo() {
3065 }$0 3149 }$0
3066 let h = 1; 3150 let h = 1;
3067 } 3151 }
3068}"##, 3152}
3069 r##" 3153"#,
3154 r#"
3070fn foo() { 3155fn foo() {
3071 loop { 3156 loop {
3072 let mut n = 1; 3157 let mut n = 1;
@@ -3083,7 +3168,8 @@ fn $0fun_name(n: i32) -> bool {
3083 return true; 3168 return true;
3084 } 3169 }
3085 false 3170 false
3086}"##, 3171}
3172"#,
3087 ); 3173 );
3088 } 3174 }
3089 3175
@@ -3091,7 +3177,7 @@ fn $0fun_name(n: i32) -> bool {
3091 fn return_from_nested_loop() { 3177 fn return_from_nested_loop() {
3092 check_assist( 3178 check_assist(
3093 extract_function, 3179 extract_function,
3094 r##" 3180 r#"
3095fn foo() { 3181fn foo() {
3096 loop { 3182 loop {
3097 let n = 1; 3183 let n = 1;
@@ -3103,8 +3189,9 @@ fn foo() {
3103 let m = k + 1;$0 3189 let m = k + 1;$0
3104 let h = 1 + m; 3190 let h = 1 + m;
3105 } 3191 }
3106}"##, 3192}
3107 r##" 3193"#,
3194 r#"
3108fn foo() { 3195fn foo() {
3109 loop { 3196 loop {
3110 let n = 1; 3197 let n = 1;
@@ -3123,7 +3210,8 @@ fn $0fun_name() -> Option<i32> {
3123 } 3210 }
3124 let m = k + 1; 3211 let m = k + 1;
3125 Some(m) 3212 Some(m)
3126}"##, 3213}
3214"#,
3127 ); 3215 );
3128 } 3216 }
3129 3217
@@ -3131,7 +3219,7 @@ fn $0fun_name() -> Option<i32> {
3131 fn break_from_nested_loop() { 3219 fn break_from_nested_loop() {
3132 check_assist( 3220 check_assist(
3133 extract_function, 3221 extract_function,
3134 r##" 3222 r#"
3135fn foo() { 3223fn foo() {
3136 loop { 3224 loop {
3137 let n = 1; 3225 let n = 1;
@@ -3142,8 +3230,9 @@ fn foo() {
3142 let m = k + 1;$0 3230 let m = k + 1;$0
3143 let h = 1 + m; 3231 let h = 1 + m;
3144 } 3232 }
3145}"##, 3233}
3146 r##" 3234"#,
3235 r#"
3147fn foo() { 3236fn foo() {
3148 loop { 3237 loop {
3149 let n = 1; 3238 let n = 1;
@@ -3159,7 +3248,8 @@ fn $0fun_name() -> i32 {
3159 } 3248 }
3160 let m = k + 1; 3249 let m = k + 1;
3161 m 3250 m
3162}"##, 3251}
3252"#,
3163 ); 3253 );
3164 } 3254 }
3165 3255
@@ -3167,7 +3257,7 @@ fn $0fun_name() -> i32 {
3167 fn break_from_nested_and_outer_loops() { 3257 fn break_from_nested_and_outer_loops() {
3168 check_assist( 3258 check_assist(
3169 extract_function, 3259 extract_function,
3170 r##" 3260 r#"
3171fn foo() { 3261fn foo() {
3172 loop { 3262 loop {
3173 let n = 1; 3263 let n = 1;
@@ -3181,8 +3271,9 @@ fn foo() {
3181 let m = k + 1;$0 3271 let m = k + 1;$0
3182 let h = 1 + m; 3272 let h = 1 + m;
3183 } 3273 }
3184}"##, 3274}
3185 r##" 3275"#,
3276 r#"
3186fn foo() { 3277fn foo() {
3187 loop { 3278 loop {
3188 let n = 1; 3279 let n = 1;
@@ -3204,7 +3295,8 @@ fn $0fun_name() -> Option<i32> {
3204 } 3295 }
3205 let m = k + 1; 3296 let m = k + 1;
3206 Some(m) 3297 Some(m)
3207}"##, 3298}
3299"#,
3208 ); 3300 );
3209 } 3301 }
3210 3302
@@ -3212,7 +3304,7 @@ fn $0fun_name() -> Option<i32> {
3212 fn return_from_nested_fn() { 3304 fn return_from_nested_fn() {
3213 check_assist( 3305 check_assist(
3214 extract_function, 3306 extract_function,
3215 r##" 3307 r#"
3216fn foo() { 3308fn foo() {
3217 loop { 3309 loop {
3218 let n = 1; 3310 let n = 1;
@@ -3223,8 +3315,9 @@ fn foo() {
3223 let m = k + 1;$0 3315 let m = k + 1;$0
3224 let h = 1 + m; 3316 let h = 1 + m;
3225 } 3317 }
3226}"##, 3318}
3227 r##" 3319"#,
3320 r#"
3228fn foo() { 3321fn foo() {
3229 loop { 3322 loop {
3230 let n = 1; 3323 let n = 1;
@@ -3240,7 +3333,8 @@ fn $0fun_name() -> i32 {
3240 } 3333 }
3241 let m = k + 1; 3334 let m = k + 1;
3242 m 3335 m
3243}"##, 3336}
3337"#,
3244 ); 3338 );
3245 } 3339 }
3246 3340
@@ -3248,7 +3342,7 @@ fn $0fun_name() -> i32 {
3248 fn break_with_value() { 3342 fn break_with_value() {
3249 check_assist( 3343 check_assist(
3250 extract_function, 3344 extract_function,
3251 r##" 3345 r#"
3252fn foo() -> i32 { 3346fn foo() -> i32 {
3253 loop { 3347 loop {
3254 let n = 1; 3348 let n = 1;
@@ -3259,8 +3353,9 @@ fn foo() -> i32 {
3259 let m = k + 1;$0 3353 let m = k + 1;$0
3260 let h = 1; 3354 let h = 1;
3261 } 3355 }
3262}"##, 3356}
3263 r##" 3357"#,
3358 r#"
3264fn foo() -> i32 { 3359fn foo() -> i32 {
3265 loop { 3360 loop {
3266 let n = 1; 3361 let n = 1;
@@ -3278,7 +3373,8 @@ fn $0fun_name() -> Option<i32> {
3278 } 3373 }
3279 let m = k + 1; 3374 let m = k + 1;
3280 None 3375 None
3281}"##, 3376}
3377"#,
3282 ); 3378 );
3283 } 3379 }
3284 3380
@@ -3286,7 +3382,7 @@ fn $0fun_name() -> Option<i32> {
3286 fn break_with_value_and_return() { 3382 fn break_with_value_and_return() {
3287 check_assist( 3383 check_assist(
3288 extract_function, 3384 extract_function,
3289 r##" 3385 r#"
3290fn foo() -> i64 { 3386fn foo() -> i64 {
3291 loop { 3387 loop {
3292 let n = 1; 3388 let n = 1;
@@ -3298,8 +3394,9 @@ fn foo() -> i64 {
3298 let m = k + 1;$0 3394 let m = k + 1;$0
3299 let h = 1 + m; 3395 let h = 1 + m;
3300 } 3396 }
3301}"##, 3397}
3302 r##" 3398"#,
3399 r#"
3303fn foo() -> i64 { 3400fn foo() -> i64 {
3304 loop { 3401 loop {
3305 let n = 1; 3402 let n = 1;
@@ -3318,7 +3415,8 @@ fn $0fun_name() -> Result<i32, i64> {
3318 } 3415 }
3319 let m = k + 1; 3416 let m = k + 1;
3320 Ok(m) 3417 Ok(m)
3321}"##, 3418}
3419"#,
3322 ); 3420 );
3323 } 3421 }
3324 3422
@@ -3326,9 +3424,8 @@ fn $0fun_name() -> Result<i32, i64> {
3326 fn try_option() { 3424 fn try_option() {
3327 check_assist( 3425 check_assist(
3328 extract_function, 3426 extract_function,
3329 r##" 3427 r#"
3330enum Option<T> { None, Some(T), } 3428//- minicore: option
3331use Option::*;
3332fn bar() -> Option<i32> { None } 3429fn bar() -> Option<i32> { None }
3333fn foo() -> Option<()> { 3430fn foo() -> Option<()> {
3334 let n = bar()?; 3431 let n = bar()?;
@@ -3336,10 +3433,9 @@ fn foo() -> Option<()> {
3336 let m = k + 1;$0 3433 let m = k + 1;$0
3337 let h = 1 + m; 3434 let h = 1 + m;
3338 Some(()) 3435 Some(())
3339}"##, 3436}
3340 r##" 3437"#,
3341enum Option<T> { None, Some(T), } 3438 r#"
3342use Option::*;
3343fn bar() -> Option<i32> { None } 3439fn bar() -> Option<i32> { None }
3344fn foo() -> Option<()> { 3440fn foo() -> Option<()> {
3345 let n = bar()?; 3441 let n = bar()?;
@@ -3352,7 +3448,8 @@ fn $0fun_name() -> Option<i32> {
3352 let k = foo()?; 3448 let k = foo()?;
3353 let m = k + 1; 3449 let m = k + 1;
3354 Some(m) 3450 Some(m)
3355}"##, 3451}
3452"#,
3356 ); 3453 );
3357 } 3454 }
3358 3455
@@ -3360,19 +3457,17 @@ fn $0fun_name() -> Option<i32> {
3360 fn try_option_unit() { 3457 fn try_option_unit() {
3361 check_assist( 3458 check_assist(
3362 extract_function, 3459 extract_function,
3363 r##" 3460 r#"
3364enum Option<T> { None, Some(T), } 3461//- minicore: option
3365use Option::*;
3366fn foo() -> Option<()> { 3462fn foo() -> Option<()> {
3367 let n = 1; 3463 let n = 1;
3368 $0let k = foo()?; 3464 $0let k = foo()?;
3369 let m = k + 1;$0 3465 let m = k + 1;$0
3370 let h = 1 + n; 3466 let h = 1 + n;
3371 Some(()) 3467 Some(())
3372}"##, 3468}
3373 r##" 3469"#,
3374enum Option<T> { None, Some(T), } 3470 r#"
3375use Option::*;
3376fn foo() -> Option<()> { 3471fn foo() -> Option<()> {
3377 let n = 1; 3472 let n = 1;
3378 fun_name()?; 3473 fun_name()?;
@@ -3384,7 +3479,8 @@ fn $0fun_name() -> Option<()> {
3384 let k = foo()?; 3479 let k = foo()?;
3385 let m = k + 1; 3480 let m = k + 1;
3386 Some(()) 3481 Some(())
3387}"##, 3482}
3483"#,
3388 ); 3484 );
3389 } 3485 }
3390 3486
@@ -3392,19 +3488,17 @@ fn $0fun_name() -> Option<()> {
3392 fn try_result() { 3488 fn try_result() {
3393 check_assist( 3489 check_assist(
3394 extract_function, 3490 extract_function,
3395 r##" 3491 r#"
3396enum Result<T, E> { Ok(T), Err(E), } 3492//- minicore: result
3397use Result::*;
3398fn foo() -> Result<(), i64> { 3493fn foo() -> Result<(), i64> {
3399 let n = 1; 3494 let n = 1;
3400 $0let k = foo()?; 3495 $0let k = foo()?;
3401 let m = k + 1;$0 3496 let m = k + 1;$0
3402 let h = 1 + m; 3497 let h = 1 + m;
3403 Ok(()) 3498 Ok(())
3404}"##, 3499}
3405 r##" 3500"#,
3406enum Result<T, E> { Ok(T), Err(E), } 3501 r#"
3407use Result::*;
3408fn foo() -> Result<(), i64> { 3502fn foo() -> Result<(), i64> {
3409 let n = 1; 3503 let n = 1;
3410 let m = fun_name()?; 3504 let m = fun_name()?;
@@ -3416,7 +3510,8 @@ fn $0fun_name() -> Result<i32, i64> {
3416 let k = foo()?; 3510 let k = foo()?;
3417 let m = k + 1; 3511 let m = k + 1;
3418 Ok(m) 3512 Ok(m)
3419}"##, 3513}
3514"#,
3420 ); 3515 );
3421 } 3516 }
3422 3517
@@ -3424,9 +3519,8 @@ fn $0fun_name() -> Result<i32, i64> {
3424 fn try_option_with_return() { 3519 fn try_option_with_return() {
3425 check_assist( 3520 check_assist(
3426 extract_function, 3521 extract_function,
3427 r##" 3522 r#"
3428enum Option<T> { None, Some(T) } 3523//- minicore: option
3429use Option::*;
3430fn foo() -> Option<()> { 3524fn foo() -> Option<()> {
3431 let n = 1; 3525 let n = 1;
3432 $0let k = foo()?; 3526 $0let k = foo()?;
@@ -3436,10 +3530,9 @@ fn foo() -> Option<()> {
3436 let m = k + 1;$0 3530 let m = k + 1;$0
3437 let h = 1 + m; 3531 let h = 1 + m;
3438 Some(()) 3532 Some(())
3439}"##, 3533}
3440 r##" 3534"#,
3441enum Option<T> { None, Some(T) } 3535 r#"
3442use Option::*;
3443fn foo() -> Option<()> { 3536fn foo() -> Option<()> {
3444 let n = 1; 3537 let n = 1;
3445 let m = fun_name()?; 3538 let m = fun_name()?;
@@ -3454,7 +3547,8 @@ fn $0fun_name() -> Option<i32> {
3454 } 3547 }
3455 let m = k + 1; 3548 let m = k + 1;
3456 Some(m) 3549 Some(m)
3457}"##, 3550}
3551"#,
3458 ); 3552 );
3459 } 3553 }
3460 3554
@@ -3462,9 +3556,8 @@ fn $0fun_name() -> Option<i32> {
3462 fn try_result_with_return() { 3556 fn try_result_with_return() {
3463 check_assist( 3557 check_assist(
3464 extract_function, 3558 extract_function,
3465 r##" 3559 r#"
3466enum Result<T, E> { Ok(T), Err(E), } 3560//- minicore: result
3467use Result::*;
3468fn foo() -> Result<(), i64> { 3561fn foo() -> Result<(), i64> {
3469 let n = 1; 3562 let n = 1;
3470 $0let k = foo()?; 3563 $0let k = foo()?;
@@ -3474,10 +3567,9 @@ fn foo() -> Result<(), i64> {
3474 let m = k + 1;$0 3567 let m = k + 1;$0
3475 let h = 1 + m; 3568 let h = 1 + m;
3476 Ok(()) 3569 Ok(())
3477}"##, 3570}
3478 r##" 3571"#,
3479enum Result<T, E> { Ok(T), Err(E), } 3572 r#"
3480use Result::*;
3481fn foo() -> Result<(), i64> { 3573fn foo() -> Result<(), i64> {
3482 let n = 1; 3574 let n = 1;
3483 let m = fun_name()?; 3575 let m = fun_name()?;
@@ -3492,7 +3584,8 @@ fn $0fun_name() -> Result<i32, i64> {
3492 } 3584 }
3493 let m = k + 1; 3585 let m = k + 1;
3494 Ok(m) 3586 Ok(m)
3495}"##, 3587}
3588"#,
3496 ); 3589 );
3497 } 3590 }
3498 3591
@@ -3501,9 +3594,8 @@ fn $0fun_name() -> Result<i32, i64> {
3501 cov_mark::check!(external_control_flow_try_and_bc); 3594 cov_mark::check!(external_control_flow_try_and_bc);
3502 check_assist_not_applicable( 3595 check_assist_not_applicable(
3503 extract_function, 3596 extract_function,
3504 r##" 3597 r#"
3505enum Option<T> { None, Some(T) } 3598//- minicore: option
3506use Option::*;
3507fn foo() -> Option<()> { 3599fn foo() -> Option<()> {
3508 loop { 3600 loop {
3509 let n = Some(1); 3601 let n = Some(1);
@@ -3514,7 +3606,8 @@ fn foo() -> Option<()> {
3514 let r = n + k; 3606 let r = n + k;
3515 } 3607 }
3516 Some(()) 3608 Some(())
3517}"##, 3609}
3610"#,
3518 ); 3611 );
3519 } 3612 }
3520 3613
@@ -3523,9 +3616,8 @@ fn foo() -> Option<()> {
3523 cov_mark::check!(external_control_flow_try_and_return_non_err); 3616 cov_mark::check!(external_control_flow_try_and_return_non_err);
3524 check_assist_not_applicable( 3617 check_assist_not_applicable(
3525 extract_function, 3618 extract_function,
3526 r##" 3619 r#"
3527enum Result<T, E> { Ok(T), Err(E), } 3620//- minicore: result
3528use Result::*;
3529fn foo() -> Result<(), i64> { 3621fn foo() -> Result<(), i64> {
3530 let n = 1; 3622 let n = 1;
3531 $0let k = foo()?; 3623 $0let k = foo()?;
@@ -3535,7 +3627,8 @@ fn foo() -> Result<(), i64> {
3535 let m = k + 1;$0 3627 let m = k + 1;$0
3536 let h = 1 + m; 3628 let h = 1 + m;
3537 Ok(()) 3629 Ok(())
3538}"##, 3630}
3631"#,
3539 ); 3632 );
3540 } 3633 }
3541 3634
@@ -3543,7 +3636,7 @@ fn foo() -> Result<(), i64> {
3543 fn param_usage_in_macro() { 3636 fn param_usage_in_macro() {
3544 check_assist( 3637 check_assist(
3545 extract_function, 3638 extract_function,
3546 r" 3639 r#"
3547macro_rules! m { 3640macro_rules! m {
3548 ($val:expr) => { $val }; 3641 ($val:expr) => { $val };
3549} 3642}
@@ -3552,8 +3645,9 @@ fn foo() {
3552 let n = 1; 3645 let n = 1;
3553 $0let k = n * m!(n);$0 3646 $0let k = n * m!(n);$0
3554 let m = k + 1; 3647 let m = k + 1;
3555}", 3648}
3556 r" 3649"#,
3650 r#"
3557macro_rules! m { 3651macro_rules! m {
3558 ($val:expr) => { $val }; 3652 ($val:expr) => { $val };
3559} 3653}
@@ -3567,7 +3661,8 @@ fn foo() {
3567fn $0fun_name(n: i32) -> i32 { 3661fn $0fun_name(n: i32) -> i32 {
3568 let k = n * m!(n); 3662 let k = n * m!(n);
3569 k 3663 k
3570}", 3664}
3665"#,
3571 ); 3666 );
3572 } 3667 }
3573 3668
@@ -3575,7 +3670,8 @@ fn $0fun_name(n: i32) -> i32 {
3575 fn extract_with_await() { 3670 fn extract_with_await() {
3576 check_assist( 3671 check_assist(
3577 extract_function, 3672 extract_function,
3578 r#"fn main() { 3673 r#"
3674fn main() {
3579 $0some_function().await;$0 3675 $0some_function().await;$0
3580} 3676}
3581 3677
@@ -3603,7 +3699,8 @@ async fn some_function() {
3603 fn extract_with_await_in_args() { 3699 fn extract_with_await_in_args() {
3604 check_assist( 3700 check_assist(
3605 extract_function, 3701 extract_function,
3606 r#"fn main() { 3702 r#"
3703fn main() {
3607 $0function_call("a", some_function().await);$0 3704 $0function_call("a", some_function().await);$0
3608} 3705}
3609 3706
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
index da6df9106..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
@@ -48,6 +48,7 @@ pub(crate) fn extract_struct_from_enum_variant(
48 let variant_name = variant.name()?; 48 let variant_name = variant.name()?;
49 let variant_hir = ctx.sema.to_def(&variant)?; 49 let variant_hir = ctx.sema.to_def(&variant)?;
50 if existing_definition(ctx.db(), &variant_name, &variant_hir) { 50 if existing_definition(ctx.db(), &variant_name, &variant_hir) {
51 cov_mark::hit!(test_extract_enum_not_applicable_if_struct_exists);
51 return None; 52 return None;
52 } 53 }
53 54
@@ -300,18 +301,10 @@ fn reference_to_node(
300 301
301#[cfg(test)] 302#[cfg(test)]
302mod tests { 303mod tests {
303 use ide_db::helpers::FamousDefs;
304
305 use crate::tests::{check_assist, check_assist_not_applicable}; 304 use crate::tests::{check_assist, check_assist_not_applicable};
306 305
307 use super::*; 306 use super::*;
308 307
309 fn check_not_applicable(ra_fixture: &str) {
310 let fixture =
311 format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
312 check_assist_not_applicable(extract_struct_from_enum_variant, &fixture)
313 }
314
315 #[test] 308 #[test]
316 fn test_extract_struct_several_fields_tuple() { 309 fn test_extract_struct_several_fields_tuple() {
317 check_assist( 310 check_assist(
@@ -699,29 +692,33 @@ fn foo() {
699 692
700 #[test] 693 #[test]
701 fn test_extract_enum_not_applicable_for_element_with_no_fields() { 694 fn test_extract_enum_not_applicable_for_element_with_no_fields() {
702 check_not_applicable("enum A { $0One }"); 695 check_assist_not_applicable(extract_struct_from_enum_variant, r#"enum A { $0One }"#);
703 } 696 }
704 697
705 #[test] 698 #[test]
706 fn test_extract_enum_not_applicable_if_struct_exists() { 699 fn test_extract_enum_not_applicable_if_struct_exists() {
707 check_not_applicable( 700 cov_mark::check!(test_extract_enum_not_applicable_if_struct_exists);
708 r#"struct One; 701 check_assist_not_applicable(
709 enum A { $0One(u8, u32) }"#, 702 extract_struct_from_enum_variant,
703 r#"
704struct One;
705enum A { $0One(u8, u32) }
706"#,
710 ); 707 );
711 } 708 }
712 709
713 #[test] 710 #[test]
714 fn test_extract_not_applicable_one_field() { 711 fn test_extract_not_applicable_one_field() {
715 check_not_applicable(r"enum A { $0One(u32) }"); 712 check_assist_not_applicable(extract_struct_from_enum_variant, r"enum A { $0One(u32) }");
716 } 713 }
717 714
718 #[test] 715 #[test]
719 fn test_extract_not_applicable_no_field_tuple() { 716 fn test_extract_not_applicable_no_field_tuple() {
720 check_not_applicable(r"enum A { $0None() }"); 717 check_assist_not_applicable(extract_struct_from_enum_variant, r"enum A { $0None() }");
721 } 718 }
722 719
723 #[test] 720 #[test]
724 fn test_extract_not_applicable_no_field_named() { 721 fn test_extract_not_applicable_no_field_named() {
725 check_not_applicable(r"enum A { $0None {} }"); 722 check_assist_not_applicable(extract_struct_from_enum_variant, r"enum A { $0None {} }");
726 } 723 }
727} 724}
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs
index cd0f6dba9..318faa0fc 100644
--- a/crates/ide_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ide_assists/src/handlers/fill_match_arms.rs
@@ -481,26 +481,21 @@ fn main() {
481 check_assist( 481 check_assist(
482 fill_match_arms, 482 fill_match_arms,
483 r#" 483 r#"
484enum Option<T> { Some(T), None } 484//- minicore: option
485use Option::*;
486
487fn main() { 485fn main() {
488 match None$0 { 486 match None$0 {
489 None => {} 487 None => {}
490 } 488 }
491} 489}
492 "#, 490"#,
493 r#" 491 r#"
494enum Option<T> { Some(T), None }
495use Option::*;
496
497fn main() { 492fn main() {
498 match None { 493 match None {
499 None => {} 494 None => {}
500 Some(${0:_}) => todo!(), 495 Some(${0:_}) => todo!(),
501 } 496 }
502} 497}
503 "#, 498"#,
504 ); 499 );
505 } 500 }
506 501
diff --git a/crates/ide_assists/src/handlers/remove_dbg.rs b/crates/ide_assists/src/handlers/remove_dbg.rs
index b20fe992d..5866d8974 100644
--- a/crates/ide_assists/src/handlers/remove_dbg.rs
+++ b/crates/ide_assists/src/handlers/remove_dbg.rs
@@ -35,14 +35,14 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
35 .prev_sibling_or_token() 35 .prev_sibling_or_token()
36 .and_then(whitespace_start) 36 .and_then(whitespace_start)
37 .map(|start| TextRange::new(start, macro_call.syntax().text_range().end())) 37 .map(|start| TextRange::new(start, macro_call.syntax().text_range().end()))
38 .unwrap_or(macro_call.syntax().text_range()) 38 .unwrap_or_else(|| macro_call.syntax().text_range())
39 }, 39 },
40 ast::ExprStmt(it) => { 40 ast::ExprStmt(it) => {
41 let start = it 41 let start = it
42 .syntax() 42 .syntax()
43 .prev_sibling_or_token() 43 .prev_sibling_or_token()
44 .and_then(whitespace_start) 44 .and_then(whitespace_start)
45 .unwrap_or(it.syntax().text_range().start()); 45 .unwrap_or_else(|| it.syntax().text_range().start());
46 let end = it.syntax().text_range().end(); 46 let end = it.syntax().text_range().end();
47 47
48 TextRange::new(start, end) 48 TextRange::new(start, end)
diff --git a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
index 9404aa26d..f37aa0d53 100644
--- a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
@@ -262,9 +262,7 @@ impl VariantData {
262 check_assist( 262 check_assist(
263 replace_if_let_with_match, 263 replace_if_let_with_match,
264 r#" 264 r#"
265enum Option<T> { Some(T), None } 265//- minicore: option
266use Option::*;
267
268fn foo(x: Option<i32>) { 266fn foo(x: Option<i32>) {
269 $0if let Some(x) = x { 267 $0if let Some(x) = x {
270 println!("{}", x) 268 println!("{}", x)
@@ -272,18 +270,15 @@ fn foo(x: Option<i32>) {
272 println!("none") 270 println!("none")
273 } 271 }
274} 272}
275 "#, 273"#,
276 r#" 274 r#"
277enum Option<T> { Some(T), None }
278use Option::*;
279
280fn foo(x: Option<i32>) { 275fn foo(x: Option<i32>) {
281 match x { 276 match x {
282 Some(x) => println!("{}", x), 277 Some(x) => println!("{}", x),
283 None => println!("none"), 278 None => println!("none"),
284 } 279 }
285} 280}
286 "#, 281"#,
287 ); 282 );
288 } 283 }
289 284
@@ -292,9 +287,7 @@ fn foo(x: Option<i32>) {
292 check_assist( 287 check_assist(
293 replace_if_let_with_match, 288 replace_if_let_with_match,
294 r#" 289 r#"
295enum Option<T> { Some(T), None } 290//- minicore: option
296use Option::*;
297
298fn foo(x: Option<i32>) { 291fn foo(x: Option<i32>) {
299 $0if let None = x { 292 $0if let None = x {
300 println!("none") 293 println!("none")
@@ -302,18 +295,15 @@ fn foo(x: Option<i32>) {
302 println!("some") 295 println!("some")
303 } 296 }
304} 297}
305 "#, 298"#,
306 r#" 299 r#"
307enum Option<T> { Some(T), None }
308use Option::*;
309
310fn foo(x: Option<i32>) { 300fn foo(x: Option<i32>) {
311 match x { 301 match x {
312 None => println!("none"), 302 None => println!("none"),
313 Some(_) => println!("some"), 303 Some(_) => println!("some"),
314 } 304 }
315} 305}
316 "#, 306"#,
317 ); 307 );
318 } 308 }
319 309
@@ -322,9 +312,7 @@ fn foo(x: Option<i32>) {
322 check_assist( 312 check_assist(
323 replace_if_let_with_match, 313 replace_if_let_with_match,
324 r#" 314 r#"
325enum Result<T, E> { Ok(T), Err(E) } 315//- minicore: result
326use Result::*;
327
328fn foo(x: Result<i32, ()>) { 316fn foo(x: Result<i32, ()>) {
329 $0if let Ok(x) = x { 317 $0if let Ok(x) = x {
330 println!("{}", x) 318 println!("{}", x)
@@ -332,18 +320,15 @@ fn foo(x: Result<i32, ()>) {
332 println!("none") 320 println!("none")
333 } 321 }
334} 322}
335 "#, 323"#,
336 r#" 324 r#"
337enum Result<T, E> { Ok(T), Err(E) }
338use Result::*;
339
340fn foo(x: Result<i32, ()>) { 325fn foo(x: Result<i32, ()>) {
341 match x { 326 match x {
342 Ok(x) => println!("{}", x), 327 Ok(x) => println!("{}", x),
343 Err(_) => println!("none"), 328 Err(_) => println!("none"),
344 } 329 }
345} 330}
346 "#, 331"#,
347 ); 332 );
348 } 333 }
349 334
@@ -352,9 +337,7 @@ fn foo(x: Result<i32, ()>) {
352 check_assist( 337 check_assist(
353 replace_if_let_with_match, 338 replace_if_let_with_match,
354 r#" 339 r#"
355enum Result<T, E> { Ok(T), Err(E) } 340//- minicore: result
356use Result::*;
357
358fn foo(x: Result<i32, ()>) { 341fn foo(x: Result<i32, ()>) {
359 $0if let Err(x) = x { 342 $0if let Err(x) = x {
360 println!("{}", x) 343 println!("{}", x)
@@ -362,18 +345,15 @@ fn foo(x: Result<i32, ()>) {
362 println!("ok") 345 println!("ok")
363 } 346 }
364} 347}
365 "#, 348"#,
366 r#" 349 r#"
367enum Result<T, E> { Ok(T), Err(E) }
368use Result::*;
369
370fn foo(x: Result<i32, ()>) { 350fn foo(x: Result<i32, ()>) {
371 match x { 351 match x {
372 Err(x) => println!("{}", x), 352 Err(x) => println!("{}", x),
373 Ok(_) => println!("ok"), 353 Ok(_) => println!("ok"),
374 } 354 }
375} 355}
376 "#, 356"#,
377 ); 357 );
378 } 358 }
379 359
@@ -488,20 +468,15 @@ impl VariantData {
488 check_assist( 468 check_assist(
489 replace_match_with_if_let, 469 replace_match_with_if_let,
490 r#" 470 r#"
491enum Option<T> { Some(T), None } 471//- minicore: option
492use Option::*;
493
494fn foo(x: Option<i32>) { 472fn foo(x: Option<i32>) {
495 $0match x { 473 $0match x {
496 Some(x) => println!("{}", x), 474 Some(x) => println!("{}", x),
497 None => println!("none"), 475 None => println!("none"),
498 } 476 }
499} 477}
500 "#, 478"#,
501 r#" 479 r#"
502enum Option<T> { Some(T), None }
503use Option::*;
504
505fn foo(x: Option<i32>) { 480fn foo(x: Option<i32>) {
506 if let Some(x) = x { 481 if let Some(x) = x {
507 println!("{}", x) 482 println!("{}", x)
@@ -509,7 +484,7 @@ fn foo(x: Option<i32>) {
509 println!("none") 484 println!("none")
510 } 485 }
511} 486}
512 "#, 487"#,
513 ); 488 );
514 } 489 }
515 490
@@ -518,20 +493,15 @@ fn foo(x: Option<i32>) {
518 check_assist( 493 check_assist(
519 replace_match_with_if_let, 494 replace_match_with_if_let,
520 r#" 495 r#"
521enum Result<T, E> { Ok(T), Err(E) } 496//- minicore: result
522use Result::*;
523
524fn foo(x: Result<i32, ()>) { 497fn foo(x: Result<i32, ()>) {
525 $0match x { 498 $0match x {
526 Ok(x) => println!("{}", x), 499 Ok(x) => println!("{}", x),
527 Err(_) => println!("none"), 500 Err(_) => println!("none"),
528 } 501 }
529} 502}
530 "#, 503"#,
531 r#" 504 r#"
532enum Result<T, E> { Ok(T), Err(E) }
533use Result::*;
534
535fn foo(x: Result<i32, ()>) { 505fn foo(x: Result<i32, ()>) {
536 if let Ok(x) = x { 506 if let Ok(x) = x {
537 println!("{}", x) 507 println!("{}", x)
@@ -539,7 +509,7 @@ fn foo(x: Result<i32, ()>) {
539 println!("none") 509 println!("none")
540 } 510 }
541} 511}
542 "#, 512"#,
543 ); 513 );
544 } 514 }
545 515
diff --git a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
index a3bfa221c..f39c48d8f 100644
--- a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
@@ -20,17 +20,16 @@ use ide_db::ty_filter::TryEnum;
20// Replaces `unwrap` with a `match` expression. Works for Result and Option. 20// Replaces `unwrap` with a `match` expression. Works for Result and Option.
21// 21//
22// ``` 22// ```
23// enum Result<T, E> { Ok(T), Err(E) } 23// # //- minicore: result
24// fn main() { 24// fn main() {
25// let x: Result<i32, i32> = Result::Ok(92); 25// let x: Result<i32, i32> = Ok(92);
26// let y = x.$0unwrap(); 26// let y = x.$0unwrap();
27// } 27// }
28// ``` 28// ```
29// -> 29// ->
30// ``` 30// ```
31// enum Result<T, E> { Ok(T), Err(E) }
32// fn main() { 31// fn main() {
33// let x: Result<i32, i32> = Result::Ok(92); 32// let x: Result<i32, i32> = Ok(92);
34// let y = match x { 33// let y = match x {
35// Ok(it) => it, 34// Ok(it) => it,
36// $0_ => unreachable!(), 35// $0_ => unreachable!(),
@@ -97,25 +96,24 @@ mod tests {
97 fn test_replace_result_unwrap_with_match() { 96 fn test_replace_result_unwrap_with_match() {
98 check_assist( 97 check_assist(
99 replace_unwrap_with_match, 98 replace_unwrap_with_match,
100 r" 99 r#"
101enum Result<T, E> { Ok(T), Err(E) } 100//- minicore: result
102fn i<T>(a: T) -> T { a } 101fn i<T>(a: T) -> T { a }
103fn main() { 102fn main() {
104 let x: Result<i32, i32> = Result::Ok(92); 103 let x: Result<i32, i32> = Ok(92);
105 let y = i(x).$0unwrap(); 104 let y = i(x).$0unwrap();
106} 105}
107 ", 106"#,
108 r" 107 r#"
109enum Result<T, E> { Ok(T), Err(E) }
110fn i<T>(a: T) -> T { a } 108fn i<T>(a: T) -> T { a }
111fn main() { 109fn main() {
112 let x: Result<i32, i32> = Result::Ok(92); 110 let x: Result<i32, i32> = Ok(92);
113 let y = match i(x) { 111 let y = match i(x) {
114 Ok(it) => it, 112 Ok(it) => it,
115 $0_ => unreachable!(), 113 $0_ => unreachable!(),
116 }; 114 };
117} 115}
118 ", 116"#,
119 ) 117 )
120 } 118 }
121 119
@@ -123,25 +121,24 @@ fn main() {
123 fn test_replace_option_unwrap_with_match() { 121 fn test_replace_option_unwrap_with_match() {
124 check_assist( 122 check_assist(
125 replace_unwrap_with_match, 123 replace_unwrap_with_match,
126 r" 124 r#"
127enum Option<T> { Some(T), None } 125//- minicore: option
128fn i<T>(a: T) -> T { a } 126fn i<T>(a: T) -> T { a }
129fn main() { 127fn main() {
130 let x = Option::Some(92); 128 let x = Some(92);
131 let y = i(x).$0unwrap(); 129 let y = i(x).$0unwrap();
132} 130}
133 ", 131"#,
134 r" 132 r#"
135enum Option<T> { Some(T), None }
136fn i<T>(a: T) -> T { a } 133fn i<T>(a: T) -> T { a }
137fn main() { 134fn main() {
138 let x = Option::Some(92); 135 let x = Some(92);
139 let y = match i(x) { 136 let y = match i(x) {
140 Some(it) => it, 137 Some(it) => it,
141 $0_ => unreachable!(), 138 $0_ => unreachable!(),
142 }; 139 };
143} 140}
144 ", 141"#,
145 ); 142 );
146 } 143 }
147 144
@@ -149,25 +146,24 @@ fn main() {
149 fn test_replace_result_unwrap_with_match_chaining() { 146 fn test_replace_result_unwrap_with_match_chaining() {
150 check_assist( 147 check_assist(
151 replace_unwrap_with_match, 148 replace_unwrap_with_match,
152 r" 149 r#"
153enum Result<T, E> { Ok(T), Err(E) } 150//- minicore: result
154fn i<T>(a: T) -> T { a } 151fn i<T>(a: T) -> T { a }
155fn main() { 152fn main() {
156 let x: Result<i32, i32> = Result::Ok(92); 153 let x: Result<i32, i32> = Ok(92);
157 let y = i(x).$0unwrap().count_zeroes(); 154 let y = i(x).$0unwrap().count_zeroes();
158} 155}
159 ", 156"#,
160 r" 157 r#"
161enum Result<T, E> { Ok(T), Err(E) }
162fn i<T>(a: T) -> T { a } 158fn i<T>(a: T) -> T { a }
163fn main() { 159fn main() {
164 let x: Result<i32, i32> = Result::Ok(92); 160 let x: Result<i32, i32> = Ok(92);
165 let y = match i(x) { 161 let y = match i(x) {
166 Ok(it) => it, 162 Ok(it) => it,
167 $0_ => unreachable!(), 163 $0_ => unreachable!(),
168 }.count_zeroes(); 164 }.count_zeroes();
169} 165}
170 ", 166"#,
171 ) 167 )
172 } 168 }
173 169
@@ -175,14 +171,14 @@ fn main() {
175 fn replace_unwrap_with_match_target() { 171 fn replace_unwrap_with_match_target() {
176 check_assist_target( 172 check_assist_target(
177 replace_unwrap_with_match, 173 replace_unwrap_with_match,
178 r" 174 r#"
179enum Option<T> { Some(T), None } 175//- minicore: option
180fn i<T>(a: T) -> T { a } 176fn i<T>(a: T) -> T { a }
181fn main() { 177fn main() {
182 let x = Option::Some(92); 178 let x = Some(92);
183 let y = i(x).$0unwrap(); 179 let y = i(x).$0unwrap();
184} 180}
185 ", 181"#,
186 r"i(x).unwrap()", 182 r"i(x).unwrap()",
187 ); 183 );
188 } 184 }
diff --git a/crates/ide_assists/src/lib.rs b/crates/ide_assists/src/lib.rs
index fa378a622..86a57ce5d 100644
--- a/crates/ide_assists/src/lib.rs
+++ b/crates/ide_assists/src/lib.rs
@@ -15,7 +15,6 @@ mod assist_context;
15#[cfg(test)] 15#[cfg(test)]
16mod tests; 16mod tests;
17pub mod utils; 17pub mod utils;
18pub mod path_transform;
19 18
20use hir::Semantics; 19use hir::Semantics;
21use ide_db::{base_db::FileRange, RootDatabase}; 20use ide_db::{base_db::FileRange, RootDatabase};
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index b6f224b21..841537c77 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -36,6 +36,7 @@ pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
36 RootDatabase::with_single_file(text) 36 RootDatabase::with_single_file(text)
37} 37}
38 38
39#[track_caller]
39pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) { 40pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) {
40 let ra_fixture_after = trim_indent(ra_fixture_after); 41 let ra_fixture_after = trim_indent(ra_fixture_after);
41 check(assist, ra_fixture_before, ExpectedResult::After(&ra_fixture_after), None); 42 check(assist, ra_fixture_before, ExpectedResult::After(&ra_fixture_after), None);
diff --git a/crates/ide_assists/src/tests/generated.rs b/crates/ide_assists/src/tests/generated.rs
index de5d9e55a..1509c3c63 100644
--- a/crates/ide_assists/src/tests/generated.rs
+++ b/crates/ide_assists/src/tests/generated.rs
@@ -209,10 +209,7 @@ fn doctest_convert_into_to_from() {
209 check_doc_test( 209 check_doc_test(
210 "convert_into_to_from", 210 "convert_into_to_from",
211 r#####" 211 r#####"
212//- /lib.rs crate:core 212//- minicore: from
213pub mod convert { pub trait Into<T> { pub fn into(self) -> T; } }
214//- /lib.rs crate:main deps:core
215use core::convert::Into;
216impl $0Into<Thing> for usize { 213impl $0Into<Thing> for usize {
217 fn into(self) -> Thing { 214 fn into(self) -> Thing {
218 Thing { 215 Thing {
@@ -223,7 +220,6 @@ impl $0Into<Thing> for usize {
223} 220}
224"#####, 221"#####,
225 r#####" 222 r#####"
226use core::convert::Into;
227impl From<usize> for Thing { 223impl From<usize> for Thing {
228 fn from(val: usize) -> Self { 224 fn from(val: usize) -> Self {
229 Thing { 225 Thing {
@@ -241,23 +237,19 @@ fn doctest_convert_iter_for_each_to_for() {
241 check_doc_test( 237 check_doc_test(
242 "convert_iter_for_each_to_for", 238 "convert_iter_for_each_to_for",
243 r#####" 239 r#####"
244//- /lib.rs crate:core 240//- minicore: iterators
245pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } } 241use core::iter;
246pub struct SomeIter;
247impl self::iter::traits::iterator::Iterator for SomeIter {}
248//- /lib.rs crate:main deps:core
249use core::SomeIter;
250fn main() { 242fn main() {
251 let iter = SomeIter; 243 let iter = iter::repeat((9, 2));
252 iter.for_each$0(|(x, y)| { 244 iter.for_each$0(|(x, y)| {
253 println!("x: {}, y: {}", x, y); 245 println!("x: {}, y: {}", x, y);
254 }); 246 });
255} 247}
256"#####, 248"#####,
257 r#####" 249 r#####"
258use core::SomeIter; 250use core::iter;
259fn main() { 251fn main() {
260 let iter = SomeIter; 252 let iter = iter::repeat((9, 2));
261 for (x, y) in iter { 253 for (x, y) in iter {
262 println!("x: {}, y: {}", x, y); 254 println!("x: {}, y: {}", x, y);
263 } 255 }
@@ -1519,16 +1511,15 @@ fn doctest_replace_unwrap_with_match() {
1519 check_doc_test( 1511 check_doc_test(
1520 "replace_unwrap_with_match", 1512 "replace_unwrap_with_match",
1521 r#####" 1513 r#####"
1522enum Result<T, E> { Ok(T), Err(E) } 1514//- minicore: result
1523fn main() { 1515fn main() {
1524 let x: Result<i32, i32> = Result::Ok(92); 1516 let x: Result<i32, i32> = Ok(92);
1525 let y = x.$0unwrap(); 1517 let y = x.$0unwrap();
1526} 1518}
1527"#####, 1519"#####,
1528 r#####" 1520 r#####"
1529enum Result<T, E> { Ok(T), Err(E) }
1530fn main() { 1521fn main() {
1531 let x: Result<i32, i32> = Result::Ok(92); 1522 let x: Result<i32, i32> = Ok(92);
1532 let y = match x { 1523 let y = match x {
1533 Ok(it) => it, 1524 Ok(it) => it,
1534 $0_ => unreachable!(), 1525 $0_ => unreachable!(),
diff --git a/crates/ide_assists/src/utils.rs b/crates/ide_assists/src/utils.rs
index 068df005b..0ec236aa0 100644
--- a/crates/ide_assists/src/utils.rs
+++ b/crates/ide_assists/src/utils.rs
@@ -8,6 +8,7 @@ use ast::TypeBoundsOwner;
8use hir::{Adt, HasSource, Semantics}; 8use hir::{Adt, HasSource, Semantics};
9use ide_db::{ 9use ide_db::{
10 helpers::{FamousDefs, SnippetCap}, 10 helpers::{FamousDefs, SnippetCap},
11 path_transform::PathTransform,
11 RootDatabase, 12 RootDatabase,
12}; 13};
13use itertools::Itertools; 14use itertools::Itertools;
@@ -22,10 +23,7 @@ use syntax::{
22 SyntaxNode, TextSize, T, 23 SyntaxNode, TextSize, T,
23}; 24};
24 25
25use crate::{ 26use crate::assist_context::{AssistBuilder, AssistContext};
26 assist_context::{AssistBuilder, AssistContext},
27 path_transform::PathTransform,
28};
29 27
30pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { 28pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
31 extract_trivial_expression(&block) 29 extract_trivial_expression(&block)
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs
index f3b11e72d..78fc30e16 100644
--- a/crates/ide_completion/src/completions/attribute.rs
+++ b/crates/ide_completion/src/completions/attribute.rs
@@ -17,12 +17,14 @@ use crate::{
17 17
18mod derive; 18mod derive;
19mod lint; 19mod lint;
20mod repr;
20 21
21pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { 22pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
22 let attribute = ctx.attribute_under_caret.as_ref()?; 23 let attribute = ctx.attribute_under_caret.as_ref()?;
23 match (attribute.path().and_then(|p| p.as_single_name_ref()), attribute.token_tree()) { 24 match (attribute.path().and_then(|p| p.as_single_name_ref()), attribute.token_tree()) {
24 (Some(path), Some(token_tree)) => match path.text().as_str() { 25 (Some(path), Some(token_tree)) => match path.text().as_str() {
25 "derive" => derive::complete_derive(acc, ctx, token_tree), 26 "derive" => derive::complete_derive(acc, ctx, token_tree),
27 "repr" => repr::complete_repr(acc, ctx, token_tree),
26 "feature" => lint::complete_lint(acc, ctx, token_tree, FEATURES), 28 "feature" => lint::complete_lint(acc, ctx, token_tree, FEATURES),
27 "allow" | "warn" | "deny" | "forbid" => { 29 "allow" | "warn" | "deny" | "forbid" => {
28 lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS); 30 lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS);
@@ -786,13 +788,13 @@ mod tests {
786 at target_feature = "…" 788 at target_feature = "…"
787 at test 789 at test
788 at track_caller 790 at track_caller
789 kw return
790 "#]], 791 "#]],
791 ); 792 );
792 } 793 }
793 794
794 #[test] 795 #[test]
795 fn complete_attribute_on_expr() { 796 fn complete_attribute_on_expr() {
797 cov_mark::check!(no_keyword_completion_in_attr_of_expr);
796 check( 798 check(
797 r#"fn main() { #[$0] foo() }"#, 799 r#"fn main() { #[$0] foo() }"#,
798 expect![[r#" 800 expect![[r#"
@@ -802,7 +804,6 @@ mod tests {
802 at deny(…) 804 at deny(…)
803 at forbid(…) 805 at forbid(…)
804 at warn(…) 806 at warn(…)
805 kw return
806 "#]], 807 "#]],
807 ); 808 );
808 } 809 }
diff --git a/crates/ide_completion/src/completions/attribute/repr.rs b/crates/ide_completion/src/completions/attribute/repr.rs
new file mode 100644
index 000000000..92a262a43
--- /dev/null
+++ b/crates/ide_completion/src/completions/attribute/repr.rs
@@ -0,0 +1,199 @@
1//! Completion for representations.
2
3use syntax::ast;
4
5use crate::{
6 context::CompletionContext,
7 item::{CompletionItem, CompletionItemKind, CompletionKind},
8 Completions,
9};
10
11pub(super) fn complete_repr(
12 acc: &mut Completions,
13 ctx: &CompletionContext,
14 derive_input: ast::TokenTree,
15) {
16 if let Some(existing_reprs) = super::parse_comma_sep_input(derive_input) {
17 for repr_completion in REPR_COMPLETIONS {
18 if existing_reprs
19 .iter()
20 .any(|it| repr_completion.label == it || repr_completion.collides.contains(&&**it))
21 {
22 continue;
23 }
24 let mut item = CompletionItem::new(
25 CompletionKind::Attribute,
26 ctx.source_range(),
27 repr_completion.label,
28 );
29 item.kind(CompletionItemKind::Attribute);
30 if let Some(lookup) = repr_completion.lookup {
31 item.lookup_by(lookup);
32 }
33 if let Some((snippet, cap)) = repr_completion.snippet.zip(ctx.config.snippet_cap) {
34 item.insert_snippet(cap, snippet);
35 }
36 item.add_to(acc);
37 }
38 }
39}
40
41struct ReprCompletion {
42 label: &'static str,
43 snippet: Option<&'static str>,
44 lookup: Option<&'static str>,
45 collides: &'static [&'static str],
46}
47
48const fn attr(label: &'static str, collides: &'static [&'static str]) -> ReprCompletion {
49 ReprCompletion { label, snippet: None, lookup: None, collides }
50}
51
52#[rustfmt::skip]
53const REPR_COMPLETIONS: &[ReprCompletion] = &[
54 ReprCompletion { label: "align($0)", snippet: Some("align($0)"), lookup: Some("align"), collides: &["transparent", "packed"] },
55 attr("packed", &["transparent", "align"]),
56 attr("transparent", &["C", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
57 attr("C", &["transparent"]),
58 attr("u8", &["transparent", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
59 attr("u16", &["transparent", "u8", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
60 attr("u32", &["transparent", "u8", "u16", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
61 attr("u64", &["transparent", "u8", "u16", "u32", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
62 attr("u128", &["transparent", "u8", "u16", "u32", "u64", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
63 attr("usize", &["transparent", "u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128", "isize"]),
64 attr("i8", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i16", "i32", "i64", "i128", "isize"]),
65 attr("i16", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i32", "i64", "i128", "isize"]),
66 attr("i32", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i64", "i128", "isize"]),
67 attr("i64", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i128", "isize"]),
68 attr("i28", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "isize"]),
69 attr("isize", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128"]),
70];
71
72#[cfg(test)]
73mod tests {
74 use expect_test::{expect, Expect};
75
76 use crate::tests::completion_list;
77
78 fn check(ra_fixture: &str, expect: Expect) {
79 let actual = completion_list(ra_fixture);
80 expect.assert_eq(&actual);
81 }
82
83 #[test]
84 fn no_completion_for_incorrect_repr() {
85 check(r#"#[repr{$0)] struct Test;"#, expect![[]])
86 }
87
88 #[test]
89 fn empty() {
90 check(
91 r#"#[repr($0)] struct Test;"#,
92 expect![[r#"
93 at align($0)
94 at packed
95 at transparent
96 at C
97 at u8
98 at u16
99 at u32
100 at u64
101 at u128
102 at usize
103 at i8
104 at i16
105 at i32
106 at i64
107 at i28
108 at isize
109 "#]],
110 );
111 }
112
113 #[test]
114 fn transparent() {
115 check(r#"#[repr(transparent, $0)] struct Test;"#, expect![[r#""#]]);
116 }
117
118 #[test]
119 fn align() {
120 check(
121 r#"#[repr(align(1), $0)] struct Test;"#,
122 expect![[r#"
123 at align($0)
124 at transparent
125 at C
126 at u8
127 at u16
128 at u32
129 at u64
130 at u128
131 at usize
132 at i8
133 at i16
134 at i32
135 at i64
136 at i28
137 at isize
138 "#]],
139 );
140 }
141
142 #[test]
143 fn packed() {
144 check(
145 r#"#[repr(packed, $0)] struct Test;"#,
146 expect![[r#"
147 at transparent
148 at C
149 at u8
150 at u16
151 at u32
152 at u64
153 at u128
154 at usize
155 at i8
156 at i16
157 at i32
158 at i64
159 at i28
160 at isize
161 "#]],
162 );
163 }
164
165 #[test]
166 fn c() {
167 check(
168 r#"#[repr(C, $0)] struct Test;"#,
169 expect![[r#"
170 at align($0)
171 at packed
172 at u8
173 at u16
174 at u32
175 at u64
176 at u128
177 at usize
178 at i8
179 at i16
180 at i32
181 at i64
182 at i28
183 at isize
184 "#]],
185 );
186 }
187
188 #[test]
189 fn prim() {
190 check(
191 r#"#[repr(usize, $0)] struct Test;"#,
192 expect![[r#"
193 at align($0)
194 at packed
195 at C
196 "#]],
197 );
198 }
199}
diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs
index 7f75d4298..286d7cb67 100644
--- a/crates/ide_completion/src/completions/dot.rs
+++ b/crates/ide_completion/src/completions/dot.rs
@@ -498,10 +498,7 @@ mod foo {
498 fn issue_8931() { 498 fn issue_8931() {
499 check( 499 check(
500 r#" 500 r#"
501#[lang = "fn_once"] 501//- minicore: fn
502trait FnOnce<Args> {
503 type Output;
504}
505struct S; 502struct S;
506 503
507struct Foo; 504struct Foo;
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs
index c99fdef05..07541c79c 100644
--- a/crates/ide_completion/src/completions/keyword.rs
+++ b/crates/ide_completion/src/completions/keyword.rs
@@ -48,6 +48,10 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
48 cov_mark::hit!(no_keyword_completion_in_record_lit); 48 cov_mark::hit!(no_keyword_completion_in_record_lit);
49 return; 49 return;
50 } 50 }
51 if ctx.attribute_under_caret.is_some() {
52 cov_mark::hit!(no_keyword_completion_in_attr_of_expr);
53 return;
54 }
51 55
52 // Suggest .await syntax for types that implement Future trait 56 // Suggest .await syntax for types that implement Future trait
53 if let Some(receiver) = ctx.dot_receiver() { 57 if let Some(receiver) = ctx.dot_receiver() {
diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs
index c3c7e4589..4e20ec003 100644
--- a/crates/ide_completion/src/completions/postfix.rs
+++ b/crates/ide_completion/src/completions/postfix.rs
@@ -436,18 +436,15 @@ fn main() {
436 check_edit( 436 check_edit(
437 "ifl", 437 "ifl",
438 r#" 438 r#"
439enum Option<T> { Some(T), None } 439//- minicore: option
440
441fn main() { 440fn main() {
442 let bar = Option::Some(true); 441 let bar = Some(true);
443 bar.$0 442 bar.$0
444} 443}
445"#, 444"#,
446 r#" 445 r#"
447enum Option<T> { Some(T), None }
448
449fn main() { 446fn main() {
450 let bar = Option::Some(true); 447 let bar = Some(true);
451 if let Some($1) = bar { 448 if let Some($1) = bar {
452 $0 449 $0
453} 450}
@@ -461,18 +458,15 @@ fn main() {
461 check_edit( 458 check_edit(
462 "match", 459 "match",
463 r#" 460 r#"
464enum Result<T, E> { Ok(T), Err(E) } 461//- minicore: result
465
466fn main() { 462fn main() {
467 let bar = Result::Ok(true); 463 let bar = Ok(true);
468 bar.$0 464 bar.$0
469} 465}
470"#, 466"#,
471 r#" 467 r#"
472enum Result<T, E> { Ok(T), Err(E) }
473
474fn main() { 468fn main() {
475 let bar = Result::Ok(true); 469 let bar = Ok(true);
476 match bar { 470 match bar {
477 Ok(${1:_}) => {$2}, 471 Ok(${1:_}) => {$2},
478 Err(${3:_}) => {$0}, 472 Err(${3:_}) => {$0},
@@ -515,18 +509,15 @@ fn main() {
515 check_edit( 509 check_edit(
516 "ifl", 510 "ifl",
517 r#" 511 r#"
518enum Option<T> { Some(T), None } 512//- minicore: option
519
520fn main() { 513fn main() {
521 let bar = &Option::Some(true); 514 let bar = &Some(true);
522 bar.$0 515 bar.$0
523} 516}
524"#, 517"#,
525 r#" 518 r#"
526enum Option<T> { Some(T), None }
527
528fn main() { 519fn main() {
529 let bar = &Option::Some(true); 520 let bar = &Some(true);
530 if let Some($1) = bar { 521 if let Some($1) = bar {
531 $0 522 $0
532} 523}
diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs
index dc1d198cc..65f0f3843 100644
--- a/crates/ide_completion/src/completions/trait_impl.rs
+++ b/crates/ide_completion/src/completions/trait_impl.rs
@@ -32,7 +32,7 @@
32//! ``` 32//! ```
33 33
34use hir::{self, HasAttrs, HasSource}; 34use hir::{self, HasAttrs, HasSource};
35use ide_db::{traits::get_missing_assoc_items, SymbolKind}; 35use ide_db::{path_transform::PathTransform, traits::get_missing_assoc_items, SymbolKind};
36use syntax::{ 36use syntax::{
37 ast::{self, edit}, 37 ast::{self, edit},
38 display::function_declaration, 38 display::function_declaration,
@@ -52,24 +52,26 @@ enum ImplCompletionKind {
52 52
53pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { 53pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) {
54 if let Some((kind, trigger, impl_def)) = completion_match(ctx.token.clone()) { 54 if let Some((kind, trigger, impl_def)) = completion_match(ctx.token.clone()) {
55 get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| match item { 55 if let Some(hir_impl) = ctx.sema.to_def(&impl_def) {
56 hir::AssocItem::Function(fn_item) 56 get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| match item {
57 if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Fn => 57 hir::AssocItem::Function(fn_item)
58 { 58 if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Fn =>
59 add_function_impl(&trigger, acc, ctx, fn_item) 59 {
60 } 60 add_function_impl(&trigger, acc, ctx, fn_item, hir_impl)
61 hir::AssocItem::TypeAlias(type_item) 61 }
62 if kind == ImplCompletionKind::All || kind == ImplCompletionKind::TypeAlias => 62 hir::AssocItem::TypeAlias(type_item)
63 { 63 if kind == ImplCompletionKind::All || kind == ImplCompletionKind::TypeAlias =>
64 add_type_alias_impl(&trigger, acc, ctx, type_item) 64 {
65 } 65 add_type_alias_impl(&trigger, acc, ctx, type_item)
66 hir::AssocItem::Const(const_item) 66 }
67 if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Const => 67 hir::AssocItem::Const(const_item)
68 { 68 if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Const =>
69 add_const_impl(&trigger, acc, ctx, const_item) 69 {
70 } 70 add_const_impl(&trigger, acc, ctx, const_item, hir_impl)
71 _ => {} 71 }
72 }); 72 _ => {}
73 });
74 }
73 } 75 }
74} 76}
75 77
@@ -129,6 +131,7 @@ fn add_function_impl(
129 acc: &mut Completions, 131 acc: &mut Completions,
130 ctx: &CompletionContext, 132 ctx: &CompletionContext,
131 func: hir::Function, 133 func: hir::Function,
134 impl_def: hir::Impl,
132) { 135) {
133 let fn_name = func.name(ctx.db).to_string(); 136 let fn_name = func.name(ctx.db).to_string();
134 137
@@ -147,23 +150,55 @@ fn add_function_impl(
147 CompletionItemKind::SymbolKind(SymbolKind::Function) 150 CompletionItemKind::SymbolKind(SymbolKind::Function)
148 }; 151 };
149 let range = replacement_range(ctx, fn_def_node); 152 let range = replacement_range(ctx, fn_def_node);
150 if let Some(src) = func.source(ctx.db) { 153
151 let function_decl = function_declaration(&src.value); 154 if let Some(source) = func.source(ctx.db) {
152 match ctx.config.snippet_cap { 155 let assoc_item = ast::AssocItem::Fn(source.value);
153 Some(cap) => { 156 if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
154 let snippet = format!("{} {{\n $0\n}}", function_decl); 157 let transformed_fn = match transformed_item {
155 item.snippet_edit(cap, TextEdit::replace(range, snippet)); 158 ast::AssocItem::Fn(func) => func,
156 } 159 _ => unreachable!(),
157 None => { 160 };
158 let header = format!("{} {{", function_decl); 161
159 item.text_edit(TextEdit::replace(range, header)); 162 let function_decl = function_declaration(&transformed_fn);
160 } 163 match ctx.config.snippet_cap {
161 }; 164 Some(cap) => {
162 item.kind(completion_kind); 165 let snippet = format!("{} {{\n $0\n}}", function_decl);
163 item.add_to(acc); 166 item.snippet_edit(cap, TextEdit::replace(range, snippet));
167 }
168 None => {
169 let header = format!("{} {{", function_decl);
170 item.text_edit(TextEdit::replace(range, header));
171 }
172 };
173 item.kind(completion_kind);
174 item.add_to(acc);
175 }
164 } 176 }
165} 177}
166 178
179/// Transform a relevant associated item to inline generics from the impl, remove attrs and docs, etc.
180fn get_transformed_assoc_item(
181 ctx: &CompletionContext,
182 assoc_item: ast::AssocItem,
183 impl_def: hir::Impl,
184) -> Option<ast::AssocItem> {
185 let assoc_item = assoc_item.clone_for_update();
186 let trait_ = impl_def.trait_(ctx.db)?;
187 let source_scope = &ctx.sema.scope_for_def(trait_);
188 let target_scope = &ctx.sema.scope(impl_def.source(ctx.db)?.syntax().value);
189 let transform = PathTransform {
190 subst: (trait_, impl_def.source(ctx.db)?.value),
191 source_scope,
192 target_scope,
193 };
194
195 transform.apply(assoc_item.clone());
196 Some(match assoc_item {
197 ast::AssocItem::Fn(func) => ast::AssocItem::Fn(edit::remove_attrs_and_docs(&func)),
198 _ => assoc_item,
199 })
200}
201
167fn add_type_alias_impl( 202fn add_type_alias_impl(
168 type_def_node: &SyntaxNode, 203 type_def_node: &SyntaxNode,
169 acc: &mut Completions, 204 acc: &mut Completions,
@@ -188,21 +223,30 @@ fn add_const_impl(
188 acc: &mut Completions, 223 acc: &mut Completions,
189 ctx: &CompletionContext, 224 ctx: &CompletionContext,
190 const_: hir::Const, 225 const_: hir::Const,
226 impl_def: hir::Impl,
191) { 227) {
192 let const_name = const_.name(ctx.db).map(|n| n.to_string()); 228 let const_name = const_.name(ctx.db).map(|n| n.to_string());
193 229
194 if let Some(const_name) = const_name { 230 if let Some(const_name) = const_name {
195 if let Some(source) = const_.source(ctx.db) { 231 if let Some(source) = const_.source(ctx.db) {
196 let snippet = make_const_compl_syntax(&source.value); 232 let assoc_item = ast::AssocItem::Const(source.value);
197 233 if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
198 let range = replacement_range(ctx, const_def_node); 234 let transformed_const = match transformed_item {
199 let mut item = 235 ast::AssocItem::Const(const_) => const_,
200 CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone()); 236 _ => unreachable!(),
201 item.text_edit(TextEdit::replace(range, snippet)) 237 };
202 .lookup_by(const_name) 238
203 .kind(SymbolKind::Const) 239 let snippet = make_const_compl_syntax(&transformed_const);
204 .set_documentation(const_.docs(ctx.db)); 240
205 item.add_to(acc); 241 let range = replacement_range(ctx, const_def_node);
242 let mut item =
243 CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone());
244 item.text_edit(TextEdit::replace(range, snippet))
245 .lookup_by(const_name)
246 .kind(SymbolKind::Const)
247 .set_documentation(const_.docs(ctx.db));
248 item.add_to(acc);
249 }
206 } 250 }
207 } 251 }
208} 252}
@@ -779,4 +823,183 @@ impl Foo for T {{
779 test("Type", "type T$0", "type Type = "); 823 test("Type", "type T$0", "type Type = ");
780 test("CONST", "const C$0", "const CONST: i32 = "); 824 test("CONST", "const C$0", "const CONST: i32 = ");
781 } 825 }
826
827 #[test]
828 fn generics_are_inlined_in_return_type() {
829 check_edit(
830 "function",
831 r#"
832trait Foo<T> {
833 fn function() -> T;
834}
835struct Bar;
836
837impl Foo<u32> for Bar {
838 fn f$0
839}
840"#,
841 r#"
842trait Foo<T> {
843 fn function() -> T;
844}
845struct Bar;
846
847impl Foo<u32> for Bar {
848 fn function() -> u32 {
849 $0
850}
851}
852"#,
853 )
854 }
855
856 #[test]
857 fn generics_are_inlined_in_parameter() {
858 check_edit(
859 "function",
860 r#"
861trait Foo<T> {
862 fn function(bar: T);
863}
864struct Bar;
865
866impl Foo<u32> for Bar {
867 fn f$0
868}
869"#,
870 r#"
871trait Foo<T> {
872 fn function(bar: T);
873}
874struct Bar;
875
876impl Foo<u32> for Bar {
877 fn function(bar: u32) {
878 $0
879}
880}
881"#,
882 )
883 }
884
885 #[test]
886 fn generics_are_inlined_when_part_of_other_types() {
887 check_edit(
888 "function",
889 r#"
890trait Foo<T> {
891 fn function(bar: Vec<T>);
892}
893struct Bar;
894
895impl Foo<u32> for Bar {
896 fn f$0
897}
898"#,
899 r#"
900trait Foo<T> {
901 fn function(bar: Vec<T>);
902}
903struct Bar;
904
905impl Foo<u32> for Bar {
906 fn function(bar: Vec<u32>) {
907 $0
908}
909}
910"#,
911 )
912 }
913
914 #[test]
915 fn generics_are_inlined_complex() {
916 check_edit(
917 "function",
918 r#"
919trait Foo<T, U, V> {
920 fn function(bar: Vec<T>, baz: U) -> Arc<Vec<V>>;
921}
922struct Bar;
923
924impl Foo<u32, Vec<usize>, u8> for Bar {
925 fn f$0
926}
927"#,
928 r#"
929trait Foo<T, U, V> {
930 fn function(bar: Vec<T>, baz: U) -> Arc<Vec<V>>;
931}
932struct Bar;
933
934impl Foo<u32, Vec<usize>, u8> for Bar {
935 fn function(bar: Vec<u32>, baz: Vec<usize>) -> Arc<Vec<u8>> {
936 $0
937}
938}
939"#,
940 )
941 }
942
943 #[test]
944 fn generics_are_inlined_in_associated_const() {
945 check_edit(
946 "BAR",
947 r#"
948trait Foo<T> {
949 const BAR: T;
950}
951struct Bar;
952
953impl Foo<u32> for Bar {
954 const B$0;
955}
956"#,
957 r#"
958trait Foo<T> {
959 const BAR: T;
960}
961struct Bar;
962
963impl Foo<u32> for Bar {
964 const BAR: u32 = ;
965}
966"#,
967 )
968 }
969
970 #[test]
971 fn generics_are_inlined_in_where_clause() {
972 check_edit(
973 "function",
974 r#"
975trait SomeTrait<T> {}
976
977trait Foo<T> {
978 fn function()
979 where Self: SomeTrait<T>;
980}
981struct Bar;
982
983impl Foo<u32> for Bar {
984 fn f$0
985}
986"#,
987 r#"
988trait SomeTrait<T> {}
989
990trait Foo<T> {
991 fn function()
992 where Self: SomeTrait<T>;
993}
994struct Bar;
995
996impl Foo<u32> for Bar {
997 fn function()
998where Self: SomeTrait<u32> {
999 $0
1000}
1001}
1002"#,
1003 )
1004 }
782} 1005}
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 98fb36042..e49e434fa 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -942,13 +942,12 @@ fn foo() -> u32 {
942 // FIXME: make this work with `|| $0` 942 // FIXME: make this work with `|| $0`
943 check_expected_type_and_name( 943 check_expected_type_and_name(
944 r#" 944 r#"
945//- minicore: fn
945fn foo() { 946fn foo() {
946 bar(|| a$0); 947 bar(|| a$0);
947} 948}
948 949
949fn bar(f: impl FnOnce() -> u32) {} 950fn bar(f: impl FnOnce() -> u32) {}
950#[lang = "fn_once"]
951trait FnOnce { type Output; }
952"#, 951"#,
953 expect![[r#"ty: u32, name: ?"#]], 952 expect![[r#"ty: u32, name: ?"#]],
954 ); 953 );
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 4b55f7504..9bec03e17 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -1269,16 +1269,11 @@ fn bar(t: &Foo) {}
1269 fn suggest_deref_fn_ret() { 1269 fn suggest_deref_fn_ret() {
1270 check_relevance( 1270 check_relevance(
1271 r#" 1271 r#"
1272#[lang = "deref"] 1272//- minicore: deref
1273trait Deref {
1274 type Target;
1275 fn deref(&self) -> &Self::Target;
1276}
1277
1278struct S; 1273struct S;
1279struct T(S); 1274struct T(S);
1280 1275
1281impl Deref for T { 1276impl core::ops::Deref for T {
1282 type Target = S; 1277 type Target = S;
1283 1278
1284 fn deref(&self) -> &Self::Target { 1279 fn deref(&self) -> &Self::Target {
@@ -1292,15 +1287,16 @@ fn bar() -> T {}
1292fn main() { 1287fn main() {
1293 foo($0); 1288 foo($0);
1294} 1289}
1295 "#, 1290"#,
1296 expect![[r#" 1291 expect![[r#"
1297 tt Deref []
1298 fn bar() []
1299 fn &bar() [type]
1300 fn foo(…) []
1301 st T [] 1292 st T []
1302 st S [] 1293 st S []
1303 fn main() [] 1294 fn main() []
1295 fn bar() []
1296 fn &bar() [type]
1297 fn foo(…) []
1298 md core []
1299 tt Sized []
1304 "#]], 1300 "#]],
1305 ) 1301 )
1306 } 1302 }
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs
index 00900cdc2..d96028cbc 100644
--- a/crates/ide_db/src/helpers.rs
+++ b/crates/ide_db/src/helpers.rs
@@ -74,12 +74,19 @@ pub fn visit_file_defs(
74/// somewhat similar to the known paths infra inside hir, but it different; We 74/// somewhat similar to the known paths infra inside hir, but it different; We
75/// want to make sure that IDE specific paths don't become interesting inside 75/// want to make sure that IDE specific paths don't become interesting inside
76/// the compiler itself as well. 76/// the compiler itself as well.
77///
78/// Note that, by default, rust-analyzer tests **do not** include core or std
79/// libraries. If you are writing tests for functionality using [`FamousDefs`],
80/// you'd want to include [minicore](test_utils::MiniCore) declaration at the
81/// start of your tests:
82///
83/// ```
84/// //- minicore: iterator, ord, derive
85/// ```
77pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option<Crate>); 86pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option<Crate>);
78 87
79#[allow(non_snake_case)] 88#[allow(non_snake_case)]
80impl FamousDefs<'_, '_> { 89impl FamousDefs<'_, '_> {
81 pub const FIXTURE: &'static str = include_str!("helpers/famous_defs_fixture.rs");
82
83 pub fn std(&self) -> Option<Crate> { 90 pub fn std(&self) -> Option<Crate> {
84 self.find_crate("std") 91 self.find_crate("std")
85 } 92 }
diff --git a/crates/ide_db/src/helpers/famous_defs_fixture.rs b/crates/ide_db/src/helpers/famous_defs_fixture.rs
deleted file mode 100644
index fa4fc5307..000000000
--- a/crates/ide_db/src/helpers/famous_defs_fixture.rs
+++ /dev/null
@@ -1,36 +0,0 @@
1//- /libcore.rs crate:core
2//! Signatures of traits, types and functions from the core lib for use in tests.
3pub mod cmp {
4
5 pub trait Ord {
6 fn cmp(&self, other: &Self) -> Ordering;
7 fn max(self, other: Self) -> Self;
8 fn min(self, other: Self) -> Self;
9 fn clamp(self, min: Self, max: Self) -> Self;
10 }
11}
12
13pub mod prelude {
14 pub mod rust_2018 {
15 pub use crate::{
16 cmp::Ord,
17 convert::{From, Into},
18 default::Default,
19 iter::{IntoIterator, Iterator},
20 ops::{Fn, FnMut, FnOnce},
21 option::Option::{self, *},
22 };
23 }
24}
25#[prelude_import]
26pub use prelude::rust_2018::*;
27//- /libstd.rs crate:std deps:core
28//! Signatures of traits, types and functions from the std lib for use in tests.
29
30/// Docs for return_keyword
31mod return_keyword {}
32
33/// Docs for prim_str
34mod prim_str {}
35
36pub use core::ops;
diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs
index 7bbd08d6f..bde8767dd 100644
--- a/crates/ide_db/src/lib.rs
+++ b/crates/ide_db/src/lib.rs
@@ -14,6 +14,7 @@ pub mod ty_filter;
14pub mod traits; 14pub mod traits;
15pub mod call_info; 15pub mod call_info;
16pub mod helpers; 16pub mod helpers;
17pub mod path_transform;
17 18
18pub mod search; 19pub mod search;
19pub mod rename; 20pub mod rename;
diff --git a/crates/ide_assists/src/path_transform.rs b/crates/ide_db/src/path_transform.rs
index 48a7fa06a..f3d7aa920 100644
--- a/crates/ide_assists/src/path_transform.rs
+++ b/crates/ide_db/src/path_transform.rs
@@ -1,7 +1,7 @@
1//! See [`PathTransform`]. 1//! See [`PathTransform`].
2 2
3use crate::helpers::mod_path_to_ast;
3use hir::{HirDisplay, SemanticsScope}; 4use hir::{HirDisplay, SemanticsScope};
4use ide_db::helpers::mod_path_to_ast;
5use rustc_hash::FxHashMap; 5use rustc_hash::FxHashMap;
6use syntax::{ 6use syntax::{
7 ast::{self, AstNode}, 7 ast::{self, AstNode},
@@ -31,14 +31,14 @@ use syntax::{
31/// } 31/// }
32/// } 32/// }
33/// ``` 33/// ```
34pub(crate) struct PathTransform<'a> { 34pub struct PathTransform<'a> {
35 pub(crate) subst: (hir::Trait, ast::Impl), 35 pub subst: (hir::Trait, ast::Impl),
36 pub(crate) target_scope: &'a SemanticsScope<'a>, 36 pub target_scope: &'a SemanticsScope<'a>,
37 pub(crate) source_scope: &'a SemanticsScope<'a>, 37 pub source_scope: &'a SemanticsScope<'a>,
38} 38}
39 39
40impl<'a> PathTransform<'a> { 40impl<'a> PathTransform<'a> {
41 pub(crate) fn apply(&self, item: ast::AssocItem) { 41 pub fn apply(&self, item: ast::AssocItem) {
42 if let Some(ctx) = self.build_ctx() { 42 if let Some(ctx) = self.build_ctx() {
43 ctx.apply(item) 43 ctx.apply(item)
44 } 44 }
diff --git a/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs b/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
index 63de54570..c0edcd7d3 100644
--- a/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
+++ b/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
@@ -49,26 +49,15 @@ mod tests {
49 fn test_wrap_return_type_option() { 49 fn test_wrap_return_type_option() {
50 check_fix( 50 check_fix(
51 r#" 51 r#"
52//- /main.rs crate:main deps:core 52//- minicore: option, result
53use core::option::Option::{self, Some, None};
54
55fn div(x: i32, y: i32) -> Option<i32> { 53fn div(x: i32, y: i32) -> Option<i32> {
56 if y == 0 { 54 if y == 0 {
57 return None; 55 return None;
58 } 56 }
59 x / y$0 57 x / y$0
60} 58}
61//- /core/lib.rs crate:core
62pub mod result {
63 pub enum Result<T, E> { Ok(T), Err(E) }
64}
65pub mod option {
66 pub enum Option<T> { Some(T), None }
67}
68"#, 59"#,
69 r#" 60 r#"
70use core::option::Option::{self, Some, None};
71
72fn div(x: i32, y: i32) -> Option<i32> { 61fn div(x: i32, y: i32) -> Option<i32> {
73 if y == 0 { 62 if y == 0 {
74 return None; 63 return None;
@@ -83,26 +72,15 @@ fn div(x: i32, y: i32) -> Option<i32> {
83 fn test_wrap_return_type() { 72 fn test_wrap_return_type() {
84 check_fix( 73 check_fix(
85 r#" 74 r#"
86//- /main.rs crate:main deps:core 75//- minicore: option, result
87use core::result::Result::{self, Ok, Err};
88
89fn div(x: i32, y: i32) -> Result<i32, ()> { 76fn div(x: i32, y: i32) -> Result<i32, ()> {
90 if y == 0 { 77 if y == 0 {
91 return Err(()); 78 return Err(());
92 } 79 }
93 x / y$0 80 x / y$0
94} 81}
95//- /core/lib.rs crate:core
96pub mod result {
97 pub enum Result<T, E> { Ok(T), Err(E) }
98}
99pub mod option {
100 pub enum Option<T> { Some(T), None }
101}
102"#, 82"#,
103 r#" 83 r#"
104use core::result::Result::{self, Ok, Err};
105
106fn div(x: i32, y: i32) -> Result<i32, ()> { 84fn div(x: i32, y: i32) -> Result<i32, ()> {
107 if y == 0 { 85 if y == 0 {
108 return Err(()); 86 return Err(());
@@ -117,26 +95,15 @@ fn div(x: i32, y: i32) -> Result<i32, ()> {
117 fn test_wrap_return_type_handles_generic_functions() { 95 fn test_wrap_return_type_handles_generic_functions() {
118 check_fix( 96 check_fix(
119 r#" 97 r#"
120//- /main.rs crate:main deps:core 98//- minicore: option, result
121use core::result::Result::{self, Ok, Err};
122
123fn div<T>(x: T) -> Result<T, i32> { 99fn div<T>(x: T) -> Result<T, i32> {
124 if x == 0 { 100 if x == 0 {
125 return Err(7); 101 return Err(7);
126 } 102 }
127 $0x 103 $0x
128} 104}
129//- /core/lib.rs crate:core
130pub mod result {
131 pub enum Result<T, E> { Ok(T), Err(E) }
132}
133pub mod option {
134 pub enum Option<T> { Some(T), None }
135}
136"#, 105"#,
137 r#" 106 r#"
138use core::result::Result::{self, Ok, Err};
139
140fn div<T>(x: T) -> Result<T, i32> { 107fn div<T>(x: T) -> Result<T, i32> {
141 if x == 0 { 108 if x == 0 {
142 return Err(7); 109 return Err(7);
@@ -151,9 +118,7 @@ fn div<T>(x: T) -> Result<T, i32> {
151 fn test_wrap_return_type_handles_type_aliases() { 118 fn test_wrap_return_type_handles_type_aliases() {
152 check_fix( 119 check_fix(
153 r#" 120 r#"
154//- /main.rs crate:main deps:core 121//- minicore: option, result
155use core::result::Result::{self, Ok, Err};
156
157type MyResult<T> = Result<T, ()>; 122type MyResult<T> = Result<T, ()>;
158 123
159fn div(x: i32, y: i32) -> MyResult<i32> { 124fn div(x: i32, y: i32) -> MyResult<i32> {
@@ -162,17 +127,8 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
162 } 127 }
163 x $0/ y 128 x $0/ y
164} 129}
165//- /core/lib.rs crate:core
166pub mod result {
167 pub enum Result<T, E> { Ok(T), Err(E) }
168}
169pub mod option {
170 pub enum Option<T> { Some(T), None }
171}
172"#, 130"#,
173 r#" 131 r#"
174use core::result::Result::{self, Ok, Err};
175
176type MyResult<T> = Result<T, ()>; 132type MyResult<T> = Result<T, ()>;
177 133
178fn div(x: i32, y: i32) -> MyResult<i32> { 134fn div(x: i32, y: i32) -> MyResult<i32> {
@@ -189,18 +145,8 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
189 fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() { 145 fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() {
190 check_diagnostics( 146 check_diagnostics(
191 r#" 147 r#"
192//- /main.rs crate:main deps:core 148//- minicore: option, result
193use core::result::Result::{self, Ok, Err};
194
195fn foo() -> Result<(), i32> { 0 } 149fn foo() -> Result<(), i32> { 0 }
196
197//- /core/lib.rs crate:core
198pub mod result {
199 pub enum Result<T, E> { Ok(T), Err(E) }
200}
201pub mod option {
202 pub enum Option<T> { Some(T), None }
203}
204"#, 150"#,
205 ); 151 );
206 } 152 }
@@ -209,20 +155,10 @@ pub mod option {
209 fn test_wrap_return_type_not_applicable_when_return_type_is_not_result_or_option() { 155 fn test_wrap_return_type_not_applicable_when_return_type_is_not_result_or_option() {
210 check_diagnostics( 156 check_diagnostics(
211 r#" 157 r#"
212//- /main.rs crate:main deps:core 158//- minicore: option, result
213use core::result::Result::{self, Ok, Err};
214
215enum SomeOtherEnum { Ok(i32), Err(String) } 159enum SomeOtherEnum { Ok(i32), Err(String) }
216 160
217fn foo() -> SomeOtherEnum { 0 } 161fn foo() -> SomeOtherEnum { 0 }
218
219//- /core/lib.rs crate:core
220pub mod result {
221 pub enum Result<T, E> { Ok(T), Err(E) }
222}
223pub mod option {
224 pub enum Option<T> { Some(T), None }
225}
226"#, 162"#,
227 ); 163 );
228 } 164 }
diff --git a/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs b/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
index cd87a10bb..839ceac03 100644
--- a/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
+++ b/crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
@@ -55,44 +55,16 @@ fn fixes(
55 55
56#[cfg(test)] 56#[cfg(test)]
57mod tests { 57mod tests {
58 use crate::tests::check_fix; 58 use crate::tests::{check_diagnostics, check_fix};
59
60 // Register the required standard library types to make the tests work
61 #[track_caller]
62 fn check_diagnostics(ra_fixture: &str) {
63 let prefix = r#"
64//- /main.rs crate:main deps:core
65use core::iter::Iterator;
66use core::option::Option::{self, Some, None};
67"#;
68 let suffix = r#"
69//- /core/lib.rs crate:core
70pub mod option {
71 pub enum Option<T> { Some(T), None }
72}
73pub mod iter {
74 pub trait Iterator {
75 type Item;
76 fn filter_map<B, F>(self, f: F) -> FilterMap where F: FnMut(Self::Item) -> Option<B> { FilterMap }
77 fn next(&mut self) -> Option<Self::Item>;
78 }
79 pub struct FilterMap {}
80 impl Iterator for FilterMap {
81 type Item = i32;
82 fn next(&mut self) -> i32 { 7 }
83 }
84}
85"#;
86 crate::tests::check_diagnostics(&format!("{}{}{}", prefix, ra_fixture, suffix))
87 }
88 59
89 #[test] 60 #[test]
90 fn replace_filter_map_next_with_find_map2() { 61 fn replace_filter_map_next_with_find_map2() {
91 check_diagnostics( 62 check_diagnostics(
92 r#" 63 r#"
93 fn foo() { 64//- minicore: iterators
94 let m = [1, 2, 3].iter().filter_map(|x| Some(92)).next(); 65fn foo() {
95 } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 💡 weak: replace filter_map(..).next() with find_map(..) 66 let m = core::iter::repeat(()).filter_map(|()| Some(92)).next();
67} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 💡 weak: replace filter_map(..).next() with find_map(..)
96"#, 68"#,
97 ); 69 );
98 } 70 }
@@ -101,11 +73,11 @@ pub mod iter {
101 fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() { 73 fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() {
102 check_diagnostics( 74 check_diagnostics(
103 r#" 75 r#"
76//- minicore: iterators
104fn foo() { 77fn foo() {
105 let m = [1, 2, 3] 78 let m = core::iter::repeat(())
106 .iter() 79 .filter_map(|()| Some(92))
107 .filter_map(|x| Some(92)) 80 .count();
108 .len();
109} 81}
110"#, 82"#,
111 ); 83 );
@@ -115,12 +87,12 @@ fn foo() {
115 fn replace_filter_map_next_with_find_map_no_diagnostic_with_intervening_methods() { 87 fn replace_filter_map_next_with_find_map_no_diagnostic_with_intervening_methods() {
116 check_diagnostics( 88 check_diagnostics(
117 r#" 89 r#"
90//- minicore: iterators
118fn foo() { 91fn foo() {
119 let m = [1, 2, 3] 92 let m = core::iter::repeat(())
120 .iter() 93 .filter_map(|()| Some(92))
121 .filter_map(|x| Some(92))
122 .map(|x| x + 2) 94 .map(|x| x + 2)
123 .len(); 95 .next();
124} 96}
125"#, 97"#,
126 ); 98 );
@@ -130,10 +102,10 @@ fn foo() {
130 fn replace_filter_map_next_with_find_map_no_diagnostic_if_not_in_chain() { 102 fn replace_filter_map_next_with_find_map_no_diagnostic_if_not_in_chain() {
131 check_diagnostics( 103 check_diagnostics(
132 r#" 104 r#"
105//- minicore: iterators
133fn foo() { 106fn foo() {
134 let m = [1, 2, 3] 107 let m = core::iter::repeat(())
135 .iter() 108 .filter_map(|()| Some(92));
136 .filter_map(|x| Some(92));
137 let n = m.next(); 109 let n = m.next();
138} 110}
139"#, 111"#,
@@ -144,34 +116,14 @@ fn foo() {
144 fn replace_with_wind_map() { 116 fn replace_with_wind_map() {
145 check_fix( 117 check_fix(
146 r#" 118 r#"
147//- /main.rs crate:main deps:core 119//- minicore: iterators
148use core::iter::Iterator;
149use core::option::Option::{self, Some, None};
150fn foo() { 120fn foo() {
151 let m = [1, 2, 3].iter().$0filter_map(|x| Some(92)).next(); 121 let m = core::iter::repeat(()).$0filter_map(|()| Some(92)).next();
152}
153//- /core/lib.rs crate:core
154pub mod option {
155 pub enum Option<T> { Some(T), None }
156}
157pub mod iter {
158 pub trait Iterator {
159 type Item;
160 fn filter_map<B, F>(self, f: F) -> FilterMap where F: FnMut(Self::Item) -> Option<B> { FilterMap }
161 fn next(&mut self) -> Option<Self::Item>;
162 }
163 pub struct FilterMap {}
164 impl Iterator for FilterMap {
165 type Item = i32;
166 fn next(&mut self) -> i32 { 7 }
167 }
168} 122}
169"#, 123"#,
170 r#" 124 r#"
171use core::iter::Iterator;
172use core::option::Option::{self, Some, None};
173fn foo() { 125fn foo() {
174 let m = [1, 2, 3].iter().find_map(|x| Some(92)); 126 let m = core::iter::repeat(()).find_map(|()| Some(92));
175} 127}
176"#, 128"#,
177 ) 129 )
diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs
index 01ee26a53..5a78675fb 100644
--- a/crates/parser/src/grammar/params.rs
+++ b/crates/parser/src/grammar/params.rs
@@ -184,8 +184,7 @@ fn opt_self_param(p: &mut Parser, m: Marker) -> Result<(), Marker> {
184 if !matches!( 184 if !matches!(
185 (p.current(), la1, la2, la3), 185 (p.current(), la1, la2, la3),
186 (T![&], T![self], _, _) 186 (T![&], T![self], _, _)
187 | (T![&], T![mut], T![self], _) 187 | (T![&], T![mut] | LIFETIME_IDENT, T![self], _)
188 | (T![&], LIFETIME_IDENT, T![self], _)
189 | (T![&], LIFETIME_IDENT, T![mut], T![self]) 188 | (T![&], LIFETIME_IDENT, T![mut], T![self])
190 ) { 189 ) {
191 return Err(m); 190 return Err(m);
diff --git a/crates/proc_macro_api/src/version.rs b/crates/proc_macro_api/src/version.rs
index 28a4ac086..434decc7e 100644
--- a/crates/proc_macro_api/src/version.rs
+++ b/crates/proc_macro_api/src/version.rs
@@ -28,23 +28,23 @@ pub fn read_dylib_info(dylib_path: &Path) -> io::Result<RustCInfo> {
28 28
29 let ver_str = read_version(dylib_path)?; 29 let ver_str = read_version(dylib_path)?;
30 let mut items = ver_str.split_whitespace(); 30 let mut items = ver_str.split_whitespace();
31 let tag = items.next().ok_or(err!("version format error"))?; 31 let tag = items.next().ok_or_else(|| err!("version format error"))?;
32 if tag != "rustc" { 32 if tag != "rustc" {
33 return Err(err!("version format error (No rustc tag)")); 33 return Err(err!("version format error (No rustc tag)"));
34 } 34 }
35 35
36 let version_part = items.next().ok_or(err!("no version string"))?; 36 let version_part = items.next().ok_or_else(|| err!("no version string"))?;
37 let mut version_parts = version_part.split('-'); 37 let mut version_parts = version_part.split('-');
38 let version = version_parts.next().ok_or(err!("no version"))?; 38 let version = version_parts.next().ok_or_else(|| err!("no version"))?;
39 let channel = version_parts.next().unwrap_or_default().to_string(); 39 let channel = version_parts.next().unwrap_or_default().to_string();
40 40
41 let commit = items.next().ok_or(err!("no commit info"))?; 41 let commit = items.next().ok_or_else(|| err!("no commit info"))?;
42 // remove ( 42 // remove (
43 if commit.len() == 0 { 43 if commit.len() == 0 {
44 return Err(err!("commit format error")); 44 return Err(err!("commit format error"));
45 } 45 }
46 let commit = commit[1..].to_string(); 46 let commit = commit[1..].to_string();
47 let date = items.next().ok_or(err!("no date info"))?; 47 let date = items.next().ok_or_else(|| err!("no date info"))?;
48 // remove ) 48 // remove )
49 if date.len() == 0 { 49 if date.len() == 0 {
50 return Err(err!("date format error")); 50 return Err(err!("date format error"));
diff --git a/crates/project_model/src/build_data.rs b/crates/project_model/src/build_data.rs
index 53cb4bae7..45bbb08dc 100644
--- a/crates/project_model/src/build_data.rs
+++ b/crates/project_model/src/build_data.rs
@@ -187,7 +187,7 @@ impl WorkspaceBuildData {
187 let mut deserializer = serde_json::Deserializer::from_str(line); 187 let mut deserializer = serde_json::Deserializer::from_str(line);
188 deserializer.disable_recursion_limit(); 188 deserializer.disable_recursion_limit();
189 let message = Message::deserialize(&mut deserializer) 189 let message = Message::deserialize(&mut deserializer)
190 .unwrap_or(Message::TextLine(line.to_string())); 190 .unwrap_or_else(|_| Message::TextLine(line.to_string()));
191 191
192 match message { 192 match message {
193 Message::BuildScriptExecuted(BuildScript { 193 Message::BuildScriptExecuted(BuildScript {
@@ -229,7 +229,7 @@ impl WorkspaceBuildData {
229 Message::CompilerArtifact(message) => { 229 Message::CompilerArtifact(message) => {
230 progress(format!("metadata {}", message.target.name)); 230 progress(format!("metadata {}", message.target.name));
231 231
232 if message.target.kind.contains(&"proc-macro".to_string()) { 232 if message.target.kind.iter().any(|k| k == "proc-macro") {
233 let package_id = message.package_id; 233 let package_id = message.package_id;
234 // Skip rmeta file 234 // Skip rmeta file
235 if let Some(filename) = 235 if let Some(filename) =
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index 8d8f3b560..44656267f 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -131,7 +131,7 @@ impl Fixture {
131 res.push(meta) 131 res.push(meta)
132 } else { 132 } else {
133 if line.starts_with("// ") 133 if line.starts_with("// ")
134 && line.contains(":") 134 && line.contains(':')
135 && !line.contains("::") 135 && !line.contains("::")
136 && line.chars().all(|it| !it.is_uppercase()) 136 && line.chars().all(|it| !it.is_uppercase())
137 { 137 {
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
index a5a7c2f7d..ce6ad8541 100644
--- a/crates/test_utils/src/minicore.rs
+++ b/crates/test_utils/src/minicore.rs
@@ -15,15 +15,21 @@
15//! range: 15//! range:
16//! deref: sized 16//! deref: sized
17//! deref_mut: deref 17//! deref_mut: deref
18//! index: sized
18//! fn: 19//! fn:
19//! pin: 20//! pin:
20//! future: pin 21//! future: pin
21//! option: 22//! option:
22//! result: 23//! result:
23//! iterator: option 24//! iterator: option
24//! iterators: iterator 25//! iterators: iterator, fn
25//! default: sized 26//! default: sized
27//! clone: sized
28//! copy: clone
26//! from: sized 29//! from: sized
30//! eq: sized
31//! ord: eq, option
32//! derive:
27 33
28pub mod marker { 34pub mod marker {
29 // region:sized 35 // region:sized
@@ -37,6 +43,38 @@ pub mod marker {
37 #[lang = "unsize"] 43 #[lang = "unsize"]
38 pub trait Unsize<T: ?Sized> {} 44 pub trait Unsize<T: ?Sized> {}
39 // endregion:unsize 45 // endregion:unsize
46
47 // region:copy
48 #[lang = "copy"]
49 pub trait Copy: Clone {}
50 // region:derive
51 #[rustc_builtin_macro]
52 pub macro Copy($item:item) {}
53 // endregion:derive
54
55 mod copy_impls {
56 use super::Copy;
57
58 macro_rules! impl_copy {
59 ($($t:ty)*) => {
60 $(
61 impl Copy for $t {}
62 )*
63 }
64 }
65
66 impl_copy! {
67 usize u8 u16 u32 u64 u128
68 isize i8 i16 i32 i64 i128
69 f32 f64
70 bool char
71 }
72
73 impl<T: ?Sized> Copy for *const T {}
74 impl<T: ?Sized> Copy for *mut T {}
75 impl<T: ?Sized> Copy for &T {}
76 }
77 // endregion:copy
40} 78}
41 79
42// region:default 80// region:default
@@ -47,6 +85,19 @@ pub mod default {
47} 85}
48// endregion:default 86// endregion:default
49 87
88// region:clone
89pub mod clone {
90 #[lang = "clone"]
91 pub trait Clone: Sized {
92 fn clone(&self) -> Self;
93 }
94 // region:derive
95 #[rustc_builtin_macro]
96 pub macro Clone($item:item) {}
97 // endregion:derive
98}
99// endregion:clone
100
50// region:from 101// region:from
51pub mod convert { 102pub mod convert {
52 pub trait From<T>: Sized { 103 pub trait From<T>: Sized {
@@ -111,9 +162,53 @@ pub mod ops {
111 } 162 }
112 // endregion:deref_mut 163 // endregion:deref_mut
113 } 164 }
114 pub use self::deref::Deref; 165 pub use self::deref::{
115 pub use self::deref::DerefMut; //:deref_mut 166 Deref,
116 // endregion:deref 167 DerefMut, // :deref_mut
168 };
169 // endregion:deref
170
171 // region:index
172 mod index {
173 #[lang = "index"]
174 pub trait Index<Idx: ?Sized> {
175 type Output: ?Sized;
176 fn index(&self, index: Idx) -> &Self::Output;
177 }
178 #[lang = "index_mut"]
179 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
180 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
181 }
182
183 // region:slice
184 impl<T, I> Index<I> for [T]
185 where
186 I: SliceIndex<[T]>,
187 {
188 type Output = I::Output;
189 fn index(&self, index: I) -> &I::Output {
190 loop {}
191 }
192 }
193 impl<T, I> IndexMut<I> for [T]
194 where
195 I: SliceIndex<[T]>,
196 {
197 fn index_mut(&mut self, index: I) -> &mut I::Output {
198 loop {}
199 }
200 }
201
202 pub unsafe trait SliceIndex<T: ?Sized> {
203 type Output: ?Sized;
204 }
205 unsafe impl<T> SliceIndex<[T]> for usize {
206 type Output = T;
207 }
208 // endregion:slice
209 }
210 pub use self::index::{Index, IndexMut};
211 // endregion:index
117 212
118 // region:range 213 // region:range
119 mod range { 214 mod range {
@@ -173,6 +268,49 @@ pub mod ops {
173 // endregion:fn 268 // endregion:fn
174} 269}
175 270
271// region:eq
272pub mod cmp {
273 #[lang = "eq"]
274 pub trait PartialEq<Rhs: ?Sized = Self> {
275 fn eq(&self, other: &Rhs) -> bool;
276 }
277
278 pub trait Eq: PartialEq<Self> {}
279
280 // region:derive
281 #[rustc_builtin_macro]
282 pub macro PartialEq($item:item) {}
283 #[rustc_builtin_macro]
284 pub macro Eq($item:item) {}
285 // endregion:derive
286
287 // region:ord
288 #[lang = "partial_ord"]
289 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
290 fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
291 }
292
293 pub trait Ord: Eq + PartialOrd<Self> {
294 fn cmp(&self, other: &Self) -> Ordering;
295 }
296
297 pub enum Ordering {
298 Less = -1,
299 Equal = 0,
300 Greater = 1,
301 }
302
303 // region:derive
304 #[rustc_builtin_macro]
305 pub macro PartialOrd($item:item) {}
306 #[rustc_builtin_macro]
307 pub macro Ord($item:item) {}
308 // endregion:derive
309
310 // endregion:ord
311}
312// endregion:eq
313
176// region:slice 314// region:slice
177pub mod slice { 315pub mod slice {
178 #[lang = "slice"] 316 #[lang = "slice"]
@@ -252,7 +390,6 @@ pub mod iter {
252 iter: I, 390 iter: I,
253 n: usize, 391 n: usize,
254 } 392 }
255
256 impl<I> Iterator for Take<I> 393 impl<I> Iterator for Take<I>
257 where 394 where
258 I: Iterator, 395 I: Iterator,
@@ -263,6 +400,22 @@ pub mod iter {
263 loop {} 400 loop {}
264 } 401 }
265 } 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 }
266 } 419 }
267 pub use self::adapters::Take; 420 pub use self::adapters::Take;
268 421
@@ -310,6 +463,13 @@ pub mod iter {
310 fn take(self, n: usize) -> crate::iter::Take<Self> { 463 fn take(self, n: usize) -> crate::iter::Take<Self> {
311 loop {} 464 loop {}
312 } 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 }
313 // endregion:iterators 473 // endregion:iterators
314 } 474 }
315 impl<I: Iterator + ?Sized> Iterator for &mut I { 475 impl<I: Iterator + ?Sized> Iterator for &mut I {
@@ -342,16 +502,32 @@ pub mod iter {
342} 502}
343// endregion:iterator 503// endregion:iterator
344 504
505// region:derive
506mod macros {
507 pub(crate) mod builtin {
508 #[rustc_builtin_macro]
509 pub macro derive($item:item) {
510 /* compiler built-in */
511 }
512 }
513}
514// endregion:derive
515
345pub mod prelude { 516pub mod prelude {
346 pub mod v1 { 517 pub mod v1 {
347 pub use crate::{ 518 pub use crate::{
519 clone::Clone, // :clone
520 cmp::{Eq, PartialEq}, // :eq
521 cmp::{Ord, PartialOrd}, // :ord
522 convert::{From, Into}, // :from
348 default::Default, // :default 523 default::Default, // :default
349 iter::{IntoIterator, Iterator}, // :iterator 524 iter::{IntoIterator, Iterator}, // :iterator
525 macros::builtin::derive, // :derive
526 marker::Copy, // :copy
350 marker::Sized, // :sized 527 marker::Sized, // :sized
351 ops::{Fn, FnMut, FnOnce}, // :fn 528 ops::{Fn, FnMut, FnOnce}, // :fn
352 option::Option::{self, None, Some}, // :option 529 option::Option::{self, None, Some}, // :option
353 result::Result::{self, Err, Ok}, // :result 530 result::Result::{self, Err, Ok}, // :result
354 convert::{From, Into}, // :from
355 }; 531 };
356 } 532 }
357 533
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 52ffc0f9f..d22c80754 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -986,9 +986,9 @@
986 } 986 }
987 }, 987 },
988 "node_modules/css-what": { 988 "node_modules/css-what": {
989 "version": "5.0.0", 989 "version": "5.0.1",
990 "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.0.tgz", 990 "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
991 "integrity": "sha512-qxyKHQvgKwzwDWC/rGbT821eJalfupxYW2qbSJSAtdSTimsr/MlaGONoNLllaUPZWf8QnbcKM/kPVYUQuEKAFA==", 991 "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==",
992 "dev": true, 992 "dev": true,
993 "engines": { 993 "engines": {
994 "node": ">= 6" 994 "node": ">= 6"
@@ -4345,9 +4345,9 @@
4345 } 4345 }
4346 }, 4346 },
4347 "css-what": { 4347 "css-what": {
4348 "version": "5.0.0", 4348 "version": "5.0.1",
4349 "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.0.tgz", 4349 "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
4350 "integrity": "sha512-qxyKHQvgKwzwDWC/rGbT821eJalfupxYW2qbSJSAtdSTimsr/MlaGONoNLllaUPZWf8QnbcKM/kPVYUQuEKAFA==", 4350 "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==",
4351 "dev": true 4351 "dev": true
4352 }, 4352 },
4353 "debug": { 4353 "debug": {
diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs
index 06219d155..a9d434e20 100644
--- a/xtask/src/tidy.rs
+++ b/xtask/src/tidy.rs
@@ -371,7 +371,7 @@ fn check_trailing_ws(path: &Path, text: &str) {
371 } 371 }
372 for (line_number, line) in text.lines().enumerate() { 372 for (line_number, line) in text.lines().enumerate() {
373 if line.chars().last().map(char::is_whitespace) == Some(true) { 373 if line.chars().last().map(char::is_whitespace) == Some(true) {
374 panic!("Trailing whitespace in {} at line {}", path.display(), line_number) 374 panic!("Trailing whitespace in {} at line {}", path.display(), line_number + 1)
375 } 375 }
376 } 376 }
377} 377}