Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking issue for const extern fn and const unsafe extern fn #64926

Closed
1 task done
Aaron1011 opened this issue Sep 30, 2019 · 19 comments · Fixed by #129753
Closed
1 task done

Tracking issue for const extern fn and const unsafe extern fn #64926

Aaron1011 opened this issue Sep 30, 2019 · 19 comments · Fixed by #129753
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. A-FFI Area: Foreign function interface (FFI) B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC F-const_extern_fn `#![feature(const_extern_fn)]` S-tracking-ready-to-stabilize Status: This is ready to stabilize; it may need a stabilization report and a PR T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@Aaron1011
Copy link
Member

Aaron1011 commented Sep 30, 2019

This is a tracking issue for implementing and stabilizing defining a const extern fn and const unsafe extern fn

Stabilizaton Report

Summary

This allows writing const unsafe extern "calling-convention" fn and const extern "calling-convention" fn:

Today Rust and C calling conventions are stable (as of 1.62, see #95346). All other calling conventions are still unstable.

const extern fn foo1(val: u8) -> u8 { val + 1 }
const extern "C" fn foo2(val: u8) -> u8 { val + 1}
const unsafe extern fn bar1(val: bool) -> bool { !val }
const unsafe extern "C" fn bar2(val: bool) -> bool { !val }

This can be used to const-ify an extern fn (or equivalently, to make a const fn callable from external code).

Test cases

  1. Test for defining and calling in Rust code: https://github.com/rust-lang/rust/blob/master/src/test/ui/consts/const-extern-fn/const-extern-fn.rs
  2. Test that calling with the wrong calling convention (from a const context) leads to an error: https://github.com/rust-lang/rust/blob/master/src/test/ui/consts/miri_unleashed/abi-mismatch.rs
@jonas-schievink jonas-schievink added A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Sep 30, 2019
@Centril Centril added the F-const_extern_fn `#![feature(const_extern_fn)]` label Sep 30, 2019
@RalfJung
Copy link
Member

RalfJung commented Oct 1, 2019

Could you explain a bit more what this means and what the point is? What does the bare extern keyword even do? extern "Rust" fn and fn are the same thing, after all. (extern fn is poorly named; AFAIK it really is about specifying the ABI and has little to do with extern visibility.)

@Aaron1011
Copy link
Member Author

Aaron1011 commented Oct 1, 2019

@RalfJung: The point is to be able to define an const extern fn (i.e. const extern "C" fn), which has a C-compatible ABI and can be invoked from const contexts.

@jonas-schievink jonas-schievink added the A-FFI Area: Foreign function interface (FFI) label Oct 1, 2019
Manishearth added a commit to Manishearth/rust that referenced this issue Oct 2, 2019
…r=Centril

Add support for `const unsafe? extern fn`

This works just as you might expect - an `const extern fn` is a `const fn` that is callable from foreign code.

Currently, panicking is not allowed in `const`s. When rust-lang/rfcs#2345 (rust-lang#51999) is stabilized, then panicking in an `const extern fn` will produce a compile-time error when invoked at compile time, and an abort when invoked at runtime.

Since this is extending the language (we're allowing the `const` keyword in a new context), I believe that this will need an FCP. However, it's a very minor change, so I didn't think that filing an RFC was necessary.

This will allow libc (and other FFI crates) to make many functions `const`, without having to give up on making them `extern` as well.

Tracking issue: rust-lang#64926.
bors added a commit that referenced this issue Oct 7, 2019
Add support for `const unsafe? extern fn`

This works just as you might expect - an `const extern fn` is a `const fn` that is callable from foreign code.

Currently, panicking is not allowed in `const`s. When rust-lang/rfcs#2345 (#51999) is stabilized, then panicking in an `const extern fn` will produce a compile-time error when invoked at compile time, and an abort when invoked at runtime.

Since this is extending the language (we're allowing the `const` keyword in a new context), I believe that this will need an FCP. However, it's a very minor change, so I didn't think that filing an RFC was necessary.

This will allow libc (and other FFI crates) to make many functions `const`, without having to give up on making them `extern` as well.

Tracking issue: #64926.
@Centril
Copy link
Contributor

Centril commented Oct 7, 2019

Implemented in #64906 (2019-10-07).

@Aaron1011
Copy link
Member Author

From #64906 (comment):

@Aaron1011 Could we also get a test making sure that we properly report an error when calling a const fn using the wrong ABI, such as calling an extern "C" const fn with the call site assuming it is an extern "Rust" const fn? The checks for that should already exist in the engine (for standalone Miri).

@RalfJung: Are you talking about a miri-unleashed test involved function pointers? As far I as know, that's the only way for such an ABI mismatch to occur.

@RalfJung
Copy link
Member

Yes, I meant a miri-unleashed test.

Aaron1011 added a commit to Aaron1011/rust that referenced this issue Jan 27, 2020
pietroalbini added a commit to pietroalbini/rust that referenced this issue Jan 27, 2020
…Jung

Ensure that we error when calling "const extern fn" with wrong convention

See rust-lang#64926
@Aaron1011
Copy link
Member Author

@Centril: In #64906 (comment), you said:

However, I think we may eventually want a stabilization RFC that takes into account all of the discussion thus far and elaborates on semantics, use-cases, etc.

Since this PR was merged, rust-lang/libc#1536 was merged, which takes advantage of this feature. Do you still want an RFC prior to stabilization? If so, I'd be happy to start writing one up.

@Centril
Copy link
Contributor

Centril commented Mar 26, 2020

Some points:

  • The pre-expansion gating of the syntax no longer happens. Post expansion gating is used now instead (so you might want to use that to your advantage).

  • An RFC is perhaps unnecessary, but a detailed stabilization report could serve the same purpose, and we'd want that for any stabilization.

  • To stabilize this now would be to extend the surface arena under which the soundness hole in Default behavior of unwinding in FFI functions #58794 (comment) applies, so I would like to see that fixed before stabilizing.

@RalfJung
Copy link
Member

To stabilize this now would be to extend the surface arena under which the soundness hole in #58794 (comment) applies, so I would like to see that fixed before stabilizing.

Also see #63943 where the soundness hole is tracked.

@eira-fransham
Copy link

All the issues that were blocking this feature from being stablised appear to have been addressed, could this be stablised now? I think any code that would want to use it could just use a non-const extern function which wraps a const fn Rust-ABI function but if there's no reason for it not to be stablised it then it might as well be.

@Aaron1011 Aaron1011 added the S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). label Feb 25, 2022
@rfcbot
Copy link

rfcbot commented Mar 18, 2022

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

@rfcbot rfcbot added to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Mar 18, 2022
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Mar 24, 2022
Aaron1011 added a commit to Aaron1011/rust that referenced this issue Mar 26, 2022
All other ABIs are left unstable for now.

cc rust-lang#64926
fee1-dead added a commit to fee1-dead-contrib/rust that referenced this issue Apr 15, 2022
… r=pnkfelix

Stablize `const_extern_fn` for "Rust" and "C"

All other ABIs are left unstable for now.

cc rust-lang#64926
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 15, 2022
… r=pnkfelix

Stablize `const_extern_fn` for "Rust" and "C"

All other ABIs are left unstable for now.

cc rust-lang#64926
RalfJung added a commit to RalfJung/rust that referenced this issue Apr 15, 2022
… r=pnkfelix

Stablize `const_extern_fn` for "Rust" and "C"

All other ABIs are left unstable for now.

cc rust-lang#64926
RalfJung added a commit to RalfJung/rust that referenced this issue Apr 15, 2022
… r=pnkfelix

Stablize `const_extern_fn` for "Rust" and "C"

All other ABIs are left unstable for now.

cc rust-lang#64926
RalfJung added a commit to RalfJung/rust that referenced this issue Apr 15, 2022
… r=pnkfelix

Stablize `const_extern_fn` for "Rust" and "C"

All other ABIs are left unstable for now.

cc rust-lang#64926
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 16, 2022
… r=pnkfelix

Stablize `const_extern_fn` for "Rust" and "C"

All other ABIs are left unstable for now.

cc rust-lang#64926
@joshtriplett joshtriplett added S-tracking-impl-incomplete Status: The implementation is incomplete. S-tracking-ready-to-stabilize Status: This is ready to stabilize; it may need a stabilization report and a PR and removed disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). S-tracking-impl-incomplete Status: The implementation is incomplete. labels Jun 22, 2022
@joshtriplett
Copy link
Member

It looks like "C" and "Rust" calling conventions were stabilized for the upcoming 1.62 release.

Other calling conventions could be stabilized as well; is there a blocker for doing so?

@RalfJung
Copy link
Member

I am not aware of any calling convention being special here. (Other than variadics, but those are generally unstable, not just for const fn.)

@bors bors closed this as completed in 4f1be92 Sep 15, 2024
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Sep 16, 2024
stabilize `const_extern_fn`

closes rust-lang/rust#64926

tracking issue: rust-lang/rust#64926
reference PR: rust-lang/reference#1596

## Stabilizaton Report

### Summary

Using `const extern "Rust"` and `const extern "C"` was already stabilized (since version 1.62.0, see rust-lang/rust#95346). This PR stabilizes the other calling conventions: it is now possible to write  `const unsafe extern "calling-convention" fn` and `const extern "calling-convention" fn` for any supported calling convention:

```rust
const extern "C-unwind" fn foo1(val: u8) -> u8 { val + 1}
const extern "stdcall" fn foo2(val: u8) -> u8 { val + 1}
const unsafe extern "C-unwind" fn bar1(val: bool) -> bool { !val }
const unsafe extern "stdcall" fn bar2(val: bool) -> bool { !val }
```

This can be used to const-ify an `extern fn`, or conversely, to make a `const fn` callable from external code.

r? T-lang

cc `@RalfJung`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. A-FFI Area: Foreign function interface (FFI) B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC F-const_extern_fn `#![feature(const_extern_fn)]` S-tracking-ready-to-stabilize Status: This is ready to stabilize; it may need a stabilization report and a PR T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants