diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 712c3af..23191dd 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -21,6 +21,7 @@ - [Doc alias policy](./policy/doc-alias.md) - [Safety comments policy](./policy/safety-comments.md) - [Reviewing target-specific code](./policy/target-code.md) + - [Why the standard library uses extension traits](./policy/extension-traits.md) - [Tricky situations]() - [Drop and `#[may_dangle]`](./tricky/may-dangle.md) diff --git a/src/policy/extension-traits.md b/src/policy/extension-traits.md new file mode 100644 index 0000000..b69f28c --- /dev/null +++ b/src/policy/extension-traits.md @@ -0,0 +1,22 @@ +# Why the standard library uses extension traits (and not `cfg`-guarded items) + +A common pattern in the standard library is to put target-specific methods into +extension traits, rather than providing them as `cfg`-guarded methods directly +on objects themselves. For example, the many extension traits in +[`std::os::unix::prelude`](https://doc.rust-lang.org/std/os/unix/prelude/index.html) +provide UNIX-specific methods on standard types. + +The standard library could, instead, provide these methods directly on the +standard types, guarded by `#[cfg(unix)]`. However, it does not do so, and PRs +adding `cfg`-guarded methods are often rejected. + +Providing these methods via extension traits forces code to explicitly use +those extension traits in order to access the methods. This, effectively, +requires code to declare whether it depends on target-specific functionality, +either because the code is target-specific, or because it has appropriately +`cfg`-guarded code for different targets. Without these extension traits, code +could more easily use target-specific functionality "accidentally". + +This policy may change in the future if Rust develops better mechanisms for +helping code explicitly declare its portability, or lack of portability, before +accessing target-specific functionality.