|
2 | 2 |
|
3 | 3 | use std::sync::Arc;
|
4 | 4 |
|
5 |
| -use hir_def::{expr::Statement, path::path, resolver::HasResolver, AdtId, DefWithBodyId}; |
6 |
| -use hir_expand::diagnostics::DiagnosticSink; |
| 5 | +use hir_def::{AdtId, AssocItemId, DefWithBodyId, expr::Statement, path::path, resolver::HasResolver}; |
| 6 | +use hir_expand::{diagnostics::DiagnosticSink, name}; |
7 | 7 | use rustc_hash::FxHashSet;
|
8 | 8 | use syntax::{ast, AstPtr};
|
9 | 9 |
|
@@ -155,19 +155,39 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
155 | 155 | }
|
156 | 156 |
|
157 | 157 | fn check_for_filter_map_next(&mut self, db: &dyn HirDatabase) {
|
| 158 | + // Find the FunctionIds for Iterator::filter_map and Iterator::next |
| 159 | + let iterator_path = path![core::iter::Iterator]; |
| 160 | + let resolver = self.owner.resolver(db.upcast()); |
| 161 | + let iterator_trait_id = match resolver.resolve_known_trait(db.upcast(), &iterator_path) { |
| 162 | + Some(id) => id, |
| 163 | + None => return, |
| 164 | + }; |
| 165 | + 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]) { |
| 167 | + Some((_, AssocItemId::FunctionId(id))) => id, |
| 168 | + _ => return, |
| 169 | + }; |
| 170 | + let next_function_id = match iterator_trait_items.iter().find(|item| item.0 == name![next]) { |
| 171 | + Some((_, AssocItemId::FunctionId(id))) => id, |
| 172 | + _ => return, |
| 173 | + }; |
| 174 | + |
| 175 | + // Search function body for instances of .filter_map(..).next() |
158 | 176 | let body = db.body(self.owner.into());
|
159 | 177 | let mut prev = None;
|
160 |
| - |
161 | 178 | for (id, expr) in body.exprs.iter() {
|
162 |
| - if let Expr::MethodCall { receiver, method_name, args, .. } = expr { |
163 |
| - let method_name = format!("{}", method_name); |
| 179 | + if let Expr::MethodCall { receiver, .. } = expr { |
| 180 | + let function_id = match self.infer.method_resolution(id) { |
| 181 | + Some(id) => id, |
| 182 | + None => continue, |
| 183 | + }; |
164 | 184 |
|
165 |
| - if method_name == "filter_map" && args.len() == 1 { |
| 185 | + if function_id == *filter_map_function_id { |
166 | 186 | prev = Some(id);
|
167 | 187 | continue;
|
168 | 188 | }
|
169 | 189 |
|
170 |
| - if method_name == "next" { |
| 190 | + if function_id == *next_function_id { |
171 | 191 | if let Some(filter_map_id) = prev {
|
172 | 192 | if *receiver == filter_map_id {
|
173 | 193 | let (_, source_map) = db.body_with_source_map(self.owner.into());
|
|
0 commit comments