1 use clippy_utils
::diagnostics
::span_lint_and_help
;
2 use clippy_utils
::source
::snippet
;
3 use clippy_utils
::{is_entrypoint_fn, is_no_std_crate}
;
4 use rustc_hir
::{Expr, ExprKind, QPath}
;
5 use rustc_lint
::{LateContext, LateLintPass}
;
6 use rustc_session
::impl_lint_pass
;
10 /// Checks for recursion using the entrypoint.
12 /// ### Why is this bad?
13 /// Apart from special setups (which we could detect following attributes like #![no_std]),
14 /// recursing into main() seems like an unintuitive anti-pattern we should be able to detect.
22 #[clippy::version = "1.38.0"]
25 "recursion using the entrypoint"
29 pub struct MainRecursion
{
30 has_no_std_attr
: bool
,
33 impl_lint_pass
!(MainRecursion
=> [MAIN_RECURSION
]);
35 impl LateLintPass
<'_
> for MainRecursion
{
36 fn check_crate(&mut self, cx
: &LateContext
<'_
>) {
37 self.has_no_std_attr
= is_no_std_crate(cx
);
40 fn check_expr_post(&mut self, cx
: &LateContext
<'_
>, expr
: &Expr
<'_
>) {
41 if self.has_no_std_attr
{
45 if let ExprKind
::Call(func
, _
) = &expr
.kind
46 && let ExprKind
::Path(QPath
::Resolved(_
, path
)) = &func
.kind
47 && let Some(def_id
) = path
.res
.opt_def_id()
48 && is_entrypoint_fn(cx
, def_id
)
54 format
!("recursing into entrypoint `{}`", snippet(cx
, func
.span
, "main")),
56 "consider using another function for this recursion",