-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
250 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
use crate::rustc_target::abi::LayoutOf; | ||
use crate::utils::span_lint_and_then; | ||
use if_chain::if_chain; | ||
use rustc::mir::interpret::ConstValue; | ||
use rustc::ty::{self, ConstKind}; | ||
use rustc_errors::Applicability; | ||
use rustc_hir::{Item, ItemKind}; | ||
use rustc_lint::{LateContext, LateLintPass}; | ||
use rustc_session::{declare_tool_lint, impl_lint_pass}; | ||
use rustc_span::{BytePos, Pos, Span}; | ||
use rustc_typeck::hir_ty_to_ty; | ||
|
||
declare_clippy_lint! { | ||
/// **What it does:** Checks for large `const` arrays that should | ||
/// be defined as `static` instead. | ||
/// | ||
/// **Why is this bad?** Performance: const variables are inlined upon use. | ||
/// Static items result in only one instance and has a fixed location in memory. | ||
/// | ||
/// **Known problems:** None. | ||
/// | ||
/// **Example:** | ||
/// ```rust,ignore | ||
/// // Bad | ||
/// pub const a = [0u32; 1_000_000]; | ||
/// | ||
/// // Good | ||
/// pub static a = [0u32; 1_000_000]; | ||
/// ``` | ||
pub LARGE_CONST_ARRAYS, | ||
perf, | ||
"large non-scalar const array may cause performance overhead" | ||
} | ||
|
||
pub struct LargeConstArrays { | ||
maximum_allowed_size: u64, | ||
} | ||
|
||
impl LargeConstArrays { | ||
#[must_use] | ||
pub fn new(maximum_allowed_size: u64) -> Self { | ||
Self { maximum_allowed_size } | ||
} | ||
} | ||
|
||
impl_lint_pass!(LargeConstArrays => [LARGE_CONST_ARRAYS]); | ||
|
||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeConstArrays { | ||
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { | ||
if_chain! { | ||
if !item.span.from_expansion(); | ||
if let ItemKind::Const(hir_ty, _) = &item.kind; | ||
let ty = hir_ty_to_ty(cx.tcx, hir_ty); | ||
if let ty::Array(element_type, cst) = ty.kind; | ||
if let ConstKind::Value(val) = cst.val; | ||
if let ConstValue::Scalar(element_count) = 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 { | ||
let hi_pos = item.ident.span.lo() - BytePos::from_usize(1); | ||
let sugg_span = Span::new( | ||
hi_pos - BytePos::from_usize("const".len()), | ||
hi_pos, | ||
item.span.ctxt(), | ||
); | ||
span_lint_and_then( | ||
cx, | ||
LARGE_CONST_ARRAYS, | ||
item.span, | ||
"large array defined as const", | ||
|db| { | ||
db.span_suggestion( | ||
sugg_span, | ||
"make this a static item", | ||
"static".to_string(), | ||
Applicability::MachineApplicable, | ||
); | ||
} | ||
); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// run-rustfix | ||
|
||
#![warn(clippy::large_const_arrays)] | ||
#![allow(dead_code)] | ||
|
||
#[derive(Clone, Copy)] | ||
pub struct S { | ||
pub data: [u64; 32], | ||
} | ||
|
||
// Should lint | ||
pub(crate) static FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
pub static FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
static FOO: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
|
||
// Good | ||
pub(crate) const G_FOO_PUB_CRATE: [u32; 1_000] = [0u32; 1_000]; | ||
pub const G_FOO_PUB: [u32; 1_000] = [0u32; 1_000]; | ||
const G_FOO: [u32; 1_000] = [0u32; 1_000]; | ||
|
||
fn main() { | ||
// Should lint | ||
pub static BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
static BAR: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
pub static BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | ||
static BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | ||
pub static BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000]; | ||
static BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000]; | ||
|
||
// Good | ||
pub const G_BAR_PUB: [u32; 1_000] = [0u32; 1_000]; | ||
const G_BAR: [u32; 1_000] = [0u32; 1_000]; | ||
pub const G_BAR_STRUCT_PUB: [S; 500] = [S { data: [0; 32] }; 500]; | ||
const G_BAR_STRUCT: [S; 500] = [S { data: [0; 32] }; 500]; | ||
pub const G_BAR_S_PUB: [Option<&str>; 200] = [Some("str"); 200]; | ||
const G_BAR_S: [Option<&str>; 200] = [Some("str"); 200]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// run-rustfix | ||
|
||
#![warn(clippy::large_const_arrays)] | ||
#![allow(dead_code)] | ||
|
||
#[derive(Clone, Copy)] | ||
pub struct S { | ||
pub data: [u64; 32], | ||
} | ||
|
||
// Should lint | ||
pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
const FOO: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
|
||
// Good | ||
pub(crate) const G_FOO_PUB_CRATE: [u32; 1_000] = [0u32; 1_000]; | ||
pub const G_FOO_PUB: [u32; 1_000] = [0u32; 1_000]; | ||
const G_FOO: [u32; 1_000] = [0u32; 1_000]; | ||
|
||
fn main() { | ||
// Should lint | ||
pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
const BAR: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | ||
const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | ||
pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000]; | ||
const BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000]; | ||
|
||
// Good | ||
pub const G_BAR_PUB: [u32; 1_000] = [0u32; 1_000]; | ||
const G_BAR: [u32; 1_000] = [0u32; 1_000]; | ||
pub const G_BAR_STRUCT_PUB: [S; 500] = [S { data: [0; 32] }; 500]; | ||
const G_BAR_STRUCT: [S; 500] = [S { data: [0; 32] }; 500]; | ||
pub const G_BAR_S_PUB: [Option<&str>; 200] = [Some("str"); 200]; | ||
const G_BAR_S: [Option<&str>; 200] = [Some("str"); 200]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:12:1 | ||
| | ||
LL | pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
| ^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
| | ||
= note: `-D clippy::large-const-arrays` implied by `-D warnings` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:13:1 | ||
| | ||
LL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:14:1 | ||
| | ||
LL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:23:5 | ||
| | ||
LL | pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:24:5 | ||
| | ||
LL | const BAR: [u32; 1_000_000] = [0u32; 1_000_000]; | ||
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:25:5 | ||
| | ||
LL | pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | ||
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:26:5 | ||
| | ||
LL | const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | ||
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:27:5 | ||
| | ||
LL | pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000]; | ||
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: large array defined as const | ||
--> $DIR/large_const_arrays.rs:28:5 | ||
| | ||
LL | const BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000]; | ||
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| help: make this a static item: `static` | ||
|
||
error: aborting due to 9 previous errors | ||
|