diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/hir_ty/src/diagnostics.rs | 48 | ||||
| -rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 16 |
2 files changed, 48 insertions, 16 deletions
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs index 6eaa1beb8..323c5f963 100644 --- a/crates/hir_ty/src/diagnostics.rs +++ b/crates/hir_ty/src/diagnostics.rs | |||
| @@ -670,21 +670,49 @@ fn foo() { break; } | |||
| 670 | ); | 670 | ); |
| 671 | } | 671 | } |
| 672 | 672 | ||
| 673 | // Register the required standard library types to make the tests work | ||
| 674 | fn add_filter_map_with_find_next_boilerplate(body: &str) -> String { | ||
| 675 | let prefix = r#" | ||
| 676 | //- /main.rs crate:main deps:core | ||
| 677 | use core::iter::Iterator; | ||
| 678 | use core::option::Option::{self, Some, None}; | ||
| 679 | "#; | ||
| 680 | let suffix = r#" | ||
| 681 | //- /core/lib.rs crate:core | ||
| 682 | pub mod option { | ||
| 683 | pub enum Option<T> { Some(T), None } | ||
| 684 | } | ||
| 685 | pub mod iter { | ||
| 686 | pub trait Iterator { | ||
| 687 | type Item; | ||
| 688 | fn filter_map<B, F>(self, f: F) -> FilterMap where F: FnMut(Self::Item) -> Option<B> { FilterMap } | ||
| 689 | fn next(&mut self) -> Option<Self::Item>; | ||
| 690 | } | ||
| 691 | pub struct FilterMap {} | ||
| 692 | impl Iterator for FilterMap { | ||
| 693 | type Item = i32; | ||
| 694 | fn next(&mut self) -> i32 { 7 } | ||
| 695 | } | ||
| 696 | } | ||
| 697 | "#; | ||
| 698 | format!("{}{}{}", prefix, body, suffix) | ||
| 699 | } | ||
| 700 | |||
| 673 | #[test] | 701 | #[test] |
| 674 | fn replace_filter_map_next_with_find_map() { | 702 | fn replace_filter_map_next_with_find_map2() { |
| 675 | check_diagnostics( | 703 | check_diagnostics(&add_filter_map_with_find_next_boilerplate( |
| 676 | r#" | 704 | r#" |
| 677 | fn foo() { | 705 | fn foo() { |
| 678 | let m = [1, 2, 3].iter().filter_map(|x| if *x == 2 { Some (4) } else { None }).next(); | 706 | let m = [1, 2, 3].iter().filter_map(|x| if *x == 2 { Some (4) } else { None }).next(); |
| 679 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ replace filter_map(..).next() with find_map(..) | 707 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ replace filter_map(..).next() with find_map(..) |
| 680 | } | 708 | } |
| 681 | "#, | 709 | "#, |
| 682 | ); | 710 | )); |
| 683 | } | 711 | } |
| 684 | 712 | ||
| 685 | #[test] | 713 | #[test] |
| 686 | fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() { | 714 | fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() { |
| 687 | check_diagnostics( | 715 | check_diagnostics(&add_filter_map_with_find_next_boilerplate( |
| 688 | r#" | 716 | r#" |
| 689 | fn foo() { | 717 | fn foo() { |
| 690 | let m = [1, 2, 3] | 718 | let m = [1, 2, 3] |
| @@ -693,12 +721,12 @@ fn foo() { break; } | |||
| 693 | .len(); | 721 | .len(); |
| 694 | } | 722 | } |
| 695 | "#, | 723 | "#, |
| 696 | ); | 724 | )); |
| 697 | } | 725 | } |
| 698 | 726 | ||
| 699 | #[test] | 727 | #[test] |
| 700 | fn replace_filter_map_next_with_find_map_no_diagnostic_with_intervening_methods() { | 728 | fn replace_filter_map_next_with_find_map_no_diagnostic_with_intervening_methods() { |
| 701 | check_diagnostics( | 729 | check_diagnostics(&add_filter_map_with_find_next_boilerplate( |
| 702 | r#" | 730 | r#" |
| 703 | fn foo() { | 731 | fn foo() { |
| 704 | let m = [1, 2, 3] | 732 | let m = [1, 2, 3] |
| @@ -708,12 +736,12 @@ fn foo() { break; } | |||
| 708 | .len(); | 736 | .len(); |
| 709 | } | 737 | } |
| 710 | "#, | 738 | "#, |
| 711 | ); | 739 | )); |
| 712 | } | 740 | } |
| 713 | 741 | ||
| 714 | #[test] | 742 | #[test] |
| 715 | fn replace_filter_map_next_with_find_map_no_diagnostic_if_not_in_chain() { | 743 | fn replace_filter_map_next_with_find_map_no_diagnostic_if_not_in_chain() { |
| 716 | check_diagnostics( | 744 | check_diagnostics(&add_filter_map_with_find_next_boilerplate( |
| 717 | r#" | 745 | r#" |
| 718 | fn foo() { | 746 | fn foo() { |
| 719 | let m = [1, 2, 3] | 747 | let m = [1, 2, 3] |
| @@ -722,6 +750,6 @@ fn foo() { break; } | |||
| 722 | let n = m.next(); | 750 | let n = m.next(); |
| 723 | } | 751 | } |
| 724 | "#, | 752 | "#, |
| 725 | ); | 753 | )); |
| 726 | } | 754 | } |
| 727 | } | 755 | } |
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 16bbd48fb..d740b7265 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
| @@ -2,7 +2,9 @@ | |||
| 2 | 2 | ||
| 3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
| 4 | 4 | ||
| 5 | use hir_def::{AdtId, AssocItemId, DefWithBodyId, expr::Statement, path::path, resolver::HasResolver}; | 5 | use hir_def::{ |
| 6 | expr::Statement, path::path, resolver::HasResolver, AdtId, AssocItemId, DefWithBodyId, | ||
| 7 | }; | ||
| 6 | use hir_expand::{diagnostics::DiagnosticSink, name}; | 8 | use hir_expand::{diagnostics::DiagnosticSink, name}; |
| 7 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
| 8 | use syntax::{ast, AstPtr}; | 10 | use syntax::{ast, AstPtr}; |
| @@ -163,11 +165,13 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
| 163 | None => return, | 165 | None => return, |
| 164 | }; | 166 | }; |
| 165 | let iterator_trait_items = &db.trait_data(iterator_trait_id).items; | 167 | let iterator_trait_items = &db.trait_data(iterator_trait_id).items; |
| 166 | let filter_map_function_id = match iterator_trait_items.iter().find(|item| item.0 == name![filter_map]) { | 168 | let filter_map_function_id = |
| 167 | Some((_, AssocItemId::FunctionId(id))) => id, | 169 | match iterator_trait_items.iter().find(|item| item.0 == name![filter_map]) { |
| 168 | _ => return, | 170 | Some((_, AssocItemId::FunctionId(id))) => id, |
| 169 | }; | 171 | _ => return, |
| 170 | let next_function_id = match iterator_trait_items.iter().find(|item| item.0 == name![next]) { | 172 | }; |
| 173 | let next_function_id = match iterator_trait_items.iter().find(|item| item.0 == name![next]) | ||
| 174 | { | ||
| 171 | Some((_, AssocItemId::FunctionId(id))) => id, | 175 | Some((_, AssocItemId::FunctionId(id))) => id, |
| 172 | _ => return, | 176 | _ => return, |
| 173 | }; | 177 | }; |
