@@ -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)
{
@@ -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;
@@ -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 (
@@ -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)
{
@@ -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;