Repository navigation
fix(cargo-gamma): complete cfg-tail and dashboard timing follow-ups - #356
Martin Taillefer (geeknoid) wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The non-unit-arm check includes cfg-disabled match arms, which can incorrectly mark an active unit-returning call as undeletable and suppress a valid deletion candidate.
1 open issue
What changed in this PR
This PR follows up on #352 by extending cargo-gamma’s cfg-aware tail analysis, making dashboard timing controllable, and documenting process-reader constants.
Changes:
- Share cfg-active statement selection across nested type, numeric, and divergence analysis, with regressions and design updates.
- Inject one dashboard clock for lifecycle timing, redraws, rendering, and throughput.
- Name the existing read-buffer size and polling interval without changing behavior.
| File | Description |
|---|---|
crates/cargo-gamma/docs/DESIGN.md |
Document nested cfg-active tail behavior. |
crates/cargo-gamma-process/src/process_tree.rs |
Name and document reader constants. |
crates/cargo-gamma-lib/src/commands/run.rs |
Supply clocks when constructing dashboards. |
crates/cargo-gamma-lib/src/commands/dashboard.rs |
Unify timing under an injected clock and add controlled-clock tests. |
crates/cargo-gamma-lib/src/commands/console_events.rs |
Adapt dashboard tests to clock injection. |
crates/cargo-gamma-engine/src/ops/collect/collector/tests.rs |
Add nested cfg-tail and barrier regressions. |
crates/cargo-gamma-engine/src/ops/collect/collector/survivor_tests.rs |
Pass cfg context into existing regression helpers. |
crates/cargo-gamma-engine/src/ops/collect/collector/predicates.rs |
Share active-statement filtering and apply it to divergence analysis. |
crates/cargo-gamma-engine/src/ops/collect/collector.rs |
Propagate cfg-aware selection through nested tail analysis. |
crates/cargo-gamma-engine/docs/DESIGN.md |
Specify recursive tail selection and preserved barriers. |
Review effort: Balanced
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #356 +/- ##
========================================
- Coverage 99.5% 99.2% -0.3%
========================================
Files 351 179 -172
Lines 64328 41244 -23084
========================================
- Hits 64029 40949 -23080
+ Misses 299 295 -4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
16e650f to
ae98a54
Compare
|
The original Windows Fast Checks failure occurred in the cargo-binstall installation step: its download connection closed unexpectedly, before the Anvil checks started (job 129309191394). No workflow change is needed for that infrastructure failure. The amended head ae98a54 triggers a fresh CI run, which I will continue monitoring. |
ae98a54 to
ba81af9
Compare
ba81af9 to
0862e9b
Compare
0862e9b to
5b6e12e
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Match-arm type inference mishandles binding scope and known callee return types, suppressing a valid deletion while allowing a continue deletion that changes a value-required arm to unit.
2 open issues
1 resolved since last review
Review effort: Balanced
5b6e12e to
b2ec7c4
Compare
|
The current-head Anvil workflow failed before its check groups started with GitHub reporting: Internal server error (correlation ID 94f421c5-9b62-48b9-a882-17e680f577bc). The successful impact-analysis job was the only executed job; there is no code-check failure log to fix. I retried Anvil (42672649154), regenerate-check (42672648997), and Windows coverage diagnostics (42672648567), the latter two having failed before creating jobs. No source or workflow changes were made. GitHub rejected retrying the separate Copilot review run (42674029533) with This workflow run cannot be retried. Monitoring the CI retries and ADO build continues. |
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
Copilot review overview
3 open issues
As written, labeled blocks (Expr::Blockwithlabel: Some(_)) fall through to_ => false, so… · New This recordsmandatory_tail_statementsfor all arms, including cfg-disabled ones, even though the… · New Both pattern collection and lookup allocateStrings (ident.to_string()), and the lookup path… · New
2 resolved since last review
Review effort: Lite
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved type-freezing and import-resolution bugs can admit invalid replacements, suppress valid ones, and erase evidence that protects a continue statement from removal.
3 open issues
3 resolved since last review
Review effort: Balanced
38d730e to
d8f7cc6
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Critical type-identity and path-resolution bugs can erase constructor payload types or resolve frozen standard-library types to caller-local lookalikes, allowing incompatible operator mutations and incorrect replacements.
3 open issues
3 resolved since last review
Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
The interacting inference, provenance, type-identity, and operator-compatibility changes warrant human review alongside the requested fresh mutation-CI results before approval.
No open issues 🎉
2 resolved since last review
Review effort: Balanced
|
Reviewed head Field-backed method chains lose the output's declaration contextCould struct Maker;
impl Maker {
fn unwrap(self) -> Option<&'static bool> { Some(&true) }
}
mod caller {
extern crate self as std;
struct Holder { maker: crate::Maker }
fn f(h: Holder) -> bool {
!h.maker.unwrap().unwrap()
}
}The inner method's frozen output retains its declaration's genuine standard A lexical generic disables the frozen-field progress proofCould the generic-root rejection apply only to paths without a leading struct Owner { characters: Vec<char> }
fn f<std>(owner: &Owner, mut index: usize, end: usize) {
while index < end && owner.characters[index] == 'x' {
index += 1;
}
}That removes the projected Qualify the earlier negation contractCould the earlier design paragraph distinguish unavailable inference from present-but-incomplete evidence? "Each negation site emits one replacement" is no longer unconditional: incomplete inferred evidence deliberately emits nothing, as the later design paragraph correctly states. These are source-analysis findings; no builds or tests were run for this review. All three are nonblocking suggestions. 🤖 Authored by Copilot. |
|
Addressed all three points from the follow-up review in c91af69.
Representative originals compile with rustc. All 1,990 engine tests pass on stable and Rust 1.97.1, affected library/integration suites pass, generated formatting/Clippy are clean, and both coverage configurations meet the unchanged 99.4% gate. The preceding head killed all 1,113 mutants; fresh CI is running for this amendment. No standalone local mutation campaign or Miri run was performed. |
There was a problem hiding this comment.
🟡 Changes recommended
Inconsistent crate-root alias normalization inside generic types can prevent matching the declared Add operator, allowing add-to-sub candidates even when Add and Sub return incompatible types.
1 open issue
1 resolved since last review
Review effort: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Generated constructor replacements lose the leading :: and can resolve to shadowing local modules, while incomplete slice and pointer alias normalization incorrectly suppresses valid operator mutations.
3 open issues
Review effort: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Primitive normalization misresolves absolute crate-root paths under nested extern rebinding, causing unary.remove_not to emit a replacement with the wrong value type.
1 open issue
3 resolved since last review
Review effort: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Critical alias-inference and caller-root rebinding bugs misidentify operand types, causing operator lookup to miss matching implementations and admit incompatible mutations.
3 open issues
2 resolved since last review
Review effort: Balanced
Apply cfg-active tail selection consistently through nested expected-type, block-inference, numeric, and divergence analysis, preserving active tail barriers and covering the deferred cases with focused regressions. Inject a shared dashboard clock for lifecycle timing, redraw throttling, and throughput measurements. Name and document the process-reader chunk size and polling interval without changing behavior. Preserve declaration-scoped type evidence through indexed values, calls, fields, operators, aliases, and constructor payloads. Keep genuine external namespaces separate from source self aliases, and retain frozen identities when crossing caller scopes. Select primitive output roots using lexical and crate-root provenance instead of accepting local lookalikes. Cover demonstrated review regressions and campaign survivors with focused candidate controls, remove redundant equivalent branches, and synchronize the engine design contract. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 20685d26-9888-4c4d-a75f-e85c49d00b4e
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved crate-alias resolution errors can misidentify external types and lose borrowed-boolean or iterator type evidence, causing incorrect replacements or suppressing valid rewrites.
3 open issues
3 resolved since last review
Review effort: Balanced
| // #[gamma::skip(return_value.default, reason = "None is already Option::default(); replacing just this value cannot change an outcome.", tag = "equivalent")] | ||
| None; | ||
| } | ||
| "crate".clone_into(&mut names[0]); |
| if let Some(imported) = imports.get(root) { | ||
| let _old = names.splice(..1, imported.as_ref()?.iter().cloned()); | ||
| } |
| let root = roots.iter().find(|root| self.standard_external_root(root))?; | ||
| Some(vec![(*root).into(), module.into(), name.clone()]) |



Summary
Addresses the three review conversations deferred from #352:
Review follow-ups preserve declaration-scoped type evidence across calls, imports, fields, operators, constructor payloads, and reusable result payloads. The design contract is synchronized.
Latest correction: alias constructors and frozen operands
Reproduced all three new reports before changing production:
Stringresult plus a string literal cannot gain an invalid subtraction candidate when a caller rebindsstdthrough an extern alias, self alias, or named import.The two new tests and expanded alias regression failed against the preceding production code and pass with the fixes. Supported originals compile with rustc under both
coreandstdroot-collision configurations.Earlier provenance corrections
core/stdprimitive identities compare consistently without changing inferred output roots.Mutation regressions
The
1ca58f8dWindows campaign reported 1,210 mutants: 1,202 killed, eight survived, zero uncovered (job 129782715628).Six effects targeted redundant local-root clauses; those clauses are removed rather than excluded. The constructor and primitive-length effects were individually injected and failed their executed regressions. Exact production bytes were restored, and the restored suites pass. A further isolated proof confirms the relative source-alias regression detects bypassing its normalization.
Earlier campaign follow-ups remain included: 14 individually detected effects from the 17-survivor
de41011ecampaign, deletion of the redundant constructor-inventory guard from the one-survivore54bfa97campaign, and five individually detected effects from5f854b23. The earlier99bd40fdhead killed all 1,113 mutants. Existing exactly equivalent exclusions remain narrowly documented.Fresh CI must confirm the new head. No standalone local mutation campaign or Miri run was performed.
Local validation
just anvil-fmt --fix, workspacejust anvil-clippy, andgit diff --checkpassed.