lint: [move-only] Move cpp related lints to lint_cpp.rs
What changed, and why it matters
This commit is a pure code reorganization: it moves four existing C++ lint checks from the main Rust file into a new dedicated module named lint_cpp.rs. No lint logic, rules, or behavior changed. It is comparable to moving files into a new folder without editing their contents.
No security action needed. Treat as routine maintenance/refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff creates test/lint/test_runner/src/lint_cpp.rs and adds mod lint_cpp plus a use statement in main.rs. The bodies of lint_std_filesystem, lint_rpc_assert, lint_boost_assert, and lint_includes_build_config are removed from main.rs and placed unchanged into lint_cpp.rs, with their function visibility changed from fn to pub fn. This is a move-only refactor of the project’s internal lint test runner.
Changed components
test/lint/test_runner/src/main.rstest/lint/test_runner/src/lint_cpp.rsInspect captured patch +184 / −173
diff --git a/test/lint/test_runner/src/lint_cpp.rs b/test/lint/test_runner/src/lint_cpp.rs
new file mode 100644
index 00000000..250ebb46
--- /dev/null
+++ b/test/lint/test_runner/src/lint_cpp.rs
@@ -0,0 +1,180 @@
+// Copyright (c) The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or https://opensource.org/license/mit/.
+
+use std::process::Command;
+
+use crate::util::{check_output, get_pathspecs_default_excludes, git, LintResult};
+
+pub fn lint_includes_build_config() -> LintResult {
+ let config_path = "./cmake/bitcoin-build-config.h.in";
+ let defines_regex = format!(
+ r"^\s*(?!//).*({})",
+ check_output(Command::new("grep").args(["define", "--", config_path]))
+ .expect("grep failed")
+ .lines()
+ .map(|line| {
+ line.split_whitespace()
+ .nth(1)
+ .unwrap_or_else(|| panic!("Could not extract name in line: {line}"))
+ })
+ .collect::<Vec<_>>()
+ .join("|")
+ );
+ let print_affected_files = |mode: bool| {
+ // * mode==true: Print files which use the define, but lack the include
+ // * mode==false: Print files which lack the define, but use the include
+ let defines_files = check_output(
+ git()
+ .args([
+ "grep",
+ "--perl-regexp",
+ if mode {
+ "--files-with-matches"
+ } else {
+ "--files-without-match"
+ },
+ &defines_regex,
+ "--",
+ "*.cpp",
+ "*.h",
+ ])
+ .args(get_pathspecs_default_excludes()),
+ )
+ .expect("grep failed");
+ git()
+ .args([
+ "grep",
+ if mode {
+ "--files-without-match"
+ } else {
+ "--files-with-matches"
+ },
+ if mode {
+ "^#include <bitcoin-build-config.h> // IWYU pragma: keep$"
+ } else {
+ "#include <bitcoin-build-config.h>" // Catch redundant includes with and without the IWYU pragma
+ },
+ "--",
+ ])
+ .args(defines_files.lines())
+ .status()
+ .expect("command error")
+ .success()
+ };
+ let missing = print_affected_files(true);
+ if missing {
+ return Err(format!(
+ r#"
+One or more files use a symbol declared in the bitcoin-build-config.h header. However, they are not
+including the header. This is problematic, because the header may or may not be indirectly
+included. If the indirect include were to be intentionally or accidentally removed, the build could
+still succeed, but silently be buggy. For example, a slower fallback algorithm could be picked,
+even though bitcoin-build-config.h indicates that a faster feature is available and should be used.
+
+If you are unsure which symbol is used, you can find it with this command:
+git grep --perl-regexp '{defines_regex}' -- file_name
+
+Make sure to include it with the IWYU pragma. Otherwise, IWYU may falsely instruct to remove the
+include again.
+
+#include <bitcoin-build-config.h> // IWYU pragma: keep
+ "#
+ )
+ .trim()
+ .to_string());
+ }
+ let redundant = print_affected_files(false);
+ if redundant {
+ return Err(r#"
+None of the files use a symbol declared in the bitcoin-build-config.h header. However, they are including
+the header. Consider removing the unused include.
+ "#
+ .to_string());
+ }
+ Ok(())
+}
+
+pub fn lint_std_filesystem() -> LintResult {
+ let found = git()
+ .args([
+ "grep",
+ "--line-number",
+ "std::filesystem",
+ "--",
+ "./src/",
+ ":(exclude)src/ipc/libmultiprocess/",
+ ":(exclude)src/util/fs.h",
+ ":(exclude)src/test/kernel/test_kernel.cpp",
+ ":(exclude)src/bitcoin-chainstate.cpp",
+ ])
+ .status()
+ .expect("command error")
+ .success();
+ if found {
+ Err(r#"
+Direct use of std::filesystem may be dangerous and buggy. Please include <util/fs.h> and use the
+fs:: namespace, which has unsafe filesystem functions marked as deleted.
+ "#
+ .trim()
+ .to_string())
+ } else {
+ Ok(())
+ }
+}
+
+pub fn lint_rpc_assert() -> LintResult {
+ let found = git()
+ .args([
+ "grep",
+ "--line-number",
+ "--extended-regexp",
+ r"\<(A|a)ss(ume|ert)\(",
+ "--",
+ "src/rpc/",
+ "src/wallet/rpc*",
+ ":(exclude)src/rpc/server.cpp",
+ // src/rpc/server.cpp is excluded from this check since it's mostly meta-code.
+ ])
+ .status()
+ .expect("command error")
+ .success();
+ if found {
+ Err(r#"
+CHECK_NONFATAL(condition) or NONFATAL_UNREACHABLE should be used instead of assert for RPC code.
+
+Aborting the whole process is undesirable for RPC code. So nonfatal
+checks should be used over assert. See: src/util/check.h
+ "#
+ .trim()
+ .to_string())
+ } else {
+ Ok(())
+ }
+}
+
+pub fn lint_boost_assert() -> LintResult {
+ let found = git()
+ .args([
+ "grep",
+ "--line-number",
+ "--extended-regexp",
+ r"BOOST_ASSERT\(",
+ "--",
+ "*.cpp",
+ "*.h",
+ ])
+ .status()
+ .expect("command error")
+ .success();
+ if found {
+ Err(r#"
+BOOST_ASSERT must be replaced with Assert, BOOST_REQUIRE, or BOOST_CHECK to avoid an unnecessary
+include of the boost/assert.hpp dependency.
+ "#
+ .trim()
+ .to_string())
+ } else {
+ Ok(())
+ }
+}
diff --git a/test/lint/test_runner/src/main.rs b/test/lint/test_runner/src/main.rs
index 9adbe369..eddbff9d 100644
--- a/test/lint/test_runner/src/main.rs
+++ b/test/lint/test_runner/src/main.rs
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/license/mit/.
+mod lint_cpp;
mod lint_docs;
mod lint_text_format;
mod util;
@@ -11,6 +12,9 @@ use std::fs;
use std::io::ErrorKind;
use std::process::{Command, ExitCode};
+use lint_cpp::{
+ lint_boost_assert, lint_includes_build_config, lint_rpc_assert, lint_std_filesystem,
+};
use lint_docs::{lint_doc_args, lint_doc_release_note_snippets, lint_markdown};
use lint_text_format::{
lint_commit_msg, lint_tabs_whitespace, lint_trailing_newline, lint_trailing_whitespace,
@@ -262,179 +266,6 @@ fn lint_py_lint() -> LintResult {
}
}
-fn lint_std_filesystem() -> LintResult {
- let found = git()
- .args([
- "grep",
- "--line-number",
- "std::filesystem",
- "--",
- "./src/",
- ":(exclude)src/ipc/libmultiprocess/",
- ":(exclude)src/util/fs.h",
- ":(exclude)src/test/kernel/test_kernel.cpp",
- ":(exclude)src/bitcoin-chainstate.cpp",
- ])
- .status()
- .expect("command error")
- .success();
- if found {
- Err(r#"
-Direct use of std::filesystem may be dangerous and buggy. Please include <util/fs.h> and use the
-fs:: namespace, which has unsafe filesystem functions marked as deleted.
- "#
- .trim()
- .to_string())
- } else {
- Ok(())
- }
-}
-
-fn lint_rpc_assert() -> LintResult {
- let found = git()
- .args([
- "grep",
- "--line-number",
- "--extended-regexp",
- r"\<(A|a)ss(ume|ert)\(",
- "--",
- "src/rpc/",
- "src/wallet/rpc*",
- ":(exclude)src/rpc/server.cpp",
- // src/rpc/server.cpp is excluded from this check since it's mostly meta-code.
- ])
- .status()
- .expect("command error")
- .success();
- if found {
- Err(r#"
-CHECK_NONFATAL(condition) or NONFATAL_UNREACHABLE should be used instead of assert for RPC code.
-
-Aborting the whole process is undesirable for RPC code. So nonfatal
-checks should be used over assert. See: src/util/check.h
- "#
- .trim()
- .to_string())
- } else {
- Ok(())
- }
-}
-
-fn lint_boost_assert() -> LintResult {
- let found = git()
- .args([
- "grep",
- "--line-number",
- "--extended-regexp",
- r"BOOST_ASSERT\(",
- "--",
- "*.cpp",
- "*.h",
- ])
- .status()
- .expect("command error")
- .success();
- if found {
- Err(r#"
-BOOST_ASSERT must be replaced with Assert, BOOST_REQUIRE, or BOOST_CHECK to avoid an unnecessary
-include of the boost/assert.hpp dependency.
- "#
- .trim()
- .to_string())
- } else {
- Ok(())
- }
-}
-
-fn lint_includes_build_config() -> LintResult {
- let config_path = "./cmake/bitcoin-build-config.h.in";
- let defines_regex = format!(
- r"^\s*(?!//).*({})",
- check_output(Command::new("grep").args(["define", "--", config_path]))
- .expect("grep failed")
- .lines()
- .map(|line| {
- line.split_whitespace()
- .nth(1)
- .unwrap_or_else(|| panic!("Could not extract name in line: {line}"))
- })
- .collect::<Vec<_>>()
- .join("|")
- );
- let print_affected_files = |mode: bool| {
- // * mode==true: Print files which use the define, but lack the include
- // * mode==false: Print files which lack the define, but use the include
- let defines_files = check_output(
- git()
- .args([
- "grep",
- "--perl-regexp",
- if mode {
- "--files-with-matches"
- } else {
- "--files-without-match"
- },
- &defines_regex,
- "--",
- "*.cpp",
- "*.h",
- ])
- .args(get_pathspecs_default_excludes()),
- )
- .expect("grep failed");
- git()
- .args([
- "grep",
- if mode {
- "--files-without-match"
- } else {
- "--files-with-matches"
- },
- if mode {
- "^#include <bitcoin-build-config.h> // IWYU pragma: keep$"
- } else {
- "#include <bitcoin-build-config.h>" // Catch redundant includes with and without the IWYU pragma
- },
- "--",
- ])
- .args(defines_files.lines())
- .status()
- .expect("command error")
- .success()
- };
- let missing = print_affected_files(true);
- if missing {
- return Err(format!(
- r#"
-One or more files use a symbol declared in the bitcoin-build-config.h header. However, they are not
-including the header. This is problematic, because the header may or may not be indirectly
-included. If the indirect include were to be intentionally or accidentally removed, the build could
-still succeed, but silently be buggy. For example, a slower fallback algorithm could be picked,
-even though bitcoin-build-config.h indicates that a faster feature is available and should be used.
-
-If you are unsure which symbol is used, you can find it with this command:
-git grep --perl-regexp '{defines_regex}' -- file_name
-
-Make sure to include it with the IWYU pragma. Otherwise, IWYU may falsely instruct to remove the
-include again.
-
-#include <bitcoin-build-config.h> // IWYU pragma: keep
- "#
- )
- .trim()
- .to_string());
- }
- let redundant = print_affected_files(false);
- if redundant {
- return Err(r#"
-None of the files use a symbol declared in the bitcoin-build-config.h header. However, they are including
-the header. Consider removing the unused include.
- "#
- .to_string());
- }
- Ok(())
-}
-
fn run_all_python_linters() -> LintResult {
let mut good = true;
let lint_dir = get_git_root().join("test/lint");
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.