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