Skip to content

Commit d73b935

Browse files
committed
Auto merge of #11596 - ehuss:semver-lints, r=epage
Add semver rule for lints This adds a new rule to the semver compatibility list explaining the expectations around diagnostic lints. cc #8736
2 parents 50eb688 + 408b8d5 commit d73b935

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

src/doc/semver-check/src/main.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ fn doit() -> Result<(), Box<dyn Error>> {
3131

3232
loop {
3333
// Find a rust block.
34-
let (block_start, run_program) = loop {
34+
let (block_start, run_program, deny_warnings) = loop {
3535
match lines.next() {
3636
Some((lineno, line)) => {
3737
if line.trim().starts_with("```rust") && !line.contains("skip") {
38-
break (lineno + 1, line.contains("run-fail"));
38+
break (
39+
lineno + 1,
40+
line.contains("run-fail"),
41+
!line.contains("dont-deny"),
42+
);
3943
}
4044
}
4145
None => return Ok(()),
@@ -73,7 +77,10 @@ fn doit() -> Result<(), Box<dyn Error>> {
7377
}
7478
let join = |part: &[&str]| {
7579
let mut result = String::new();
76-
result.push_str("#![allow(unused)]\n#![deny(warnings)]\n");
80+
result.push_str("#![allow(unused)]\n");
81+
if deny_warnings {
82+
result.push_str("#![deny(warnings)]\n");
83+
}
7784
result.push_str(&part.join("\n"));
7885
if !result.ends_with('\n') {
7986
result.push('\n');

src/doc/src/reference/semver.md

+55
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ considered incompatible.
9393
* Tooling and environment compatibility
9494
* [Possibly-breaking: changing the minimum version of Rust required](#env-new-rust)
9595
* [Possibly-breaking: changing the platform and environment requirements](#env-change-requirements)
96+
* [Minor: introducing new lints](#new-lints)
9697
* Cargo
9798
* [Minor: adding a new Cargo feature](#cargo-feature-add)
9899
* [Major: removing a Cargo feature](#cargo-feature-remove)
@@ -1164,6 +1165,60 @@ Mitigation strategies:
11641165
* Document the platforms and environments you specifically support.
11651166
* Test your code on a wide range of environments in CI.
11661167

1168+
<a id="new-lints"></a>
1169+
### Minor: introducing new lints
1170+
1171+
Some changes to a library may cause new lints to be triggered in users of that library.
1172+
This should generally be considered a compatible change.
1173+
1174+
```rust,ignore,dont-deny
1175+
// MINOR CHANGE
1176+
1177+
///////////////////////////////////////////////////////////
1178+
// Before
1179+
pub fn foo() {}
1180+
1181+
///////////////////////////////////////////////////////////
1182+
// After
1183+
#[deprecated]
1184+
pub fn foo() {}
1185+
1186+
///////////////////////////////////////////////////////////
1187+
// Example use of the library that will safely work.
1188+
1189+
fn main() {
1190+
updated_crate::foo(); // Warning: use of deprecated function
1191+
}
1192+
```
1193+
1194+
Beware that it may be possible for this to technically cause a project to fail if they have explicitly denied the warning, and the updated crate is a direct dependency.
1195+
Denying warnings should be done with care and the understanding that new lints may be introduced over time.
1196+
However, library authors should be cautious about introducing new warnings and may want to consider the potential impact on their users.
1197+
1198+
The following lints are examples of those that may be introduced when updating a dependency:
1199+
1200+
* [`deprecated`][deprecated-lint] — Introduced when a dependency adds the [`#[deprecated]` attribute][deprecated] to an item you are using.
1201+
* [`unused_must_use`] — Introduced when a dependency adds the [`#[must_use]` attribute][must-use-attr] to an item where you are not consuming the result.
1202+
* [`unused_unsafe`] — Introduced when a dependency *removes* the `unsafe` qualifier from a function, and that is the only unsafe function called in an unsafe block.
1203+
1204+
Additionally, updating `rustc` to a new version may introduce new lints.
1205+
1206+
Transitive dependencies which introduce new lints should not usually cause a failure because Cargo uses [`--cap-lints`](../../rustc/lints/levels.html#capping-lints) to suppress all lints in dependencies.
1207+
1208+
Mitigating strategies:
1209+
* If you build with warnings denied, understand you may need to deal with resolving new warnings whenever you update your dependencies.
1210+
If using RUSTFLAGS to pass `-Dwarnings`, also add the `-A` flag to allow lints that are likely to cause issues, such as `-Adeprecated`.
1211+
* Introduce deprecations behind a [feature][Cargo features].
1212+
For example `#[cfg_attr(feature = "deprecated", deprecated="use bar instead")]`.
1213+
Then, when you plan to remove an item in a future SemVer breaking change, you can communicate with your users that they should enable the `deprecated` feature *before* updating to remove the use of the deprecated items.
1214+
This allows users to choose when to respond to deprecations without needing to immediately respond to them.
1215+
A downside is that it can be difficult to communicate to users that they need to take these manual steps to prepare for a major update.
1216+
1217+
[`unused_must_use`]: ../../rustc/lints/listing/warn-by-default.html#unused-must-use
1218+
[deprecated-lint]: ../../rustc/lints/listing/warn-by-default.html#deprecated
1219+
[must-use-attr]: ../../reference/attributes/diagnostics.html#the-must_use-attribute
1220+
[`unused_unsafe`]: ../../rustc/lints/listing/warn-by-default.html#unused-unsafe
1221+
11671222
### Cargo
11681223

11691224
<a id="cargo-feature-add"></a>

0 commit comments

Comments
 (0)