[gccrs COMMIT 1/3] Remove metadata export visitor

[email protected] Mon, 3 Aug 2026 03:35:51 +0000
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Pierre-Emmanuel Patry <[email protected]>

The metadata format will likely change over the upcoming month and right
now it doesn't support trait impl. This commit simplifies metadata export
by dumping the whole AST within metadatas. This is slower but it should
be more complete and correct.

gcc/rust/ChangeLog:

	* ast/rust-collect-lang-items.cc (CollectLangItems::visit): Visit
	extern crate's content when collecting lang items.
	* ast/rust-collect-lang-items.h: Add function protototype.
	* metadata/rust-export-metadata.cc (ExportContext::push_module_scope):
	Remove.
	(ExportContext::emit_crate): Add a function to export the whole crate.
	(ExportContext::pop_module_scope): Remove.
	(ExportContext::emit_trait): Likewise.
	(ExportContext::emit_use_declaration): Likewise.
	(ExportContext::emit_function): Likewise.
	(ExportContext::emit_extern_block): Likewise.
	(ExportContext::emit_module): Likewise.
	(class ExportVisItems): Likewise.
	(PublicInterface::gather_export_data): Dump the AST.
	* metadata/rust-export-metadata.h: Update prototypes.

gcc/testsuite/ChangeLog:

	* rust/link/simple_function_0.rs: Remove bogus match.

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: https://github.com/Rust-GCC/gccrs/commit/d420c224300c203eb4999ffb57a97714adea29a0

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4694

 gcc/rust/ast/rust-collect-lang-items.cc      |  14 +++
 gcc/rust/ast/rust-collect-lang-items.h       |   2 +
 gcc/rust/metadata/rust-export-metadata.cc    | 123 +------------------
 gcc/rust/metadata/rust-export-metadata.h     |  12 +-
 gcc/testsuite/rust/link/simple_function_0.rs |   1 -
 5 files changed, 20 insertions(+), 132 deletions(-)

diff --git a/gcc/rust/ast/rust-collect-lang-items.cc b/gcc/rust/ast/rust-collect-lang-items.cc
index a8d906492..7a5ac6dd2 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -131,5 +131,19 @@ CollectLangItems::visit (AST::EnumItemDiscriminant &item)
   DefaultASTVisitor::visit (item);
 }
 
+void
+CollectLangItems::visit (AST::ExternCrate &extern_crate)
+{
+  auto &mappings = Analysis::Mappings::get ();
+  auto crate_num
+    = mappings.lookup_crate_name (extern_crate.get_referenced_crate ());
+  if (crate_num)
+    {
+      visit (mappings.get_ast_crate (*crate_num));
+    }
+
+  DefaultASTVisitor::visit (extern_crate);
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-collect-lang-items.h b/gcc/rust/ast/rust-collect-lang-items.h
index 60b5ff401..76e7adb9a 100644
--- a/gcc/rust/ast/rust-collect-lang-items.h
+++ b/gcc/rust/ast/rust-collect-lang-items.h
@@ -45,6 +45,8 @@ public:
 
   using DefaultASTVisitor::visit;
 
+  // Should we move this to the default ast visitor ?
+  void visit (AST::ExternCrate &extern_crate) override;
   void visit (AST::Trait &item) override;
   void visit (AST::TraitItemType &item) override;
   void visit (AST::Function &item) override;
diff --git a/gcc/rust/metadata/rust-export-metadata.cc b/gcc/rust/metadata/rust-export-metadata.cc
index 6998319d8..5d01c5425 100644
--- a/gcc/rust/metadata/rust-export-metadata.cc
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -39,95 +39,14 @@ ExportContext::ExportContext () : mappings (Analysis::Mappings::get ()) {}
 ExportContext::~ExportContext () {}
 
 void
-ExportContext::push_module_scope (const HIR::Module &module)
+ExportContext::emit_crate (AST::Crate &c)
 {
-  module_stack.push_back (module);
-}
-
-const HIR::Module &
-ExportContext::pop_module_scope ()
-{
-  rust_assert (!module_stack.empty ());
-  const HIR::Module &poped = module_stack.back ();
-  module_stack.pop_back ();
-  return poped;
-}
-
-void
-ExportContext::emit_trait (AST::Trait &trait)
-{
-  std::stringstream oss;
-  AST::Dump dumper (oss);
-  dumper.process (trait);
-
-  public_interface_buffer += oss.str ();
-}
-
-void
-ExportContext::emit_use_declaration (AST::UseDeclaration &use_decl)
-{
-  std::stringstream oss;
-  AST::Dump dumper (oss);
-  dumper.process (use_decl);
-
-  public_interface_buffer += oss.str ();
-}
-
-void
-ExportContext::emit_function (AST::Function &fn)
-{
-  // is this a CFG macro or not
-  if (fn.is_marked_for_strip ())
-    return;
-
-  // if its a generic function we need to output the full declaration
-  // otherwise we can let people link against this
-
   std::stringstream oss;
   AST::Dump dumper (oss);
-  if (!fn.has_generics ())
-    {
-      std::vector<std::unique_ptr<AST::ExternalItem>> external_items;
-      external_items.emplace_back (fn.clone_external_item ());
-
-      AST::ExternBlock extern_block (get_string_from_abi (Rust::ABI::RUST),
-				     std::move (external_items),
-				     fn.get_visibility (), {}, {},
-				     fn.get_locus ());
+  dumper.process (c);
 
-      dumper.go (extern_block);
-    }
-  else
-    {
-      dumper.process (fn);
-    }
-
-  // store the dump
   public_interface_buffer += oss.str ();
 }
-
-void
-ExportContext::emit_extern_block (const AST::ExternBlock &block,
-				  std::function<void (void)> sub_visitor)
-{
-  public_interface_buffer += "extern \"" + block.get_abi () + "\" {\n";
-  sub_visitor ();
-  public_interface_buffer += "}\n";
-}
-
-void
-ExportContext::emit_module (const AST::Module &module,
-			    std::function<void (void)> sub_visitor)
-{
-  if (module.get_visibility ().is_public ())
-    {
-      public_interface_buffer
-	+= "pub mod " + module.get_name ().as_string () + "{\n";
-      sub_visitor ();
-      public_interface_buffer += "}\n";
-    }
-}
-
 void
 ExportContext::emit_macro (AST::MacroRulesDefinition &macro)
 {
@@ -145,41 +64,6 @@ ExportContext::get_interface_buffer () const
   return public_interface_buffer;
 }
 
-// implicitly by using HIR nodes we know that these have passed CFG expansion
-// and they exist in the compilation unit
-class ExportVisItems : public AST::DefaultASTVisitor
-{
-public:
-  using AST::DefaultASTVisitor::visit;
-  ExportVisItems (ExportContext &context) : ctx (context) {}
-
-  void go (AST::Crate &c) { visit (c); }
-
-  void visit (AST::Function &function) override
-  {
-    ctx.emit_function (function);
-  }
-  void visit (AST::ExternBlock &block) override
-  {
-    auto sub_visitor = [&] () { AST::DefaultASTVisitor::visit (block); };
-    ctx.emit_extern_block (block, sub_visitor);
-  }
-  void visit (AST::Trait &trait) override { ctx.emit_trait (trait); }
-  void visit (AST::Module &module) override
-  {
-    auto sub_visitor = [&] () { AST::DefaultASTVisitor::visit (module); };
-    ctx.emit_module (module, sub_visitor);
-  }
-
-  void visit (AST::UseDeclaration &use_decl) override
-  {
-    ctx.emit_use_declaration (use_decl);
-  }
-
-private:
-  ExportContext &ctx;
-};
-
 PublicInterface::PublicInterface (HIR::Crate &crate)
   : crate (crate), mappings (Analysis::Mappings::get ()), context ()
 {}
@@ -203,11 +87,10 @@ PublicInterface::ExportTo (HIR::Crate &crate, const std::string &output_path)
 void
 PublicInterface::gather_export_data ()
 {
-  ExportVisItems visitor (context);
   auto crate_num
     = mappings.lookup_crate_num (crate.get_mappings ().get_nodeid ());
   auto &ast_crate = mappings.get_ast_crate (crate_num.value ());
-  visitor.go (ast_crate);
+  context.emit_crate (ast_crate);
 
   for (auto &macro : mappings.get_exported_macros ())
     context.emit_macro (macro);
diff --git a/gcc/rust/metadata/rust-export-metadata.h b/gcc/rust/metadata/rust-export-metadata.h
index b1e12f264..e9b2e963d 100644
--- a/gcc/rust/metadata/rust-export-metadata.h
+++ b/gcc/rust/metadata/rust-export-metadata.h
@@ -36,17 +36,7 @@ public:
 
   ~ExportContext ();
 
-  void push_module_scope (const HIR::Module &module);
-
-  const HIR::Module &pop_module_scope ();
-
-  void emit_trait (AST::Trait &trait);
-  void emit_function (AST::Function &fn);
-  void emit_extern_block (const AST::ExternBlock &block,
-			  std::function<void (void)> sub_visitor);
-  void emit_use_declaration (AST::UseDeclaration &use_decl);
-  void emit_module (const AST::Module &,
-		    std::function<void (void)> sub_visitor);
+  void emit_crate (AST::Crate &c);
 
   /**
    * Macros are a bit particular - they only live at the AST level, so we can
diff --git a/gcc/testsuite/rust/link/simple_function_0.rs b/gcc/testsuite/rust/link/simple_function_0.rs
index 35771901b..44e0fe441 100644
--- a/gcc/testsuite/rust/link/simple_function_0.rs
+++ b/gcc/testsuite/rust/link/simple_function_0.rs
@@ -6,6 +6,5 @@ use simple_function_1::test_func;
 
 fn main() -> i32 {
     let a = test_func(123);
-    // { dg-bogus "call to extern function" "" { xfail *-*-* } .-1 }
     a - 124
 }

base-commit: 481e776ea58e78dd2a76aab9b9e307571dabe7d5
-- 
2.54.0