]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix ICE cloning trait functions without return types
authorlishin <lishin1008@gmail.com>
Mon, 20 Apr 2026 18:39:04 +0000 (19:39 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 1 Jun 2026 13:24:50 +0000 (15:24 +0200)
Fixes Rust-GCC/gccrs#3972.

Trait functions without an explicit return type can have a null
`return_type` in `TraitFunctionDecl`. When such declarations are copied,
the copy constructor and assignment operator currently try to clone the
return type unconditionally, and this can lead to an ICE.

Handle this case by keeping `nullptr` when there is no return type to
clone. Also add a regression test for the example from Rust-GCC/gccrs#3972.

gcc/rust/ChangeLog:

* hir/tree/rust-hir-item.cc (TraitFunctionDecl::TraitFunctionDecl):
Handle null return types in copy constructor.
(TraitFunctionDecl::operator=): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/issue-3972.rs: New test.

Signed-off-by: lishin <lishin1008@gmail.com>
gcc/rust/hir/tree/rust-hir-item.cc
gcc/testsuite/rust/compile/issue-3972.rs [new file with mode: 0644]

index 5e5d9b7833acce07cb2ff0081c1a9088ba1e7d05..309118cff434ca351693ed9a47e0eeca0e6e884f 100644 (file)
@@ -630,7 +630,8 @@ TraitFunctionDecl::TraitFunctionDecl (
 TraitFunctionDecl::TraitFunctionDecl (TraitFunctionDecl const &other)
   : qualifiers (other.qualifiers), function_name (other.function_name),
     function_params (other.function_params),
-    return_type (other.return_type->clone_type ()),
+    return_type (other.return_type != nullptr ? other.return_type->clone_type ()
+                                             : nullptr),
     where_clause (other.where_clause), self (other.self)
 {
   generic_params.reserve (other.generic_params.size ());
@@ -644,7 +645,9 @@ TraitFunctionDecl::operator= (TraitFunctionDecl const &other)
   function_name = other.function_name;
   qualifiers = other.qualifiers;
   function_params = other.function_params;
-  return_type = other.return_type->clone_type ();
+  return_type
+    = other.return_type != nullptr ? other.return_type->clone_type () : nullptr;
+
   where_clause = other.where_clause;
   self = other.self;
 
diff --git a/gcc/testsuite/rust/compile/issue-3972.rs b/gcc/testsuite/rust/compile/issue-3972.rs
new file mode 100644 (file)
index 0000000..466efc3
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-options "-frust-compile-until=lowering" }
+#![feature(no_core)]
+#![no_core]
+
+struct Expr<const N: u32>;
+
+trait Trait0 {
+    fn required(
+        _: Expr<
+            {
+                trait Trait0 {
+                    fn required();
+                }
+
+                0
+            },
+        >,
+    );
+}