https://gcc.gnu.org/g:954ff2f1d0844557fc70eedbc77936f63b9dc378
commit r17-1898-g954ff2f1d0844557fc70eedbc77936f63b9dc378 Author: Arthur Cohen <[email protected]> Date: Wed Jan 21 19:00:17 2026 +0100 gccrs: nr: Add modules to types NS gcc/rust/ChangeLog: * util/rust-hir-map.cc (Mappings::insert_module_id): New function. (Mappings::is_module): Likewise. * util/rust-hir-map.h: Store a set of AST modules, declare functions for adding and retrieving them. * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Insert modules in the type namespace and store them in mappings. * resolve/rust-late-name-resolver-2.0.cc (resolve_type_path_like): Error out when an expected type resolves to a module. * resolve/rust-name-resolution.h: Add empty Definition constructor. * resolve/rust-resolve-builtins.cc (find_builtin_node_id): New function. * resolve/rust-resolve-builtins.h: Declare it. gcc/testsuite/ChangeLog: * rust/compile/mod_in_types_ns.rs: New test. * rust/compile/mod_in_types_ns2.rs: New test. Diff: --- gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 28 ++++++++++++++++++++++ gcc/rust/resolve/rust-name-resolution.h | 3 +++ gcc/rust/resolve/rust-resolve-builtins.cc | 10 ++++++++ gcc/rust/resolve/rust-resolve-builtins.h | 6 +++++ .../resolve/rust-toplevel-name-resolver-2.0.cc | 8 +++++-- gcc/rust/util/rust-hir-map.cc | 12 ++++++++++ gcc/rust/util/rust-hir-map.h | 7 ++++++ gcc/testsuite/rust/compile/mod_in_types_ns.rs | 8 +++++++ gcc/testsuite/rust/compile/mod_in_types_ns2.rs | 8 +++++++ 9 files changed, 88 insertions(+), 2 deletions(-) diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc index 20d8bc8c28fd..c6ae6ffa1bf0 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -537,6 +537,34 @@ resolve_type_path_like (NameResolutionContext &ctx, bool block_big_self, "declared identifiers"); } + if (Analysis::Mappings::get ().is_module ( + resolved->definition.get_node_id ())) + { + if (type.get_segments ().size () == 1) + { + if (auto resolved + = Builtins::find_builtin_node_id (type.as_string ())) + { + ctx.map_usage (Usage (type.get_node_id ()), + Definition (*resolved), Namespace::Types); + + // In that specific case, we also override the segment resolution + // as it causes issues later down the line during typechecking + ctx.map_usage (Usage (unwrap_segment_node_id ( + type.get_segments ().front ())), + Definition (*resolved), Namespace::Types); + } + else + { + rust_error_at (type.get_locus (), ErrorCode::E0573, + "expected type, found module %qs", + unwrap_segment_error_string (type).c_str ()); + } + } + + return; + } + ctx.map_usage (Usage (type.get_node_id ()), Definition (resolved->definition.get_node_id ()), Namespace::Types); diff --git a/gcc/rust/resolve/rust-name-resolution.h b/gcc/rust/resolve/rust-name-resolution.h index 6d5b4ec874d0..8506d18977d5 100644 --- a/gcc/rust/resolve/rust-name-resolution.h +++ b/gcc/rust/resolve/rust-name-resolution.h @@ -19,6 +19,8 @@ #ifndef RUST_NAME_RESOLVER_2_0_H #define RUST_NAME_RESOLVER_2_0_H +#include "rust-mapping-common.h" + namespace Rust { namespace Resolver2_0 { @@ -39,6 +41,7 @@ public: class Definition { public: + explicit Definition () : id (UNKNOWN_NODEID) {} explicit Definition (NodeId id) : id (id) {} NodeId id; diff --git a/gcc/rust/resolve/rust-resolve-builtins.cc b/gcc/rust/resolve/rust-resolve-builtins.cc index c42b0e745dec..7665d45152aa 100644 --- a/gcc/rust/resolve/rust-resolve-builtins.cc +++ b/gcc/rust/resolve/rust-resolve-builtins.cc @@ -120,6 +120,16 @@ setup_type_ctx () unit_type); } +tl::optional<NodeId> +find_builtin_node_id (const std::string &name) +{ + for (size_t i = 0; i < builtin_count; i++) + if (strcmp (name.c_str (), builtin_names[i]) == 0) + return builtin_node_ids[i]; + + return tl::nullopt; +} + } // namespace Builtins } // namespace Resolver2_0 } // namespace Rust diff --git a/gcc/rust/resolve/rust-resolve-builtins.h b/gcc/rust/resolve/rust-resolve-builtins.h index d3ced39633e8..cd0ebeec2c8d 100644 --- a/gcc/rust/resolve/rust-resolve-builtins.h +++ b/gcc/rust/resolve/rust-resolve-builtins.h @@ -19,6 +19,9 @@ #ifndef RUST_RESOLVE_BUILTINS_H #define RUST_RESOLVE_BUILTINS_H +#include "optional.h" +#include "rust-ast.h" + namespace Rust { namespace Resolver2_0 { @@ -30,6 +33,9 @@ namespace Builtins { void setup_lang_prelude (NameResolutionContext &ctx); void setup_type_ctx (); +// Return the NodeId associated with a builtin type name if it exists +tl::optional<NodeId> find_builtin_node_id (const std::string &name); + } // namespace Builtins } // namespace Resolver2_0 } // namespace Rust 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 84961ae2e594..60426122a24f 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc @@ -107,12 +107,16 @@ TopLevel::go (AST::Crate &crate) void TopLevel::visit (AST::Module &module) { - DefaultResolver::visit (module); - if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ()) == tl::nullopt) Analysis::Mappings::get ().insert_glob_container (module.get_node_id (), &module); + + insert_or_error_out (module.get_name (), module, Namespace::Types); + + Analysis::Mappings::get ().insert_module_id (module.get_node_id ()); + + DefaultResolver::visit (module); } void diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index 2f804e48d789..f5ad6db55471 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -1168,6 +1168,18 @@ Mappings::insert_glob_container (NodeId id, AST::GlobContainer *container) glob_containers[id] = container; } +void +Mappings::insert_module_id (NodeId id) +{ + module_ids.insert (id); +} + +bool +Mappings::is_module (NodeId id) +{ + return module_ids.find (id) != module_ids.end (); +} + tl::optional<AST::GlobContainer *> Mappings::lookup_glob_container (NodeId id) { diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index 7012dd5c2e04..a1544a15283f 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -323,6 +323,10 @@ public: void insert_glob_container (NodeId, AST::GlobContainer *); tl::optional<AST::GlobContainer *> lookup_glob_container (NodeId id); + + void insert_module_id (NodeId); + bool is_module (NodeId id); + void insert_module_child (NodeId module, NodeId child); tl::optional<std::vector<NodeId> &> lookup_module_children (NodeId module); @@ -441,10 +445,13 @@ private: // Module tree maps // Maps each module's node id to a list of its children + // TODO: I think these are only used by the old resolved and can be removed 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::GlobContainer *> glob_containers; + std::set<NodeId> module_ids; // AST mappings std::map<NodeId, AST::Item *> ast_item_mappings; diff --git a/gcc/testsuite/rust/compile/mod_in_types_ns.rs b/gcc/testsuite/rust/compile/mod_in_types_ns.rs new file mode 100644 index 000000000000..3c3edcde50eb --- /dev/null +++ b/gcc/testsuite/rust/compile/mod_in_types_ns.rs @@ -0,0 +1,8 @@ +#![feature(no_core)] +#![no_core] + +mod foo { + mod bar {} + + struct bar; // { dg-error "defined multiple times" } +} diff --git a/gcc/testsuite/rust/compile/mod_in_types_ns2.rs b/gcc/testsuite/rust/compile/mod_in_types_ns2.rs new file mode 100644 index 000000000000..75f0424861ee --- /dev/null +++ b/gcc/testsuite/rust/compile/mod_in_types_ns2.rs @@ -0,0 +1,8 @@ +#![feature(no_core)] +#![no_core] + +mod foo { + mod bar {} + + fn baz() -> bar {} // { dg-error "expected type, found module" } +}
