semver_status.md
1 # Semver tracking 2 3 We no longer use this file for semver tracking. Instead, we use one 4 `semver.md` file per crate. 5 6 When you make a change to a crate that affects source compatibility, 7 please append a paragraph to that crate's `semver.md`, creating it as 8 necessary. 9 10 Every line should begin with one of the following: 11 * BREAKING 12 * MODIFIED 13 14 A "BREAKING" change is one that may break other crates that depend on 15 this crate directly. 16 17 A "MODIFIED" change is one the introduces a new API, such that crates 18 using the new API will not work with older versions of the crate. 19 20 When we release a new version, we use these files to determine which 21 crates need major-version, minor-version, or patch-level version bumps. 22 We also use them to help write the "breaking changes" section of the 23 changelog. They aren't user-facing, so they don't go into much detail. 24 25 Here is an example `semver.md` file: 26 27 >``` 28 >BREAKING: Removed the obsolete `detect_thylacine()` function. 29 > 30 >MODIFIED: New `Wombat::feed()` method. 31 > 32 >MODIFIED: `Numbat` now implements `Display`. 33 > 34 >BREAKING: The `Quokka` trait now inherits from Debug. 35 >``` 36 37 ## What is a breaking change? 38 39 We will add guidance to this section as we come up with it. For now, see 40 [SemVer compatibility] in the Cargo book. 41 42 [SemVer Compatibility]: https://doc.rust-lang.org/cargo/reference/semver.html 43 44 ### When types from lower-level crates appear in the APIs of higher-level crates 45 46 If a type (concrete type or trait) from a lower-level crate 47 is returned (or accepted) 48 by an API of a higher-level crate, 49 then a breaking change to that lower-level crate is a breaking change 50 for the higher-level crate, too. 51 52 This includes any case where a higher-layer type 53 implements a public trait from a lower-layer; 54 even if the type is not itself re-exported by the higher-layer crate. 55 56 #### Reasoning, and worked example: 57 58 Suppose `tor_error::ErrorKind` gets a breaking change, 59 and we bump the major[1] for `tor_error` but not for `arti_client`. 60 Obviously our new `arti_client` uses the new `tor_error`. 61 62 A downstream might use both `tor-error` and `arti-client`. 63 If they do this in the usual way, 64 a `cargo update` will get them the new `arti_client` but old `tor_error`. 65 Now their program has *two* instances of `tor_error`: 66 one whose `ErrorKind` is implemented by `arti_client::Error`, 67 and one that the downstream application code sees. 68 The effect is that the downstream application 69 can no longer call `.has_kind()` on an `arti_client::Error` 70 because they don't have the *right* `HasKind` method in scope. 71 72 Note that this does not depend on the nature of the breaking change, 73 nor on the re-export of any names. 74 It only depends on the exposure of the type and its trait implementations. 75 76 (The ["semver trick"](https://github.com/dtolnay/semver-trick) 77 can sometimes be used to help multiple different versions 78 of the same crate share global state, or perhaps, traits etc.) 79 80 [1] "Major" here includes the 2nd component in a 0.x version.