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 05b2b56b0df..17847968e02 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -517,6 +517,33 @@ resolve_type_path_like (NameResolutionContext &ctx, bool block_big_self, "declared identifiers"); } + if (Analysis::Mappings::get ().is_module (resolved->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)); + + // 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)); + } + 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->get_node_id ())); } diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc b/gcc/rust/resolve/rust-name-resolution-context.cc index 45b78cb899f..ed3324359d9 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.cc +++ b/gcc/rust/resolve/rust-name-resolution-context.cc @@ -252,10 +252,10 @@ NameResolutionContext::insert_globbed (Identifier name, NodeId id, Namespace ns) void NameResolutionContext::map_usage (Usage usage, Definition definition) { - auto inserted = resolved_nodes.emplace (usage, definition).second; + resolved_nodes[usage] = definition; - // is that valid? - rust_assert (inserted); + // TODO: Are reinsertions okay? + // rust_assert (inserted); } tl::optional diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index 2d1ce3117b5..261021189aa 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -153,6 +153,7 @@ class Usage 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 98245846d43..e7f2bd22aa6 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc @@ -106,12 +106,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 1f30739a5ed..87304acdde1 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 c04e2efb7a4..c89c686c276 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -323,6 +323,10 @@ class Mappings 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); @@ -438,10 +442,13 @@ class Mappings // 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" } +}