aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2025-04-06 18:17:41 +0200
committerP-E-P <32375388+P-E-P@users.noreply.github.com>2025-04-24 16:53:44 +0000
commit5d6320ceb3b00a7ea6b988ec55c772f563dfd675 (patch)
tree4ed20c6a233d38f090964f68f0fb7e8920ccf5e4
parentca4175b0e5c86d864d973875f7bb793bdcd2c7dd (diff)
downloadgcc-5d6320ceb3b00a7ea6b988ec55c772f563dfd675.zip
gcc-5d6320ceb3b00a7ea6b988ec55c772f563dfd675.tar.gz
gcc-5d6320ceb3b00a7ea6b988ec55c772f563dfd675.tar.bz2
Add pattern bindings
gcc/rust/ChangeLog: * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add binding creation in visitor. * resolve/rust-late-name-resolver-2.0.h: Add function prototypes. * resolve/rust-name-resolution-context.h: Add binding context. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc155
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h5
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h1
3 files changed, 156 insertions, 5 deletions
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index a86f196..a452d44 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -129,6 +129,54 @@ Late::new_label (Identifier name, NodeId id)
}
void
+Late::visit (AST::ForLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+
+ ctx.bindings.new_binding (BindingSource::For);
+
+ visit (expr.get_pattern ());
+
+ ctx.bindings.clear ();
+
+ visit (expr.get_iterator_expr ());
+ visit (expr.get_loop_label ());
+ visit (expr.get_loop_block ());
+}
+
+void
+Late::visit (AST::IfLetExpr &expr)
+{
+ visit_outer_attrs (expr);
+
+ ctx.bindings.new_binding (BindingSource::Let);
+
+ for (auto &pattern : expr.get_patterns ())
+ visit (pattern);
+
+ ctx.bindings.clear ();
+
+ visit (expr.get_value_expr ());
+ visit (expr.get_if_block ());
+}
+
+void
+Late::visit (AST::MatchArm &arm)
+{
+ visit_outer_attrs (arm);
+
+ ctx.bindings.new_binding (BindingSource::Match);
+
+ for (auto &pattern : arm.get_patterns ())
+ visit (pattern);
+
+ ctx.bindings.clear ();
+
+ if (arm.has_match_arm_guard ())
+ visit (arm.get_guard_expr ());
+}
+
+void
Late::visit (AST::LetStmt &let)
{
DefaultASTVisitor::visit_outer_attrs (let);
@@ -138,8 +186,13 @@ Late::visit (AST::LetStmt &let)
// this makes variable shadowing work properly
if (let.has_init_expr ())
visit (let.get_init_expr ());
+
+ ctx.bindings.new_binding (BindingSource::Let);
+
visit (let.get_pattern ());
+ ctx.bindings.clear ();
+
if (let.has_else_expr ())
visit (let.get_init_expr ());
@@ -167,9 +220,80 @@ Late::visit (AST::IdentifierPattern &identifier)
// but values does not allow shadowing... since functions cannot shadow
// do we insert functions in labels as well?
- // We do want to ignore duplicated data because some situations rely on it.
- std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
- identifier.get_node_id ());
+ if (ctx.bindings.and_binded (identifier.get_ident ()))
+ {
+ if (ctx.bindings.get_source () == BindingSource::Param)
+ rust_error_at (
+ identifier.get_locus (), ErrorCode::E0415,
+ "identifier %qs is bound more than once in the same parameter list",
+ identifier.as_string ().c_str ());
+ else
+ rust_error_at (
+ identifier.get_locus (), ErrorCode::E0416,
+ "identifier %qs is bound more than once in the same pattern",
+ identifier.as_string ().c_str ());
+ return;
+ }
+
+ ctx.bindings.insert_ident (identifier.get_ident ());
+
+ if (ctx.bindings.or_binded (identifier.get_ident ()))
+ {
+ // FIXME: map usage instead
+ std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
+ identifier.get_node_id ());
+ }
+ else
+ {
+ // We do want to ignore duplicated data because some situations rely on
+ // it.
+ std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
+ identifier.get_node_id ());
+ }
+}
+
+void
+Late::visit (AST::AltPattern &pattern)
+{
+ ctx.bindings.push (Binding::Kind::Or);
+ for (auto &alt : pattern.get_alts ())
+ {
+ ctx.bindings.push (Binding::Kind::Product);
+ visit (alt);
+ ctx.bindings.merge ();
+ }
+ ctx.bindings.merge ();
+}
+
+void
+Late::visit (AST::Function &function)
+{
+ auto def_fn = [this, &function] () {
+ visit_outer_attrs (function);
+ visit (function.get_visibility ());
+ visit (function.get_qualifiers ());
+ for (auto &generic : function.get_generic_params ())
+ visit (generic);
+
+ // We only care about params
+ ctx.bindings.new_binding (BindingSource::Param);
+
+ for (auto &param : function.get_function_params ())
+ visit (param);
+
+ ctx.bindings.clear ();
+
+ // Back to regular visit
+
+ if (function.has_return_type ())
+ visit (function.get_return_type ());
+ if (function.has_where_clause ())
+ visit (function.get_where_clause ());
+ if (function.has_body ())
+ visit (*function.get_definition ());
+ };
+
+ ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
}
void
@@ -525,14 +649,35 @@ void
Late::visit (AST::ClosureExprInner &closure)
{
add_captures (closure, ctx);
- DefaultResolver::visit (closure);
+
+ visit_outer_attrs (closure);
+
+ ctx.bindings.new_binding (BindingSource::Param);
+
+ for (auto &param : closure.get_params ())
+ visit (param);
+
+ ctx.bindings.clear ();
+
+ visit (closure.get_definition_expr ());
}
void
Late::visit (AST::ClosureExprInnerTyped &closure)
{
add_captures (closure, ctx);
- DefaultResolver::visit (closure);
+
+ visit_outer_attrs (closure);
+
+ ctx.bindings.new_binding (BindingSource::Param);
+
+ for (auto &param : closure.get_params ())
+ visit (param);
+
+ ctx.bindings.clear ();
+
+ visit (closure.get_return_type ());
+ visit (closure.get_definition_block ());
}
} // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 34f3c28..90113f2 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -43,7 +43,12 @@ public:
// void visit (AST::Method &) override;
void visit (AST::IdentifierPattern &) override;
void visit (AST::StructPatternFieldIdent &) override;
+ void visit (AST::AltPattern &) override;
+ void visit (AST::Function &) override;
void visit (AST::SelfParam &) override;
+ void visit (AST::MatchArm &) override;
+ void visit (AST::ForLoopExpr &) override;
+ void visit (AST::IfLetExpr &) override;
// resolutions
void visit (AST::IdentifierExpr &) override;
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index cb2df64..10318b1 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -293,6 +293,7 @@ public:
ForeverStack<Namespace::Labels> labels;
Analysis::Mappings &mappings;
+ BindingContext bindings;
// TODO: Rename
// TODO: Use newtype pattern for Usage and Definition