diff options
Diffstat (limited to 'gcc/rust/resolve/rust-late-name-resolver-2.0.cc')
-rw-r--r-- | gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 206 |
1 files changed, 187 insertions, 19 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 7d32374..6ec0422 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.enter (BindingSource::For); + + visit (expr.get_pattern ()); + + ctx.bindings.exit (); + + 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.enter (BindingSource::Let); + + for (auto &pattern : expr.get_patterns ()) + visit (pattern); + + ctx.bindings.exit (); + + visit (expr.get_value_expr ()); + visit (expr.get_if_block ()); +} + +void +Late::visit (AST::MatchArm &arm) +{ + visit_outer_attrs (arm); + + ctx.bindings.enter (BindingSource::Match); + + for (auto &pattern : arm.get_patterns ()) + visit (pattern); + + ctx.bindings.exit (); + + 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.enter (BindingSource::Let); + visit (let.get_pattern ()); + ctx.bindings.exit (); + if (let.has_else_expr ()) visit (let.get_init_expr ()); @@ -167,9 +220,68 @@ Late::visit (AST::IdentifierPattern &identifier) // but values does not allow shadowing... since functions cannot shadow // do we insert functions in labels as well? + if (ctx.bindings.peek ().is_and_bound (identifier.get_ident ())) + { + if (ctx.bindings.peek ().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.peek ().insert_ident (identifier.get_ident ()); + + if (ctx.bindings.peek ().is_or_bound (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.peek ().push (Binding::Kind::Or); + for (auto &alt : pattern.get_alts ()) + { + ctx.bindings.peek ().push (Binding::Kind::Product); + visit (alt); + ctx.bindings.peek ().merge (); + } + ctx.bindings.peek ().merge (); +} + +void +Late::visit_function_params (AST::Function &function) +{ + ctx.bindings.enter (BindingSource::Param); + + for (auto ¶m : function.get_function_params ()) + visit (param); + + ctx.bindings.exit (); +} + +void +Late::visit (AST::StructPatternFieldIdent &field) +{ // 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 ()); + std::ignore = ctx.values.insert_shadowable (field.get_identifier (), + field.get_node_id ()); } void @@ -187,6 +299,9 @@ Late::visit (AST::SelfParam ¶m) void Late::visit (AST::BreakExpr &expr) { + if (expr.has_label ()) + resolve_label (expr.get_label_unchecked ().get_lifetime ()); + if (expr.has_break_expr ()) { auto &break_expr = expr.get_break_expr (); @@ -213,6 +328,38 @@ Late::visit (AST::BreakExpr &expr) } void +Late::visit (AST::LoopLabel &label) +{ + auto &lifetime = label.get_lifetime (); + ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()), + lifetime.get_node_id ()); +} + +void +Late::resolve_label (AST::Lifetime &lifetime) +{ + if (auto resolved = ctx.labels.get (lifetime.as_string ())) + { + if (resolved->get_node_id () != lifetime.get_node_id ()) + ctx.map_usage (Usage (lifetime.get_node_id ()), + Definition (resolved->get_node_id ())); + } + else + rust_error_at (lifetime.get_locus (), ErrorCode::E0426, + "use of undeclared label %qs", + lifetime.as_string ().c_str ()); +} + +void +Late::visit (AST::ContinueExpr &expr) +{ + if (expr.has_label ()) + resolve_label (expr.get_label_unchecked ()); + + DefaultResolver::visit (expr); +} + +void Late::visit (AST::IdentifierExpr &expr) { // TODO: same thing as visit(PathInExpression) here? @@ -307,14 +454,13 @@ Late::visit (AST::PathInExpression &expr) return; } - auto resolved = ctx.resolve_path (expr.get_segments (), Namespace::Values, - Namespace::Types); + auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types); if (!resolved) { if (!ctx.lookup (expr.get_segments ().front ().get_node_id ())) - rust_error_at (expr.get_locus (), - "could not resolve path expression: %qs", + rust_error_at (expr.get_locus (), ErrorCode::E0433, + "Cannot find path %qs in this scope", expr.as_simple_path ().as_string ().c_str ()); return; } @@ -340,13 +486,9 @@ Late::visit (AST::TypePath &type) DefaultResolver::visit (type); - // take care of only simple cases - // TODO: remove this? - rust_assert (!type.has_opening_scope_resolution_op ()); - // this *should* mostly work // TODO: make sure typepath-like path resolution (?) is working - auto resolved = ctx.resolve_path (type.get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (type, Namespace::Types); if (!resolved.has_value ()) { @@ -363,6 +505,14 @@ Late::visit (AST::TypePath &type) return; } + if (ctx.types.forward_declared (resolved->get_node_id (), + type.get_node_id ())) + { + rust_error_at (type.get_locus (), ErrorCode::E0128, + "type parameters with a default cannot use forward " + "declared identifiers"); + } + ctx.map_usage (Usage (type.get_node_id ()), Definition (resolved->get_node_id ())); } @@ -394,8 +544,7 @@ Late::visit (AST::StructExprStruct &s) visit_inner_attrs (s); DefaultResolver::visit (s.get_struct_name ()); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); @@ -409,8 +558,7 @@ Late::visit (AST::StructExprStructBase &s) DefaultResolver::visit (s.get_struct_name ()); visit (s.get_struct_base ()); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); @@ -427,8 +575,7 @@ Late::visit (AST::StructExprStructFields &s) for (auto &field : s.get_fields ()) visit (field); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); @@ -482,14 +629,35 @@ void Late::visit (AST::ClosureExprInner &closure) { add_captures (closure, ctx); - DefaultResolver::visit (closure); + + visit_outer_attrs (closure); + + ctx.bindings.enter (BindingSource::Param); + + for (auto ¶m : closure.get_params ()) + visit (param); + + ctx.bindings.exit (); + + visit (closure.get_definition_expr ()); } void Late::visit (AST::ClosureExprInnerTyped &closure) { add_captures (closure, ctx); - DefaultResolver::visit (closure); + + visit_outer_attrs (closure); + + ctx.bindings.enter (BindingSource::Param); + + for (auto ¶m : closure.get_params ()) + visit (param); + + ctx.bindings.exit (); + + visit (closure.get_return_type ()); + visit (closure.get_definition_block ()); } } // namespace Resolver2_0 |