Skip to content

Commit bcc87b6

Browse files
committed
rust-lang#333 Catches calls to main() unless #![no_std] attr set (2nd commit: the remaining changes)
1 parent b83c83f commit bcc87b6

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ A collection of lints to catch common mistakes and improve your Rust code.
66
[Jump to usage instructions](#usage)
77

88
##Lints
9-
There are 58 lints included in this crate:
9+
There are 59 lints included in this crate:
1010

1111
name | default | meaning
1212
-------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1313
[approx_constant](https://github.com/Manishearth/rust-clippy/wiki#approx_constant) | warn | the approximate of a known float constant (in `std::f64::consts` or `std::f32::consts`) is found; suggests to use the constant
1414
[bad_bit_mask](https://github.com/Manishearth/rust-clippy/wiki#bad_bit_mask) | warn | expressions of the form `_ & mask == select` that will only ever return `true` or `false` (because in the example `select` containing bits that `mask` doesn't have)
1515
[box_vec](https://github.com/Manishearth/rust-clippy/wiki#box_vec) | warn | usage of `Box<Vec<T>>`, vector elements are already on the heap
16+
[calling_main](https://github.com/Manishearth/rust-clippy/wiki#calling_main) | warn | calling into main detected
1617
[cast_possible_truncation](https://github.com/Manishearth/rust-clippy/wiki#cast_possible_truncation) | allow | casts that may cause truncation of the value, e.g `x as u8` where `x: u32`, or `x as i32` where `x: f32`
1718
[cast_possible_wrap](https://github.com/Manishearth/rust-clippy/wiki#cast_possible_wrap) | allow | casts that may cause wrapping around the value, e.g `x as i32` where `x: u32` and `x > i32::MAX`
1819
[cast_precision_loss](https://github.com/Manishearth/rust-clippy/wiki#cast_precision_loss) | allow | casts that cause loss of precision, e.g `x as f32` where `x: u64`

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
127127
loops::WHILE_LET_LOOP,
128128
matches::MATCH_REF_PATS,
129129
matches::SINGLE_MATCH,
130+
methods::CALLING_MAIN,
130131
methods::SHOULD_IMPLEMENT_TRAIT,
131132
methods::STR_TO_STRING,
132133
methods::STRING_TO_STRING,

src/methods.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
extern crate syntax;
2+
13
use rustc_front::hir::*;
24
use rustc::lint::*;
35
use rustc::middle::ty;
46
use rustc::middle::subst::Subst;
57
use std::iter;
68
use std::borrow::Cow;
9+
use syntax::ast::{Attribute, MetaWord};
710

811
use utils::{snippet, span_lint, match_path, match_type, walk_ptrs_ty_depth};
912
use utils::{OPTION_PATH, RESULT_PATH, STRING_PATH};
@@ -30,16 +33,37 @@ declare_lint!(pub WRONG_SELF_CONVENTION, Warn,
3033
declare_lint!(pub WRONG_PUB_SELF_CONVENTION, Allow,
3134
"defining a public method named with an established prefix (like \"into_\") that takes \
3235
`self` with the wrong convention");
36+
declare_lint!(pub CALLING_MAIN, Warn,
37+
"calling into main detected");
3338

3439
impl LintPass for MethodsPass {
3540
fn get_lints(&self) -> LintArray {
3641
lint_array!(OPTION_UNWRAP_USED, RESULT_UNWRAP_USED, STR_TO_STRING, STRING_TO_STRING,
37-
SHOULD_IMPLEMENT_TRAIT, WRONG_SELF_CONVENTION)
42+
SHOULD_IMPLEMENT_TRAIT, WRONG_SELF_CONVENTION, CALLING_MAIN)
3843
}
3944
}
4045

4146
impl LateLintPass for MethodsPass {
4247
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
48+
fn no_std_present(cx: &LateContext) -> bool {
49+
let attrs : &[Attribute] = &cx.krate.attrs; // TODO replace these two...
50+
for attr in attrs { // lines with ...
51+
// for &attr in cx.krate.attrs { ... once type inf on nightly fixed
52+
if let MetaWord(ref mword) = attr.node.value.node {
53+
if mword == &"no_std" { return true; }
54+
}
55+
}
56+
false
57+
}
58+
if let ExprCall(ref func, ref args) = expr.node {
59+
if args.is_empty() {
60+
if let ExprPath(_, path) = func.node.clone() {
61+
if !path.global && path.segments[0].identifier.name.as_str() == "main" && !no_std_present(cx) {
62+
span_lint(cx, CALLING_MAIN, expr.span, "calling into main() detected");
63+
}
64+
}
65+
}
66+
}
4367
if let ExprMethodCall(ref name, _, ref args) = expr.node {
4468
let (obj_ty, ptr_depth) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&args[0]));
4569
if name.node.as_str() == "unwrap" {

0 commit comments

Comments
 (0)