Skip to content

Commit 760f293

Browse files
committed
Auto merge of rust-lang#8727 - Serial-ATA:lint-large-includes, r=xFrednet
Add `large_include_file` lint changelog: Add [`large_include_file`] lint closes rust-lang#7005
2 parents 388e6b7 + a85dc87 commit 760f293

File tree

11 files changed

+136
-1
lines changed

11 files changed

+136
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3478,6 +3478,7 @@ Released 2018-09-13
34783478
[`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
34793479
[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups
34803480
[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
3481+
[`large_include_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file
34813482
[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays
34823483
[`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value
34833484
[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use clippy_utils::diagnostics::span_lint_and_note;
2+
use clippy_utils::is_lint_allowed;
3+
use clippy_utils::macros::root_macro_call_first_node;
4+
use rustc_ast::LitKind;
5+
use rustc_hir::Expr;
6+
use rustc_hir::ExprKind;
7+
use rustc_lint::{LateContext, LateLintPass};
8+
use rustc_session::{declare_tool_lint, impl_lint_pass};
9+
use rustc_span::sym;
10+
11+
declare_clippy_lint! {
12+
/// ### What it does
13+
/// Checks for the inclusion of large files via `include_bytes!()`
14+
/// and `include_str!()`
15+
///
16+
/// ### Why is this bad?
17+
/// Including large files can increase the size of the binary
18+
///
19+
/// ### Example
20+
/// ```rust,ignore
21+
/// let included_str = include_str!("very_large_file.txt");
22+
/// let included_bytes = include_bytes!("very_large_file.txt);
23+
/// ```
24+
///
25+
/// Instead, you can load the file at runtime:
26+
/// ```rust,ignore
27+
/// use std::fs;
28+
///
29+
/// let string = fs::read_to_string("very_large_file.txt")?;
30+
/// let bytes = fs::read("very_large_file.txt")?;
31+
/// ```
32+
#[clippy::version = "1.62.0"]
33+
pub LARGE_INCLUDE_FILE,
34+
restriction,
35+
"including a large file"
36+
}
37+
38+
pub struct LargeIncludeFile {
39+
max_file_size: u64,
40+
}
41+
42+
impl LargeIncludeFile {
43+
#[must_use]
44+
pub fn new(max_file_size: u64) -> Self {
45+
Self { max_file_size }
46+
}
47+
}
48+
49+
impl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]);
50+
51+
impl LateLintPass<'_> for LargeIncludeFile {
52+
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
53+
if_chain! {
54+
if let Some(macro_call) = root_macro_call_first_node(cx, expr);
55+
if !is_lint_allowed(cx, LARGE_INCLUDE_FILE, expr.hir_id);
56+
if cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id)
57+
|| cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id);
58+
if let ExprKind::Lit(lit) = &expr.kind;
59+
then {
60+
let len = match &lit.node {
61+
// include_bytes
62+
LitKind::ByteStr(bstr) => bstr.len(),
63+
// include_str
64+
LitKind::Str(sym, _) => sym.as_str().len(),
65+
_ => return,
66+
};
67+
68+
if len as u64 <= self.max_file_size {
69+
return;
70+
}
71+
72+
span_lint_and_note(
73+
cx,
74+
LARGE_INCLUDE_FILE,
75+
expr.span,
76+
"attempted to include a large file",
77+
None,
78+
&format!(
79+
"the configuration allows a maximum size of {} bytes",
80+
self.max_file_size
81+
),
82+
);
83+
}
84+
}
85+
}
86+
}

clippy_lints/src/lib.register_lints.rs

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ store.register_lints(&[
209209
iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
210210
large_const_arrays::LARGE_CONST_ARRAYS,
211211
large_enum_variant::LARGE_ENUM_VARIANT,
212+
large_include_file::LARGE_INCLUDE_FILE,
212213
large_stack_arrays::LARGE_STACK_ARRAYS,
213214
len_zero::COMPARISON_TO_EMPTY,
214215
len_zero::LEN_WITHOUT_IS_EMPTY,

clippy_lints/src/lib.register_restriction.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
2727
LintId::of(indexing_slicing::INDEXING_SLICING),
2828
LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
2929
LintId::of(integer_division::INTEGER_DIVISION),
30+
LintId::of(large_include_file::LARGE_INCLUDE_FILE),
3031
LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
3132
LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
3233
LintId::of(map_err_ignore::MAP_ERR_IGNORE),

clippy_lints/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ mod items_after_statements;
262262
mod iter_not_returning_iterator;
263263
mod large_const_arrays;
264264
mod large_enum_variant;
265+
mod large_include_file;
265266
mod large_stack_arrays;
266267
mod len_zero;
267268
mod let_if_seq;
@@ -884,6 +885,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
884885
store.register_early_pass(|| Box::new(pub_use::PubUse));
885886
store.register_late_pass(|| Box::new(format_push_string::FormatPushString));
886887
store.register_late_pass(|| Box::new(bytes_count_to_len::BytesCountToLen));
888+
let max_include_file_size = conf.max_include_file_size;
889+
store.register_late_pass(move || Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
887890
// add lints here, do not remove this comment, it's used in `new_lint`
888891
}
889892

clippy_lints/src/utils/conf.rs

+4
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,10 @@ define_Conf! {
312312
(max_suggested_slice_pattern_length: u64 = 3),
313313
/// Lint: AWAIT_HOLDING_INVALID_TYPE
314314
(await_holding_invalid_types: Vec<crate::utils::conf::DisallowedType> = Vec::new()),
315+
/// Lint: LARGE_INCLUDE_FILE.
316+
///
317+
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
318+
(max_include_file_size: u64 = 1_000_000),
315319
}
316320

317321
/// Search for the configuration file.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
max-include-file-size = 600
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![warn(clippy::large_include_file)]
2+
3+
// Good
4+
const GOOD_INCLUDE_BYTES: &[u8; 581] = include_bytes!("large_include_file.rs");
5+
const GOOD_INCLUDE_STR: &str = include_str!("large_include_file.rs");
6+
7+
#[allow(clippy::large_include_file)]
8+
const ALLOWED_TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
9+
#[allow(clippy::large_include_file)]
10+
const ALLOWED_TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
11+
12+
// Bad
13+
const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
14+
const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error: attempted to include a large file
2+
--> $DIR/large_include_file.rs:13:43
3+
|
4+
LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::large-include-file` implied by `-D warnings`
8+
= note: the configuration allows a maximum size of 600 bytes
9+
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
10+
11+
error: attempted to include a large file
12+
--> $DIR/large_include_file.rs:14:35
13+
|
14+
LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= note: the configuration allows a maximum size of 600 bytes
18+
= note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
19+
20+
error: aborting due to 2 previous errors
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Maecenas accumsan lacus vel facilisis volutpat. Etiam dignissim diam quis enim lobortis scelerisque fermentum dui faucibus. Tellus id interdum velit laoreet id donec ultrices. Est ultricies integer quis auctor elit sed vulputate. Erat velit scelerisque in dictum non consectetur a erat nam. Sed blandit libero volutpat sed. Tortor condimentum lacinia quis vel eros. Enim ut tellus elementum sagittis vitae et leo duis. Congue mauris rhoncus aenean vel elit scelerisque. Id consectetur purus ut faucibus pulvinar elementum integer.
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `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`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `third-party` at line 5 column 1
1+
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `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`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `max-include-file-size`, `third-party` at line 5 column 1
22

33
error: aborting due to previous error
44

0 commit comments

Comments
 (0)