aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-name-resolution-context.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-name-resolution-context.h')
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h72
1 files changed, 24 insertions, 48 deletions
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index 10318b1..aab04cc 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -23,6 +23,7 @@
#include "rust-forever-stack.h"
#include "rust-hir-map.h"
#include "rust-rib.h"
+#include "rust-stacked-contexts.h"
namespace Rust {
namespace Resolver2_0 {
@@ -169,72 +170,47 @@ struct Binding
Binding (Binding::Kind kind) : kind (kind) {}
};
+/**
+ * Used to identify the source of a binding, and emit the correct error message.
+ */
enum class BindingSource
{
Match,
Let,
For,
+ /* Closure param or function param */
Param
};
-class BindingContext
+class BindingLayer
{
- // FIXME: Use std::vector<std::vector<Binding>> to handle nested patterns
- std::vector<Binding> bindings;
-
BindingSource source;
+ std::vector<Binding> bindings;
- 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;
- }
+ bool bind_test (Identifier ident, Binding::Kind kind);
public:
- bool and_binded (Identifier ident)
- {
- return bind_test (ident, Binding::Kind::Product);
- }
+ void push (Binding::Kind kind);
- bool or_binded (Identifier ident)
- {
- return bind_test (ident, Binding::Kind::Or);
- }
+ BindingLayer (BindingSource source);
- void insert_ident (Identifier ident) { bindings.back ().set.insert (ident); }
+ /**
+ * Identifies if the identifier has been used in a product binding context.
+ * eg. `let (a, a) = test();`
+ */
+ bool is_and_bound (Identifier ident);
- void push (Binding::Kind kind) { bindings.push_back (Binding (kind)); }
+ /**
+ * Identifies if the identifier has been used in a or context.
+ * eg. `let (a, 1) | (a, 2) = test()`
+ */
+ bool is_or_bound (Identifier ident);
- void new_binding (BindingSource source)
- {
- rust_assert (bindings.size () == 0);
- this->source = source;
- push (Binding::Kind::Product);
- }
+ void insert_ident (Identifier ident);
- 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);
- }
- }
+ void merge ();
- BindingSource get_source () const { return source; }
+ BindingSource get_source () const;
};
// Now our resolver, which keeps track of all the `ForeverStack`s we could want
@@ -293,7 +269,7 @@ public:
ForeverStack<Namespace::Labels> labels;
Analysis::Mappings &mappings;
- BindingContext bindings;
+ StackedContexts<BindingLayer> bindings;
// TODO: Rename
// TODO: Use newtype pattern for Usage and Definition