From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

We need to differentiate bindings types, so the same binding cannot be
reused multiple time in a product binding.

gcc/rust/ChangeLog:

        * resolve/rust-name-resolution-context.h (struct Binding): Add Binding
        struct to differentiate Or and Product bindings in patterns.
        (enum class): Add Binding kind.
        (class BindingContext): Add binding context with Binding stack.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
---
 .../resolve/rust-name-resolution-context.h    | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index 51c08efe3df..d0736bcd1ba 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -156,6 +156,87 @@ public:
   NodeId id;
 };
 
+struct Binding
+{
+  enum class Kind
+  {
+    Product,
+    Or,
+  } kind;
+
+  std::unordered_set<Identifier> set;
+
+  Binding (Binding::Kind kind) : kind (kind) {}
+};
+
+enum class BindingSource
+{
+  Match,
+  Let,
+  For,
+  Param
+};
+
+class BindingContext
+{
+  // FIXME: Use std::vector<std::vector<Binding>> to handle nested patterns
+  std::vector<Binding> bindings;
+
+  BindingSource source;
+
+  bool bind_test (Identifier ident, Binding::Kind kind)
+  {
+    for (auto &bind : bindings)
+      {
+       if (bind.set.find (ident) != bind.set.cend () && bind.kind == kind)
+         {
+           return true;
+         }
+      }
+    return false;
+  }
+
+public:
+  bool and_binded (Identifier ident)
+  {
+    return bind_test (ident, Binding::Kind::Product);
+  }
+
+  bool or_binded (Identifier ident)
+  {
+    return bind_test (ident, Binding::Kind::Or);
+  }
+
+  void insert_ident (Identifier ident) { bindings.back ().set.insert (ident); }
+
+  void push (Binding::Kind kind) { bindings.push_back (Binding (kind)); }
+
+  void new_binding (BindingSource source)
+  {
+    rust_assert (bindings.size () == 0);
+    this->source = source;
+    push (Binding::Kind::Product);
+  }
+
+  void clear ()
+  {
+    rust_assert (bindings.size () == 1);
+    bindings.clear ();
+  }
+
+  void merge ()
+  {
+    auto last_binding = bindings.back ();
+    bindings.pop_back ();
+    for (auto &value : last_binding.set)
+      {
+       bindings.back ().set.insert (value);
+      }
+  }
+
+  BindingSource get_source () const { return source; }
+};
+
 // Now our resolver, which keeps track of all the `ForeverStack`s we could want
 class NameResolutionContext
 {
-- 
2.49.0

Reply via email to