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

Add support for const unsafe? extern fn #64906

Merged
merged 3 commits into from
Oct 7, 2019

Conversation

Aaron1011
Copy link
Member

@Aaron1011 Aaron1011 commented Sep 29, 2019

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

@rust-highfive
Copy link
Collaborator

r? @petrochenkov

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 29, 2019
@Centril
Copy link
Contributor

Centril commented Sep 30, 2019

r? @Centril

src/libsyntax/parse/parser/item.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser/item.rs Outdated Show resolved Hide resolved
@Centril
Copy link
Contributor

Centril commented Sep 30, 2019

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 should definitely be feature gated (pre-expansion, see #64672 for examples) and not insta-stabilized. Please create a new tracking issue and think add it to the list in #57563.

@Aaron1011
Copy link
Member Author

@Centril: I've added a feature gate. changed the grammar, and created a tracking issue.

src/libsyntax/parse/mod.rs Outdated Show resolved Hide resolved
src/libsyntax/feature_gate/active.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser/item.rs Outdated Show resolved Hide resolved
src/test/ui/parser/removed-syntax-extern-const-fn.rs Outdated Show resolved Hide resolved
src/test/ui/reify-intrinsic.stderr Outdated Show resolved Hide resolved
src/test/ui/consts/const-fn-extern.rs Outdated Show resolved Hide resolved
src/test/ui/feature-gates/feature-gate-const_extern_fn.rs Outdated Show resolved Hide resolved
src/test/ui/consts/const-fn-extern.rs Outdated Show resolved Hide resolved
@Centril Centril changed the title Add support for 'extern const fn' Add support for const unsafe? extern fn Sep 30, 2019
@Centril Centril added F-const_extern_fn `#![feature(const_extern_fn)]` S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 30, 2019
@Aaron1011
Copy link
Member Author

@Centril I've added more tests

src/libsyntax/parse/mod.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser/item.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser/item.rs Outdated Show resolved Hide resolved
src/libsyntax/parse/parser/item.rs Show resolved Hide resolved
src/test/ui/consts/const-extern-fn/const-extern-fn.stderr Outdated Show resolved Hide resolved
src/test/ui/parser/no-const-fn-in-extern-block-unsafe.rs Outdated Show resolved Hide resolved
@rust-highfive

This comment has been minimized.

@Aaron1011
Copy link
Member Author

@Centril: I've added more tests, and implemented parsing recovering for extern blocks.

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

Currently, panicking is not allowed in consts. When RFC 2345 is
stabilized, then panicking in an 'extern const 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.
@Centril
Copy link
Contributor

Centril commented Oct 2, 2019

Thanks! -- Implementation looks good now.

@rust-lang/lang N.B. this adds support for const unsafe? extern ABI? fn under a feature gate const_extern_fn. The changes are syntactic in nature and the semantic changes mainly just fall out. I'll r+ this since I think it's fine to land for experimentation purposes and the discussion can progress on the tracking issue. 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.

@bors r+

@bors
Copy link
Contributor

bors commented Oct 2, 2019

📌 Commit 84b680f has been approved by Centril

@bors bors 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 2, 2019
Manishearth added a commit to Manishearth/rust that referenced this pull request 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.
Aaron1011 added a commit to Aaron1011/rust that referenced this pull request Oct 5, 2019
Previously, we were using an `FxHashMap` to collect module re-exports.
However, re-exports end up getting serialized into crate metadata, which
means that metadata generation was non-deterministic. This resulted in
spurious error messages changes (e.g. PR rust-lang#64906) due to pretty-printing
implicitly depending on the order of re-exports when computing the
proper path to show to the user.

See rust-lang#65042 for a long-term strategy to detect this kind of issue
bors added a commit that referenced this pull request Oct 6, 2019
…nkov

Make re-export collection deterministic

Fixes #65036

Previously, we were using an `FxHashMap` to collect module re-exports.
However, re-exports end up getting serialized into crate metadata, which
means that metadata generation was non-deterministic. This resulted in
spurious error messages changes (e.g. PR #64906) due to pretty-printing
implicitly depending on the order of re-exports when computing the
proper path to show to the user.

See #65042 for a long-term strategy to detect this kind of issue
@Aaron1011
Copy link
Member Author

@Centril : This is ready to be merged now that the non-determinism has been fixed

@Centril Centril closed this Oct 6, 2019
@Centril Centril reopened this Oct 6, 2019
@Centril
Copy link
Contributor

Centril commented Oct 6, 2019

@bors r+

@bors
Copy link
Contributor

bors commented Oct 6, 2019

📌 Commit a4cad41 has been approved by Centril

@bors bors 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 6, 2019
@bors
Copy link
Contributor

bors commented Oct 7, 2019

⌛ Testing commit a4cad41 with merge 4ac4809...

bors added a commit that referenced this pull request 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.
@bors
Copy link
Contributor

bors commented Oct 7, 2019

☀️ Test successful - checks-azure
Approved by: Centril
Pushing 4ac4809 to master...

@RalfJung
Copy link
Member

RalfJung commented Oct 9, 2019

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

@Centril
Copy link
Contributor

Centril commented Oct 9, 2019

@RalfJung Excellent point; added a check-box to the tracking issue.

bors added a commit to rust-lang/libc that referenced this pull request Nov 18, 2019
Add support for making functions `const`

PR rust-lang/rust#64906 adds the ability to write `const extern fn` and `const unsafe extern fn`, which will allow manys functions in `libc` to become `const`.

This is particuarly useful for functions which correspond to C macros (e.g. `CMSG_SPACE`). In C, these macros are constant expressions, allowing them to be used when declaring arrays. However, since the corresponding `libc` functions are not `const`, writing equivalent Rust code is impossible. Users must either perform an unecessary heap allocation, or pull in `bindgen` to evaluate the macro for specific values (e.g. `CMSG_SPACE(1)`).

However, the syntax `const extern fn` is not currently parsed by rust. To allow libc to use this without breaking backwards compatibility (i.e. bumping the minimum Rust version), I've taken the following approach:

1. A new off-by-default feature `extern-const-fn` is added to `libc`.
2. The internal `f!` macro has two versions, selected at compile-time by a `cfg_if`. When `extern-const-fn` is enabled, the declared `f!` macro passes through the `const` keyword from the macro user to the final definition (`pub const unsafe extern fn foo`. When  `extern-const-fn` is disabled, the `const` keyword passed by the macro user is discarded, resulting in a plain `pub extern const fn` being declared.

Unfortunately, I couldn't manage to get `macro_rules` to accept a normal `const` token in the proper place (after `pub`). I had to resort to placing it in curly brackets:

```rust
pub {const} fn foo(val: u8) -> i8 {
}
```

The `f!` macro then translates this to a function definition with `const` in the proper position.

I'd appreciate it if someone who's more familiar with `macro_rules!` could see if I missed a way to get the desired syntax.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-const_extern_fn `#![feature(const_extern_fn)]` merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants