Skip to content

Commit ff0806a

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 <0001jayant@gmail.com>
1 parent c35ffdb commit ff0806a

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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+
#[derive(Copy)] // { dg-error "derive may only be applied to structs, enums and unions" }
10+
impl Bar for i32 {}
11+
12+
fn main() {}

0 commit comments

Comments
 (0)