about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-07-20 18:58:14 +0200
committerGitHub <noreply@github.com>2022-07-20 18:58:14 +0200
commit857afc75e6ca69cc7dcae36a6fac8c093ee6fa31 (patch)
treede307833a7c06a03bbcfa7da7bfb7ae54bf26f5f /src/test
parent14dbfebfa25a0e626ad827526934381b2545cbb4 (diff)
parente5872990d13abb088397e23b226439b1b4926b91 (diff)
Rollup merge of #99212 - davidtwco:partial-stability-implies, r=michaelwoerister
introduce `implied_by` in `#[unstable]` attribute

Requested by the library team [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/better.20support.20for.20partial.20stabilizations/near/285581519).

If part of a feature is stabilized and a new feature is added for the remaining parts, then the `implied_by` meta-item can be added to `#[unstable]` to indicate which now-stable feature was used previously.

```diagnostic
error: the feature `foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `foobar`
  --> $DIR/stability-attribute-implies-using-unstable.rs:3:12
   |
LL | #![feature(foo)]
   |            ^^^
   |
note: the lint level is defined here
  --> $DIR/stability-attribute-implies-using-stable.rs:2:9
   |
LL | #![deny(stable_features)]
   |         ^^^^^^^^^^^^^^^
help: if you are using features which are still unstable, change to using `foobar`
   |
LL | #![feature(foobar)]
   |            ~~~~~~
help: if you are using features which are now stable, remove this line
   |
LL - #![feature(foo)]
   |
```

When a `#![feature(..)]` attribute still exists for the now-stable attribute, then there this has two effects:

- There will not be an stability error for uses of items from the implied feature which are still unstable (until the `#![feature(..)]` is removed or updated to the new feature).
- There will be an improved diagnostic for the remaining use of the feature attribute for the now-stable feature.

```rust
        /// If part of a feature is stabilized and a new feature is added for the remaining parts,
        /// then the `implied_by` attribute is used to indicate which now-stable feature previously
        /// contained a item.
        ///
        /// ```pseudo-Rust
        /// #[unstable(feature = "foo", issue = "...")]
        /// fn foo() {}
        /// #[unstable(feature = "foo", issue = "...")]
        /// fn foobar() {}
        /// ```
        ///
        /// ...becomes...
        ///
        /// ```pseudo-Rust
        /// #[stable(feature = "foo", since = "1.XX.X")]
        /// fn foo() {}
        /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")]
        /// fn foobar() {}
        /// ```
```

In the Zulip discussion, this was envisioned as `implies` on `#[stable]` but I went with `implied_by` on `#[unstable]` because it means that only the unstable attribute needs to be changed in future, not the new stable attribute, which seems less error-prone. It also isn't particularly feasible for me to detect whether items from the implied feature are used and then only suggest updating _or_ removing the `#![feature(..)]` as appropriate, so I always do both.

There's some new information in the cross-crate metadata as a result of this change, that's a little unfortunate, but without requiring that the `#[unstable]` and `#[stable]` attributes both contain the implication information, it's necessary:

```rust
    /// This mapping is necessary unless both the `#[stable]` and `#[unstable]` attributes should
    /// specify their implications (both `implies` and `implied_by`). If only one of the two
    /// attributes do (as in the current implementation, `implied_by` in `#[unstable]`), then this
    /// mapping is necessary for diagnostics. When a "unnecessary feature attribute" error is
    /// reported, only the `#[stable]` attribute information is available, so the map is necessary
    /// to know that the feature implies another feature. If it were reversed, and the `#[stable]`
    /// attribute had an `implies` meta item, then a map would be necessary when avoiding a "use of
    /// unstable feature" error for a feature that was implied.
```

I also change some comments to documentation comments in the compiler, add a helper for going from a `Span` to a `Span` for the entire line, and fix a incorrect part of the pre-existing stability attribute diagnostics.

cc `@yaahc`
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/stability-attribute/auxiliary/stability-attribute-implies.rs8
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-missing.rs10
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-missing.stderr8
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-no-feature.rs13
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-no-feature.stderr21
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-using-stable.rs15
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-using-stable.stderr22
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.rs17
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.stderr22
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr2
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.stderr2
11 files changed, 138 insertions, 2 deletions
diff --git a/src/test/ui/stability-attribute/auxiliary/stability-attribute-implies.rs b/src/test/ui/stability-attribute/auxiliary/stability-attribute-implies.rs
new file mode 100644
index 00000000000..468be1bc144
--- /dev/null
+++ b/src/test/ui/stability-attribute/auxiliary/stability-attribute-implies.rs
@@ -0,0 +1,8 @@
+#![feature(staged_api)]
+#![stable(feature = "stability_attribute_implies", since = "1.0.0")]
+
+#[stable(feature = "foo", since = "1.62.0")]
+pub fn foo() {}
+
+#[unstable(feature = "foobar", issue = "1", implied_by = "foo")]
+pub fn foobar() {}
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-missing.rs b/src/test/ui/stability-attribute/stability-attribute-implies-missing.rs
new file mode 100644
index 00000000000..61387853672
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-missing.rs
@@ -0,0 +1,10 @@
+#![feature(staged_api)]
+#![stable(feature = "stability_attribute_implies", since = "1.0.0")]
+
+// Tests that `implied_by = "bar"` results in an error being emitted if `bar` does not exist.
+
+#[unstable(feature = "foobar", issue = "1", implied_by = "bar")]
+//~^ ERROR feature `bar` implying `foobar` does not exist
+pub fn foobar() {}
+
+fn main() {}
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-missing.stderr b/src/test/ui/stability-attribute/stability-attribute-implies-missing.stderr
new file mode 100644
index 00000000000..ff1856f1763
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-missing.stderr
@@ -0,0 +1,8 @@
+error: feature `bar` implying `foobar` does not exist
+  --> $DIR/stability-attribute-implies-missing.rs:6:1
+   |
+LL | #[unstable(feature = "foobar", issue = "1", implied_by = "bar")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-no-feature.rs b/src/test/ui/stability-attribute/stability-attribute-implies-no-feature.rs
new file mode 100644
index 00000000000..947f9f73eff
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-no-feature.rs
@@ -0,0 +1,13 @@
+// aux-build:stability-attribute-implies.rs
+
+// Tests that despite the `foobar` feature being implied by now-stable feature `foo`, if `foobar`
+// isn't allowed in this crate then an error will be emitted.
+
+extern crate stability_attribute_implies;
+use stability_attribute_implies::{foo, foobar};
+//~^ ERROR use of unstable library feature 'foobar'
+
+fn main() {
+    foo(); // no error - stable
+    foobar(); //~ ERROR use of unstable library feature 'foobar'
+}
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-no-feature.stderr b/src/test/ui/stability-attribute/stability-attribute-implies-no-feature.stderr
new file mode 100644
index 00000000000..c2331f6766c
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-no-feature.stderr
@@ -0,0 +1,21 @@
+error[E0658]: use of unstable library feature 'foobar'
+  --> $DIR/stability-attribute-implies-no-feature.rs:7:40
+   |
+LL | use stability_attribute_implies::{foo, foobar};
+   |                                        ^^^^^^
+   |
+   = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
+   = help: add `#![feature(foobar)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'foobar'
+  --> $DIR/stability-attribute-implies-no-feature.rs:12:5
+   |
+LL |     foobar();
+   |     ^^^^^^
+   |
+   = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
+   = help: add `#![feature(foobar)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-using-stable.rs b/src/test/ui/stability-attribute/stability-attribute-implies-using-stable.rs
new file mode 100644
index 00000000000..1a2d8e271de
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-using-stable.rs
@@ -0,0 +1,15 @@
+// aux-build:stability-attribute-implies.rs
+#![deny(stable_features)]
+#![feature(foo)]
+//~^ ERROR the feature `foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `foobar`
+
+// Tests that the use of `implied_by` in the `#[unstable]` attribute results in a diagnostic
+// mentioning partial stabilization, and that given the implied unstable feature is unused (there
+// is no `foobar` call), that the compiler suggests removing the flag.
+
+extern crate stability_attribute_implies;
+use stability_attribute_implies::foo;
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-using-stable.stderr b/src/test/ui/stability-attribute/stability-attribute-implies-using-stable.stderr
new file mode 100644
index 00000000000..c9b3f07cc70
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-using-stable.stderr
@@ -0,0 +1,22 @@
+error: the feature `foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `foobar`
+  --> $DIR/stability-attribute-implies-using-stable.rs:3:12
+   |
+LL | #![feature(foo)]
+   |            ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/stability-attribute-implies-using-stable.rs:2:9
+   |
+LL | #![deny(stable_features)]
+   |         ^^^^^^^^^^^^^^^
+help: if you are using features which are still unstable, change to using `foobar`
+   |
+LL | #![feature(foobar)]
+   |            ~~~~~~
+help: if you are using features which are now stable, remove this line
+   |
+LL - #![feature(foo)]
+   |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.rs b/src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.rs
new file mode 100644
index 00000000000..3c73c5abf3b
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.rs
@@ -0,0 +1,17 @@
+// aux-build:stability-attribute-implies.rs
+#![deny(stable_features)]
+#![feature(foo)]
+//~^ ERROR the feature `foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `foobar`
+
+// Tests that the use of `implied_by` in the `#[unstable]` attribute results in a diagnostic
+// mentioning partial stabilization and that given the implied unstable feature is used (there is a
+// `foobar` call), that the compiler suggests changing to that feature and doesn't error about its
+// use.
+
+extern crate stability_attribute_implies;
+use stability_attribute_implies::{foo, foobar};
+
+fn main() {
+    foo();
+    foobar(); // no error!
+}
diff --git a/src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.stderr b/src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.stderr
new file mode 100644
index 00000000000..9a5c7ef5a47
--- /dev/null
+++ b/src/test/ui/stability-attribute/stability-attribute-implies-using-unstable.stderr
@@ -0,0 +1,22 @@
+error: the feature `foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `foobar`
+  --> $DIR/stability-attribute-implies-using-unstable.rs:3:12
+   |
+LL | #![feature(foo)]
+   |            ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/stability-attribute-implies-using-unstable.rs:2:9
+   |
+LL | #![deny(stable_features)]
+   |         ^^^^^^^^^^^^^^^
+help: if you are using features which are still unstable, change to using `foobar`
+   |
+LL | #![feature(foobar)]
+   |            ~~~~~~
+help: if you are using features which are now stable, remove this line
+   |
+LL - #![feature(foo)]
+   |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr
index bd7b88da158..8dbcc6c97ef 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr
@@ -8,7 +8,7 @@ error[E0541]: unknown meta item 'sinse'
   --> $DIR/stability-attribute-sanity-2.rs:10:25
    |
 LL | #[stable(feature = "a", sinse = "1.0.0")]
-   |                         ^^^^^^^^^^^^^^^ expected one of `since`, `note`
+   |                         ^^^^^^^^^^^^^^^ expected one of `feature`, `since`
 
 error[E0545]: `issue` must be a non-zero numeric string or "none"
   --> $DIR/stability-attribute-sanity-2.rs:13:27
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
index fcb1eefddbc..079230b2a31 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
@@ -14,7 +14,7 @@ error[E0541]: unknown meta item 'reason'
   --> $DIR/stability-attribute-sanity.rs:8:42
    |
 LL |     #[stable(feature = "a", since = "b", reason)]
-   |                                          ^^^^^^ expected one of `since`, `note`
+   |                                          ^^^^^^ expected one of `feature`, `since`
 
 error[E0539]: incorrect meta item
   --> $DIR/stability-attribute-sanity.rs:11:29