Skip to content

Commit 8929853

Browse files
committed
Auto merge of #16647 - Young-Flash:fix_replace_filter_map_next_with_find_map, r=Veykril
fix: replace_filter_map_next_with_find_map shouldn't work for dyn trait close #16596
2 parents e1983d2 + 7a58a23 commit 8929853

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

crates/hir-ty/src/diagnostics/expr.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use tracing::debug;
1717
use triomphe::Arc;
1818
use typed_arena::Arena;
1919

20+
use crate::Interner;
2021
use crate::{
2122
db::HirDatabase,
2223
diagnostics::match_check::{
@@ -149,17 +150,18 @@ impl ExprValidator {
149150
None => return,
150151
};
151152

152-
if filter_map_next_checker
153-
.get_or_insert_with(|| {
154-
FilterMapNextChecker::new(&self.owner.resolver(db.upcast()), db)
155-
})
156-
.check(call_id, receiver, &callee)
157-
.is_some()
158-
{
153+
let checker = filter_map_next_checker.get_or_insert_with(|| {
154+
FilterMapNextChecker::new(&self.owner.resolver(db.upcast()), db)
155+
});
156+
157+
if checker.check(call_id, receiver, &callee).is_some() {
159158
self.diagnostics.push(BodyValidationDiagnostic::ReplaceFilterMapNextWithFindMap {
160159
method_call_expr: call_id,
161160
});
162161
}
162+
163+
let receiver_ty = self.infer[*receiver].clone();
164+
checker.prev_receiver_ty = Some(receiver_ty);
163165
}
164166
}
165167

@@ -393,6 +395,7 @@ struct FilterMapNextChecker {
393395
filter_map_function_id: Option<hir_def::FunctionId>,
394396
next_function_id: Option<hir_def::FunctionId>,
395397
prev_filter_map_expr_id: Option<ExprId>,
398+
prev_receiver_ty: Option<chalk_ir::Ty<Interner>>,
396399
}
397400

398401
impl FilterMapNextChecker {
@@ -417,7 +420,12 @@ impl FilterMapNextChecker {
417420
),
418421
None => (None, None),
419422
};
420-
Self { filter_map_function_id, next_function_id, prev_filter_map_expr_id: None }
423+
Self {
424+
filter_map_function_id,
425+
next_function_id,
426+
prev_filter_map_expr_id: None,
427+
prev_receiver_ty: None,
428+
}
421429
}
422430

423431
// check for instances of .filter_map(..).next()
@@ -434,7 +442,11 @@ impl FilterMapNextChecker {
434442

435443
if *function_id == self.next_function_id? {
436444
if let Some(prev_filter_map_expr_id) = self.prev_filter_map_expr_id {
437-
if *receiver_expr_id == prev_filter_map_expr_id {
445+
let is_dyn_trait = self
446+
.prev_receiver_ty
447+
.as_ref()
448+
.map_or(false, |it| it.strip_references().dyn_trait().is_some());
449+
if *receiver_expr_id == prev_filter_map_expr_id && !is_dyn_trait {
438450
return Some(());
439451
}
440452
}

crates/ide-diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,21 @@ fn foo() {
8080
);
8181
}
8282

83+
#[test]
84+
fn replace_filter_map_next_dont_work_for_not_sized_issues_16596() {
85+
check_diagnostics(
86+
r#"
87+
//- minicore: iterators
88+
fn foo() {
89+
let mut j = [0].into_iter();
90+
let i: &mut dyn Iterator<Item = i32> = &mut j;
91+
let dummy_fn = |v| (v > 0).then_some(v + 1);
92+
let _res = i.filter_map(dummy_fn).next();
93+
}
94+
"#,
95+
);
96+
}
97+
8398
#[test]
8499
fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() {
85100
check_diagnostics(

0 commit comments

Comments
 (0)