From: Kushal Pal Date: Fri, 26 Jan 2024 06:05:24 +0000 (+0530) Subject: gccrs: Add missing visitors for AST::Function. X-Git-Tag: basepoints/gcc-15~1277 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=41cbf917de55341069efa389ec21f90a1197da53;p=thirdparty%2Fgcc.git gccrs: Add missing visitors for AST::Function. To use AST::Function instead of AST::TraitItemFunc and AST::TraitItemMethod, we need to provide similar visitors during lowering and resolving phase. gcc/rust/ChangeLog: * hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit): Provide visitor for AST::Function. * hir/rust-ast-lower-implitem.h: Likewise. * resolve/rust-ast-resolve-implitem.h: Likewise. * resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit): Likewise. * resolve/rust-ast-resolve-item.h: Likewise. Signed-off-by: Kushal Pal --- diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc index 98db1dccd7c0..77230e7a8bfa 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.cc +++ b/gcc/rust/hir/rust-ast-lower-implitem.cc @@ -227,6 +227,92 @@ ASTLowerTraitItem::translate (AST::AssociatedItem *item) return resolver.translated; } +void +ASTLowerTraitItem::visit (AST::Function &func) +{ + std::vector > where_clause_items; + HIR::WhereClause where_clause (std::move (where_clause_items)); + HIR::FunctionQualifiers qualifiers + = lower_qualifiers (func.get_qualifiers ()); + + std::vector > generic_params; + if (func.has_generics ()) + generic_params = lower_generic_params (func.get_generic_params ()); + + std::unique_ptr return_type + = func.has_return_type () ? std::unique_ptr ( + ASTLoweringType::translate (func.get_return_type ().get ())) + : nullptr; + + // set self parameter to error if this is a method + // else lower to hir + HIR::SelfParam self_param = func.has_self_param () + ? lower_self (func.get_self_param ()) + : HIR::SelfParam::error (); + + std::vector function_params; + for (auto &p : func.get_function_params ()) + { + if (p->is_variadic () || p->is_self ()) + continue; + + auto param = static_cast (p.get ()); + + auto translated_pattern = std::unique_ptr ( + ASTLoweringPattern::translate (param->get_pattern ().get ())); + auto translated_type = std::unique_ptr ( + ASTLoweringType::translate (param->get_type ().get ())); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, param->get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + auto hir_param + = HIR::FunctionParam (mapping, std::move (translated_pattern), + std::move (translated_type), param->get_locus ()); + function_params.push_back (hir_param); + } + + HIR::TraitFunctionDecl decl (func.get_function_name (), + std::move (qualifiers), + std::move (generic_params), + std::move (self_param), + std::move (function_params), + std::move (return_type), + std::move (where_clause)); + bool terminated = false; + std::unique_ptr block_expr + = func.has_body () ? std::unique_ptr ( + ASTLoweringBlock::translate (func.get_definition ()->get (), + &terminated)) + : nullptr; + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, func.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + auto *trait_item + = new HIR::TraitItemFunc (mapping, std::move (decl), std::move (block_expr), + func.get_outer_attrs (), func.get_locus ()); + translated = trait_item; + if (func.has_self_param ()) + { + // insert mappings for self + mappings->insert_hir_self_param (&self_param); + mappings->insert_location (self_param.get_mappings ().get_hirid (), + self_param.get_locus ()); + } + + // add the mappings for the function params at the end + for (auto ¶m : trait_item->get_decl ().get_function_params ()) + { + mappings->insert_hir_param (¶m); + mappings->insert_location (mapping.get_hirid (), param.get_locus ()); + } +} + void ASTLowerTraitItem::visit (AST::TraitItemFunc &func) { diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h index 3a266b41ed47..b9d12cc4a561 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.h +++ b/gcc/rust/hir/rust-ast-lower-implitem.h @@ -48,6 +48,7 @@ class ASTLowerTraitItem : public ASTLoweringBase public: static HIR::TraitItem *translate (AST::AssociatedItem *item); + void visit (AST::Function &func) override; void visit (AST::TraitItemFunc &func) override; void visit (AST::TraitItemMethod &method) override; void visit (AST::TraitItemConst &constant) override; diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h index 365bdd6135f5..d9c9bcb28c93 100644 --- a/gcc/rust/resolve/rust-ast-resolve-implitem.h +++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h @@ -110,6 +110,26 @@ public: item->accept_vis (resolver); }; + void visit (AST::Function &function) override + { + auto decl + = CanonicalPath::new_seg (function.get_node_id (), + function.get_function_name ().as_string ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + + resolver->get_name_scope ().insert ( + path, function.get_node_id (), function.get_locus (), false, + Rib::ItemType::Function, + [&] (const CanonicalPath &, NodeId, location_t locus) -> void { + rich_location r (line_table, function.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + mappings->insert_canonical_path (function.get_node_id (), cpath); + } + void visit (AST::TraitItemFunc &function) override { auto decl = CanonicalPath::new_seg ( diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc index 60eca5b13c7b..6037fe59f5b6 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ b/gcc/rust/resolve/rust-ast-resolve-item.cc @@ -45,6 +45,94 @@ ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix, item->accept_vis (resolver); } +void +ResolveTraitItems::visit (AST::Function &function) +{ + auto decl + = CanonicalPath::new_seg (function.get_node_id (), + function.get_function_name ().as_string ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (function.get_node_id (), cpath); + + NodeId scope_node_id = function.get_node_id (); + resolver->get_name_scope ().push (scope_node_id); + resolver->get_type_scope ().push (scope_node_id); + resolver->get_label_scope ().push (scope_node_id); + resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); + resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); + resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); + + if (function.has_generics ()) + for (auto &generic : function.get_generic_params ()) + ResolveGenericParam::go (generic.get (), prefix, canonical_prefix); + + if (function.has_return_type ()) + ResolveType::go (function.get_return_type ().get ()); + + // self turns into (self: Self) as a function param + std::vector bindings + = {PatternBinding (PatternBoundCtx::Product, std::set ())}; + + // we make a new scope so the names of parameters are resolved and shadowed + // correctly + for (auto &p : function.get_function_params ()) + { + if (p->is_variadic ()) + { + auto param = static_cast (p.get ()); + PatternDeclaration::go (param->get_pattern ().get (), + Rib::ItemType::Param, bindings); + } + else if (p->is_self ()) + { + auto param = static_cast (p.get ()); + // FIXME: which location should be used for Rust::Identifier `self`? + AST::IdentifierPattern self_pattern ( + param->get_node_id (), {"self"}, param->get_locus (), + param->get_has_ref (), param->get_is_mut (), + std::unique_ptr (nullptr)); + + PatternDeclaration::go (&self_pattern, Rib::ItemType::Param); + + if (param->has_type ()) + { + // This shouldn't happen the parser should already error for this + rust_assert (!param->get_has_ref ()); + ResolveType::go (param->get_type ().get ()); + } + else + { + // here we implicitly make self have a type path of Self + std::vector> segments; + segments.push_back (std::unique_ptr ( + new AST::TypePathSegment ("Self", false, param->get_locus ()))); + + AST::TypePath self_type_path (std::move (segments), + param->get_locus ()); + ResolveType::go (&self_type_path); + } + } + else + { + auto param = static_cast (p.get ()); + ResolveType::go (param->get_type ().get ()); + PatternDeclaration::go (param->get_pattern ().get (), + Rib::ItemType::Param, bindings); + } + } + + if (function.has_where_clause ()) + ResolveWhereClause::Resolve (function.get_where_clause ()); + + // trait items have an optional body + if (function.has_body ()) + ResolveExpr::go (function.get_definition ()->get (), path, cpath); + + resolver->get_name_scope ().pop (); + resolver->get_type_scope ().pop (); + resolver->get_label_scope ().pop (); +} void ResolveTraitItems::visit (AST::TraitItemType &type) { diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 712fe62336fa..33a78e21957d 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -35,6 +35,7 @@ public: static void go (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix); + void visit (AST::Function &type) override; void visit (AST::TraitItemType &type) override; void visit (AST::TraitItemFunc &func) override; void visit (AST::TraitItemMethod &func) override;