diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 38235f188e6..78111023045 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -101,6 +101,7 @@ GRS_OBJS = \
rust/rust-derive-partial-eq.o \
rust/rust-derive-eq.o \
rust/rust-derive-hash.o \
+ rust/rust-node-id-fix-visitor.o \
rust/rust-proc-macro.o \
rust/rust-macro-invoc-lexer.o \
rust/rust-proc-macro-invoc-lexer.o \
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 9581dd57b73..daa45758863 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1496,6 +1496,11 @@ class Type : public Visitable
NodeId get_node_id () const { return node_id; }
+ void reset_node_id ()
+ {
+ node_id = Analysis::Mappings::get ().get_next_node_id ();
+ }
+
protected:
Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 6f53188d9a3..160b2966ac1 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -887,6 +887,11 @@ class TypePathSegment
NodeId get_node_id () const { return node_id; }
+ void reset_node_id ()
+ {
+ node_id = Analysis::Mappings::get ().get_next_node_id ();
+ }
+
bool is_crate_path_seg () const
{
return get_ident_segment ().is_crate_path_seg ();
diff --git a/gcc/rust/expand/rust-derive-default.cc b/gcc/rust/expand/rust-derive-default.cc
index 2e8b4568199..b38980a2ca6 100644
--- a/gcc/rust/expand/rust-derive-default.cc
+++ b/gcc/rust/expand/rust-derive-default.cc
@@ -17,6 +17,7 @@
// .
#include "rust-derive-default.h"
+#include "rust-node-id-fix-visitor.h"
#include "rust-ast.h"
#include "rust-diagnostics.h"
#include "rust-path.h"
@@ -100,6 +101,8 @@ DeriveDefault::visit_struct (StructStruct &item)
auto name = field.get_field_name ().as_string ();
auto expr = default_call (field.get_field_type ().clone_type ());
+ NodeIdFixVisitor::fix (expr);
+
cloned_fields.emplace_back (
builder.struct_expr_field (std::move (name), std::move (expr)));
}
@@ -121,6 +124,8 @@ DeriveDefault::visit_tuple (TupleStruct &tuple_item)
{
auto type = field.get_field_type ().clone_type ();
+ NodeIdFixVisitor::fix (type);
+
defaulted_fields.emplace_back (default_call (std::move (type)));
}
diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc
index 5e7a8946dfd..fe45ceec5e4 100644
--- a/gcc/rust/expand/rust-derive-eq.cc
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -17,6 +17,7 @@
// .
#include "rust-derive-eq.h"
+#include "rust-node-id-fix-visitor.h"
#include "rust-ast.h"
#include "rust-expr.h"
#include "rust-item.h"
@@ -34,6 +35,8 @@ DeriveEq::go (Item &item)
{
item.accept_vis (*this);
+ NodeIdFixVisitor::fix (expanded);
+
return std::move (expanded);
}
diff --git a/gcc/rust/expand/rust-node-id-fix-visitor.cc b/gcc/rust/expand/rust-node-id-fix-visitor.cc
new file mode 100644
index 00000000000..880dabb3561
--- /dev/null
+++ b/gcc/rust/expand/rust-node-id-fix-visitor.cc
@@ -0,0 +1,58 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// .
+
+#include "rust-node-id-fix-visitor.h"
+
+namespace Rust {
+
+void
+NodeIdFixVisitor::visit (AST::TypePathSegment &seg)
+{
+ DefaultASTVisitor::visit (seg);
+ seg.reset_node_id ();
+}
+
+void
+NodeIdFixVisitor::visit (AST::TypePathSegmentGeneric &seg)
+{
+ DefaultASTVisitor::visit (seg);
+ seg.reset_node_id ();
+}
+
+void
+NodeIdFixVisitor::visit (AST::TypePathSegmentFunction &seg)
+{
+ DefaultASTVisitor::visit (seg);
+ seg.reset_node_id ();
+}
+
+void
+NodeIdFixVisitor::visit (AST::TypePath &path)
+{
+ DefaultASTVisitor::visit (path);
+ path.reset_node_id ();
+}
+
+void
+NodeIdFixVisitor::visit (AST::QualifiedPathInType &path)
+{
+ DefaultASTVisitor::visit (path);
+ path.reset_node_id ();
+}
+
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-node-id-fix-visitor.h b/gcc/rust/expand/rust-node-id-fix-visitor.h
new file mode 100644
index 00000000000..c7318562e69
--- /dev/null
+++ b/gcc/rust/expand/rust-node-id-fix-visitor.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// .
+
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+
+// This class reassigns node ids to AST nodes
+// It's a bit of a hack to work around cloning copying node ids
+
+class NodeIdFixVisitor : public AST::DefaultASTVisitor
+{
+public:
+ using DefaultASTVisitor::visit;
+
+ template static void fix (T &node)
+ {
+ NodeIdFixVisitor instance;
+ instance.visit (node);
+ }
+
+ template void visit (std::vector &nodes)
+ {
+ for (auto &ent : nodes)
+ visit (ent);
+ }
+
+ // TODO: add more visitors
+
+ void visit (AST::TypePathSegment &) override;
+ void visit (AST::TypePathSegmentGeneric &) override;
+ void visit (AST::TypePathSegmentFunction &) override;
+ void visit (AST::TypePath &) override;
+ void visit (AST::QualifiedPathInType &) override;
+};
+
+} // namespace Rust
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index 312964c6b14..d4e066a5f72 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -6,8 +6,6 @@ pub_restricted_1.rs
pub_restricted_2.rs
pub_restricted_3.rs
issue-2905-2.rs
-derive-default1.rs
-derive-eq-invalid.rs
torture/alt_patterns1.rs
torture/name_resolve1.rs
issue-3671.rs