Skip to content

Stabilize extern "custom" - #158504

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
folkertdev:stabilize-extern-custom
Aug 15, 2026
Merged

Stabilize extern "custom"#158504
rust-bors[bot] merged 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

This comment has been minimized.

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

@folkertdev folkertdev mentioned this pull request Jul 1, 2026
4 tasks
@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 proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jul 1, 2026
@rustbot rustbot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Aug 9, 2026
@tgross35

tgross35 commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Second question: should we reject #[cold]? I don't think there's anything we can do with it, assuming it can't bubble up through inline asm somehow.

Currently accepted https://rust.godbolt.org/z/rh5aMbcGK

@tgross35 tgross35 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.

Some small test suggestions, otherwise stabilization looks fine to me against rust-lang/reference#2300 at 66b3bc5b8688 with the possible exception of generics and #[cold]. I guess generics are probably fine, would just like somebody from lang to confirm since I haven't seen it discussed anywhere.

View changes since this review

Comment thread tests/ui/abi/bad-custom.rs
Comment thread tests/ui/abi/custom.rs
@traviscross

Copy link
Copy Markdown
Contributor

Thanks @tgross35 for flagging those. For my own part, I agree that generics should be accepted and that cold likely should not be.

@rust-bors

This comment has been minimized.

@traviscross traviscross added the P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang label Aug 12, 2026
@joshtriplett

Copy link
Copy Markdown
Member

As I understand it, in some cases #[cold] might cause something to get placed differently in the binary (e.g. adjacent to other cold items)? If that were the behavior, that could still work, right?

@joshtriplett

Copy link
Copy Markdown
Member

If #[cold] is currently having zero effect on a custom function, then we should reject it at compile time.

If at some point this becomes capable of affecting function placement in the binary, that makes sense to apply to custom, and at that point we should accept it.

@traviscross

Copy link
Copy Markdown
Contributor

We discussed this in the lang call. We agree that generics should be supported and that, for now, cold on these items should be made an error.

@traviscross

Copy link
Copy Markdown
Contributor

In the lang call, we also discussed the rule for the return type. (Thanks to @folkertdev for raising this.) The return type on these items is constrained to unit. Is that constraint syntactic (i.e., the return type must be elided or () written explicitly) or semantic (i.e., true after normalization of type aliases)?

We agreed this rule should be enforced syntactically.

@traviscross traviscross 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 Aug 12, 2026
@folkertdev
folkertdev force-pushed the stabilize-extern-custom branch from 364b5d7 to 652ab85 Compare August 14, 2026 20:29
@rustbot

rustbot commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@tgross35 tgross35 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.

#[cold] is rejected since #161002 and lang decided generics should be accepted, so everything seems in order to me!

@bors r+

View changes since this review

@rust-bors

rust-bors Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 652ab85 has been approved by tgross35

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 14, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request Aug 15, 2026
…, r=tgross35

Stabilize `extern "custom"`

tracking issue: rust-lang#140829
reference PR: rust-lang/reference#2300
closes rust-lang#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.

```rust
#[unsafe(naked)]
pub unsafe extern "custom" fn __aeabi_uidivmod() {
    core::arch::naked_asm!(
        "push {{lr}}",
        "sub sp, sp, rust-lang#4",
        "mov r2, sp",
        "bl {trampoline}",
        "ldr r1, [sp]",
        "add sp, sp, rust-lang#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](https://github.com/rust-lang/rust/blob/main/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](https://github.com/rust-lang/rust/blob/main/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

* rust-lang#140566
* rust-lang#140829
* rust-lang#140770
* rust-lang#159780

## unresolved questions

None
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 15, 2026
…, r=tgross35

Stabilize `extern "custom"`

tracking issue: rust-lang#140829
reference PR: rust-lang/reference#2300
closes rust-lang#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.

```rust
#[unsafe(naked)]
pub unsafe extern "custom" fn __aeabi_uidivmod() {
    core::arch::naked_asm!(
        "push {{lr}}",
        "sub sp, sp, rust-lang#4",
        "mov r2, sp",
        "bl {trampoline}",
        "ldr r1, [sp]",
        "add sp, sp, rust-lang#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](https://github.com/rust-lang/rust/blob/main/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](https://github.com/rust-lang/rust/blob/main/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

* rust-lang#140566
* rust-lang#140829
* rust-lang#140770
* rust-lang#159780

## unresolved questions

None
rust-bors Bot pushed a commit that referenced this pull request Aug 15, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - #161111 (Take bors try-perf branch into account in verify-channel.sh)
 - #158504 (Stabilize `extern "custom"`)
 - #161030 (mailmap: fix nia's gazillion emails)
 - #161105 (rustdoc: Small `doc_cfg` messages improvements)
rust-bors Bot pushed a commit that referenced this pull request Aug 15, 2026
…uwer

Rollup of 5 pull requests

Successful merges:

 - #161111 (Take bors try-perf branch into account in verify-channel.sh)
 - #158504 (Stabilize `extern "custom"`)
 - #161030 (mailmap: fix nia's gazillion emails)
 - #161105 (rustdoc: Small `doc_cfg` messages improvements)
 - #161123 (bootstrap: Clean up some inconsistent imports and paths)
@rust-bors
rust-bors Bot merged commit 0692376 into rust-lang:main Aug 15, 2026
13 checks passed
rust-bors Bot pushed a commit that referenced this pull request Aug 15, 2026
Rollup merge of #158504 - folkertdev:stabilize-extern-custom, r=tgross35

Stabilize `extern "custom"`

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.

```rust
#[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](https://github.com/rust-lang/rust/blob/main/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](https://github.com/rust-lang/rust/blob/main/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

* #140566
* #140829
* #140770
* #159780

## unresolved questions

None
@rustbot rustbot added this to the 1.99.0 milestone Aug 15, 2026
rust-timer added a commit that referenced this pull request Aug 15, 2026
Rollup merge of #158504 - folkertdev:stabilize-extern-custom, r=tgross35

Stabilize `extern "custom"`

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.

```rust
#[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](https://github.com/rust-lang/rust/blob/main/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](https://github.com/rust-lang/rust/blob/main/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

* #140566
* #140829
* #140770
* #159780

## unresolved questions

None
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)]` finished-final-comment-period The final comment period is finished for this PR / Issue. has-reference-pr This language change has an approved Reference PR. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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. to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking Issue for abi_custom