From: Owen Avery <[email protected]>

gcc/rust/ChangeLog:

        * resolve/rust-finalize-imports-2.0.cc
        (GlobbingVisitor::glob_definitions): Offload details to
        Rib::insert_globbed.
        (GlobbingVisitor::glob_definition): Remove member function
        definition.
        * resolve/rust-finalize-imports-2.0.h
        (GlobbingVisitor::glob_definition): Remove member function
        declaration.
        * resolve/rust-rib.cc (Rib::insert_globbed): New member function
        definition.
        * resolve/rust-rib.h (Rib::insert_globbed): New member function
        declaration.

gcc/testsuite/ChangeLog:

        * rust/compile/glob-import-ambiguous.rs: New test.

Signed-off-by: Owen Avery <[email protected]>
---
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/7791037cb7f88f24634039e062ca4f0382a13504

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/4726

 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 23 +------------
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  2 --
 gcc/rust/resolve/rust-rib.cc                  | 34 +++++++++++++++++++
 gcc/rust/resolve/rust-rib.h                   | 10 ++++++
 .../rust/compile/glob-import-ambiguous.rs     | 26 ++++++++++++++
 5 files changed, 71 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/glob-import-ambiguous.rs

diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index 7fbbb921a..06e61a04c 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -68,28 +68,7 @@ void
 GlobbingVisitor::glob_definitions (Rib &dst, Rib &src)
 {
   for (auto &ent : src.get_values ())
-    {
-      auto globbed = glob_definition (ent.second);
-      if (globbed.has_value ())
-       {
-         auto res = dst.insert (ent.first, globbed.value ());
-         // inserting a globbed definition should (?) always succeed
-         // TODO: double check
-         rust_assert (res.has_value ()
-                      || res.error ().existing
-                           == globbed.value ().get_node_id ());
-         dirty |= res.has_value ();
-       }
-    }
-}
-
-tl::optional<Rib::Definition>
-GlobbingVisitor::glob_definition (const Rib::Definition &def)
-{
-  // TODO: normal error?
-  rust_assert (!def.is_ambiguous ());
-
-  return Rib::Definition::Globbed (def.get_node_id ());
+    dirty |= dst.insert_globbed (ent.first, ent.second);
 }
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h 
b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index dfbd1fe9a..4e3c1e92d 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -39,8 +39,6 @@ public:
 
   void glob_definitions (Rib &dst, Rib &src);
 
-  tl::optional<Rib::Definition> glob_definition (const Rib::Definition &def);
-
   bool is_dirty () const { return dirty; }
 
 private:
diff --git a/gcc/rust/resolve/rust-rib.cc b/gcc/rust/resolve/rust-rib.cc
index 73e7f70e5..5ddd0293d 100644
--- a/gcc/rust/resolve/rust-rib.cc
+++ b/gcc/rust/resolve/rust-rib.cc
@@ -174,6 +174,40 @@ Rib::insert (std::string name, Definition def)
   return def.ids_globbed.back ();
 }
 
+bool
+Rib::insert_globbed (std::string name, const Definition &def)
+{
+  bool dirty = false;
+
+  const std::vector<NodeId> *ids_src;
+
+  if (!def.ids_shadowable.empty ())
+    ids_src = &def.ids_shadowable;
+  else if (!def.ids_non_shadowable.empty ())
+    ids_src = &def.ids_non_shadowable;
+  else
+    ids_src = &def.ids_globbed;
+
+  auto it = values.find (name);
+  if (it == values.end ())
+    {
+      values[name].ids_globbed = *ids_src;
+      return true;
+    }
+
+  for (NodeId id : *ids_src)
+    {
+      auto &ids_dst = it->second.ids_globbed;
+      if (std::find (ids_dst.cbegin (), ids_dst.cend (), id) == ids_dst.cend 
())
+       {
+         dirty = true;
+         ids_dst.push_back (id);
+       }
+    }
+
+  return dirty;
+}
+
 tl::optional<Rib::Definition>
 Rib::get (const std::string &name)
 {
diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h
index c5de20bc8..96d122093 100644
--- a/gcc/rust/resolve/rust-rib.h
+++ b/gcc/rust/resolve/rust-rib.h
@@ -245,6 +245,16 @@ public:
   tl::expected<NodeId, DuplicateNameError> insert (std::string name,
                                                   Definition def);
 
+  /**
+   * Insert a new node, but as a glob import, in the rib
+   *
+   * @param name The name associated with the AST node
+   * @param def The `Definition` to insert
+   *
+   * @return true if the insertion wasn't redundant
+   */
+  bool insert_globbed (std::string name, const Definition &def);
+
   /**
    * Access an inserted NodeId.
    *
diff --git a/gcc/testsuite/rust/compile/glob-import-ambiguous.rs 
b/gcc/testsuite/rust/compile/glob-import-ambiguous.rs
new file mode 100644
index 000000000..62be7dab0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/glob-import-ambiguous.rs
@@ -0,0 +1,26 @@
+#![feature(no_core)]
+#![no_core]
+
+mod a {
+    pub fn x() {}
+    pub fn y() {}
+}
+
+mod b {
+    pub fn x() {}
+    pub fn z() {}
+}
+
+mod c {
+    pub use crate::a::*;
+    pub use crate::b::*;
+}
+
+pub fn main() -> i32 {
+    use crate::c::*;
+    a::x();
+    b::x();
+    y();
+    z();
+    0
+}

base-commit: 57f5c23a9b9246a2d96679c3939c86ffe896c066
-- 
2.54.0

Reply via email to