https://gcc.gnu.org/g:55e8094a286be16f138d78d618ab461d2340bec5

commit r16-229-g55e8094a286be16f138d78d618ab461d2340bec5
Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
Date:   Sun Apr 6 17:09:42 2025 +0200

    gccrs: Add binding context class
    
    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>

Diff:
---
 gcc/rust/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 51c08efe3df6..d0736bcd1baa 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
 {

Reply via email to