https://gcc.gnu.org/g:168b1ecd8f2bf57c680859e4ede8295cc0b12d43
commit r16-7773-g168b1ecd8f2bf57c680859e4ede8295cc0b12d43 Author: Arthur Cohen <[email protected]> Date: Thu Dec 25 11:16:22 2025 +0100 gccrs: ast: Add new GlobContainer class and use it 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. Diff: --- gcc/rust/ast/rust-ast-full-decls.h | 1 + gcc/rust/ast/rust-ast.h | 20 +++++- gcc/rust/ast/rust-item.h | 14 +++- gcc/rust/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 +- .../resolve/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 e6eb256fb921..f839348c7f5a 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 950774b6eb83..4d5eddc6a66c 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 aaa541c4e933..2347978244cd 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 9e0e6a258789..fe40bcd7f6e0 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 858fbce2b29e..5feb44070524 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 d03f84b79468..f4a6b57e1e4c 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 ed93911fbab1..98245846d43c 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 25e6554f5728..1f30739a5edf 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 67846a9f0dac..c04e2efb7a40 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;
