fix: value used by exprs are not warned (#1664)

This commit is contained in:
Myriad-Dreamin 2025-04-16 15:37:11 +08:00 committed by GitHub
parent 4d13734fed
commit 14f0a20ed6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 94 additions and 10 deletions

View file

@ -112,6 +112,7 @@ impl<'w> Linter<'w> {
linter: self,
func_info,
return_block_info: None,
expr_context: ExprContext::Block,
})
}
@ -393,6 +394,7 @@ struct LateFuncLinter<'a, 'b> {
linter: &'a mut Linter<'b>,
func_info: FuncInfo,
return_block_info: Option<ReturnBlockInfo>,
expr_context: ExprContext,
}
impl LateFuncLinter<'_, '_> {
@ -410,6 +412,16 @@ impl LateFuncLinter<'_, '_> {
self.expr(expr.body())
}
fn expr_ctx<F>(&mut self, ctx: ExprContext, f: F) -> Option<()>
where
F: FnOnce(&mut Self) -> Option<()>,
{
let old = std::mem::replace(&mut self.expr_context, ctx);
f(self);
self.expr_context = old;
Some(())
}
fn join(&mut self, parent: Option<ReturnBlockInfo>) {
if let Some(parent) = parent {
match &mut self.return_block_info {
@ -438,7 +450,7 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
}
fn block<'a>(&mut self, exprs: impl DoubleEndedIterator<Item = ast::Expr<'a>>) -> Option<()> {
self.exprs(exprs)
self.expr_ctx(ExprContext::Block, |this| this.exprs(exprs))
}
fn loop_break(&mut self, _expr: ast::LoopBreak<'_>) -> Option<()> {
@ -490,6 +502,20 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
Some(())
}
fn field_access(&mut self, _expr: ast::FieldAccess<'_>) -> Option<()> {
Some(())
}
fn unary(&mut self, expr: ast::Unary<'_>) -> Option<()> {
self.expr_ctx(ExprContext::Expr, |this| this.expr(expr.expr()))
}
fn binary(&mut self, expr: ast::Binary<'_>) -> Option<()> {
self.expr_ctx(ExprContext::Expr, |this| {
this.exprs([expr.lhs(), expr.rhs()].into_iter())
})
}
fn equation(&mut self, expr: ast::Equation<'_>) -> Option<()> {
self.value(ast::Expr::Equation(expr));
Some(())
@ -505,6 +531,11 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
Some(())
}
fn include(&mut self, expr: ast::ModuleInclude<'_>) -> Option<()> {
self.value(ast::Expr::Include(expr));
Some(())
}
fn func_call(&mut self, _expr: ast::FuncCall<'_>) -> Option<()> {
Some(())
}
@ -532,6 +563,11 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
}
fn value(&mut self, expr: ast::Expr) -> Option<()> {
match self.expr_context {
ExprContext::Block => {}
ExprContext::Expr => return None,
}
let ri = self.return_block_info.as_mut()?;
if ri.warned {
return None;
@ -573,10 +609,6 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
Some(())
}
fn field_access(&mut self, _expr: ast::FieldAccess<'_>) -> Option<()> {
Some(())
}
fn show(&mut self, expr: ast::ShowRule<'_>) -> Option<()> {
self.value(ast::Expr::Show(expr));
Some(())
@ -594,11 +626,6 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
fn while_loop(&mut self, expr: ast::WhileLoop<'_>) -> Option<()> {
self.expr(expr.body())
}
fn include(&mut self, expr: ast::ModuleInclude<'_>) -> Option<()> {
self.value(ast::Expr::Include(expr));
Some(())
}
}
#[derive(Clone, Default)]
@ -974,6 +1001,11 @@ impl BuggyBlockLoc<'_> {
}
}
enum ExprContext {
Block,
Expr,
}
fn is_show_set(it: ast::Expr) -> bool {
matches!(it, ast::Expr::Set(..) | ast::Expr::Show(..))
}