From: Arthur Cohen <[email protected]>

Allow crates to be used as targets for glob imports, like modules and enums.

gcc/rust/ChangeLog:

        * ast/rust-ast-full-decls.h (class GlobContainer): New.
        * ast/rust-ast.h (class GlobContainer): New.
        (struct Crate): Inherit from GlobContainer.
        * ast/rust-item.h (class Module): Likewise.
        (class Enum): Likewise.
        * resolve/rust-finalize-imports-2.0.cc (GlobbingVisitor::go): Handle 
crates.
        (GlobbingVisitor::visit_crate_container): New.
        (GlobbingVisitor::visit): Remove privacy check as it is wrong.
        * resolve/rust-finalize-imports-2.0.h: Declare new methods.
        * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::go): Handle 
crates.
        (TopLevel::visit): Use new insert_glob_container API.
        * util/rust-hir-map.cc (Mappings::get_ast_crate_by_node_id_raw): New 
private method.
        (Mappings::get_ast_crate_by_node_id): Use it.
        (Mappings::insert_glob_container): New API.
        * util/rust-hir-map.h: Likewise.
        * resolve/rust-early-name-resolver-2.0.cc 
(Early::finalize_glob_import): Likewise.
---
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/f0558a0f18bcca5819c44edef3949cc8d184d4ea

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

 gcc/rust/ast/rust-ast-full-decls.h            |  1 +
 gcc/rust/ast/rust-ast.h                       | 20 ++++-
 gcc/rust/ast/rust-item.h                      | 14 +++-
 .../resolve/rust-early-name-resolver-2.0.cc   |  7 +-
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 77 +++++++++----------
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  3 +-
 .../rust-toplevel-name-resolver-2.0.cc        | 11 ++-
 gcc/rust/util/rust-hir-map.cc                 | 22 ++++--
 gcc/rust/util/rust-hir-map.h                  |  8 +-
 9 files changed, 105 insertions(+), 58 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-full-decls.h 
b/gcc/rust/ast/rust-ast-full-decls.h
index e6eb256fb..f839348c7 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -40,6 +40,7 @@ class AttrInputMetaItemContainer;
 class MetaItem;
 class Stmt;
 class Item;
+class GlobContainer;
 class Expr;
 class ExprWithoutBlock;
 class IdentifierExpr;
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 950774b6e..4d5eddc6a 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1143,6 +1143,19 @@ protected:
   Item *clone_stmt_impl () const final override { return clone_item_impl (); }
 };
 
+class GlobContainer
+{
+public:
+  enum class Kind
+  {
+    Crate,
+    Module,
+    Enum,
+  };
+
+  virtual Kind get_glob_container_kind () const = 0;
+};
+
 // Item that supports visibility - abstract base class
 class VisItem : public Item
 {
@@ -2021,7 +2034,7 @@ public:
 };
 
 // A crate AST object - holds all the data for a single compilation unit
-struct Crate
+struct Crate : public GlobContainer
 {
   std::vector<Attribute> inner_attrs;
   // dodgy spacing required here
@@ -2094,6 +2107,11 @@ public:
   {
     items = std::move (new_items);
   }
+
+  GlobContainer::Kind get_glob_container_kind () const override
+  {
+    return GlobContainer::Kind::Crate;
+  }
 };
 
 } // namespace AST
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index aaa541c4e..234797824 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -750,7 +750,7 @@ public:
 };
 
 // Rust module item - abstract base class
-class Module : public VisItem
+class Module : public VisItem, public GlobContainer
 {
 public:
   // Type of the current module. A module can be either loaded or unloaded,
@@ -911,6 +911,11 @@ protected:
   /* Use covariance to implement clone function as returning this object
    * rather than base */
   Module *clone_item_impl () const override { return new Module (*this); }
+
+  GlobContainer::Kind get_glob_container_kind () const override
+  {
+    return GlobContainer::Kind::Module;
+  }
 };
 
 // Rust extern crate declaration AST node
@@ -2247,7 +2252,7 @@ protected:
 };
 
 // AST node for Rust "enum" - tagged union
-class Enum : public VisItem
+class Enum : public VisItem, public GlobContainer
 {
   Identifier enum_name;
 
@@ -2357,6 +2362,11 @@ public:
 
   Item::Kind get_item_kind () const override { return Item::Kind::Enum; }
 
+  GlobContainer::Kind get_glob_container_kind () const override
+  {
+    return GlobContainer::Kind::Enum;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object
    * rather than base */
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 9e0e6a258..fe40bcd7f 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -19,6 +19,7 @@
 #include "rust-early-name-resolver-2.0.h"
 #include "optional.h"
 #include "options.h"
+#include "rust-ast.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-map.h"
 #include "rust-item.h"
@@ -413,10 +414,10 @@ Early::finalize_glob_import (NameResolutionContext &ctx,
 
   if (mapping.import_kind.is_prelude)
     {
-      rust_assert (container.value ()->get_item_kind ()
-                  == AST::Item::Kind::Module);
+      rust_assert (container.value ()->get_glob_container_kind ()
+                  == AST::GlobContainer::Kind::Module);
 
-      ctx.prelude = container.value ()->get_node_id ();
+      ctx.prelude = mapping.data.container ().get_node_id ();
     }
 
   GlobbingVisitor (ctx).go (container.value ());
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index 858fbce2b..5feb44070 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -28,14 +28,17 @@ namespace Rust {
 namespace Resolver2_0 {
 
 void
-GlobbingVisitor::go (AST::Item *container)
+GlobbingVisitor::go (AST::GlobContainer *container)
 {
-  switch (container->get_item_kind ())
+  switch (container->get_glob_container_kind ())
     {
-    case AST::Item::Kind::Module:
+    case AST::GlobContainer::Kind::Module:
       visit_module_container (static_cast<AST::Module &> (*container));
       break;
-    case AST::Item::Kind::Enum:
+    case AST::GlobContainer::Kind::Crate:
+      visit_crate_container (static_cast<AST::Crate &> (*container));
+      break;
+    case AST::GlobContainer::Kind::Enum:
       visit_enum_container (static_cast<AST::Enum &> (*container));
       break;
     default:
@@ -43,6 +46,13 @@ GlobbingVisitor::go (AST::Item *container)
     }
 }
 
+void
+GlobbingVisitor::visit_crate_container (AST::Crate &crate)
+{
+  for (auto &i : crate.items)
+    visit (i);
+}
+
 void
 GlobbingVisitor::visit_module_container (AST::Module &module)
 {
@@ -61,83 +71,70 @@ GlobbingVisitor::visit_enum_container (AST::Enum &item)
 void
 GlobbingVisitor::visit (AST::Module &module)
 {
-  if (module.get_visibility ().is_public ())
-    ctx.insert_globbed (module.get_name (), module.get_node_id (),
-                       Namespace::Types);
+  ctx.insert_globbed (module.get_name (), module.get_node_id (),
+                     Namespace::Types);
 }
 
 void
 GlobbingVisitor::visit (AST::MacroRulesDefinition &macro)
 {
-  if (macro.get_visibility ().is_public ())
-    ctx.insert_globbed (macro.get_rule_name (), macro.get_node_id (),
-                       Namespace::Macros);
+  ctx.insert_globbed (macro.get_rule_name (), macro.get_node_id (),
+                     Namespace::Macros);
 }
 
 void
 GlobbingVisitor::visit (AST::Function &function)
 {
-  if (function.get_visibility ().is_public ())
-    ctx.insert_globbed (function.get_function_name (), function.get_node_id (),
-                       Namespace::Values);
+  ctx.insert_globbed (function.get_function_name (), function.get_node_id (),
+                     Namespace::Values);
 }
 
 void
 GlobbingVisitor::visit (AST::StaticItem &static_item)
 {
-  if (static_item.get_visibility ().is_public ())
-    ctx.insert_globbed (static_item.get_identifier (),
-                       static_item.get_node_id (), Namespace::Values);
+  ctx.insert_globbed (static_item.get_identifier (), static_item.get_node_id 
(),
+                     Namespace::Values);
 }
 
 void
 GlobbingVisitor::visit (AST::StructStruct &struct_item)
 {
-  if (struct_item.get_visibility ().is_public ())
-    {
-      ctx.insert_globbed (struct_item.get_identifier (),
-                         struct_item.get_node_id (), Namespace::Types);
-      if (struct_item.is_unit_struct ())
-       ctx.insert_globbed (struct_item.get_identifier (),
-                           struct_item.get_node_id (), Namespace::Values);
-    }
+  ctx.insert_globbed (struct_item.get_identifier (), struct_item.get_node_id 
(),
+                     Namespace::Types);
+  if (struct_item.is_unit_struct ())
+    ctx.insert_globbed (struct_item.get_identifier (),
+                       struct_item.get_node_id (), Namespace::Values);
 }
 
 void
 GlobbingVisitor::visit (AST::TupleStruct &tuple_struct)
 {
-  if (tuple_struct.get_visibility ().is_public ())
-    {
-      ctx.insert_globbed (tuple_struct.get_identifier (),
-                         tuple_struct.get_node_id (), Namespace::Types);
+  ctx.insert_globbed (tuple_struct.get_identifier (),
+                     tuple_struct.get_node_id (), Namespace::Types);
 
-      ctx.insert_globbed (tuple_struct.get_identifier (),
-                         tuple_struct.get_node_id (), Namespace::Values);
-    }
+  ctx.insert_globbed (tuple_struct.get_identifier (),
+                     tuple_struct.get_node_id (), Namespace::Values);
 }
 
 void
 GlobbingVisitor::visit (AST::Enum &enum_item)
 {
-  if (enum_item.get_visibility ().is_public ())
-    ctx.insert_globbed (enum_item.get_identifier (), enum_item.get_node_id (),
-                       Namespace::Types);
+  ctx.insert_globbed (enum_item.get_identifier (), enum_item.get_node_id (),
+                     Namespace::Types);
 }
 
 void
 GlobbingVisitor::visit (AST::Union &union_item)
 {
-  if (union_item.get_visibility ().is_public ())
-    ctx.insert_globbed (union_item.get_identifier (), union_item.get_node_id 
(),
-                       Namespace::Values);
+  ctx.insert_globbed (union_item.get_identifier (), union_item.get_node_id (),
+                     Namespace::Values);
 }
 
 void
 GlobbingVisitor::visit (AST::ConstantItem &const_item)
 {
-  if (const_item.get_visibility ().is_public ())
-    ctx.insert_globbed (const_item.get_identifier (), const_item.get_node_id 
(),
-                       Namespace::Values);
+  ctx.insert_globbed (const_item.get_identifier (), const_item.get_node_id (),
+                     Namespace::Values);
 }
 
 void
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h 
b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index d03f84b79..f4a6b57e1 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -33,8 +33,9 @@ class GlobbingVisitor : public AST::DefaultASTVisitor
 public:
   GlobbingVisitor (NameResolutionContext &ctx) : ctx (ctx) {}
 
-  void go (AST::Item *container);
+  void go (AST::GlobContainer *container);
 
+  void visit_crate_container (AST::Crate &crate);
   void visit_module_container (AST::Module &module);
   void visit_enum_container (AST::Enum &item);
 
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index ed93911fb..98245846d 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -96,6 +96,11 @@ TopLevel::go (AST::Crate &crate)
   // responsible for this ugly and perfom a lot of error checking.
 
   visit (crate);
+
+  if (Analysis::Mappings::get ().lookup_glob_container (crate.get_node_id ())
+      == tl::nullopt)
+    Analysis::Mappings::get ().insert_glob_container (crate.get_node_id (),
+                                                     &crate);
 }
 
 void
@@ -105,7 +110,8 @@ TopLevel::visit (AST::Module &module)
 
   if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ())
       == tl::nullopt)
-    Analysis::Mappings::get ().insert_glob_container (&module);
+    Analysis::Mappings::get ().insert_glob_container (module.get_node_id (),
+                                                     &module);
 }
 
 void
@@ -345,7 +351,8 @@ TopLevel::visit (AST::Enum &enum_item)
   if (Analysis::Mappings::get ().lookup_glob_container (
        enum_item.get_node_id ())
       == tl::nullopt)
-    Analysis::Mappings::get ().insert_glob_container (&enum_item);
+    Analysis::Mappings::get ().insert_glob_container (enum_item.get_node_id (),
+                                                     &enum_item);
 }
 
 void
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 25e6554f5..1f30739a5 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -19,6 +19,7 @@
 #include "rust-hir-map.h"
 #include "optional.h"
 #include "rust-ast-full.h"
+#include "rust-ast.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-full.h"
 #include "rust-item.h"
@@ -250,6 +251,12 @@ Mappings::get_ast_crate (CrateNum crateNum)
 
 AST::Crate &
 Mappings::get_ast_crate_by_node_id (NodeId id)
+{
+  return *get_ast_crate_by_node_id_raw (id);
+}
+
+AST::Crate *
+Mappings::get_ast_crate_by_node_id_raw (NodeId id)
 {
   auto i = crate_node_to_crate_num.find (id);
   rust_assert (i != crate_node_to_crate_num.end ());
@@ -257,7 +264,7 @@ Mappings::get_ast_crate_by_node_id (NodeId id)
   CrateNum crateNum = i->second;
   auto it = ast_crate_mappings.find (crateNum);
   rust_assert (it != ast_crate_mappings.end ());
-  return *it->second;
+  return it->second;
 }
 
 AST::Crate &
@@ -1150,15 +1157,18 @@ Mappings::lookup_module_children (NodeId module)
 }
 
 void
-Mappings::insert_glob_container (AST::Item *container)
+Mappings::insert_glob_container (NodeId id, AST::GlobContainer *container)
 {
-  rust_assert (glob_containers.find (container->get_node_id ())
-              == glob_containers.end ());
+  rust_assert (glob_containers.find (id) == glob_containers.end ());
 
-  glob_containers[container->get_node_id ()] = container;
+  // Crates have different memory managements that regular items
+  if (container->get_glob_container_kind () == AST::GlobContainer::Kind::Crate)
+    glob_containers[id] = get_ast_crate_by_node_id_raw (id);
+  else
+    glob_containers[id] = container;
 }
 
-tl::optional<AST::Item *>
+tl::optional<AST::GlobContainer *>
 Mappings::lookup_glob_container (NodeId id)
 {
   auto it = glob_containers.find (id);
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 67846a9f0..c04e2efb7 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -321,8 +321,8 @@ public:
   void insert_visibility (NodeId id, Privacy::ModuleVisibility visibility);
   tl::optional<Privacy::ModuleVisibility &> lookup_visibility (NodeId id);
 
-  void insert_glob_container (AST::Item *);
-  tl::optional<AST::Item *> lookup_glob_container (NodeId id);
+  void insert_glob_container (NodeId, AST::GlobContainer *);
+  tl::optional<AST::GlobContainer *> lookup_glob_container (NodeId id);
   void insert_module_child (NodeId module, NodeId child);
   tl::optional<std::vector<NodeId> &> lookup_module_children (NodeId module);
 
@@ -363,6 +363,8 @@ private:
   std::map<CrateNum, LocalDefId> localIdIter;
   HIR::ImplBlock *builtinMarker;
 
+  AST::Crate *get_ast_crate_by_node_id_raw (NodeId id);
+
   std::map<NodeId, CrateNum> crate_node_to_crate_num;
   std::map<CrateNum, AST::Crate *> ast_crate_mappings;
   std::map<CrateNum, HIR::Crate *> hir_crate_mappings;
@@ -439,7 +441,7 @@ private:
   std::map<NodeId, std::vector<NodeId>> module_child_map;
   std::map<NodeId, std::vector<Resolver::CanonicalPath>> module_child_items;
   std::map<NodeId, NodeId> child_to_parent_module_map;
-  std::map<NodeId, AST::Item *> glob_containers;
+  std::map<NodeId, AST::GlobContainer *> glob_containers;
 
   // AST mappings
   std::map<NodeId, AST::Item *> ast_item_mappings;

base-commit: 17231c82d4b1d56e93d6ade92b1dfa80b4c2c2e8
-- 
2.52.0

Reply via email to