add extern "custom" functions - #140770
Conversation
|
These commits modify compiler targets. |
This comment has been minimized.
This comment has been minimized.
|
Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 Some changes occurred in compiler/rustc_codegen_gcc |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Did you forget to press escape before quitting vim? |
|
ah, yeah. Well it'll probably get squashed before this is ready |
|
I've made a proper tracking issue at #140829 |
|
☔ The latest upstream changes (presumably #141002) made this pull request unmergeable. Please resolve the merge conflicts. |
|
☔ The latest upstream changes (presumably #141984) made this pull request unmergeable. Please resolve the merge conflicts. |
Rollup of 9 pull requests Successful merges: - #128425 (Make `missing_fragment_specifier` an unconditional error) - #135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - #140770 (add `extern "custom"` functions) - #142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - #142248 (Add supported asm types for LoongArch32) - #142267 (assert more in release in `rustc_ast_lowering`) - #142274 (Update the stdarch submodule) - #142276 (Update dependencies in `library/Cargo.lock`) - #142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - #140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
Rollup of 9 pull requests Successful merges: - #128425 (Make `missing_fragment_specifier` an unconditional error) - #135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - #140770 (add `extern "custom"` functions) - #142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - #142248 (Add supported asm types for LoongArch32) - #142267 (assert more in release in `rustc_ast_lowering`) - #142274 (Update the stdarch submodule) - #142276 (Update dependencies in `library/Cargo.lock`) - #142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - #140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
Rollup merge of #140770 - folkertdev:custom-abi, r=tgross35 add `extern "custom"` functions tracking issue: #140829 previous discussion: #140566 In short, an `extern "custom"` function is a function with a custom ABI, that rust does not know about. Therefore, such functions can only be defined with `#[unsafe(naked)]` and `naked_asm!`, or via an `extern "C" { /* ... */ }` block. These functions cannot be called using normal rust syntax: calling them can only be done from inline assembly. The motivation is low-level scenarios where a custom calling convention is used. Currently, we often pick `extern "C"`, but that is a lie because the function does not actually respect the C calling convention. At the moment `"custom"` seems to be the name with the most support. That name is not final, but we need to pick something to actually implement this. r? `@traviscross` cc `@tgross35` try-job: x86_64-apple-2
Rollup of 9 pull requests Successful merges: - rust-lang/rust#128425 (Make `missing_fragment_specifier` an unconditional error) - rust-lang/rust#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - rust-lang/rust#140770 (add `extern "custom"` functions) - rust-lang/rust#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - rust-lang/rust#142248 (Add supported asm types for LoongArch32) - rust-lang/rust#142267 (assert more in release in `rustc_ast_lowering`) - rust-lang/rust#142274 (Update the stdarch submodule) - rust-lang/rust#142276 (Update dependencies in `library/Cargo.lock`) - rust-lang/rust#142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - rust-lang/rust#140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
Rollup of 9 pull requests Successful merges: - rust-lang/rust#128425 (Make `missing_fragment_specifier` an unconditional error) - rust-lang/rust#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - rust-lang/rust#140770 (add `extern "custom"` functions) - rust-lang/rust#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - rust-lang/rust#142248 (Add supported asm types for LoongArch32) - rust-lang/rust#142267 (assert more in release in `rustc_ast_lowering`) - rust-lang/rust#142274 (Update the stdarch submodule) - rust-lang/rust#142276 (Update dependencies in `library/Cargo.lock`) - rust-lang/rust#142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - rust-lang/rust#140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
Rollup of 9 pull requests Successful merges: - rust-lang/rust#128425 (Make `missing_fragment_specifier` an unconditional error) - rust-lang/rust#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - rust-lang/rust#140770 (add `extern "custom"` functions) - rust-lang/rust#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - rust-lang/rust#142248 (Add supported asm types for LoongArch32) - rust-lang/rust#142267 (assert more in release in `rustc_ast_lowering`) - rust-lang/rust#142274 (Update the stdarch submodule) - rust-lang/rust#142276 (Update dependencies in `library/Cargo.lock`) - rust-lang/rust#142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - rust-lang/rust#140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
|
@rust-timer build 2bf564a (Testing #142443) |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (2bf564a): comparison URL. Overall result: no relevant changes - no action neededBenchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf. @bors rollup=never Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results (primary 2.0%, secondary -1.9%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary 2.9%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 755.964s -> 690.275s (-8.69%) |
…iaskrgr Rollup of 9 pull requests Successful merges: - rust-lang#128425 (Make `missing_fragment_specifier` an unconditional error) - rust-lang#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - rust-lang#140770 (add `extern "custom"` functions) - rust-lang#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - rust-lang#142248 (Add supported asm types for LoongArch32) - rust-lang#142267 (assert more in release in `rustc_ast_lowering`) - rust-lang#142274 (Update the stdarch submodule) - rust-lang#142276 (Update dependencies in `library/Cargo.lock`) - rust-lang#142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - rust-lang#140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
Rollup of 9 pull requests Successful merges: - rust-lang/rust#128425 (Make `missing_fragment_specifier` an unconditional error) - rust-lang/rust#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - rust-lang/rust#140770 (add `extern "custom"` functions) - rust-lang/rust#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - rust-lang/rust#142248 (Add supported asm types for LoongArch32) - rust-lang/rust#142267 (assert more in release in `rustc_ast_lowering`) - rust-lang/rust#142274 (Update the stdarch submodule) - rust-lang/rust#142276 (Update dependencies in `library/Cargo.lock`) - rust-lang/rust#142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - rust-lang/rust#140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
add `extern "custom"` functions tracking issue: rust-lang#140829 previous discussion: rust-lang#140566 In short, an `extern "custom"` function is a function with a custom ABI, that rust does not know about. Therefore, such functions can only be defined with `#[unsafe(naked)]` and `naked_asm!`, or via an `extern "C" { /* ... */ }` block. These functions cannot be called using normal rust syntax: calling them can only be done from inline assembly. The motivation is low-level scenarios where a custom calling convention is used. Currently, we often pick `extern "C"`, but that is a lie because the function does not actually respect the C calling convention. At the moment `"custom"` seems to be the name with the most support. That name is not final, but we need to pick something to actually implement this. r? `@traviscross` cc `@tgross35` try-job: x86_64-apple-2
Rollup of 9 pull requests Successful merges: - rust-lang/rust#128425 (Make `missing_fragment_specifier` an unconditional error) - rust-lang/rust#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - rust-lang/rust#140770 (add `extern "custom"` functions) - rust-lang/rust#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - rust-lang/rust#142248 (Add supported asm types for LoongArch32) - rust-lang/rust#142267 (assert more in release in `rustc_ast_lowering`) - rust-lang/rust#142274 (Update the stdarch submodule) - rust-lang/rust#142276 (Update dependencies in `library/Cargo.lock`) - rust-lang/rust#142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - rust-lang/rust#140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
Rollup of 9 pull requests Successful merges: - rust-lang/rust#128425 (Make `missing_fragment_specifier` an unconditional error) - rust-lang/rust#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features) - rust-lang/rust#140770 (add `extern "custom"` functions) - rust-lang/rust#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches) - rust-lang/rust#142248 (Add supported asm types for LoongArch32) - rust-lang/rust#142267 (assert more in release in `rustc_ast_lowering`) - rust-lang/rust#142274 (Update the stdarch submodule) - rust-lang/rust#142276 (Update dependencies in `library/Cargo.lock`) - rust-lang/rust#142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library) Failed merges: - rust-lang/rust#140920 (Extract some shared code from codegen backend target feature handling) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: x86_64-msvc-1 try-job: x86_64-gnu try-job: dist-i586-gnu-i586-i686-musl try-job: test-various
…, 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
…, 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
…, 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
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
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
View all comments
tracking issue: #140829
previous discussion: #140566
In short, an
extern "custom"function is a function with a custom ABI, that rust does not know about. Therefore, such functions can only be defined with#[unsafe(naked)]andnaked_asm!, or via anextern "C" { /* ... */ }block. These functions cannot be called using normal rust syntax: calling them can only be done from inline assembly.The motivation is low-level scenarios where a custom calling convention is used. Currently, we often pick
extern "C", but that is a lie because the function does not actually respect the C calling convention.At the moment
"custom"seems to be the name with the most support. That name is not final, but we need to pick something to actually implement this.r? @traviscross
cc @tgross35
try-job: x86_64-apple-2