Skip to content

Stabilize extern "custom"#158504

Open
folkertdev wants to merge 1 commit into
rust-lang:mainfrom
folkertdev:stabilize-extern-custom
Open

Stabilize extern "custom"#158504
folkertdev wants to merge 1 commit into
rust-lang:mainfrom
folkertdev:stabilize-extern-custom

Conversation

@folkertdev

@folkertdev folkertdev commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

View all comments

tracking issue: #140829
reference PR: rust-lang/reference#2300
closes #140829

Summary

An extern "custom" fn is a function with a custom ABI that is unknown to rust. Often these are low-level functions that pass arguments in different registers than any standard calling convention.

#[unsafe(naked)]
pub unsafe extern "custom" fn __aeabi_uidivmod() {
    core::arch::naked_asm!(
        "push {{lr}}",
        "sub sp, sp, #4",
        "mov r2, sp",
        "bl {trampoline}",
        "ldr r1, [sp]",
        "add sp, sp, #4",
        "pop {{pc}}",
        trampoline = sym crate::arm::__udivmodsi4
    );
}

unsafe extern "custom" {
	fn __fentry__();
}

Design

Because rust doesn't know what calling convention to use, an extern "custom" function can only be called via inline assembly or FFI.

error: functions with the "custom" ABI cannot be called
 --> <source>:5:5
  |
5 |     bar();
  |     ^^^^^
  |
note: an `extern "custom"` function can only be called using inline assembly

An extern "custom" function definition must be a naked function:

error: items with the "custom" ABI can only be declared externally or defined via naked functions
  --> <source>:10:1
   |
10 | unsafe extern "custom" fn bar() {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
help: convert this to an `#[unsafe(naked)]` function
   |
10 + #[unsafe(naked)]
11 | unsafe extern "custom" fn bar() {
   |

An extern "custom" function definition must be unsafe. The intent here is that a safety comment is written on how this function may be called.

error: functions with the "custom" ABI must be unsafe
  --> <source>:10:1
   |
10 | extern "custom" fn bar() {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   |
help: add the `unsafe` keyword to this definition
   |
10 | unsafe extern "custom" fn bar() {
   | ++++++

In an extern "custom" block, functions cannot be marked as safe:

error: foreign functions with the "custom" ABI cannot be safe
  --> <source>:16:5
   |
16 |     safe fn foobar();
   |     ^^^^^^^^^^^^^^^^^
   |
help: remove the `safe` keyword from this definition
   |
16 -     safe fn foobar();
16 +     fn foobar();

An extern "custom" function cannot have any arguments or a return type:

error: invalid signature for `extern "custom"` function
 --> <source>:6:31
  |
6 | unsafe extern "custom" fn foo(a: i32) -> i32 {
  |                               ^^^^^^     ^^^
  |
  = note: functions with the "custom" ABI cannot have any parameters or return type
help: remove the parameters and return type
  |
6 - unsafe extern "custom" fn foo(a: i32) -> i32 {
6 + unsafe extern "custom" fn foo() {
  |

Tests

  • tests/ui/abi/custom.rs tests that the feature works as expected, e.g. that functions can be defined, symbols are defined, and extern blocks can be used.
  • tests/ui/abi/bad-custom.rs checks the restrictions: definitions must be unsafe and naked, attempting to call an extern "custom" function gives an error, etc.

History

unresolved questions

None

@folkertdev folkertdev added the F-abi_custom `#![feature(abi_custom)]` label Jun 27, 2026
@rustbot rustbot added A-compiler-builtins Area: compiler-builtins (https://github.com/rust-lang/compiler-builtins) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 27, 2026
@folkertdev

Copy link
Copy Markdown
Contributor Author

r? tgross35

@rustbot

rustbot commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

tgross35 is currently at their maximum review capacity.
They may take a while to respond.

@folkertdev folkertdev marked this pull request as ready for review June 28, 2026 15:33
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 28, 2026
@rustbot

rustbot commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

compiler-builtins is developed in its own repository. If possible, consider making this change to rust-lang/compiler-builtins instead.

cc @tgross35

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 28, 2026
@folkertdev folkertdev added the I-lang-nominated Nominated for discussion during a lang team meeting. label Jun 28, 2026
@rust-bors

rust-bors Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #158524) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

@bjorn3

bjorn3 commented Jun 28, 2026

Copy link
Copy Markdown
Member

Do we deny this on wasm? Wasm requires the function signature to be known when defining or importing it.

@folkertdev

Copy link
Copy Markdown
Contributor Author

In that case, does the whole concept of a naked function even make sense there? That is, can it do something that a normal function whose body is an asm! block cannot do?

Practically inline assembly is unstable (and extremely incomplete) for wasm, so I'm not sure if/how it'll eventually fit in.

But we can deny extern "custom" on wasm if that seems best right now.

@bjorn3

bjorn3 commented Jun 28, 2026

Copy link
Copy Markdown
Member

Naked asm can avoid touching the stack, maybe there are cases that is useful? Naked asm doesn't help for defining functions that use ref types or GC types as there isn't a way to express those using rust syntax, so those still need global_asm!().

@823984418

Copy link
Copy Markdown
Contributor

Allowing only assembly calls seems quite restrictive in terms of cross platform capabilities, as a special case, an extern "custom" fn function that internally calls only another extern "custom" fn function should be allowed and may be treated as syntactic sugar for a direct jump.

@asquared31415

Copy link
Copy Markdown
Contributor

This is a restriction on naked functions already, they must not contain Rust code.

@folkertdev

Copy link
Copy Markdown
Contributor Author

Just making this explicit: #158621 removes support for wasm and spirv targets. Neither have stable assembly, so practically this doesn't change anything, but the whole concept of extern "custom" doesn't really make sense there.

@traviscross traviscross added needs-reference-pr This language change needs an approved Reference PR to proceed. T-lang Relevant to the language team needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Jul 1, 2026
@traviscross

Copy link
Copy Markdown
Contributor

Makes sense to me. Thanks @folkertdev for your work on this.

@rfcbot fcp merge lang

cc @Amanieu

@rust-rfcbot

rust-rfcbot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

@traviscross has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Jul 1, 2026
@rust-rfcbot rust-rfcbot added disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. and removed needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Jul 1, 2026
@joshtriplett

Copy link
Copy Markdown
Member

Looks great! This will be useful for some fun low-level systems programming stunts.

@rfcbot reviewed

@nikomatsakis

Copy link
Copy Markdown
Contributor

@rfcbot reviewed

I am in favor of this and I like the name custom.

I am mildly negative on not having an RFC. I think this is skipping steps and overall that's less good, I'd like to see a (short) write-up with rationale, alternative names considered, etc.

That said, I'm leaving it up to @tmandry to make the call on whether to raise a concern.

@rust-rfcbot rust-rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Jul 1, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@traviscross

traviscross commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

In the lang call today, there was a slight preference for seeing an RFC here first.

@rfcbot concern needs-rfc

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Jul 1, 2026
@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. and removed I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Jul 1, 2026
@traviscross

Copy link
Copy Markdown
Contributor

@rustbot blocked

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 1, 2026
@traviscross traviscross added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 1, 2026
@folkertdev

Copy link
Copy Markdown
Contributor Author

RFC is up at rust-lang/rfcs#3980

@traviscross

Copy link
Copy Markdown
Contributor

Based on rust-lang/rfcs#3980 being in FCP...

@rfcbot resolve needs-rfc
@rustbot review

@rust-rfcbot rust-rfcbot added the final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. label Jul 1, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@rust-rfcbot rust-rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Jul 1, 2026
@traviscross traviscross removed the S-blocked Status: Blocked on something else such as an RFC or other implementation work. label Jul 1, 2026
@traviscross traviscross changed the title stabilize extern "custom" Stabilize extern "custom" Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-compiler-builtins Area: compiler-builtins (https://github.com/rust-lang/compiler-builtins) disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. F-abi_custom `#![feature(abi_custom)]` final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. needs-reference-pr This language change needs an approved Reference PR to proceed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking Issue for abi_custom

10 participants