From b939b6c9f7e5f3c0c54144738c1a23dc32165679 Mon Sep 17 00:00:00 2001 From: Andrei Homescu Date: Mon, 24 Nov 2025 22:50:14 -0800 Subject: [PATCH 1/3] c2rust-refactor: Implement deep structural comparison of ADTs by comparing all variants --- c2rust-refactor/src/context.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/c2rust-refactor/src/context.rs b/c2rust-refactor/src/context.rs index 3d0ced31bf..90297d46e1 100644 --- a/c2rust-refactor/src/context.rs +++ b/c2rust-refactor/src/context.rs @@ -1334,6 +1334,10 @@ impl<'a, 'tcx, 'b> TypeCompare<'a, 'tcx, 'b> { match (&ty1.kind(), &ty2.kind()) { (TyKind::Adt(def1, substs1), TyKind::Adt(def2, substs2)) => { + if def1.adt_kind() != def2.adt_kind() { + return false; + } + if substs1.types().count() != substs2.types().count() || !substs1 .types() @@ -1366,15 +1370,21 @@ impl<'a, 'tcx, 'b> TypeCompare<'a, 'tcx, 'b> { return true; } - def1.all_fields().count() == def2.all_fields().count() + def1.variants().len() == def2.variants().len() && def1 - .all_fields() - .zip(def2.all_fields()) - .all(|(field1, field2)| { - field1.ident(tcx).unnamed_equiv(&field2.ident(tcx)) - && (!match_vis || field1.vis == field2.vis) - && self.structural_eq_defs_impl( - field1.did, field2.did, match_vis, seen, + .variants() + .iter() + .zip(def2.variants().iter()) + .all(|(var1, var2)| { + var1.fields.len() == var2.fields.len() + && var1.fields.iter().zip(var2.fields.iter()).all( + |(field1, field2)| { + field1.ident(tcx).unnamed_equiv(&field2.ident(tcx)) + && (!match_vis || field1.vis == field2.vis) + && self.structural_eq_defs_impl( + field1.did, field2.did, match_vis, seen, + ) + }, ) }) } From a72e2e94ce6c3d9a3bd98e53c22eee7afefdd00e Mon Sep 17 00:00:00 2001 From: Andrei Homescu Date: Wed, 3 Dec 2025 17:37:18 -0800 Subject: [PATCH 2/3] tests: integration: Enable reorganize_definitions for nginx --- tests/integration/tests/nginx/conf.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration/tests/nginx/conf.yml b/tests/integration/tests/nginx/conf.yml index 81b6cb1ca0..24b91aa022 100644 --- a/tests/integration/tests/nginx/conf.yml +++ b/tests/integration/tests/nginx/conf.yml @@ -15,12 +15,14 @@ cargo.refactor: transpile: autogen: true # blocked on https://github.com/immunant/c2rust/issues/266 - # tflags: --reorganize-definitions + tflags: --reorganize-definitions --disable-refactoring binary: nginx refactor: autogen: true transforms: + - rename_unnamed + - reorganize_definitions - remove_unused_labels - remove_literal_suffixes - convert_cast_as_ptr From b1e71cadc012415064652cebf899a54d222eb1ce Mon Sep 17 00:00:00 2001 From: Khyber Sen Date: Mon, 8 Dec 2025 05:36:37 -0800 Subject: [PATCH 3/3] refactor: add comment explaining the variant and field comparison in `fn structural_eq_tys_impl` --- c2rust-refactor/src/context.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/c2rust-refactor/src/context.rs b/c2rust-refactor/src/context.rs index 90297d46e1..ff63b923b4 100644 --- a/c2rust-refactor/src/context.rs +++ b/c2rust-refactor/src/context.rs @@ -1370,6 +1370,9 @@ impl<'a, 'tcx, 'b> TypeCompare<'a, 'tcx, 'b> { return true; } + // Iterate separately over the variants and fields (as opposed to the `.all_fields()` flat map). + // Otherwise, we may find a false equivalence for empty variants, + // or, in general, the flattened iterator could have the same elements but different variant boundaries. def1.variants().len() == def2.variants().len() && def1 .variants()