about summary refs log tree commit diff
diff options
context:
space:
mode:
authormejrs <59372212+mejrs@users.noreply.github.com>2025-03-29 11:46:03 +0100
committermejrs <59372212+mejrs@users.noreply.github.com>2025-04-14 00:12:37 +0200
commit9abaa9d4dffeb897a1dbff97d32d3b6ac190be21 (patch)
tree6d3be36cbe4c99b99d56af0f7c4ec00db9f3df42
parent8586cad77c175a0c2ce11c0579c537aa195e6da2 (diff)
downloadrust-9abaa9d4dffeb897a1dbff97d32d3b6ac190be21.tar.gz
rust-9abaa9d4dffeb897a1dbff97d32d3b6ac190be21.zip
Disable usage on trait impls and aliases
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs17
-rw-r--r--tests/crashes/130627.rs20
-rw-r--r--tests/ui/diagnostic_namespace/on_impl_trait.rs17
-rw-r--r--tests/ui/diagnostic_namespace/on_impl_trait.stderr31
-rw-r--r--tests/ui/on-unimplemented/impl-substs.stderr2
-rw-r--r--tests/ui/on-unimplemented/multiple-impls.stderr12
-rw-r--r--tests/ui/on-unimplemented/on-impl.stderr4
7 files changed, 68 insertions, 35 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index 0478f3a7f11..ca51f177f96 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -553,6 +553,13 @@ impl<'tcx> OnUnimplementedDirective {
     }
 
     pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<Option<Self>, ErrorGuaranteed> {
+        if !tcx.is_trait(item_def_id) {
+            // It could be a trait_alias (`trait MyTrait = SomeOtherTrait`)
+            // or an implementation (`impl MyTrait for Foo {}`)
+            //
+            // We don't support those.
+            return Ok(None);
+        }
         if let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) {
             return Self::parse_attribute(attr, false, tcx, item_def_id);
         } else {
@@ -782,8 +789,10 @@ impl<'tcx> OnUnimplementedFormatString {
         Ok(result)
     }
 
-    fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuaranteed> {
-        let trait_def_id = if tcx.is_trait(item_def_id) { item_def_id } else { return Ok(()) };
+    fn verify(&self, tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> Result<(), ErrorGuaranteed> {
+        if !tcx.is_trait(trait_def_id) {
+            return Ok(());
+        };
 
         let ctx = if self.is_diagnostic_namespace_variant {
             Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }
@@ -810,10 +819,10 @@ impl<'tcx> OnUnimplementedFormatString {
                 // so that users are aware that something is not correct
                 for e in errors {
                     if self.is_diagnostic_namespace_variant {
-                        if let Some(item_def_id) = item_def_id.as_local() {
+                        if let Some(trait_def_id) = trait_def_id.as_local() {
                             tcx.emit_node_span_lint(
                                 UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                                tcx.local_def_id_to_hir_id(item_def_id),
+                                tcx.local_def_id_to_hir_id(trait_def_id),
                                 self.span,
                                 WrappedParserError { description: e.description, label: e.label },
                             );
diff --git a/tests/crashes/130627.rs b/tests/crashes/130627.rs
deleted file mode 100644
index 59d3606592b..00000000000
--- a/tests/crashes/130627.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ known-bug: #130627
-
-#![feature(trait_alias)]
-
-trait Test {}
-
-#[diagnostic::on_unimplemented(
-    message="message",
-    label="label",
-    note="note"
-)]
-trait Alias = Test;
-
-// Use trait alias as bound on type parameter.
-fn foo<T: Alias>(v: &T) {
-}
-
-pub fn main() {
-    foo(&1);
-}
diff --git a/tests/ui/diagnostic_namespace/on_impl_trait.rs b/tests/ui/diagnostic_namespace/on_impl_trait.rs
new file mode 100644
index 00000000000..32a492c53a9
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/on_impl_trait.rs
@@ -0,0 +1,17 @@
+// used to ICE, see <https://github.com/rust-lang/rust/issues/130627>
+// Instead it should just ignore the diagnostic attribute
+#![feature(trait_alias)]
+
+trait Test {}
+
+#[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")]
+//~^ WARN `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
+trait Alias = Test;
+
+// Use trait alias as bound on type parameter.
+fn foo<T: Alias>(v: &T) {}
+
+pub fn main() {
+    foo(&1);
+    //~^ ERROR the trait bound `{integer}: Alias` is not satisfied
+}
diff --git a/tests/ui/diagnostic_namespace/on_impl_trait.stderr b/tests/ui/diagnostic_namespace/on_impl_trait.stderr
new file mode 100644
index 00000000000..59b9c31bc53
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/on_impl_trait.stderr
@@ -0,0 +1,31 @@
+warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
+  --> $DIR/on_impl_trait.rs:7:1
+   |
+LL | #[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
+
+error[E0277]: the trait bound `{integer}: Alias` is not satisfied
+  --> $DIR/on_impl_trait.rs:15:9
+   |
+LL |     foo(&1);
+   |     --- ^^ the trait `Test` is not implemented for `{integer}`
+   |     |
+   |     required by a bound introduced by this call
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/on_impl_trait.rs:5:1
+   |
+LL | trait Test {}
+   | ^^^^^^^^^^
+   = note: required for `{integer}` to implement `Alias`
+note: required by a bound in `foo`
+  --> $DIR/on_impl_trait.rs:12:11
+   |
+LL | fn foo<T: Alias>(v: &T) {}
+   |           ^^^^^ required by this bound in `foo`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr
index 0eabe971492..2d83845ecb8 100644
--- a/tests/ui/on-unimplemented/impl-substs.stderr
+++ b/tests/ui/on-unimplemented/impl-substs.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `(i32, i32, i32): Foo<usize>` is not satisfied
   --> $DIR/impl-substs.rs:13:23
    |
 LL |     Foo::<usize>::foo((1i32, 1i32, 1i32));
-   |     ----------------- ^^^^^^^^^^^^^^^^^^ an impl did not match: usize {B} {C}
+   |     ----------------- ^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `(i32, i32, i32)`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/on-unimplemented/multiple-impls.stderr b/tests/ui/on-unimplemented/multiple-impls.stderr
index ba4e43ff359..2afc9b1bf3b 100644
--- a/tests/ui/on-unimplemented/multiple-impls.stderr
+++ b/tests/ui/on-unimplemented/multiple-impls.stderr
@@ -15,11 +15,10 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:36:33
    |
 LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |     ------------                ^^^^^^^^^ on impl for Foo
+   |     ------------                ^^^^^^^^^ the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    |     |
    |     required by a bound introduced by this call
    |
-   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
              `[i32]` implements `Index<Bar<usize>>`
              `[i32]` implements `Index<Foo<usize>>`
@@ -28,11 +27,10 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:39:33
    |
 LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |     ------------                ^^^^^^^^^ on impl for Bar
+   |     ------------                ^^^^^^^^^ the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    |     |
    |     required by a bound introduced by this call
    |
-   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
              `[i32]` implements `Index<Bar<usize>>`
              `[i32]` implements `Index<Foo<usize>>`
@@ -52,9 +50,8 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:36:5
    |
 LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    |
-   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
              `[i32]` implements `Index<Bar<usize>>`
              `[i32]` implements `Index<Foo<usize>>`
@@ -63,9 +60,8 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:39:5
    |
 LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    |
-   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
              `[i32]` implements `Index<Bar<usize>>`
              `[i32]` implements `Index<Foo<usize>>`
diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr
index 5e7e2c4ea77..922db9db116 100644
--- a/tests/ui/on-unimplemented/on-impl.stderr
+++ b/tests/ui/on-unimplemented/on-impl.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:47
    |
 LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
-   |     -------------------                       ^^^^ a usize is required to index into a slice
+   |     -------------------                       ^^^^ the trait `Index<u32>` is not implemented for `[i32]`
    |     |
    |     required by a bound introduced by this call
    |
@@ -14,7 +14,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:5
    |
 LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<u32>` is not implemented for `[i32]`
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
            but trait `Index<usize>` is implemented for it