Skip to content

Commit 9e84d88

Browse files
committed
expand: Add error check if derive has wrong item
The DeriveVisitor previously dispatched calls to specific handlers (like DeriveClone) without validating the input item type. This caused internal compiler errors (ICEs) when users attempted to derive traits on invalid items like functions or traits, as the handlers assumed the input was a struct, enum, or union. This patch adds a validation predicate `validate_item` to the DeriveVisitor to reject invalid items gracefully with a diagnostic error before dispatching. Fixes #3875 gcc/rust/ChangeLog: * expand/rust-derive.h (DeriveVisitor::validate_item): Add prototype. * expand/rust-derive.cc (DeriveVisitor::derive): Use visitor validation. (DeriveVisitor::validate_item): New function to check item kind. gcc/testsuite/ChangeLog: * rust/compile/issue-3875.rs: New test. Signed-off-by: Jayant Chauhan <[email protected]>
1 parent c35ffdb commit 9e84d88

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

gcc/rust/expand/rust-derive.cc

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
4040
{
4141
auto loc = attr.get_locus ();
4242

43-
using Kind = AST::Item::Kind;
44-
auto item_kind = item.get_item_kind ();
45-
if (item_kind != Kind::Enum && item_kind != Kind::Struct
46-
&& item_kind != Kind::Union)
43+
if (!DeriveVisitor::validate_item (item))
4744
{
4845
rust_error_at (loc,
4946
"derive may only be applied to structs, enums and unions");
@@ -159,5 +156,18 @@ DeriveVisitor::setup_impl_generics (
159156
return ImplGenerics{std::move (self_type_path), std::move (impl_generics)};
160157
}
161158

159+
bool
160+
DeriveVisitor::validate_item (const Item &item)
161+
{
162+
using Kind = AST::Item::Kind;
163+
auto item_kind = item.get_item_kind ();
164+
165+
if (item_kind == Kind::Enum || item_kind == Kind::Struct
166+
|| item_kind == Kind::Union)
167+
return true;
168+
169+
return false;
170+
}
171+
162172
} // namespace AST
163173
} // namespace Rust

gcc/rust/expand/rust-derive.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class DeriveVisitor : public AST::ASTVisitor
7171
= tl::nullopt) const;
7272

7373
private:
74+
static bool validate_item (const AST::Item &item);
7475
// the 4 "allowed" visitors, which a derive-visitor can specify and override
7576
virtual void visit_struct (StructStruct &struct_item) = 0;
7677
virtual void visit_tuple (TupleStruct &tuple_item) = 0;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// { dg-options "-w" }
2+
3+
#[derive(Clone)] // { dg-error "derive may only be applied to structs, enums and unions" }
4+
fn foo() {}
5+
6+
#[derive(Debug)] // { dg-error "derive may only be applied to structs, enums and unions" }
7+
trait Bar {}
8+
9+
trait Baz {} // Helper trait that actually exists
10+
11+
#[derive(Copy)] // { dg-error "derive may only be applied to structs, enums and unions" }
12+
impl Baz for i32 {}
13+
14+
fn main() {}

0 commit comments

Comments
 (0)