Skip to content

Commit 3b2788c

Browse files
authored
refactor: fix canonicalize_refs in libxml transforms (#1450)
`canonicalize_refs` used `cx.hir_map().node_to_hir_id` and unconditionally called `typeck(parent)`. When `MutVisitNodes` descends into attribute tokens or items without bodies (e.g., `extern` decls) the HIR map lacks a node or typeck tables, so the walk panicked with `span_bug!("can't type-check body …")`. This PR swaps to `opt_node_to_hir_id` so attribute-only nodes short-circuit before we ever try to fetch HIR expressions, keeping the transform aligned with what rustc actually lowers, and checks `maybe_body_owned_by(parent)` before querying typeck tables; this skips extern items and other definitions without bodies, avoiding the `primary_body_of` unwrap panic while still running the transform over real bodies.
2 parents 36563b5 + 1422b0b commit 3b2788c

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

c2rust-refactor/src/transform/canonicalize_refs.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,21 @@ struct CanonicalizeRefs;
1515
impl Transform for CanonicalizeRefs {
1616
fn transform(&self, krate: &mut Crate, _st: &CommandState, cx: &RefactorCtxt) {
1717
MutVisitNodes::visit(krate, |expr: &mut P<Expr>| {
18-
let hir_id = cx.hir_map().node_to_hir_id(expr.id);
18+
// `MutVisitNodes` walks into attributes even though rustc never lowers their bodies to HIR.
19+
// We skip such nodes by probing with `opt_node_to_hir_id`; if we ever need an attribute-only
20+
// walk we’d have to reimplement the traversal with an attribute-depth-aware visitor instead.
21+
let Some(hir_id) = cx.hir_map().opt_node_to_hir_id(expr.id) else {
22+
return;
23+
};
1924
let hir_expr = cx.hir_map().expect_expr(hir_id);
2025
let parent = cx.hir_map().get_parent_item(hir_id);
26+
if cx.hir_map().maybe_body_owned_by(parent).is_none() {
27+
// `tcx.typeck(parent)` unwraps `primary_body_of` (rustc_typeck::check::mod.rs),
28+
// so querying items without bodies (e.g. extern statics/functions) triggers a
29+
// `span_bug!("can't type-check body ...")`. Skip any expressions owned by such
30+
// items instead of poking the typeck tables.
31+
return;
32+
}
2133
let tables = cx.ty_ctxt().typeck(parent);
2234
for adjustment in tables.expr_adjustments(hir_expr) {
2335
match adjustment.kind {

0 commit comments

Comments
 (0)