-
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
Unify definitions of siginfo_t
, statvfs
and statfs
in musl
targets
#3261
base: main
Are you sure you want to change the base?
Conversation
r? @JohnTitor (rustbot has picked a reviewer for you, use r? to override) |
Thanks! @bors r+ |
Unify definitions of `siginfo_t`, `statvfs` and `statfs` in `musl` targets During #2935 I noticed there were multiple identical definitions of some of the `bits/***.h` types in the musl target, as well as a few places where a type was defined twice in the module tree (leading to the "upper-most" definition being the one exported by the library, in contradiction to the expectation that the "most-specific" definition would be used. This change moves the definitions of `struct statvfs(64)` and `struct siginfo_t` to be global for all `musl` targets (see https://git.musl-libc.org/cgit/musl/tree/include/sys/statvfs.h and https://git.musl-libc.org/cgit/musl/tree/include/signal.h which are architecture-agnostic headers) and `struct statfs(64)` to be global for all 64-bit `musl` targets (see https://git.musl-libc.org/cgit/musl/tree/arch/generic/bits/statfs.h). This also required moving `fsblkcnt64_t` and `fsfilcnt64_t` to be musl-wide too (for use in `struct statvfs64`). It also removes a bunch of redundant (and unreachable) definitions in the `riscv64` and `riscv32` targets (there seems to be a `riscv32` target in the crate, but not in `musl` itself or at least there's no `arch/riscv32` folder in tree). Upshot of the above is that this change has no externally visible effect, if the more specific types were intended to be used they weren't being so removing them is a no-op. To actually use more specific type definitions one would need to `cfg` out the general definition as well as providing the specific one. <details> <summary>To find most of these issues I used this process</summary> ``` $ for target in $(rustc --print target-list | grep musl) do echo $target RUSTDOCFLAGS="--output-format json --document-private-items" cargo +nightly doc -Z build-std=core --target $target done $ for json in target/**/doc/libc.json do echo $json jq '.index[] | select(.inner | keys[0] == "struct") | .name' $json | sort | uniq -d done ``` The first command uses rustdoc to create a JSON representation of the API of the crate for each (`musl`) target and the second searches that output for two exported structs of the same name within a single target. Where there's a duplicate, only one of the two symbols is actually usable (and due to import rules, symbols defined locally take precedence over symbols imported from submodules so the less specific symbol is the one that wins). You can do similar tests for `enum`, `typedef`, `union`, constant` by changing the second command in the obvious way, you can also do the same for `function` though you need to additionally filter on `extern "C"` (since e.g. there's many many `clone` functions defined in the crate): ``` $ jq '.index[] | select(.inner | keys[0] == "function") | select(.inner.function.header.abi | (type == "object" and keys[0] == "C")) | .name' $json | sort | uniq -d ``` </details> It feels like adding the checks in that methodology to CI for each target would be a good way to catch issues where a more specific definition is masked by a less-specific one.
💔 Test failed - checks-actions |
Turns out I was both too aggressive and not aggressive enough - every target uses the same |
This MR is in danger of going stale so I'd like to resolve the style issue. However I can't find a way to write the code that meets all the conflicting requirements/intentions:
I'm trying to avoid having 10 identical copies of this type defined simply because |
☔ The latest upstream changes (presumably #3302) made this pull request unmergeable. Please resolve the merge conflicts. |
Hey @bossmc, sorry this has been stale for so long. If you are interested in rebasing so we can merge this than that would be excellent; if not, no worries. I do need to note that I don't think this is backportable, meaning we will only get the changes once 1.0 is released (which may still be a few months off). I have to assume this isn't a problem since most of this is refactoring, but just an FYI.
Your 3+4 is totally fine here - how well things optimize in debug mode is essentially a nonissue. For cases where it is, it more common for those crates to just compile dependencies in release mode, so nothing for us to worry about here. |
Let me know if you need anything else. Just @rustbot author |
7c42066
to
d7887af
Compare
Thanks! I've made that change and rebased to (what was) @rustbot review |
#[derive(Copy, Clone)] | ||
#[allow(deprecated)] | ||
$(#[$attr])* | ||
pub struct $i { $($field)* } | ||
} | ||
#[allow(deprecated)] | ||
impl ::Copy for $i {} | ||
#[allow(deprecated)] | ||
impl ::Clone for $i { | ||
fn clone(&self) -> $i { *self } | ||
} |
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.
These changes are a nice cleanup, but would you mind moving them to a separate PR? To keep different types of changes atomic.
note="Please leave a comment on \ | ||
https://github.com/rust-lang/libc/pull/1316 if you're using \ | ||
this field" |
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.
note="Please leave a comment on \ | |
https://github.com/rust-lang/libc/pull/1316 if you're using \ | |
this field" | |
note="Please leave a comment on https://github.com/rust-lang/libc/pull/1316 \ | |
if you are using this field" |
Just to make use of the line length
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.
A couple small nits and this lgtm, please rebase and squash.
Regarding your top post - I am entirely in favor of using rustdoc
JSON output for testing. If you are up to it, please do consider putting something like this in the libc-test
crate.
During #2935 I noticed there were multiple identical definitions of some of the
bits/***.h
types in the musl target, as well as a few places where a type was defined twice in the module tree (leading to the "upper-most" definition being the one exported by the library, in contradiction to the expectation that the "most-specific" definition would be used.This change moves the definitions of
struct statvfs(64)
andstruct siginfo_t
to be global for allmusl
targets (see https://git.musl-libc.org/cgit/musl/tree/include/sys/statvfs.h and https://git.musl-libc.org/cgit/musl/tree/include/signal.h which are architecture-agnostic headers) andstruct statfs(64)
to be global for all 64-bitmusl
targets (see https://git.musl-libc.org/cgit/musl/tree/arch/generic/bits/statfs.h). This also required movingfsblkcnt64_t
andfsfilcnt64_t
to be musl-wide too (for use instruct statvfs64
).It also removes a bunch of redundant (and unreachable) definitions in the
riscv64
andriscv32
targets (there seems to be ariscv32
target in the crate, but not inmusl
itself or at least there's noarch/riscv32
folder in tree).Upshot of the above is that this change has no externally visible effect, if the more specific types were intended to be used they weren't being so removing them is a no-op. To actually use more specific type definitions one would need to
cfg
out the general definition as well as providing the specific one.To find most of these issues I used this process
The first command uses rustdoc to create a JSON representation of the API of the crate for each (
musl
) target and the second searches that output for two exported structs of the same name within a single target. Where there's a duplicate, only one of the two symbols is actually usable (and due to import rules, symbols defined locally take precedence over symbols imported from submodules so the less specific symbol is the one that wins).You can do similar tests for
enum
,typedef
,union
,constant
by changing the second command in the obvious way, you can also do the same forfunction
though you need to additionally filter onextern "C"
(since e.g. there's many manyclone
functions defined in the crate):It feels like adding the checks in that methodology to CI for each target would be a good way to catch issues where a more specific definition is masked by a less-specific one.