diff --git a/src/checklist.md b/src/checklist.md index 8db9ef1..ca4c5fb 100644 --- a/src/checklist.md +++ b/src/checklist.md @@ -68,6 +68,7 @@ - [ ] Structs have private fields ([C-STRUCT-PRIVATE]) - [ ] Newtypes encapsulate implementation details ([C-NEWTYPE-HIDE]) - [ ] Data structures do not duplicate derived trait bounds ([C-STRUCT-BOUNDS]) + - [ ] Nightly features use an explicit opt-in ([C-NIGHTLY-OPTIN]) - **Necessities** *(to whom they matter, they really matter)* - [ ] Public dependencies of a stable crate are stable ([C-STABLE]) - [ ] Crate and its dependencies have a permissive license ([C-PERMISSIVE]) @@ -135,6 +136,7 @@ [C-STRUCT-PRIVATE]: future-proofing.html#c-struct-private [C-NEWTYPE-HIDE]: future-proofing.html#c-newtype-hide [C-STRUCT-BOUNDS]: future-proofing.html#c-struct-bounds +[C-NIGHTLY-OPTIN]: future-proofing.html#c-nightly-optin [C-STABLE]: necessities.html#c-stable [C-PERMISSIVE]: necessities.html#c-permissive diff --git a/src/future-proofing.md b/src/future-proofing.md index e34edd5..c827c8b 100644 --- a/src/future-proofing.md +++ b/src/future-proofing.md @@ -202,3 +202,21 @@ on the data structure. [`std::borrow::Cow`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html [`std::boxed::Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html [`std::io::BufWriter`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html + + +## Nightly features use an explicit opt-in (C-NIGHTLY-OPTIN) + +Some libraries need to use, or want to experiment with, the [nightly channel]. +To avoid accidental breakage, libraries should either: +- Use nightly features unconditionally, so that people depending on the library must always use a nightly toolchain to build +- Add a `--cfg` flag which opts-in to the nightly features (optionally, with a test compilation to give a better error message if the feature is not present in the current compiler version). This allows people to avoid opting-in if they do not want to be exposed to possible breakage. + +Each nightly feature should be under a separate flag so that breakage to one feature does not cause breakage for others. +Each flag should be prefixed with the crate name to avoid accidentally triggering features in other crates. +For example, if your crate is named `awesome-lib` and depends on two different nightly features, `std::intrinsics::black_box` and `std::intrinsics::catch_unwind`, create two cfgs named `awesome_lib_black_box` and `awesome_lib_catch_unwind`. + +When doing feature detection, we recommend *against* simply checking whether the compiler is a nightly channel, as nightly features frequently change between compiler versions. +Feature detection should compile a sample rust program and verify that it works. +Note that flags like `-Z allow-features` may affect whether features are allowed. + +[nightly channel]: https://rust-lang.github.io/rustup/concepts/channels.html