-
Notifications
You must be signed in to change notification settings - Fork 1.3k
docs: Better document breaking change policy and recommended usage #5179
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
Open
tgross35
wants to merge
1
commit into
rust-lang:main
Choose a base branch
from
tgross35:docs-update
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+132
−23
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,4 +1,131 @@ | ||||||
| //! libc - Raw FFI bindings to platforms' system libraries | ||||||
| //! Raw FFI bindings to platforms' system libraries. | ||||||
| //! | ||||||
| //! # Usage Recommendations | ||||||
| //! | ||||||
| //! `libc` takes a differe | ||||||
| //! | ||||||
| //! - *Never* construct a `libc` struct with `MaybeUninit::uninit()`, initialize it, then call | ||||||
| //! `assume_init`. Many structures have padding fields or may gain fields in the future, and | ||||||
| //! it is far too easy to end up calling `assume_init` on partially initialized data. | ||||||
| //! | ||||||
| //! Instead, use `MaybeUninit::zeroed()` or the `Default` implementations that are slowly being | ||||||
| //! added. Alternatively, access fields only via raw pointer without ever using `assume_init`. | ||||||
| //! | ||||||
| //! - Avoid relying on the exact value of constants or the exact length of arrays, as they may | ||||||
| //! change across `libc` versions. That is, if `libc` contains code like: | ||||||
| //! | ||||||
| //! <!-- relevant for how rustdoc displays these structs: | ||||||
| //! https://github.com/rust-lang/rust/issues/102456 --> | ||||||
| //! ```ignore | ||||||
| //! const IFNAMSIZ: usize = 16; | ||||||
| //! | ||||||
| //! pub struct ifreq { | ||||||
| //! pub ifr_name: [c_char; IFNAMSIZ], | ||||||
| //! // ... | ||||||
| //! } | ||||||
| //! ``` | ||||||
| //! | ||||||
| //! Then avoid writing code like: | ||||||
| //! | ||||||
| //! ```ignore | ||||||
| //! // Bad assumption that `IFNAMSIZ` will be 16 forever | ||||||
| //! fn foo(ifr_name: [c_char; 16]) { /* ... */ } | ||||||
| //! | ||||||
| //! fn bar(ifr: ifreq) { | ||||||
| //! foo(ifr.ifr_name); | ||||||
| //! } | ||||||
| //! ``` | ||||||
| //! | ||||||
| //! Instead, use `[c_char; IFNAMSIZ]` to specify the type, or just `&[c_char]`. | ||||||
| //! | ||||||
| //! Along the same lines, if you write code along the lines of `assert_eq!(libc::ELAST, 97)`, | ||||||
| //! expect that there may be a release where this starts to fail. | ||||||
| //! | ||||||
| //! - Do not name `__c_anonymous_*` types anywhere, which exist to represent anonymous fields in | ||||||
| //! C. For example, FreeBSD defines: | ||||||
| //! | ||||||
| //! ```c | ||||||
| //! struct filestat { | ||||||
| //! int fs_type; | ||||||
| //! // ... | ||||||
| //! struct { struct filestat stqe_next; } next; | ||||||
| //! }; | ||||||
| //! ``` | ||||||
| //! | ||||||
| //! Which is represented in `libc` as: | ||||||
| //! | ||||||
| //! ```ignore | ||||||
| //! struct filestat { | ||||||
| //! fs_type: c_int, | ||||||
| //! // ... | ||||||
| //! next: __c_anonymous_filestat, | ||||||
| //! } | ||||||
| //! | ||||||
| //! struct __c_anonymous_filestat { stqe_next: *mut filestat } | ||||||
| //! ``` | ||||||
| //! | ||||||
| //! Accessing `some_filestat.next.stqe_next` is completely fine, but `__c_anonymous_filestat` | ||||||
| //! should not be used anywhere (e.g. in a function signature). This is done to permit `libc` to | ||||||
| //! switch to anonymous fields if the feature is ever added to Rust. | ||||||
| //! | ||||||
| //! - Be aware of deprecation warnings. These are used as a way to migrate necessary API changes. | ||||||
| //! | ||||||
| //! # Cargo Features | ||||||
| //! | ||||||
| //! - `std`: by default `libc` assumes that the standard library contains link directives necessary | ||||||
| //! to use the APIs in this crate. If `std` is disabled, `libc` will emit directives necessary to | ||||||
| //! link the necessary C libraries. | ||||||
| //! | ||||||
| //! This feature is slated for removal in `libc` 1.0. The intention is that no-std users of | ||||||
| //! `libc` should use their own `#[link]` attributes, `rustc-link-lib` build script directives, | ||||||
| //! or `-l` arguments for only the system libraries they need to link, rather than `libc` | ||||||
| //! possibly linking more than is needed or available. If you are using `libc` without the `std` | ||||||
| //! feature, consider starting to add link directives now for a smoother 1.0 transition. | ||||||
| //! | ||||||
| //! - `extra_traits`: all types in `libc` implement `Clone`, `Copy`, and `Debug`. The | ||||||
| //! `extra_traits` feature adds `Eq`, `Hash`, and `PartialEq`. | ||||||
| //! | ||||||
| //! This feature is expected to be removed in libc 1.0. Libraries should instead hash or check | ||||||
| //! equality of only needed fields. | ||||||
| //! | ||||||
| //! - The features `const-extern-function`, `align`, and `use_std` are all deprecated. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| //! | ||||||
| //! # Stability Expectations | ||||||
| //! | ||||||
| //! Due to `libc`'s position in the ecosystem, it can effectively never publish semver-breaking | ||||||
| //! releases. However, the API that `libc` binds changes _all the time_; sometimes in ways that | ||||||
| //! are harmless, sometimes in ways that are technically API-breaking for C users but unlikely | ||||||
| //! to be noticed (e.g. removing deprecated API), and sometimes in ways that are nonbreaking in | ||||||
| //! C but translate to breaking changes in Rust (e.g. changing integer size). `libc` tries to | ||||||
| //! strike a balance but all of this means that unfortunately, `libc` must occasionally ship | ||||||
| //! changes within a semver-compatible release that are technically semver-breaking. | ||||||
| //! | ||||||
| //! The following are examples of changes that fall into this category: | ||||||
| //! | ||||||
| //! - Fields are added to a struct that is currently exhaustive. | ||||||
| //! - Fields with names such as `padding` or `reserved` change type or are removed. | ||||||
| //! - The length of an array type changes. | ||||||
| //! - A struct field (with available padding) is changed from `int` to `long`. | ||||||
| //! | ||||||
| //! In general, `libc` aims to follow platform API changes, even when this means changes that are | ||||||
| //! user-visible in Rust. There are a few guidelines used here: | ||||||
| //! | ||||||
| //! - Adding struct fields is not considered breaking, nor is changing fields named `reserved`, | ||||||
| //! `padding`, or similar. This is because users are expected to use field-by-field | ||||||
| //! initialization. | ||||||
| //! - Changing type aliases, values of constants, or array lengths is not considered breaking. | ||||||
| //! - If the platform libc has accepted breakage on the C side (typically in the form of removing | ||||||
| //! old API), the `libc` crate will follow suit. | ||||||
| //! - Where possible, `#[deprecated(...)]` will be used to warn about changes before applying them. | ||||||
| //! Alternative mitigations may be considered. | ||||||
| //! - Potentially breaking changes will be well-identified in release notes. | ||||||
| //! - Beyond this, public API is not expected to change on Tier 1 targets. Tier 2 targets have | ||||||
| //! relaxed API stability requirements, and API stability is not enforced on tier 3 targets. | ||||||
| //! | ||||||
| //! While this section seems scary, keep in mind that it is meant to cover worst-case scenarios. In | ||||||
| //! practice, breakage is rare and following the above-discussed [Best Practices](#best-practices) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be missing something but I don't see this section. |
||||||
| //! means that most `libc` users will never encounter a problem. | ||||||
|
|
||||||
| #![crate_name = "libc"] | ||||||
| #![crate_type = "rlib"] | ||||||
| #![allow( | ||||||
|
|
||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Seems incomplete.