From 0b89d702b8d57ecab4fea28c2b9572cfd0799bf6 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 28 Aug 2026 14:45:29 +0900 Subject: [PATCH 1/4] fix(ci): keep executable expressions in coverage gate Signed-off-by: Seongho Bae --- scripts/check_coverage.py | 9 +++++++-- tests/quality/test_check_coverage.py | 25 ++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/scripts/check_coverage.py b/scripts/check_coverage.py index 73dd8977e..7827ed258 100644 --- a/scripts/check_coverage.py +++ b/scripts/check_coverage.py @@ -295,10 +295,12 @@ def is_executable_source_line( if text.startswith("Ok(Self") or text in {")}", "})"}: return False if text in {"} else {", "else {", "));"} or text.startswith( - (".", "||", "&&", "/") + (".", "||", "&&") ): return False - if text.startswith("*") and "=" not in text: + if text.startswith(("/", "*")) and not any( + character in text for character in "()=" + ): return False if text.endswith("=> event"): return False @@ -330,6 +332,9 @@ def _is_structural_comma_continuation( remain executable because their expressions can perform observable work. """ + if any(character in text for character in "()=+-*/%<>!&|?"): + return False + previous = "" for candidate in reversed(lines[: line_number - 1]): if candidate.strip(): diff --git a/tests/quality/test_check_coverage.py b/tests/quality/test_check_coverage.py index 5a1ed6694..86b103d05 100644 --- a/tests/quality/test_check_coverage.py +++ b/tests/quality/test_check_coverage.py @@ -1277,16 +1277,39 @@ def test_line_filter_excludes_split_expression_regions(self) -> None: with tempfile.TemporaryDirectory() as temporary: source = Path(temporary) / "split.rs" source.write_text("\n".join(lines) + "\n", encoding="utf-8") - for line_number in (1, 2, 5, 6, 9, 11, 12, 13): + for line_number in (1, 2, 6, 9, 11, 12, 13): self.assertFalse( coverage_contract.is_executable_source_line( str(source), line_number ) ) + self.assertTrue( + coverage_contract.is_executable_source_line(str(source), 5) + ) self.assertTrue( coverage_contract.is_executable_source_line(str(source), 17) ) + def test_line_filter_keeps_observable_nested_expressions(self) -> None: + """Structural-depth handling cannot hide calls inside expressions.""" + + cases = { + "array_call": "fn f() {\n let x = [\n side_effect(),\n ];\n}\n", + "tuple_call": "fn f() {\n let x = (\n side_effect(),\n );\n}\n", + "struct_call": "fn f() {\n let x = Item {\n field: side_effect(),\n };\n}\n", + "division_call": "fn f(a: f64) {\n let x = a\n / denominator();\n}\n", + "multiplication_call": "fn f(a: f64) {\n let x = a\n * multiplier();\n}\n", + "array_block_call": "fn f() {\n let x = [\n { side_effect(); 1 },\n ];\n}\n", + } + with tempfile.TemporaryDirectory() as temporary: + for name, source_text in cases.items(): + with self.subTest(name=name): + source = Path(temporary) / f"{name}.rs" + source.write_text(source_text, encoding="utf-8") + self.assertTrue( + coverage_contract.is_executable_source_line(str(source), 3) + ) + def test_line_filter_keeps_inline_functions_and_block_comment_followers(self) -> None: """Inline function bodies and code after quoted block comments stay visible.""" From 74311240ac64dc8240bfdf8ed05dc507d358a143 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 28 Aug 2026 15:08:59 +0900 Subject: [PATCH 2/4] fix(coverage): retain executable comma expressions Signed-off-by: Seongho Bae Commit-Message-Assisted-by: Claude (via Claude Code) --- scripts/check_coverage.py | 11 ++++++++++- tests/quality/test_check_coverage.py | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/scripts/check_coverage.py b/scripts/check_coverage.py index bfbd04aa4..6de06a1e9 100644 --- a/scripts/check_coverage.py +++ b/scripts/check_coverage.py @@ -294,6 +294,8 @@ def is_executable_source_line( return False if text.startswith("Ok(Self") or text in {")}", "})"}: return False + if text.endswith(",") and _has_executable_comma_syntax(text): + return True if text in {"} else {", "else {", "));"} or text.startswith( (".", "||", "&&") ): @@ -322,6 +324,12 @@ def is_executable_source_line( return True +def _has_executable_comma_syntax(text: str) -> bool: + """Return whether a comma line contains expression-only syntax.""" + + return any(character in text for character in ".()[]=+-*/%<>!&|?") + + def _is_structural_comma_continuation( lines: list[str], line_number: int, text: str ) -> bool: @@ -333,7 +341,7 @@ def _is_structural_comma_continuation( denominator; every other comma-terminated line remains executable. """ - if any(character in text for character in "()=+-*/%<>!&|?"): + if _has_executable_comma_syntax(text): return False previous = "" @@ -500,6 +508,7 @@ def _line_in_multiline_string(lines: list[str], line_number: int) -> bool: ) return False + def _is_multiline_match_guard(lines: list[str], line_number: int) -> bool: """Recognize a guard continued onto the lines immediately before an arm.""" diff --git a/tests/quality/test_check_coverage.py b/tests/quality/test_check_coverage.py index 86b103d05..d557ba012 100644 --- a/tests/quality/test_check_coverage.py +++ b/tests/quality/test_check_coverage.py @@ -1300,6 +1300,10 @@ def test_line_filter_keeps_observable_nested_expressions(self) -> None: "division_call": "fn f(a: f64) {\n let x = a\n / denominator();\n}\n", "multiplication_call": "fn f(a: f64) {\n let x = a\n * multiplier();\n}\n", "array_block_call": "fn f() {\n let x = [\n { side_effect(); 1 },\n ];\n}\n", + "dot_call": "fn f() {\n let x = [value\n .side_effect(),\n ];\n}\n", + "dot_await": "fn f() {\n let x = [future\n .await,\n ];\n}\n", + "indexed_value": "fn f() {\n let x = [\n values[index],\n ];\n}\n", + "dereference": "fn f() {\n let x = [\n *pointer,\n ];\n}\n", } with tempfile.TemporaryDirectory() as temporary: for name, source_text in cases.items(): @@ -1310,6 +1314,25 @@ def test_line_filter_keeps_observable_nested_expressions(self) -> None: coverage_contract.is_executable_source_line(str(source), 3) ) + def test_lcov_keeps_uncovered_dot_call_in_authored_denominator(self) -> None: + """An uncovered chained call cannot pass as structural punctuation.""" + + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + source = root / "src.rs" + source.write_text( + "fn f() {\n value\n .side_effect(),\n covered();\n}\n", + encoding="utf-8", + ) + report = self.write_lcov( + temporary, + "SF:src.rs\nDA:3,0\nDA:4,1\nend_of_record\n", + ) + self.assertEqual( + coverage_contract.load_lcov_line_totals(report, root), + {"lines": {"count": 2, "covered": 1}}, + ) + def test_line_filter_keeps_inline_functions_and_block_comment_followers(self) -> None: """Inline function bodies and code after quoted block comments stay visible.""" From e16c1a9f311bb92491961fc6323906924f3c621b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 28 Aug 2026 15:12:51 +0900 Subject: [PATCH 3/4] test(coverage): cover comma predicate branch Signed-off-by: Seongho Bae Commit-Message-Assisted-by: Claude (via Claude Code) --- tests/quality/test_check_coverage.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/quality/test_check_coverage.py b/tests/quality/test_check_coverage.py index d557ba012..483929a56 100644 --- a/tests/quality/test_check_coverage.py +++ b/tests/quality/test_check_coverage.py @@ -1519,6 +1519,11 @@ def test_multiline_string_empty_lines_returns_false(self) -> None: def test_structural_comma_continuation_edge_cases(self) -> None: """Exercise structural comma continuation detection edge branches.""" + self.assertFalse( + coverage_contract._is_structural_comma_continuation( + [], 1, ".side_effect()," + ) + ) with tempfile.TemporaryDirectory() as temporary: source = Path(temporary) / "commas.rs" # A comma-terminated line whose preceding lines are entirely blank From 7459aea0461e29c370c795ee95c3cb249f715c9b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 28 Aug 2026 15:13:13 +0900 Subject: [PATCH 4/4] fix(coverage): remove unreachable duplicate guard Signed-off-by: Seongho Bae --- scripts/check_coverage.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/check_coverage.py b/scripts/check_coverage.py index 6de06a1e9..3b26f697e 100644 --- a/scripts/check_coverage.py +++ b/scripts/check_coverage.py @@ -341,9 +341,6 @@ def _is_structural_comma_continuation( denominator; every other comma-terminated line remains executable. """ - if _has_executable_comma_syntax(text): - return False - previous = "" for candidate in reversed(lines[: line_number - 1]): if candidate.strip():