[gccrs COMMIT] gccrs: Handle ambiguous glob imports

[email protected]
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.