aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/diagnostics.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-06-13 18:32:54 +0100
committerAleksey Kladov <[email protected]>2021-06-13 18:32:54 +0100
commitde1fc70ccd3bf7a0850e036a12cf866a80d46458 (patch)
treed93cc6be7678b8be01a5162e80bb3f8df84e8c50 /crates/ide/src/diagnostics.rs
parent24262f9ff6ae9ea326fa35d238704d18e99d52a1 (diff)
internal: refactor find_map diagnostic
Diffstat (limited to 'crates/ide/src/diagnostics.rs')
-rw-r--r--crates/ide/src/diagnostics.rs88
1 files changed, 2 insertions, 86 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index e3974e1ae..ec5318594 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -13,6 +13,7 @@ mod missing_ok_or_some_in_tail_expr;
13mod missing_unsafe; 13mod missing_unsafe;
14mod no_such_field; 14mod no_such_field;
15mod remove_this_semicolon; 15mod remove_this_semicolon;
16mod replace_filter_map_next_with_find_map;
16mod unimplemented_builtin_macro; 17mod unimplemented_builtin_macro;
17mod unresolved_extern_crate; 18mod unresolved_extern_crate;
18mod unresolved_import; 19mod unresolved_import;
@@ -167,9 +168,6 @@ pub(crate) fn diagnostics(
167 .on::<hir::diagnostics::IncorrectCase, _>(|d| { 168 .on::<hir::diagnostics::IncorrectCase, _>(|d| {
168 res.borrow_mut().push(warning_with_fix(d, &sema, resolve)); 169 res.borrow_mut().push(warning_with_fix(d, &sema, resolve));
169 }) 170 })
170 .on::<hir::diagnostics::ReplaceFilterMapNextWithFindMap, _>(|d| {
171 res.borrow_mut().push(warning_with_fix(d, &sema, resolve));
172 })
173 .on::<UnlinkedFile, _>(|d| { 171 .on::<UnlinkedFile, _>(|d| {
174 // Limit diagnostic to the first few characters in the file. This matches how VS Code 172 // Limit diagnostic to the first few characters in the file. This matches how VS Code
175 // renders it with the full span, but on other editors, and is less invasive. 173 // renders it with the full span, but on other editors, and is less invasive.
@@ -225,6 +223,7 @@ pub(crate) fn diagnostics(
225 AnyDiagnostic::MissingUnsafe(d) => missing_unsafe::missing_unsafe(&ctx, &d), 223 AnyDiagnostic::MissingUnsafe(d) => missing_unsafe::missing_unsafe(&ctx, &d),
226 AnyDiagnostic::NoSuchField(d) => no_such_field::no_such_field(&ctx, &d), 224 AnyDiagnostic::NoSuchField(d) => no_such_field::no_such_field(&ctx, &d),
227 AnyDiagnostic::RemoveThisSemicolon(d) => remove_this_semicolon::remove_this_semicolon(&ctx, &d), 225 AnyDiagnostic::RemoveThisSemicolon(d) => remove_this_semicolon::remove_this_semicolon(&ctx, &d),
226 AnyDiagnostic::ReplaceFilterMapNextWithFindMap(d) => replace_filter_map_next_with_find_map::replace_filter_map_next_with_find_map(&ctx, &d),
228 AnyDiagnostic::UnimplementedBuiltinMacro(d) => unimplemented_builtin_macro::unimplemented_builtin_macro(&ctx, &d), 227 AnyDiagnostic::UnimplementedBuiltinMacro(d) => unimplemented_builtin_macro::unimplemented_builtin_macro(&ctx, &d),
229 AnyDiagnostic::UnresolvedExternCrate(d) => unresolved_extern_crate::unresolved_extern_crate(&ctx, &d), 228 AnyDiagnostic::UnresolvedExternCrate(d) => unresolved_extern_crate::unresolved_extern_crate(&ctx, &d),
230 AnyDiagnostic::UnresolvedImport(d) => unresolved_import::unresolved_import(&ctx, &d), 229 AnyDiagnostic::UnresolvedImport(d) => unresolved_import::unresolved_import(&ctx, &d),
@@ -672,89 +671,6 @@ mod foo;
672 ); 671 );
673 } 672 }
674 673
675 // Register the required standard library types to make the tests work
676 fn add_filter_map_with_find_next_boilerplate(body: &str) -> String {
677 let prefix = r#"
678 //- /main.rs crate:main deps:core
679 use core::iter::Iterator;
680 use core::option::Option::{self, Some, None};
681 "#;
682 let suffix = r#"
683 //- /core/lib.rs crate:core
684 pub mod option {
685 pub enum Option<T> { Some(T), None }
686 }
687 pub mod iter {
688 pub trait Iterator {
689 type Item;
690 fn filter_map<B, F>(self, f: F) -> FilterMap where F: FnMut(Self::Item) -> Option<B> { FilterMap }
691 fn next(&mut self) -> Option<Self::Item>;
692 }
693 pub struct FilterMap {}
694 impl Iterator for FilterMap {
695 type Item = i32;
696 fn next(&mut self) -> i32 { 7 }
697 }
698 }
699 "#;
700 format!("{}{}{}", prefix, body, suffix)
701 }
702
703 #[test]
704 fn replace_filter_map_next_with_find_map2() {
705 check_diagnostics(&add_filter_map_with_find_next_boilerplate(
706 r#"
707 fn foo() {
708 let m = [1, 2, 3].iter().filter_map(|x| if *x == 2 { Some (4) } else { None }).next();
709 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ replace filter_map(..).next() with find_map(..)
710 }
711 "#,
712 ));
713 }
714
715 #[test]
716 fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() {
717 check_diagnostics(&add_filter_map_with_find_next_boilerplate(
718 r#"
719 fn foo() {
720 let m = [1, 2, 3]
721 .iter()
722 .filter_map(|x| if *x == 2 { Some (4) } else { None })
723 .len();
724 }
725 "#,
726 ));
727 }
728
729 #[test]
730 fn replace_filter_map_next_with_find_map_no_diagnostic_with_intervening_methods() {
731 check_diagnostics(&add_filter_map_with_find_next_boilerplate(
732 r#"
733 fn foo() {
734 let m = [1, 2, 3]
735 .iter()
736 .filter_map(|x| if *x == 2 { Some (4) } else { None })
737 .map(|x| x + 2)
738 .len();
739 }
740 "#,
741 ));
742 }
743
744 #[test]
745 fn replace_filter_map_next_with_find_map_no_diagnostic_if_not_in_chain() {
746 check_diagnostics(&add_filter_map_with_find_next_boilerplate(
747 r#"
748 fn foo() {
749 let m = [1, 2, 3]
750 .iter()
751 .filter_map(|x| if *x == 2 { Some (4) } else { None });
752 let n = m.next();
753 }
754 "#,
755 ));
756 }
757
758 #[test] 674 #[test]
759 fn missing_record_pat_field_no_diagnostic_if_not_exhaustive() { 675 fn missing_record_pat_field_no_diagnostic_if_not_exhaustive() {
760 check_diagnostics( 676 check_diagnostics(