https://gcc.gnu.org/g:bfacb5f326751f980619834d09e6c87a480689f5

commit r16-5601-gbfacb5f326751f980619834d09e6c87a480689f5
Author: Lucas Ly Ba <[email protected]>
Date:   Tue Oct 14 13:40:04 2025 +0000

    gccrs: add error check if derive has wrong item
    
    Derive may only be applied to structs, enums and unions.
    
    gcc/rust/ChangeLog:
    
            * expand/rust-derive.cc (DeriveVisitor::derive):
            Add check and error.
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-3971.rs: New test.
    
    Signed-off-by: Lucas Ly Ba <[email protected]>

Diff:
---
 gcc/rust/expand/rust-derive.cc           | 11 +++++++++++
 gcc/testsuite/rust/compile/issue-3971.rs | 11 +++++++++++
 2 files changed, 22 insertions(+)

diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index 55147df26f24..2777f076f024 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -25,6 +25,7 @@
 #include "rust-derive-ord.h"
 #include "rust-derive-partial-eq.h"
 #include "rust-derive-hash.h"
+#include "rust-system.h"
 
 namespace Rust {
 namespace AST {
@@ -39,6 +40,16 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
 {
   auto loc = attr.get_locus ();
 
+  using Kind = AST::Item::Kind;
+  auto item_kind = item.get_item_kind ();
+  if (item_kind != Kind::Enum && item_kind != Kind::Struct
+      && item_kind != Kind::Union)
+    {
+      rust_error_at (loc,
+                    "derive may only be applied to structs, enums and unions");
+      return {};
+    }
+
   switch (to_derive)
     {
     case BuiltinMacro::Clone:
diff --git a/gcc/testsuite/rust/compile/issue-3971.rs 
b/gcc/testsuite/rust/compile/issue-3971.rs
new file mode 100644
index 000000000000..5607d2d74a5c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3971.rs
@@ -0,0 +1,11 @@
+#[lang = "copy"]
+trait Copy {}
+
+// since the macro expansion fails, the current nameres fixpoint error is 
emitted - just accept it for now
+#[derive(Copy)]
+// { dg-error "derive may only be applied to structs, enums and unions" "" { 
target *-*-* } .-1 }
+// { dg-excess-errors "could not resolve trait" }
+
+pub fn check_ge(a: i32, b: i32) -> bool {
+    a >= b
+}

Reply via email to