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;
6 use rustc_hir::ExprKind;
7 use rustc_lint::{LateContext, LateLintPass};
8 use rustc_session::{declare_tool_lint, impl_lint_pass};
11 declare_clippy_lint! {
13 /// Checks for the inclusion of large files via `include_bytes!()`
14 /// and `include_str!()`
16 /// ### Why is this bad?
17 /// Including large files can increase the size of the binary
21 /// let included_str = include_str!("very_large_file.txt");
22 /// let included_bytes = include_bytes!("very_large_file.txt");
29 /// // You can load the file at runtime
30 /// let string = fs::read_to_string("very_large_file.txt")?;
31 /// let bytes = fs::read("very_large_file.txt")?;
33 #[clippy::version = "1.62.0"]
34 pub LARGE_INCLUDE_FILE,
36 "including a large file"
39 pub struct LargeIncludeFile {
43 impl LargeIncludeFile {
45 pub fn new(max_file_size: u64) -> Self {
46 Self { max_file_size }
50 impl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]);
52 impl LateLintPass<'_> for LargeIncludeFile {
53 fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
55 if let Some(macro_call) = root_macro_call_first_node(cx, expr);
56 if !is_lint_allowed(cx, LARGE_INCLUDE_FILE, expr.hir_id);
57 if cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id)
58 || cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id);
59 if let ExprKind::Lit(lit) = &expr.kind;
61 let len = match &lit.node {
63 LitKind::ByteStr(bstr) => bstr.len(),
65 LitKind::Str(sym, _) => sym.as_str().len(),
69 if len as u64 <= self.max_file_size {
77 "attempted to include a large file",
80 "the configuration allows a maximum size of {} bytes",