]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Move import mapping resolution to in tree visit
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Thu, 13 Mar 2025 12:41:38 +0000 (13:41 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 24 Mar 2025 12:07:21 +0000 (13:07 +0100)
Import mapping was relying on resolve_path which in turn relies on
the cursor function. This means the mapping resolver should be called
from the correct scope instead of being called from the crate scope.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::Early): Move the
top level visitor from the function scope to attributes.
(Early::go): Remove top level visitor creation and adapt calling code.
Remove call to mapping resolution and import finalization.
(Early::finalize_simple_import): Move the finalization from it's
visitor.
(Early::finalize_glob_import): Likewise.
(Early::finalize_rebind_import): Likewise.
(Early::visit): Add mapping resolution and finalization in
UseDeclaration visitor function.
* resolve/rust-finalize-imports-2.0.cc (finalize_simple_import): Move
function.
(finalize_glob_import): Likewise.
(finalize_rebind_import): Likewise.
(FinalizeImports::visit): Remove call to finalizers.
* resolve/rust-early-name-resolver-2.0.h (class Early): Add top level
attribute.
* resolve/rust-finalize-imports-2.0.h: Add function prototypes.
* resolve/rust-toplevel-name-resolver-2.0.h: Change getter return type
to reference.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/resolve/rust-early-name-resolver-2.0.cc
gcc/rust/resolve/rust-early-name-resolver-2.0.h
gcc/rust/resolve/rust-finalize-imports-2.0.cc
gcc/rust/resolve/rust-finalize-imports-2.0.h
gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h

index b894d130ccf4e4b553a091400cff0f9006b28ea7..492a665f43e9253bbbc1bf056265e2e0e3ef292c 100644 (file)
@@ -27,7 +27,8 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty (false)
+Early::Early (NameResolutionContext &ctx)
+  : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
 {}
 
 void
@@ -52,16 +53,10 @@ void
 Early::go (AST::Crate &crate)
 {
   // First we go through TopLevel resolution to get all our declared items
-  auto toplevel = TopLevel (ctx);
   toplevel.go (crate);
 
   // We start with resolving the list of imports that `TopLevel` has built for
   // us
-  for (auto &&import : toplevel.get_imports_to_resolve ())
-    build_import_mapping (std::move (import));
-
-  // Once this is done, we finalize their resolution
-  FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
 
   dirty = toplevel.is_dirty ();
   // We now proceed with resolving macros, which can be nested in almost any
@@ -375,5 +370,94 @@ Early::visit (AST::StructStruct &s)
   DefaultResolver::visit (s);
 }
 
+void
+Early::finalize_simple_import (const Early::ImportPair &mapping)
+{
+  // FIXME: We probably need to store namespace information
+
+  auto locus = mapping.import_kind.to_resolve.get_locus ();
+  auto data = mapping.data;
+  auto identifier
+    = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
+
+  for (auto &&definition : data.definitions ())
+    toplevel
+      .insert_or_error_out (
+       identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
+}
+
+void
+Early::finalize_glob_import (NameResolutionContext &ctx,
+                            const Early::ImportPair &mapping)
+{
+  auto module = Analysis::Mappings::get ().lookup_ast_module (
+    mapping.data.module ().get_node_id ());
+  rust_assert (module);
+
+  GlobbingVisitor glob_visitor (ctx);
+  glob_visitor.go (module.value ());
+}
+
+void
+Early::finalize_rebind_import (const Early::ImportPair &mapping)
+{
+  // We can fetch the value here as `resolve_rebind` will only be called on
+  // imports of the right kind
+  auto &path = mapping.import_kind.to_resolve;
+  auto &rebind = mapping.import_kind.rebind.value ();
+  auto data = mapping.data;
+
+  location_t locus = UNKNOWN_LOCATION;
+  std::string declared_name;
+
+  // FIXME: This needs to be done in `FinalizeImports`
+  switch (rebind.get_new_bind_type ())
+    {
+    case AST::UseTreeRebind::NewBindType::IDENTIFIER:
+      declared_name = rebind.get_identifier ().as_string ();
+      locus = rebind.get_identifier ().get_locus ();
+      break;
+    case AST::UseTreeRebind::NewBindType::NONE:
+      declared_name = path.get_final_segment ().as_string ();
+      locus = path.get_final_segment ().get_locus ();
+      break;
+    case AST::UseTreeRebind::NewBindType::WILDCARD:
+      rust_unreachable ();
+      break;
+    }
+
+  for (auto &&definition : data.definitions ())
+    toplevel.insert_or_error_out (
+      declared_name, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
+}
+
+void
+Early::visit (AST::UseDeclaration &decl)
+{
+  auto &imports = toplevel.get_imports_to_resolve ();
+  auto current_import = imports.find (decl.get_node_id ());
+  if (current_import != imports.end ())
+    {
+      build_import_mapping (*current_import);
+    }
+
+  // Once this is done, we finalize their resolution
+  for (const auto &mapping : import_mappings.get (decl.get_node_id ()))
+    switch (mapping.import_kind.kind)
+      {
+      case TopLevel::ImportKind::Kind::Glob:
+       finalize_glob_import (ctx, mapping);
+       break;
+      case TopLevel::ImportKind::Kind::Simple:
+       finalize_simple_import (mapping);
+       break;
+      case TopLevel::ImportKind::Kind::Rebind:
+       finalize_rebind_import (mapping);
+       break;
+      }
+
+  DefaultResolver::visit (decl);
+}
+
 } // namespace Resolver2_0
 } // namespace Rust
index e309b50174c6bfc8e4aab1dd0dfaa204554d55e0..c4226fe9ea8b85a7d64d440e1072bc26a91a0253 100644 (file)
@@ -34,6 +34,7 @@ class Early : public DefaultResolver
 {
   using DefaultResolver::visit;
 
+  TopLevel toplevel;
   bool dirty;
 
 public:
@@ -59,6 +60,7 @@ public:
 
   void visit (AST::Function &) override;
   void visit (AST::StructStruct &) override;
+  void visit (AST::UseDeclaration &) override;
 
   struct ImportData
   {
@@ -246,6 +248,13 @@ private:
   std::vector<Error> macro_resolve_errors;
 
   void collect_error (Error e) { macro_resolve_errors.push_back (e); }
+
+  void finalize_simple_import (const Early::ImportPair &mapping);
+
+  void finalize_glob_import (NameResolutionContext &ctx,
+                            const Early::ImportPair &mapping);
+
+  void finalize_rebind_import (const Early::ImportPair &mapping);
 };
 
 } // namespace Resolver2_0
index 71916ae432bd0c842ea272c4cc32d6b7ff50c00e..bd6002a09f4d34663c7d67f053214004e7ae9d6c 100644 (file)
@@ -125,67 +125,6 @@ GlobbingVisitor::visit (AST::UseDeclaration &use)
   // Handle cycles ?
 }
 
-void
-finalize_simple_import (TopLevel &toplevel, const Early::ImportPair &mapping)
-{
-  // FIXME: We probably need to store namespace information
-
-  auto locus = mapping.import_kind.to_resolve.get_locus ();
-  auto data = mapping.data;
-  auto identifier
-    = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
-
-  for (auto &&definition : data.definitions ())
-    toplevel
-      .insert_or_error_out (
-       identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
-}
-
-void
-finalize_glob_import (NameResolutionContext &ctx,
-                     const Early::ImportPair &mapping)
-{
-  auto module = Analysis::Mappings::get ().lookup_ast_module (
-    mapping.data.module ().get_node_id ());
-  rust_assert (module);
-
-  GlobbingVisitor glob_visitor (ctx);
-  glob_visitor.go (module.value ());
-}
-
-void
-finalize_rebind_import (TopLevel &toplevel, const Early::ImportPair &mapping)
-{
-  // We can fetch the value here as `resolve_rebind` will only be called on
-  // imports of the right kind
-  auto &path = mapping.import_kind.to_resolve;
-  auto &rebind = mapping.import_kind.rebind.value ();
-  auto data = mapping.data;
-
-  location_t locus = UNKNOWN_LOCATION;
-  std::string declared_name;
-
-  // FIXME: This needs to be done in `FinalizeImports`
-  switch (rebind.get_new_bind_type ())
-    {
-    case AST::UseTreeRebind::NewBindType::IDENTIFIER:
-      declared_name = rebind.get_identifier ().as_string ();
-      locus = rebind.get_identifier ().get_locus ();
-      break;
-    case AST::UseTreeRebind::NewBindType::NONE:
-      declared_name = path.get_final_segment ().as_string ();
-      locus = path.get_final_segment ().get_locus ();
-      break;
-    case AST::UseTreeRebind::NewBindType::WILDCARD:
-      rust_unreachable ();
-      break;
-    }
-
-  for (auto &&definition : data.definitions ())
-    toplevel.insert_or_error_out (
-      declared_name, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
-}
-
 FinalizeImports::FinalizeImports (Early::ImportMappings &&data,
                                  TopLevel &toplevel,
                                  NameResolutionContext &ctx)
@@ -202,23 +141,7 @@ FinalizeImports::go (AST::Crate &crate)
 
 void
 FinalizeImports::visit (AST::UseDeclaration &use)
-{
-  auto import_mappings = data.get (use.get_node_id ());
-
-  for (const auto &mapping : import_mappings)
-    switch (mapping.import_kind.kind)
-      {
-      case TopLevel::ImportKind::Kind::Glob:
-       finalize_glob_import (ctx, mapping);
-       break;
-      case TopLevel::ImportKind::Kind::Simple:
-       finalize_simple_import (toplevel, mapping);
-       break;
-      case TopLevel::ImportKind::Kind::Rebind:
-       finalize_rebind_import (toplevel, mapping);
-       break;
-      }
-}
+{}
 
 } // namespace Resolver2_0
 } // namespace Rust
index 0fba5a517a190369c27a80d5ba620dee2d17294a..a06fe538846a1fd72aa5930375418dea190d1ce0 100644 (file)
@@ -96,11 +96,11 @@ public:
 
   void go (AST::Crate &crate);
 
+  void visit (AST::UseDeclaration &) override;
+
 private:
   using AST::DefaultASTVisitor::visit;
 
-  void visit (AST::UseDeclaration &) override;
-
   Early::ImportMappings data;
   TopLevel &toplevel;
   NameResolutionContext &ctx;
index 559c0d8757f2ae5062aee535bdd36ec548abc0db..3ff37eda16d18df908705153a46510db933050de 100644 (file)
@@ -108,10 +108,9 @@ public:
     {}
   };
 
-  std::unordered_map<NodeId, std::vector<ImportKind>> &&
-  get_imports_to_resolve ()
+  std::unordered_map<NodeId, std::vector<ImportKind>> &get_imports_to_resolve ()
   {
-    return std::move (imports_to_resolve);
+    return imports_to_resolve;
   }
 
   void check_multiple_insertion_error (