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 https://github.com/rust-lang/rust-analyzer/issues/16596
This commit is contained in:
commit
8929853df7
@ -17,6 +17,7 @@
|
|||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
use typed_arena::Arena;
|
use typed_arena::Arena;
|
||||||
|
|
||||||
|
use crate::Interner;
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
diagnostics::match_check::{
|
diagnostics::match_check::{
|
||||||
@ -149,17 +150,18 @@ fn validate_call(
|
|||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if filter_map_next_checker
|
let checker = filter_map_next_checker.get_or_insert_with(|| {
|
||||||
.get_or_insert_with(|| {
|
FilterMapNextChecker::new(&self.owner.resolver(db.upcast()), db)
|
||||||
FilterMapNextChecker::new(&self.owner.resolver(db.upcast()), db)
|
});
|
||||||
})
|
|
||||||
.check(call_id, receiver, &callee)
|
if checker.check(call_id, receiver, &callee).is_some() {
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
self.diagnostics.push(BodyValidationDiagnostic::ReplaceFilterMapNextWithFindMap {
|
self.diagnostics.push(BodyValidationDiagnostic::ReplaceFilterMapNextWithFindMap {
|
||||||
method_call_expr: call_id,
|
method_call_expr: call_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let receiver_ty = self.infer[*receiver].clone();
|
||||||
|
checker.prev_receiver_ty = Some(receiver_ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +395,7 @@ struct FilterMapNextChecker {
|
|||||||
filter_map_function_id: Option<hir_def::FunctionId>,
|
filter_map_function_id: Option<hir_def::FunctionId>,
|
||||||
next_function_id: Option<hir_def::FunctionId>,
|
next_function_id: Option<hir_def::FunctionId>,
|
||||||
prev_filter_map_expr_id: Option<ExprId>,
|
prev_filter_map_expr_id: Option<ExprId>,
|
||||||
|
prev_receiver_ty: Option<chalk_ir::Ty<Interner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterMapNextChecker {
|
impl FilterMapNextChecker {
|
||||||
@ -417,7 +420,12 @@ fn new(resolver: &hir_def::resolver::Resolver, db: &dyn HirDatabase) -> Self {
|
|||||||
),
|
),
|
||||||
None => (None, None),
|
None => (None, None),
|
||||||
};
|
};
|
||||||
Self { filter_map_function_id, next_function_id, prev_filter_map_expr_id: None }
|
Self {
|
||||||
|
filter_map_function_id,
|
||||||
|
next_function_id,
|
||||||
|
prev_filter_map_expr_id: None,
|
||||||
|
prev_receiver_ty: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for instances of .filter_map(..).next()
|
// check for instances of .filter_map(..).next()
|
||||||
@ -434,7 +442,11 @@ fn check(
|
|||||||
|
|
||||||
if *function_id == self.next_function_id? {
|
if *function_id == self.next_function_id? {
|
||||||
if let Some(prev_filter_map_expr_id) = self.prev_filter_map_expr_id {
|
if let Some(prev_filter_map_expr_id) = self.prev_filter_map_expr_id {
|
||||||
if *receiver_expr_id == prev_filter_map_expr_id {
|
let is_dyn_trait = self
|
||||||
|
.prev_receiver_ty
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |it| it.strip_references().dyn_trait().is_some());
|
||||||
|
if *receiver_expr_id == prev_filter_map_expr_id && !is_dyn_trait {
|
||||||
return Some(());
|
return Some(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,21 @@ fn foo() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn replace_filter_map_next_dont_work_for_not_sized_issues_16596() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
//- minicore: iterators
|
||||||
|
fn foo() {
|
||||||
|
let mut j = [0].into_iter();
|
||||||
|
let i: &mut dyn Iterator<Item = i32> = &mut j;
|
||||||
|
let dummy_fn = |v| (v > 0).then_some(v + 1);
|
||||||
|
let _res = i.filter_map(dummy_fn).next();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() {
|
fn replace_filter_map_next_with_find_map_no_diagnostic_without_next() {
|
||||||
check_diagnostics(
|
check_diagnostics(
|
||||||
|
Loading…
Reference in New Issue
Block a user