Skip to content

Commit 997b9da

Browse files
thomanskioli-obk
authored andcommitted
Lint calls to main unless #![no_std] attr set
fixes rust-lang#333
1 parent 4f473f7 commit 997b9da

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

clippy_lints/src/methods.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,24 @@ declare_lint! {
521521
"using `.cloned().collect()` on slice to create a `Vec`"
522522
}
523523

524+
/// **What it does:** Checks for calls to the main function
525+
///
526+
/// **Why is this bad?** Recursing the main function is unlikely what was intended
527+
///
528+
/// **Known problems:** None.
529+
///
530+
/// **Example:**
531+
/// ```rust
532+
/// fn foo() {
533+
/// ::main();
534+
/// }
535+
/// ```
536+
declare_lint! {
537+
pub CALLING_MAIN,
538+
Warn,
539+
"manually called the main function"
540+
}
541+
524542
impl LintPass for Pass {
525543
fn get_lints(&self) -> LintArray {
526544
lint_array!(OPTION_UNWRAP_USED,
@@ -545,14 +563,15 @@ impl LintPass for Pass {
545563
ITER_SKIP_NEXT,
546564
GET_UNWRAP,
547565
STRING_EXTEND_CHARS,
566+
CALLING_MAIN,
548567
ITER_CLONED_COLLECT)
549568
}
550569
}
551570

552571
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
553572
#[allow(unused_attributes)]
554573
// ^ required because `cyclomatic_complexity` attribute shows up as unused
555-
#[cyclomatic_complexity = "30"]
574+
#[cyclomatic_complexity = "31"]
556575
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
557576
if in_macro(cx, expr.span) {
558577
return;
@@ -627,6 +646,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
627646
lint_chars_next(cx, expr, rhs, lhs, op.node == hir::BiEq);
628647
}
629648
},
649+
hir::ExprCall(ref func, ref args) => {
650+
if args.is_empty() {
651+
// libs don't have a main
652+
if let Some((main, _)) = *cx.sess().entry_fn.borrow() {
653+
if let hir::ExprPath(ref qpath) = func.node {
654+
let main_did = cx.tcx.hir.local_def_id(main);
655+
let fun_did = cx.tables.qpath_def(qpath, func.id).def_id();
656+
if main_did == fun_did {
657+
span_lint(cx, CALLING_MAIN, expr.span, "called the `main` function manually");
658+
}
659+
}
660+
}
661+
}
662+
},
630663
_ => (),
631664
}
632665
}

tests/compile-fail/calling_main.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(plugin)]
2+
#![plugin(clippy)]
3+
#![deny(calling_main)]
4+
5+
fn main() {}
6+
7+
#[allow(dead_code)]
8+
fn calling_main() {
9+
main(); //~ERROR calling into main() detected
10+
}
11+

0 commit comments

Comments
 (0)