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