cfg_test_lines (src/scan.rs:1679) counts an attribute as a test marker when it matches ^#\[cfg\([^)]*\btest\b: #[cfg( with test as a word anywhere before the first ). That matches:
#[cfg(test)], #[cfg(all(test, unix))] and #[cfg(any(unix, test))], as intended
#[cfg(not(test))], which is code that runs only outside tests
#[cfg(feature = "test")], which is a feature flag, not the test harness
For the last two, exclude_cfg_test drops real hits from production code. That is the failure a scanner should never make.
#273 moved the extent to the tree-sitter grammar and kept this pattern as it was, so the behaviour predates it.
Fix direction: read the attribute from the parse tree (the token_tree under cfg) and count it only when the predicate is true under test. That means test by itself, or as an operand of all/any, and never under not. Test cases: the five spellings above, plus an inner #![cfg(test)], which is not matched today.
cfg_test_lines(src/scan.rs:1679) counts an attribute as a test marker when it matches^#\[cfg\([^)]*\btest\b:#[cfg(withtestas a word anywhere before the first). That matches:#[cfg(test)],#[cfg(all(test, unix))]and#[cfg(any(unix, test))], as intended#[cfg(not(test))], which is code that runs only outside tests#[cfg(feature = "test")], which is a feature flag, not the test harnessFor the last two,
exclude_cfg_testdrops real hits from production code. That is the failure a scanner should never make.#273 moved the extent to the tree-sitter grammar and kept this pattern as it was, so the behaviour predates it.
Fix direction: read the attribute from the parse tree (the
token_treeundercfg) and count it only when the predicate is true undertest. That meanstestby itself, or as an operand ofall/any, and never undernot. Test cases: the five spellings above, plus an inner#![cfg(test)], which is not matched today.