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 ¯o)
{
- 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