Skip to content

refactor: reorganize_definitions: use the fallback/C ABI instead of Rust - #1924

Open
ahomescu wants to merge 2 commits into
ahomescu/fix_reorganize_definitions/widen_matched_defsfrom
ahomescu/fix_reorganize_definitions/extern_abi_fallback
Open

refactor: reorganize_definitions: use the fallback/C ABI instead of Rust#1924
ahomescu wants to merge 2 commits into
ahomescu/fix_reorganize_definitions/widen_matched_defsfrom
ahomescu/fix_reorganize_definitions/extern_abi_fallback

Conversation

@ahomescu

@ahomescu ahomescu commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

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-externdeclaration fails to merge with theextern "C"duplicate, producing anextern "Rust"block and a spuriouscompute_1` rename.

reorganize_definitions.rs:843-847 and :1779-1782 both do:

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).

@ahomescu
ahomescu requested a review from thedataking July 25, 2026 00:33
@ahomescu

Copy link
Copy Markdown
Contributor Author

According to https://doc.rust-lang.org/reference/items/external-blocks.html#r-items.extern.abi.default, "C" is indeed the default.

pub mod first {
#[c2rust::header_src = "/home/user/some/workspace/first.h:1"]
pub mod first_h {
// An `extern` block without an explicit ABI string defaults to "C",

@thedataking thedataking Jul 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The transpiler always emits an explicit .extern_("C") (c2rust-transpile/src/translator/mod.rs:1231, :1459, :2009, :2236, :2781), so an implicit extern block can't come from transpiled code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, which is why we probably didn't catch this. Do we want to be defensive here, or punt this PR?

@thedataking thedataking left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From offline discussion: we don't have a C pattern that is not UB and would trigger this pattern. We assume that the transpiler operates on valid C and that the refactorer operates on whatever Rust the transpiler outputs.

@ahomescu

ahomescu commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

From offline discussion: we don't have a C pattern that is not UB and would trigger this pattern. We assume that the transpiler operates on valid C and that the refactorer operates on whatever Rust the transpiler outputs.

Did you mean to reply to this PR or #1935 ? Edit: if you meant 1935, could you approve 1924 so we can land it, since it's a legitimate bug fix?

@ahomescu
ahomescu changed the base branch from master to ahomescu/fix_reorganize_definitions/preserve_extern_link_name July 25, 2026 05:09
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 401842b to d17fbe9 Compare July 25, 2026 05:09
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from d17fbe9 to cc214be Compare July 25, 2026 05:33
@ahomescu
ahomescu changed the base branch from ahomescu/fix_reorganize_definitions/preserve_extern_link_name to ahomescu/fix_reorganize_definitions/mismatched_extern_arity July 25, 2026 05:41
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from cc214be to ddc9bbd Compare July 25, 2026 05:41
@ahomescu
ahomescu changed the base branch from ahomescu/fix_reorganize_definitions/mismatched_extern_arity to ahomescu/fix_reorganize_definitions/compare_extern_fn_sigs July 25, 2026 05:42
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from ddc9bbd to d8aec07 Compare July 25, 2026 05:42
@ahomescu
ahomescu changed the base branch from ahomescu/fix_reorganize_definitions/compare_extern_fn_sigs to ahomescu/fix_reorganize_definitions/non_ascii_idents July 25, 2026 05:47
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from d8aec07 to 1d944a8 Compare July 25, 2026 05:47
@ahomescu
ahomescu changed the base branch from ahomescu/fix_reorganize_definitions/non_ascii_idents to ahomescu/fix_reorganize_definitions/widen_matched_defs July 25, 2026 05:52
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 1d944a8 to 9f5743c Compare July 25, 2026 05:52
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 9f5743c to 141dd0b Compare July 25, 2026 05:59
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 141dd0b to b5dfa00 Compare July 25, 2026 06:05
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from b5dfa00 to 53f3d1f Compare July 25, 2026 06:16
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch 2 times, most recently from 634c092 to 368089d Compare July 25, 2026 06:43
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 368089d to dae85f6 Compare July 25, 2026 06:51
@thedataking

Copy link
Copy Markdown
Contributor

From offline discussion: we don't have a C pattern that is not UB and would trigger this pattern. We assume that the transpiler operates on valid C and that the refactorer operates on whatever Rust the transpiler outputs.

Did you mean to reply to this PR or #1935 ? Edit: if you meant 1935, could you approve 1924 so we can land it, since it's a legitimate bug fix?

My bad. Reviewing this one.

@thedataking thedataking left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From offline discussion:

  • we shouldn't add tests here since it gives the impression that this bug can be triggered
  • would be better to expect(...) here so this fails loudly.
  • alternatively, just fix the Abi to FALLBACK, don't add comments or tests.

@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from dae85f6 to 010ee5f Compare July 29, 2026 23:18
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 010ee5f to 4d14595 Compare July 30, 2026 00:19
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 4d14595 to 56e1808 Compare July 30, 2026 00:31
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 56e1808 to fe13ec8 Compare July 30, 2026 22:54
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from fe13ec8 to 473fc3d Compare July 30, 2026 22:56
ahomescu added 2 commits July 30, 2026 15:57
`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.
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`).
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/extern_abi_fallback branch from 473fc3d to 286a13f Compare July 30, 2026 22:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants