-
Notifications
You must be signed in to change notification settings - Fork 1k
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 making functions const
#1536
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @gnzlbg (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
We probably want to test enabling the |
@gnzlbg: Now that rust-lang/rust#64906 has been merged, this PR is no longer blocked. |
Why are these functions |
@gnzlbg: I'm not sure. However, changing it would be a breaking change, and I don't see any harm in them being |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing missing is documenting the feature in the README, but otherwise this LGTM.
Also @Aaron1011 do you know if libstd uses any of these functions? Right now, libstd won't enable this nightly feature, but I'm not sure if its worth it to do so. |
d9161b5
to
a1d1407
Compare
@gnzlbg: Updated. Do we want any kind of CI test for this? |
@Aaron1011 yes. One way would be to add a test file to libc/tests that's only included if the feature is defined, e.g., by using a |
Add a new feature to enable this, since `const extern fn` support is unstable
@gnzlbg: I've been having a hard time getting this to work locally. Can you show me an example of what you want this to look like? |
@Aaron1011 what I had in mind is a file in #![cfg(libc_const_extern_fn)] // If this does not hold, the file is empty
#[cfg(target_os = "linux")]
const _FOO: ... = CMSG_SPACE(...);
//^ if CMSG_SPACE is not const, this will fail to compile and just calls the Note, the two suggestions above to use |
a1d1407
to
add284a
Compare
Co-Authored-By: gnzlbg <gnzlbg@users.noreply.github.com>
@gnzlbg: There are several failures, but they seem unrelated. I'm having a really difficult time understanding how libc's test suite works, exactly what permutations of platforms and features are being tested, and whether or not I'm making my changes in a reasonable place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this looks really good. I've just left a small comment. Otherwise this LGTM.
Yes, those failures are unrelated. |
@gnzlbg: I've added the check. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @Aaron1011 !
@bors: r+ |
📌 Commit ca2d53e has been approved by |
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.
☀️ Test successful - checks-cirrus-freebsd-10, checks-cirrus-freebsd-11, checks-cirrus-freebsd-12, status-azure |
I have a problem with this PR when running the testsuite on OpenBSD. I think it is related to my use of a stable rustc (1.39.0) to test it, but I am unsure as I think CI would not have passed (we test with stable compiler too ?). rustc_minor_nightly() is now checking for nightly. The run failed with I added few debug println! in the code:
So it is failing on: let nightly_raw = otry!(otry!(pieces.next()).split('-').nth(1)); |
So I can see why it is failing. The output of We do test with many stable versions, but on the CI machines, the output of On my system, OSX, In the meantime, @Aaron1011 maybe we can patch this PR, to not return |
Probably because it's build from tarball and not on Rust's CI. The same thing could happen with Rust installed via Linux distributions package manager. |
I see, thanks. Good thing you caught this @semarie ! |
yes, it is build from tarball. |
Let's continue the discussion at #1601, since a conversation on a merged PR isn't very discoverable. |
PR rust-lang/rust#64906 adds the ability to write
const extern fn
andconst unsafe extern fn
, which will allow manys functions inlibc
to becomeconst
.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 correspondinglibc
functions are notconst
, writing equivalent Rust code is impossible. Users must either perform an unecessary heap allocation, or pull inbindgen
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:extern-const-fn
is added tolibc
.f!
macro has two versions, selected at compile-time by acfg_if
. Whenextern-const-fn
is enabled, the declaredf!
macro passes through theconst
keyword from the macro user to the final definition (pub const unsafe extern fn foo
. Whenextern-const-fn
is disabled, theconst
keyword passed by the macro user is discarded, resulting in a plainpub extern const fn
being declared.Unfortunately, I couldn't manage to get
macro_rules
to accept a normalconst
token in the proper place (afterpub
). I had to resort to placing it in curly brackets:The
f!
macro then translates this to a function definition withconst
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.