Skip to main content

forge_lint/sol/med/
non_reentrant_not_first.rs

1use super::NonReentrantNotFirst;
2use crate::{
3    linter::{LateLintPass, LintContext},
4    sol::{Severity, SolLint},
5};
6use solar::sema::{
7    Gcx,
8    hir::{self, FunctionKind},
9};
10
11declare_forge_lint!(
12    NON_REENTRANT_NOT_FIRST,
13    Severity::Med,
14    "non-reentrant-not-first",
15    "`nonReentrant` is not the first modifier"
16);
17
18impl<'gcx> LateLintPass<'gcx> for NonReentrantNotFirst {
19    fn check_function(
20        &mut self,
21        ctx: &LintContext,
22        gcx: Gcx<'gcx>,
23        func: &'gcx hir::Function<'gcx>,
24    ) {
25        if !matches!(
26            func.kind,
27            FunctionKind::Function | FunctionKind::Fallback | FunctionKind::Receive
28        ) {
29            return;
30        }
31        for modifier in func.modifiers.iter().skip(1) {
32            let is_non_reentrant = modifier.id.as_function().is_some_and(|id| {
33                gcx.hir.function(id).name.is_some_and(|name| name.as_str() == "nonReentrant")
34            });
35            if is_non_reentrant {
36                ctx.emit(&NON_REENTRANT_NOT_FIRST, modifier.span);
37            }
38        }
39    }
40}