about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-08-12 20:37:55 +1000
committerGitHub <noreply@github.com>2025-08-12 20:37:55 +1000
commit42af95b18e6ad480d72d6bffe71ff9063fc9b6de (patch)
tree814c2e9659e06966d8b7c24f0e5abe4e51f37544
parent769d32b117ee007b8872b7de3752ac7a6a64c05d (diff)
parentbcf87e4172416b96e24be998e18d81a8af183356 (diff)
downloadrust-42af95b18e6ad480d72d6bffe71ff9063fc9b6de.tar.gz
rust-42af95b18e6ad480d72d6bffe71ff9063fc9b6de.zip
Rollup merge of #145251 - tiif:support_trait, r=BoxyUwU
Support using #[unstable_feature_bound] on trait

This is needed to unblock https://github.com/rust-lang/rust/pull/145095

r? ```````@BoxyUwU```````
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs3
-rw-r--r--src/doc/rustc-dev-guide/src/stability.md7
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.fail.stderr18
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.rs33
-rw-r--r--tests/ui/unstable-feature-bound/unstable_inherent_method.rs4
-rw-r--r--tests/ui/unstable-feature-bound/unstable_inherent_method.stderr8
7 files changed, 66 insertions, 11 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 4a1f01cc5c8..b5031f5d02e 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -669,8 +669,8 @@ passes_rustc_std_internal_symbol =
     .label = not a function or static
 
 passes_rustc_unstable_feature_bound =
-    attribute should be applied to `impl` or free function outside of any `impl` or trait
-    .label = not an `impl` or free function
+    attribute should be applied to `impl`, trait or free function
+    .label = not an `impl`, trait or free function
 
 passes_should_be_applied_to_fn =
     attribute should be applied to a function definition
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index d1e58e60dbe..93b94a8ba14 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2326,7 +2326,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         match target {
             // FIXME(staged_api): There's no reason we can't support more targets here. We're just
             // being conservative to begin with.
-            Target::Fn | Target::Impl { .. } => {}
+            Target::Fn | Target::Impl { .. } | Target::Trait => {}
             Target::ExternCrate
             | Target::Use
             | Target::Static
@@ -2341,7 +2341,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             | Target::Struct
             | Target::Field
             | Target::Union
-            | Target::Trait
             | Target::TraitAlias
             | Target::Expression
             | Target::Statement
diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md
index c26d34273d7..3c4c65fdd5a 100644
--- a/src/doc/rustc-dev-guide/src/stability.md
+++ b/src/doc/rustc-dev-guide/src/stability.md
@@ -182,6 +182,11 @@ of the standard library raises it to a warning with
 `#![warn(deprecated_in_future)]`.
 
 ## unstable_feature_bound
-The `#[unstable_feature_bound(foo)]` attribute can be used together with `#[unstable]` attribute to mark an `impl` of stable type and stable trait as unstable. In std/core, an item annotated with `#[unstable_feature_bound(foo)]` can only be used by another item that is also annotated with `#[unstable_feature_bound(foo)]`. Outside of std/core, using an item with `#[unstable_feature_bound(foo)]` requires the feature to be enabled with `#![feature(foo)]` attribute on the crate. Currently, only `impl`s and free functions can be annotated with `#[unstable_feature_bound]`.
+The `#[unstable_feature_bound(foo)]` attribute can be used together with `#[unstable]` attribute to mark an `impl` of stable type and stable trait as unstable. In std/core, an item annotated with `#[unstable_feature_bound(foo)]` can only be used by another item that is also annotated with `#[unstable_feature_bound(foo)]`. Outside of std/core, using an item with `#[unstable_feature_bound(foo)]` requires the feature to be enabled with `#![feature(foo)]` attribute on the crate.
+
+Currently, the items that can be annotated with `#[unstable_feature_bound]` are:
+- `impl`
+- free function
+- trait
 
 [blog]: https://www.ralfj.de/blog/2018/07/19/const.html
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.fail.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.fail.stderr
new file mode 100644
index 00000000000..69be101a40d
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.fail.stderr
@@ -0,0 +1,18 @@
+error: unstable feature `foo` is used without being enabled.
+  --> $DIR/unstable_feature_bound_on_trait.rs:28:5
+   |
+LL |     Foo::bar();
+   |     ^^^^^^^^^^
+   |
+   = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(foo)]`
+note: required by a bound in `Bar::bar`
+  --> $DIR/unstable_feature_bound_on_trait.rs:16:1
+   |
+LL | #[unstable_feature_bound(foo)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Bar::bar`
+...
+LL |     fn bar() {}
+   |        --- required by a bound in this associated function
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.rs
new file mode 100644
index 00000000000..0ee00d5e7fb
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_on_trait.rs
@@ -0,0 +1,33 @@
+//@ revisions: pass fail
+//@[pass] check-pass
+
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![stable(feature = "a", since = "1.1.1" )]
+
+/// Test the behaviour of marking a trait with #[unstable_feature_bound].
+/// In this testcase, even though the trait method `bar` and the `struct Foo` are
+/// both stable, #[unstable_feature_bound] is still needed at the call site of Foo::bar().
+
+#[stable(feature = "a", since = "1.1.1" )]
+struct Foo;
+
+#[unstable(feature = "foo", issue = "none" )]
+#[unstable_feature_bound(foo)]
+trait Bar {
+    #[stable(feature = "a", since = "1.1.1" )]
+    fn bar() {}
+}
+
+#[unstable_feature_bound(foo)]
+impl Bar for Foo {
+}
+
+#[cfg_attr(pass, unstable_feature_bound(foo))]
+fn moo() {
+    Foo::bar();
+    //[fail]~^ ERROR: unstable feature `foo` is used without being enabled.
+}
+
+
+fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable_inherent_method.rs b/tests/ui/unstable-feature-bound/unstable_inherent_method.rs
index 5f3095430a8..0d6e4ebb408 100644
--- a/tests/ui/unstable-feature-bound/unstable_inherent_method.rs
+++ b/tests/ui/unstable-feature-bound/unstable_inherent_method.rs
@@ -9,14 +9,14 @@
 pub trait Trait {
     #[unstable(feature = "feat", issue = "none" )]
     #[unstable_feature_bound(foo)]
-    //~^ ERROR: attribute should be applied to `impl` or free function outside of any `impl` or trait
+    //~^ ERROR: attribute should be applied to `impl`, trait or free function
     fn foo();
 }
 
 #[stable(feature = "a", since = "1.1.1" )]
 impl Trait for u8 {
     #[unstable_feature_bound(foo)]
-    //~^ ERROR: attribute should be applied to `impl` or free function outside of any `impl` or trait
+    //~^ ERROR: attribute should be applied to `impl`, trait or free function
     fn foo() {}
 }
 
diff --git a/tests/ui/unstable-feature-bound/unstable_inherent_method.stderr b/tests/ui/unstable-feature-bound/unstable_inherent_method.stderr
index fa1c39db259..90cbb32df7c 100644
--- a/tests/ui/unstable-feature-bound/unstable_inherent_method.stderr
+++ b/tests/ui/unstable-feature-bound/unstable_inherent_method.stderr
@@ -1,20 +1,20 @@
-error: attribute should be applied to `impl` or free function outside of any `impl` or trait
+error: attribute should be applied to `impl`, trait or free function
   --> $DIR/unstable_inherent_method.rs:11:5
    |
 LL |     #[unstable_feature_bound(foo)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     fn foo();
-   |     --------- not an `impl` or free function
+   |     --------- not an `impl`, trait or free function
 
-error: attribute should be applied to `impl` or free function outside of any `impl` or trait
+error: attribute should be applied to `impl`, trait or free function
   --> $DIR/unstable_inherent_method.rs:18:5
    |
 LL |     #[unstable_feature_bound(foo)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     fn foo() {}
-   |     ----------- not an `impl` or free function
+   |     ----------- not an `impl`, trait or free function
 
 error: aborting due to 2 previous errors