Skip to content

Commit c01d383

Browse files
committed
start stubbing out sections
1 parent 80ea37f commit c01d383

27 files changed

+561
-0
lines changed

src/SUMMARY.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
11
# Summary
22

33
[About this guide](./about-this-guide.md)
4+
5+
[Getting started](./getting-started.md)
6+
7+
---
8+
9+
# The feature lifecycle
10+
11+
- [Landing new features](./feature-lifecycle/landing-new-features.md)
12+
- [Tracking issues](./feature-lifecycle/tracking-issues.md)
13+
- [Stabilization](./feature-lifecycle/stabilization.md)
14+
- [Deprecation](./feature-lifecycle/deprecation.md)
15+
16+
# Code considerations
17+
18+
- [Reviewer checklist](./code-considerations/reviewer-checklist.md)
19+
- [Design](./code-considerations/design/summary.md)
20+
- [Public APIs](./code-considerations/design/public-apis.md)
21+
- [Breaking changes](./code-considerations/breaking-changes/summary.md)
22+
- [Breaking behavior](./code-considerations/breaking-changes/behavior.md)
23+
- [New trait impls](./code-considerations/breaking-changes/new-trait-impls.md)
24+
- [`#[fundamental]` types](./code-considerations/breaking-changes/fundamental.md)
25+
- [Safety and soundness](./code-considerations/safety-and-soundness/summary.md)
26+
- [Generic impls and soundness](./code-considerations/safety-and-soundness/generic-impls-and-soundness.md)
27+
- [Drop and `#[may_dangle]`](./code-considerations/safety-and-soundness/may-dangle.md)
28+
- [`std::mem` and exclusive references](./code-considerations/safety-and-soundness/mem-and-exclusive-refs.md)
29+
- [Using unstable language features](./code-considerations/using-unstable-lang/summary.md)
30+
- [Const generics](./code-considerations/using-unstable-lang/const-generics.md)
31+
- [Specialization](./code-considerations/using-unstable-lang/specialization.md)
32+
- [Performance](./code-considerations/performance/summary.md)
33+
- [When to `#[inline]`](./code-considerations/performance/inline.md)
34+
35+
---
36+
37+
[Appendix A: Glossary](./appendix/glossary.md)

src/about-this-guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# About this guide
22

3+
**Status:** Stub
4+
35
This guide is for contributors and reviewers to Rust's standard library.
46

57
## Other places to find information

src/appendix/glossary.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Glossary
2+
3+
Term | Meaning
4+
-----------------------------------------------|--------
5+
<span id="fcp">FCP</span> | Final Comment Period. An FCP is a formal process that's started by `@rfcbot` to get consensus from a Rust team.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Breakage from changing behavior
2+
3+
Breaking changes aren't just limited to compilation failures. Behavioral changes to stable functions generally can't be accepted. See [the `home_dir` issue][rust/pull/46799] for an example.
4+
5+
An exception is when a behavior is specified in an RFC (such as IETF specifications for IP addresses). If a behavioral change fixes non-conformance then it can be considered a bug fix. In these cases, `@rust-lang/libs` should still be pinged for input.
6+
7+
## For reviewers
8+
9+
Look out for changes in existing implementations for stable functions, especially if assertions in test cases have been changed.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# `#[fundamental]` types
2+
3+
**Status:** Stub
4+
5+
Type annotated with the `#[fundamental]` attribute have different coherence rules. See [RFC 1023] for details. That includes:
6+
7+
- `&T`
8+
- `&mut T`
9+
- `Box<T>`
10+
- `Pin<T>`
11+
12+
Typically, the scope of [breakage in new trait impls](./reviewing-code/breakage/new-trait-impls.md) is limited to inference and deref-coercion. New trait impls on `#[fundamental]` types may overlap with downstream impls and cause other kinds of breakage.
13+
14+
[RFC 1023]: https://rust-lang.github.io/rfcs/1023-rebalancing-coherence.html
15+
16+
## For reviewers
17+
18+
Look out for blanket trait implementations for fundamental types, like:
19+
20+
```rust
21+
impl<'a, T> PublicTrait for &'a T
22+
where
23+
T: SomeBound,
24+
{
25+
26+
}
27+
```
28+
29+
unless the blanket implementation is being stabilized along with `PublicTrait`. In cases where we really want to do this, a [crater] run can help estimate the scope of the breakage.
30+
31+
[crater]: ./crater.md
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Breakage from new trait impls
2+
3+
A lot of PRs to the standard library are adding new impls for already stable traits, which can break consumers in many weird and wonderful ways. The following sections gives some examples of breakage from new trait impls that may not be obvious just from the change made to the standard library.
4+
5+
## Inference breaks when a second generic impl is introduced
6+
7+
Rust will use the fact that there's only a single impl for a generic trait during inference. This breaks once a second impl makes the type of that generic ambiguous. Say we have:
8+
9+
```rust
10+
// in `std`
11+
impl From<&str> for Arc<str> { .. }
12+
```
13+
14+
```rust
15+
// in an external `lib`
16+
let b = Arc::from("a");
17+
```
18+
19+
then we add:
20+
21+
```diff
22+
impl From<&str> for Arc<str> { .. }
23+
+ impl From<&str> for Arc<String> { .. }
24+
```
25+
26+
then
27+
28+
```rust
29+
let b = Arc::from("a");
30+
```
31+
32+
will no longer compile, because we've previously been relying on inference to figure out the `T` in `Box<T>`.
33+
34+
This kind of breakage can be ok, but a [crater] run should estimate the scope.
35+
36+
## Deref coercion breaks when a new impl is introduced
37+
38+
Rust will use deref coercion to find a valid trait impl if the arguments don't type check directly. This only seems to occur if there's a single impl so introducing a new one may break consumers relying on deref coercion. Say we have:
39+
40+
```rust
41+
// in `std`
42+
impl Add<&str> for String { .. }
43+
44+
impl Deref for String { type Target = str; .. }
45+
```
46+
47+
```rust
48+
// in an external `lib`
49+
let a = String::from("a");
50+
let b = String::from("b");
51+
52+
let c = a + &b;
53+
```
54+
55+
then we add:
56+
57+
```diff
58+
impl Add<&str> for String { .. }
59+
+ impl Add<char> for String { .. }
60+
```
61+
62+
then
63+
64+
```rust
65+
let c = a + &b;
66+
```
67+
68+
will no longer compile, because we won't attempt to use deref to coerce the `&String` into `&str`.
69+
70+
This kind of breakage can be ok, but a [crater] run should estimate the scope.
71+
72+
[crater]: ./crater.md
73+
74+
## For reviewers
75+
76+
Look out for new `#[stable]` trait implementations for existing stable traits.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Breaking changes
2+
3+
Breaking changes should be avoided when possible. [RFC 1105] lays the foundations for what constitutes a breaking change. Breakage may be deemed acceptable or not based on its actual impact, which can be approximated with a [crater] run.
4+
5+
There are strategies for mitigating breakage depending on the impact.
6+
7+
For changes where the value is high and the impact is high too:
8+
9+
- Using compiler lints to try phase out broken behavior.
10+
11+
If the impact isn't too high:
12+
13+
- Looping in maintainers of broken crates and submitting PRs to fix them.
14+
15+
[crater]: ./crater.md
16+
[RFC 1105]: https://rust-lang.github.io/rfcs/1105-api-evolution.html
17+
18+
## For reviewers
19+
20+
Look out for changes to documented behavior and new trait impls for existing stable traits.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Public API design
2+
3+
**Status:** Stub
4+
5+
Standard library APIs typically follow the [API Guidelines], which were originally spawned from the standard library itself.
6+
7+
[API Guidelines]: https://rust-lang.github.io/api-guidelines/
8+
9+
## For reviewers
10+
11+
For new unstable features, look for any prior discussion of the proposed API to see what options and tradeoffs have already been considered. If in doubt, ping `@rust-lang/libs` for input.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Design
2+
3+
**Status:** Stub
4+
5+
Most of the considerations in this guide are quality in some sense. This section has some general advice on maintaining code quality in the standard library.
6+
7+
## For reviewers
8+
9+
Think about how you would implement a feature and whether your approach would differ from what's being proposed. What trade-offs are being made? Is the weighting of those trade-offs the most appropriate?
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# When to `#[inline]`
2+
3+
Inlining is a trade-off between potential execution speed, compile time and code size. There's some discussion about it in [this PR to the `hashbrown` crate][hashbrown/pull/119]. From the thread:
4+
5+
> `#[inline]` is very different than simply just an inline hint. As I mentioned before, there's no equivalent in C++ for what `#[inline]` does. In debug mode rustc basically ignores `#[inline]`, pretending you didn't even write it. In release mode the compiler will, by default, codegen an `#[inline]` function into every single referencing codegen unit, and then it will also add `inlinehin`t. This means that if you have 16 CGUs and they all reference an item, every single one is getting the entire item's implementation inlined into it.
6+
7+
You can add `#[inline]`:
8+
9+
- To public, small, non-generic functions.
10+
11+
You shouldn't need `#[inline]`:
12+
13+
- On methods that have any generics in scope.
14+
- On methods on traits that don't have a default implementation.
15+
16+
`#[inline]` can always be introduced later, so if you're in doubt they can just be removed.
17+
18+
## What about `#[inline(always)]`?
19+
20+
You should just about never need `#[inline(always)]`. It may be beneficial for private helper methods that are used in a limited number of places or for trivial operators. A micro benchmark should justify the attribute.
21+
22+
## For reviewers
23+
24+
`#[inline]` can always be added later, so if there's any debate about whether it's appropriate feel free to defer it by removing the annotations for a start.

0 commit comments

Comments
 (0)