From: Arthur Cohen <[email protected]>

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.
---
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/ddad6c8ba4fdb8e6117e5fb441f4b50eda15d2f4

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4404

 .../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 ++++
 .../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 ++++++
 .../rust/compile/mod_in_types_ns2.rs          |  8 ++++++
 9 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/mod_in_types_ns.rs
 create mode 100644 gcc/testsuite/rust/compile/mod_in_types_ns2.rs

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 20d8bc8c2..c6ae6ffa1 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 6d5b4ec87..8506d1897 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 c42b0e745..7665d4515 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 d3ced3963..cd0ebeec2 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 84961ae2e..60426122a 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 2f804e48d..f5ad6db55 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 7012dd5c2..a1544a152 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 000000000..3c3edcde5
--- /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 000000000..75f042486
--- /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" }
+}

base-commit: 035002f8a79e872ddcb80c1d372637b561c9c854
-- 
2.54.0

Reply via email to