From 68652195d0d6b0873263734c7c6163f454669b3c Mon Sep 17 00:00:00 2001 From: Per Larsen Date: Sun, 12 Jul 2026 15:27:40 -0700 Subject: [PATCH] refactor: refuse to run transforms on crates that do not compile c2rust-refactor runs the rustc analysis passes before applying a transform, but discarded the result (`let _result = tcx.analysis(())`). When the input crate has type errors, the transform then operates on incomplete typeck tables: it may silently emit rewrites derived from bogus types, or panic on an internal invariant far from the actual problem. Because each transform in a sequence consumes the previous one's output, one transform that produces an invalid crate poisons every transform that runs after it. This surfaced while adding libgit2 to the integration testsuite. libgit2 compiles its test sources with GIT_DEPRECATE_HARD but its library sources without it, so several public structs legitimately have two incompatible declarations within one crate (a member that is a function pointer in one view is a reserved void pointer in the other). The reorganize_definitions transform, which merges duplicate declarations by name, produced an ill-typed crate from that input, but the failure CI reported was a "mismatched key trees" panic in remove_literal_suffixes, three transforms later, which took considerable effort to trace back to the transform actually at fault. Check the analysis result and exit with an error instead, so a transform sequence stops at the transform that broke the crate and rustc's diagnostics point at the real breakage. --- c2rust-refactor/src/command.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/c2rust-refactor/src/command.rs b/c2rust-refactor/src/command.rs index bb2e13e919..a7d45b8cb9 100644 --- a/c2rust-refactor/src/command.rs +++ b/c2rust-refactor/src/command.rs @@ -418,6 +418,15 @@ impl RefactorState { }; // One extra step for Phase 3: run the analysis passes let _result = tcx.analysis(()); + // Transforms assume a well-typed crate; running them + // over stale or partial typeck results produces bogus + // rewrites or panics far from the real problem. + if tcx.sess.has_errors().is_some() { + tcx.sess.fatal( + "refusing to refactor: the crate has compile errors \ + (see diagnostics above)", + ); + } let cx = RefactorCtxt::new_phase_2_3( session, max_crate_node_id.unwrap(),