Skip to content

Commit 6306fa5

Browse files
authored
Update maintaining-std.md
1 parent 6eb68c3 commit 6306fa5

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

src/libs/maintaining-std.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ You should just about never need `#[inline(always)]`. It may be beneficial for p
6161

6262
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.
6363

64-
#### Managing breakage
65-
6664
There are strategies for mitigating breakage depending on the impact.
6765

6866
For changes where the value is high and the impact is high too:
@@ -73,11 +71,11 @@ If the impact isn't too high:
7371

7472
- Looping in maintainers of broken crates and submitting PRs to fix them.
7573

76-
#### Trait impls break things
74+
### Are there new impls for stable traits?
7775

78-
The following sections outline some kinds of breakage from new trait impls that may not be obvious just from the change made to the standard library.
76+
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.
7977

80-
##### Inference breaks when a second generic impl is introduced
78+
#### Inference breaks when a second generic impl is introduced
8179

8280
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:
8381

@@ -108,7 +106,7 @@ will no longer compile, because we've previously been relying on inference to fi
108106

109107
This kind of breakage can be ok, but a [`crater`] run should estimate the scope.
110108

111-
##### Deref coercion breaks when a new impl is introduced
109+
#### Deref coercion breaks when a new impl is introduced
112110

113111
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:
114112

@@ -144,6 +142,10 @@ will no longer compile, because we won't attempt to use deref to coerce the `&St
144142

145143
This kind of breakage can be ok, but a [`crater`] run should estimate the scope.
146144

145+
### Could an implementation use existing functionality?
146+
147+
Types like `String` are implemented in terms of `Vec<u8>` and can use methods on `str` through deref coersion. `Vec<T>` can use methods on `[T]` through deref coersion. When possible, methods on a wrapping type like `String` should defer to methods that already exis on their underlying storage or deref target.
148+
147149
### Are there `#[fundamental]` items involved?
148150

149151
Blanket trait impls can't be added to `#[fundamental]` types because they have different coherence rules. See [RFC 1023] for details. That includes:
@@ -165,7 +167,7 @@ Changes to collection internals may affect the order their items are dropped in.
165167

166168
#### `mem::replace` and `mem::swap`
167169

168-
Any value behind a `&mut` reference can be replaced with a new one using `mem::replace` or `mem::swap`.
170+
Any value behind a `&mut` reference can be replaced with a new one using `mem::replace` or `mem::swap`, so code shouldn't assume any reachable mutable references can't have their internals changed by replacing.
169171

170172
#### `mem::forget`
171173

@@ -199,12 +201,14 @@ Unstable features can be merged as normal through [`bors`] once they look ready.
199201

200202
### When there’s new trait impls
201203

202-
There’s no way to make a trait impl `#[unstable]`, so **any PRs that add new impls for already stable traits must go through a FCP before merging.** If the trait itself is unstable though, then the impl needs to be unstable too.
204+
There’s no way to make a trait impl for a stable trait unstable, so **any PRs that add new impls for already stable traits must go through a FCP before merging.** If the trait itself is unstable though, then the impl needs to be unstable too.
203205

204206
### When a feature is being stabilized
205207

206208
Features can be stabilized in a PR that replaces `#[unstable]` attributes with `#[stable]` ones. The feature needs to have an accepted RFC before stabilizing. They also need to go through a FCP before merging.
207209

210+
You can find the right version to use in the `#[stable]` attribute by checking the [Forge].
211+
208212
[API Guidelines]: https://rust-lang.github.io/api-guidelines
209213
[Unsafe Code Guidelines WG]: https://github.com/rust-lang/unsafe-code-guidelines
210214
[`rust-lang/rust`]: https://github.com/rust-lang/rust
@@ -216,6 +220,7 @@ Features can be stabilized in a PR that replaces `#[unstable]` attributes with `
216220
[`rust-timer`]: https://github.com/rust-lang-nursery/rustc-perf
217221
[Libs tracking issues]: https://github.com/rust-lang/rust/issues?q=label%3AC-tracking-issue+label%3AT-libs
218222
[Drop guarantee]: https://doc.rust-lang.org/nightly/std/pin/index.html#drop-guarantee
223+
[Forge]: https://forge.rust-lang.org/
219224
[RFC 1023]: https://rust-lang.github.io/rfcs/1023-rebalancing-coherence.html
220225
[RFC 1105]: https://rust-lang.github.io/rfcs/1105-api-evolution.html
221226
[Everyone Poops]: http://cglab.ca/~abeinges/blah/everyone-poops

0 commit comments

Comments
 (0)