From: Arthur Cohen Date: Wed, 21 Jan 2026 18:00:17 +0000 (+0100) Subject: gccrs: nr: Add modules to types NS X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=954ff2f1d0844557fc70eedbc77936f63b9dc378;p=thirdparty%2Fgcc.git 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 --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc index 20d8bc8c28f..c6ae6ffa1bf 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 6d5b4ec874d..8506d18977d 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 c42b0e745de..7665d45152a 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 +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 d3ced39633e..cd0ebeec2c8 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 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 84961ae2e59..60426122a24 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 2f804e48d78..f5ad6db5547 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 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 7012dd5c2e0..a1544a15283 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 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 &> 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> module_child_map; std::map> module_child_items; std::map child_to_parent_module_map; + std::map glob_containers; + std::set module_ids; // AST mappings std::map 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 00000000000..3c3edcde50e --- /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 00000000000..75f0424861e --- /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" } +}