Auto merge of #16502 - davidsemakula:unnecessary-else-diagnostic, r=Veykril

feat: Add "unnecessary else" diagnostic and fix

Fixes #9457
This commit is contained in:
bors 2024-02-08 14:25:00 +00:00
commit e9d3565cd1
6 changed files with 447 additions and 4 deletions

View file

@ -27,7 +27,7 @@ use crate::{
pub(crate) use hir_def::{
body::Body,
hir::{Expr, ExprId, MatchArm, Pat, PatId},
hir::{Expr, ExprId, MatchArm, Pat, PatId, Statement},
LocalFieldId, VariantId,
};
@ -44,6 +44,9 @@ pub enum BodyValidationDiagnostic {
match_expr: ExprId,
uncovered_patterns: String,
},
RemoveUnnecessaryElse {
if_expr: ExprId,
},
}
impl BodyValidationDiagnostic {
@ -90,6 +93,9 @@ impl ExprValidator {
Expr::Call { .. } | Expr::MethodCall { .. } => {
self.validate_call(db, id, expr, &mut filter_map_next_checker);
}
Expr::If { .. } => {
self.check_for_unnecessary_else(id, expr, &body);
}
_ => {}
}
}
@ -237,6 +243,27 @@ impl ExprValidator {
}
pattern
}
fn check_for_unnecessary_else(&mut self, id: ExprId, expr: &Expr, body: &Body) {
if let Expr::If { condition: _, then_branch, else_branch } = expr {
if else_branch.is_none() {
return;
}
if let Expr::Block { statements, tail, .. } = &body.exprs[*then_branch] {
let last_then_expr = tail.or_else(|| match statements.last()? {
Statement::Expr { expr, .. } => Some(*expr),
_ => None,
});
if let Some(last_then_expr) = last_then_expr {
let last_then_expr_ty = &self.infer[last_then_expr];
if last_then_expr_ty.is_never() {
self.diagnostics
.push(BodyValidationDiagnostic::RemoveUnnecessaryElse { if_expr: id })
}
}
}
}
}
}
struct FilterMapNextChecker {