From: Kushal Pal <kushalpal...@gmail.com> 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 <kushalpal...@gmail.com> --- gcc/rust/hir/rust-ast-lower-implitem.cc | 86 +++++++++++++++++++ gcc/rust/hir/rust-ast-lower-implitem.h | 1 + gcc/rust/resolve/rust-ast-resolve-implitem.h | 20 +++++ gcc/rust/resolve/rust-ast-resolve-item.cc | 88 ++++++++++++++++++++ gcc/rust/resolve/rust-ast-resolve-item.h | 1 + 5 files changed, 196 insertions(+) diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc index 98db1dccd7c..77230e7a8bf 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<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + HIR::WhereClause where_clause (std::move (where_clause_items)); + HIR::FunctionQualifiers qualifiers + = lower_qualifiers (func.get_qualifiers ()); + + std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + if (func.has_generics ()) + generic_params = lower_generic_params (func.get_generic_params ()); + + std::unique_ptr<HIR::Type> return_type + = func.has_return_type () ? std::unique_ptr<HIR::Type> ( + 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<HIR::FunctionParam> function_params; + for (auto &p : func.get_function_params ()) + { + if (p->is_variadic () || p->is_self ()) + continue; + + auto param = static_cast<AST::FunctionParam *> (p.get ()); + + auto translated_pattern = std::unique_ptr<HIR::Pattern> ( + ASTLoweringPattern::translate (param->get_pattern ().get ())); + auto translated_type = std::unique_ptr<HIR::Type> ( + 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<HIR::BlockExpr> block_expr + = func.has_body () ? std::unique_ptr<HIR::BlockExpr> ( + 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 3a266b41ed4..b9d12cc4a56 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 365bdd6135f..d9c9bcb28c9 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 60eca5b13c7..6037fe59f5b 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<PatternBinding> bindings + = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())}; + + // 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<AST::VariadicParam *> (p.get ()); + PatternDeclaration::go (param->get_pattern ().get (), + Rib::ItemType::Param, bindings); + } + else if (p->is_self ()) + { + auto param = static_cast<AST::SelfParam *> (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<AST::Pattern> (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<std::unique_ptr<AST::TypePathSegment>> segments; + segments.push_back (std::unique_ptr<AST::TypePathSegment> ( + 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<AST::FunctionParam *> (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 712fe62336f..33a78e21957 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; -- 2.42.1