Skip to content

Commit 56e1808

Browse files
committed
refactor: reorganize_definitions: use the fallback/C ABI instead of Rust
Both sites now use `Abi::FALLBACK` (= `Abi::C { unwind: false }`). `Regression test: `test_reorganize_implicit_extern` (`tests/snapshots/reorganize_implicit_extern.rs`); on pre-fix code its implicit-`extern` declaration fails to merge with the `extern "C"` duplicate, producing an `extern "Rust"` block and a spurious `compute_1` rename. `reorganize_definitions.rs:843-847` and `:1779-1782` both do: ```rust let abi = m.abi.and_then(|abi| abi::lookup(&abi.symbol.as_str())).unwrap_or(Abi::Rust); ``` Rust's default ABI for `extern {}` blocks is `"C"` (rustc's own lowering uses `Abi::FALLBACK`, which is `Abi::C`). Consequences: - An implicit `extern { fn foo(); }` block never dedups against an `extern "C" { fn foo(); }` declaration — the ABI-mismatch `continue` at `:2144` in `find_foreign_item` skips it. - Worse, its items are re-emitted by `into_items` via `mk().extern_(Abi::Rust)` (`:1990`), silently changing the declared ABI of foreign functions. Latent only because transpiled code usually writes `extern "C"` explicitly. Fix: fall back to `Abi::C { unwind: false }` (or `Abi::FALLBACK`).
1 parent fae12b7 commit 56e1808

2 files changed

Lines changed: 9 additions & 10 deletions

File tree

c2rust-refactor/src/transform/reorganize_definitions.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -881,10 +881,12 @@ impl<'a, 'tcx> Reorganizer<'a, 'tcx> {
881881
.into_iter()
882882
.filter_map(|mut item| {
883883
if let ItemKind::ForeignMod(m) = &mut item.kind {
884+
// `extern` without an explicit ABI string defaults
885+
// to "C", same as rustc's lowering.
884886
let abi = m
885887
.abi
886888
.and_then(|abi| abi::lookup(&abi.symbol.as_str()))
887-
.unwrap_or(Abi::Rust);
889+
.unwrap_or(Abi::FALLBACK);
888890
m.items.retain(|item| {
889891
match declarations.find_foreign_item(item, abi) {
890892
ContainsDecl::NotContained => true,
@@ -1847,10 +1849,12 @@ impl<'a, 'tcx> HeaderDeclarations<'a, 'tcx> {
18471849
// defined in ident_map after processing the whole list of items.
18481850
ItemKind::ForeignMod(f) => {
18491851
for item in f.items.iter() {
1852+
// `extern` without an explicit ABI string defaults to "C",
1853+
// same as rustc's lowering.
18501854
let abi = f
18511855
.abi
18521856
.and_then(|abi| abi::lookup(&abi.symbol.as_str()))
1853-
.unwrap_or(Abi::Rust);
1857+
.unwrap_or(Abi::FALLBACK);
18541858
self.insert_foreign_item(item.clone(), abi, parent_header.clone());
18551859
}
18561860
true

c2rust-refactor/tests/snapshots/snapshots__refactor-reorganize_definitions-reorganize_implicit_extern.rs.snap

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ expression: c2rust-refactor reorganize_definitions --rewrite-mode alongside -- t
1111
pub mod first {
1212

1313
// =============== BEGIN first_h ================
14-
extern "Rust" {
14+
extern "C" {
1515

1616
pub fn compute(x: i32) -> i32;
1717
}
@@ -23,15 +23,10 @@ pub mod first {
2323

2424
pub mod second {
2525

26-
// =============== BEGIN second_h ================
27-
extern "C" {
28-
29-
#[link_name = "compute"]
30-
pub fn compute_1(x: i32) -> i32;
31-
}
26+
use crate::first::compute;
3227

3328
pub fn call_second(x: i32) -> i32 {
34-
unsafe { crate::second::compute_1(x) }
29+
unsafe { crate::first::compute(x) }
3530
}
3631
}
3732

0 commit comments

Comments
 (0)