mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
Add new lint: large stack array
added documentation minor style fix change as to ::from add ignore to doc include threshold in lint message/make suggestion more apparent/use Scalar api instead of matching style fix shange snippet_opt to snippet
This commit is contained in:
parent
79d3b30cd7
commit
7fddac0404
9 changed files with 150 additions and 3 deletions
|
@ -1059,6 +1059,7 @@ Released 2018-09-13
|
|||
[`just_underscores_and_digits`]: https://rust-lang.github.io/rust-clippy/master/index.html#just_underscores_and_digits
|
||||
[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups
|
||||
[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
|
||||
[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays
|
||||
[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
|
||||
[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero
|
||||
[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
||||
|
||||
[There are 333 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
||||
[There are 334 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
||||
|
||||
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
||||
|
||||
|
|
67
clippy_lints/src/large_stack_arrays.rs
Normal file
67
clippy_lints/src/large_stack_arrays.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
use rustc::ty;
|
||||
use rustc::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
use if_chain::if_chain;
|
||||
|
||||
use crate::rustc_target::abi::LayoutOf;
|
||||
use crate::utils::{snippet, span_help_and_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for local arrays that may be too large.
|
||||
///
|
||||
/// **Why is this bad?** Large local arrays may cause stack overflow.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// let a = [0u32; 1_000_000];
|
||||
/// ```
|
||||
pub LARGE_STACK_ARRAYS,
|
||||
pedantic,
|
||||
"allocating large arrays on stack may cause stack overflow"
|
||||
}
|
||||
|
||||
pub struct LargeStackArrays {
|
||||
maximum_allowed_size: u64,
|
||||
}
|
||||
|
||||
impl LargeStackArrays {
|
||||
#[must_use]
|
||||
pub fn new(maximum_allowed_size: u64) -> Self {
|
||||
Self { maximum_allowed_size }
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]);
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeStackArrays {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) {
|
||||
if_chain! {
|
||||
if let ExprKind::Repeat(_, _) = expr.kind;
|
||||
if let ty::Array(element_type, cst) = cx.tables.expr_ty(expr).kind;
|
||||
if let ConstValue::Scalar(element_count) = cst.val;
|
||||
if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx);
|
||||
if let Ok(element_size) = cx.layout_of(element_type).map(|l| l.size.bytes());
|
||||
if self.maximum_allowed_size < element_count * element_size;
|
||||
then {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
LARGE_STACK_ARRAYS,
|
||||
expr.span,
|
||||
&format!(
|
||||
"allocating a local array larger than {} bytes",
|
||||
self.maximum_allowed_size
|
||||
),
|
||||
&format!(
|
||||
"consider allocating on the heap with vec!{}.into_boxed_slice()",
|
||||
snippet(cx, expr.span, "[...]")
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -211,6 +211,7 @@ pub mod int_plus_one;
|
|||
pub mod integer_division;
|
||||
pub mod items_after_statements;
|
||||
pub mod large_enum_variant;
|
||||
pub mod large_stack_arrays;
|
||||
pub mod len_zero;
|
||||
pub mod let_if_seq;
|
||||
pub mod lifetimes;
|
||||
|
@ -537,6 +538,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||
&integer_division::INTEGER_DIVISION,
|
||||
&items_after_statements::ITEMS_AFTER_STATEMENTS,
|
||||
&large_enum_variant::LARGE_ENUM_VARIANT,
|
||||
&large_stack_arrays::LARGE_STACK_ARRAYS,
|
||||
&len_zero::LEN_WITHOUT_IS_EMPTY,
|
||||
&len_zero::LEN_ZERO,
|
||||
&let_if_seq::USELESS_LET_IF_SEQ,
|
||||
|
@ -949,6 +951,8 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||
store.register_late_pass(|| box mutable_debug_assertion::DebugAssertWithMutCall);
|
||||
store.register_late_pass(|| box exit::Exit);
|
||||
store.register_late_pass(|| box to_digit_is_some::ToDigitIsSome);
|
||||
let array_size_threshold = conf.array_size_threshold;
|
||||
store.register_late_pass(move || box large_stack_arrays::LargeStackArrays::new(array_size_threshold));
|
||||
|
||||
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
|
||||
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
|
||||
|
@ -1002,6 +1006,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||
LintId::of(&if_not_else::IF_NOT_ELSE),
|
||||
LintId::of(&infinite_iter::MAYBE_INFINITE_ITER),
|
||||
LintId::of(&items_after_statements::ITEMS_AFTER_STATEMENTS),
|
||||
LintId::of(&large_stack_arrays::LARGE_STACK_ARRAYS),
|
||||
LintId::of(&literal_representation::LARGE_DIGIT_GROUPS),
|
||||
LintId::of(&loops::EXPLICIT_INTO_ITER_LOOP),
|
||||
LintId::of(&loops::EXPLICIT_ITER_LOOP),
|
||||
|
|
|
@ -151,6 +151,8 @@ define_Conf! {
|
|||
(trivial_copy_size_limit, "trivial_copy_size_limit", None => Option<u64>),
|
||||
/// Lint: TOO_MANY_LINES. The maximum number of lines a function or method can have
|
||||
(too_many_lines_threshold, "too_many_lines_threshold", 100 => u64),
|
||||
/// Lint: LARGE_STACK_ARRAYS. The maximum allowed size for arrays on the stack
|
||||
(array_size_threshold, "array_size_threshold", 512_000 => u64),
|
||||
}
|
||||
|
||||
impl Default for Conf {
|
||||
|
|
|
@ -6,7 +6,7 @@ pub use lint::Lint;
|
|||
pub use lint::LINT_LEVELS;
|
||||
|
||||
// begin lint list, do not remove this comment, it’s used in `update_lints`
|
||||
pub const ALL_LINTS: [Lint; 333] = [
|
||||
pub const ALL_LINTS: [Lint; 334] = [
|
||||
Lint {
|
||||
name: "absurd_extreme_comparisons",
|
||||
group: "correctness",
|
||||
|
@ -903,6 +903,13 @@ pub const ALL_LINTS: [Lint; 333] = [
|
|||
deprecation: None,
|
||||
module: "large_enum_variant",
|
||||
},
|
||||
Lint {
|
||||
name: "large_stack_arrays",
|
||||
group: "pedantic",
|
||||
desc: "allocating large arrays on stack may cause stack overflow",
|
||||
deprecation: None,
|
||||
module: "large_stack_arrays",
|
||||
},
|
||||
Lint {
|
||||
name: "len_without_is_empty",
|
||||
group: "style",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `third-party` at line 5 column 1
|
||||
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `third-party` at line 5 column 1
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
30
tests/ui/large_stack_arrays.rs
Normal file
30
tests/ui/large_stack_arrays.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
#![warn(clippy::large_stack_arrays)]
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct S {
|
||||
pub data: [u64; 32],
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum E {
|
||||
S(S),
|
||||
T(u32),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let bad = (
|
||||
[0u32; 20_000_000],
|
||||
[S { data: [0; 32] }; 5000],
|
||||
[Some(""); 20_000_000],
|
||||
[E::T(0); 5000],
|
||||
);
|
||||
|
||||
let good = (
|
||||
[0u32; 1000],
|
||||
[S { data: [0; 32] }; 1000],
|
||||
[Some(""); 1000],
|
||||
[E::T(0); 1000],
|
||||
[(); 20_000_000],
|
||||
);
|
||||
}
|
35
tests/ui/large_stack_arrays.stderr
Normal file
35
tests/ui/large_stack_arrays.stderr
Normal file
|
@ -0,0 +1,35 @@
|
|||
error: allocating a local array larger than 512000 bytes
|
||||
--> $DIR/large_stack_arrays.rs:17:9
|
||||
|
|
||||
LL | [0u32; 20_000_000],
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::large-stack-arrays` implied by `-D warnings`
|
||||
= help: consider allocating on the heap with vec![0u32; 20_000_000].into_boxed_slice()
|
||||
|
||||
error: allocating a local array larger than 512000 bytes
|
||||
--> $DIR/large_stack_arrays.rs:18:9
|
||||
|
|
||||
LL | [S { data: [0; 32] }; 5000],
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider allocating on the heap with vec![S { data: [0; 32] }; 5000].into_boxed_slice()
|
||||
|
||||
error: allocating a local array larger than 512000 bytes
|
||||
--> $DIR/large_stack_arrays.rs:19:9
|
||||
|
|
||||
LL | [Some(""); 20_000_000],
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider allocating on the heap with vec![Some(""); 20_000_000].into_boxed_slice()
|
||||
|
||||
error: allocating a local array larger than 512000 bytes
|
||||
--> $DIR/large_stack_arrays.rs:20:9
|
||||
|
|
||||
LL | [E::T(0); 5000],
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider allocating on the heap with vec![E::T(0); 5000].into_boxed_slice()
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
Loading…
Reference in a new issue