Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify TraitItemMethod & TraitItemFunc with Function #2811

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion gcc/rust/ast/rust-ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,7 @@ Union::as_string () const
}

Function::Function (Function const &other)
: VisItem (other), qualifiers (other.qualifiers),
: VisItem (other), TraitItem (other), qualifiers (other.qualifiers),
function_name (other.function_name), where_clause (other.where_clause),
locus (other.locus), is_default (other.is_default)
{
Expand All @@ -1087,6 +1087,7 @@ Function &
Function::operator= (Function const &other)
{
VisItem::operator= (other);
TraitItem::operator=(other);
function_name = other.function_name;
qualifiers = other.qualifiers;
where_clause = other.where_clause;
Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1685,6 +1685,10 @@ class TraitItem : public TraitImplItem
locus (locus)
{}

TraitItem (Visibility vis, location_t locus, NodeId node_id)
: node_id (node_id), vis (vis), locus (locus)
{}

// Clone function implementation as pure virtual method
virtual TraitItem *clone_associated_item_impl () const override = 0;

Expand Down
19 changes: 11 additions & 8 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
#ifndef RUST_AST_ITEM_H
#define RUST_AST_ITEM_H

#include "optional.h"
#include "rust-ast.h"
#include "rust-hir-map.h"
#include "rust-mapping-common.h"
#include "rust-path.h"
#include "rust-common.h"
#include "rust-expr.h"
#include <memory>

namespace Rust {
namespace AST {
Expand Down Expand Up @@ -1289,7 +1291,7 @@ class UseDeclaration : public VisItem
class LetStmt;

// Rust function declaration AST node
class Function : public VisItem, public TraitImplItem
class Function : public VisItem, public TraitItem
{
FunctionQualifiers qualifiers;
Identifier function_name;
Expand Down Expand Up @@ -1323,6 +1325,12 @@ class Function : public VisItem, public TraitImplItem

bool has_body () const { return function_body.has_value (); }

tl::optional<std::unique_ptr<BlockExpr>>& get_definition () { return function_body; }

// Returns node_id, function is needed as VisItem and TraitItem both have
// get_node_id()
NodeId get_node_id () const { return VisItem::node_id; }

// Mega-constructor with all possible fields
Function (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
Expand All @@ -1331,7 +1339,8 @@ class Function : public VisItem, public TraitImplItem
tl::optional<std::unique_ptr<BlockExpr>> function_body,
Visibility vis, std::vector<Attribute> outer_attrs,
location_t locus, bool is_default = false)
: VisItem (std::move (vis), std::move (outer_attrs)),
: VisItem (vis, std::move (outer_attrs)),
TraitItem (vis, locus, VisItem::get_node_id ()),
qualifiers (std::move (qualifiers)),
function_name (std::move (function_name)),
generic_params (std::move (generic_params)),
Expand Down Expand Up @@ -1389,12 +1398,6 @@ class Function : public VisItem, public TraitImplItem
return generic_params;
}

// TODO: is this better? Or is a "vis_block" better?
tl::optional<std::unique_ptr<BlockExpr>> &get_definition ()
{
return function_body;
}

const FunctionQualifiers &get_qualifiers () const { return qualifiers; }

FunctionQualifiers &get_qualifiers () { return qualifiers; }
Expand Down
48 changes: 48 additions & 0 deletions gcc/rust/backend/rust-compile-implitem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,54 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
reference = const_expr;
}

void
CompileTraitItem::visit (HIR::Function &func)
{
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete);
fntype->monomorphize ();
// items can be forward compiled which means we may not need to invoke this
// code. We might also have already compiled this generic function as well.
tree lookup = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
fntype->get_id (), fntype))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
{
tree dummy = NULL_TREE;
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
{
ctx->insert_function_decl (fntype, lookup);
}

reference = address_expression (lookup, ref_locus);
return;
}
}

if (fntype->has_substitutions_defined ())
{
// override the Hir Lookups for the substituions in this context
fntype->override_context ();
}

const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
func.get_mappings ().get_nodeid (), &canonical_path);
rust_assert (ok);

// FIXME: How do we get the proper visibility here?
auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC);
tree fndecl
= compile_function (func.get_function_name ().as_string (),
func.get_self (), func.get_function_params (),
func.get_qualifiers (), vis,
func.get_outer_attrs (), func.get_locus (),
func.get_definition ().get (), canonical_path, fntype);
reference = address_expression (fndecl, ref_locus);
}

void
CompileTraitItem::visit (HIR::TraitItemFunc &func)
{
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/backend/rust-compile-implitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class CompileTraitItem : public HIRCompileBase, public HIR::HIRTraitItemVisitor

void visit (HIR::TraitItemConst &constant) override;
void visit (HIR::TraitItemFunc &func) override;
void visit (HIR::Function &func) override;

void visit (HIR::TraitItemType &typ) override {}

Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/backend/rust-mangle-v0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
}
else if (trait_item != nullptr)
{
switch (trait_item->get_item_kind ())
switch (trait_item->get_trait_item_kind ())
{
case HIR::TraitItem::FUNC: {
HIR::Function *fn = static_cast<HIR::Function *> (impl_item);
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/checks/errors/rust-ast-validation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void
ASTValidation::visit (AST::Function &function)
{
std::set<Context> valid_context
= {Context::INHERENT_IMPL, Context::TRAIT_IMPL};
= {Context::INHERENT_IMPL, Context::TRAIT_IMPL, Context::TRAIT};

const auto &qualifiers = function.get_qualifiers ();
if (qualifiers.is_async () && qualifiers.is_const ())
Expand Down
76 changes: 76 additions & 0 deletions gcc/rust/hir/rust-ast-lower-implitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-block.h"
#include "rust-ast-lower.h"
#include "rust-item.h"

namespace Rust {
Expand Down Expand Up @@ -240,6 +241,81 @@ class ASTLowerTraitItem : public ASTLoweringBase
return resolver.translated;
}

void visit (AST::Function &function) override
{
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::FunctionQualifiers qualifiers
= lower_qualifiers (function.get_qualifiers ());

std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
if (function.has_generics ())
{
generic_params = lower_generic_params (function.get_generic_params ());
}

std::unique_ptr<HIR::Type> return_type
= function.has_return_type () ? std::unique_ptr<HIR::Type> (
ASTLoweringType::translate (function.get_return_type ().get ()))
: nullptr;

HIR::SelfParam self_param = lower_self (function.get_self_param ());
std::vector<HIR::FunctionParam> function_params;
for (auto &p : function.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 (std::move (hir_param));
}

bool terminated = false;
std::unique_ptr<HIR::BlockExpr> block_expr
= function.has_body () ? std::unique_ptr<HIR::BlockExpr> (
ASTLoweringBlock::translate (function.get_definition ()->get (),
&terminated))
: nullptr;

auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));

HIR::Visibility vis = translate_visibility (function.get_visibility ());
HIR::Function *trait_item
= new HIR::Function (mapping, function.get_function_name (),
std::move (qualifiers), std::move (generic_params),
std::move (function_params), std::move (return_type),
std::move (where_clause), std::move (block_expr),
vis, function.get_outer_attrs (), self_param,
function.get_locus ());

translated = trait_item;

// add the mappings for the function params at the end
for (auto &param : trait_item->get_function_params ())
{
mappings->insert_hir_param (&param);
mappings->insert_location (mapping.get_hirid (), param.get_locus ());
}
}

void visit (AST::TraitItemFunc &func) override
{
AST::TraitFunctionDecl &ref = func.get_trait_function_decl ();
Expand Down
58 changes: 50 additions & 8 deletions gcc/rust/hir/tree/rust-hir-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "rust-hir-expr.h"
#include "rust-hir.h"
#include "rust-hir-path.h"
#include <memory>

namespace Rust {
namespace HIR {
Expand Down Expand Up @@ -1081,7 +1082,7 @@ class UseDeclaration : public VisItem
class LetStmt;

// Rust function declaration HIR node
class Function : public VisItem, public ImplItem
class Function : public VisItem, public ImplItem, public TraitItem
{
FunctionQualifiers qualifiers;
Identifier function_name;
Expand Down Expand Up @@ -1115,6 +1116,40 @@ class Function : public VisItem, public ImplItem

ItemKind get_item_kind () const override { return ItemKind::Function; }

TraitItemKind get_trait_item_kind () const override
{
return TraitItemKind::FUNC;
}

const std::string trait_identifier () const override
{
return function_name.as_string ();
}

location_t get_trait_locus () const override { return locus; }

AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }

const AST::AttrVec &get_outer_attrs () const override final
{
return outer_attrs;
}

// Returns mappings, this function is needed otherwise call is ambigious as
// both VisItem and TraiItem have this function
const Analysis::NodeMapping &get_mappings () const
{
return VisItem::get_mappings ();
}

// Returns whether function has a body
bool has_body () const { return function_body != nullptr; }

// Returns function body/definition
std::unique_ptr<BlockExpr> &get_body () { return function_body; }

SelfParam &get_self () { return self; }

// Mega-constructor with all possible fields
Function (Analysis::NodeMapping mappings, Identifier function_name,
FunctionQualifiers qualifiers,
Expand All @@ -1123,8 +1158,8 @@ class Function : public VisItem, public ImplItem
std::unique_ptr<Type> return_type, WhereClause where_clause,
std::unique_ptr<BlockExpr> function_body, Visibility vis,
AST::AttrVec outer_attrs, SelfParam self, location_t locus)
: VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
qualifiers (std::move (qualifiers)),
: VisItem (mappings, std::move (vis), std::move (outer_attrs)),
TraitItem (std::move (mappings)), qualifiers (std::move (qualifiers)),
function_name (std::move (function_name)),
generic_params (std::move (generic_params)),
function_params (std::move (function_params)),
Expand All @@ -1136,7 +1171,7 @@ class Function : public VisItem, public ImplItem

// Copy constructor with clone
Function (Function const &other)
: VisItem (other), qualifiers (other.qualifiers),
: VisItem (other), TraitItem (other), qualifiers (other.qualifiers),
function_name (other.function_name),
function_params (other.function_params),
where_clause (other.where_clause),
Expand All @@ -1158,6 +1193,7 @@ class Function : public VisItem, public ImplItem
Function &operator= (Function const &other)
{
VisItem::operator= (other);
TraitItem::operator= (other);
function_name = other.function_name;
qualifiers = other.qualifiers;
function_params = other.function_params;
Expand Down Expand Up @@ -1188,12 +1224,13 @@ class Function : public VisItem, public ImplItem

void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRImplVisitor &vis) override;
void accept_vis (HIRTraitItemVisitor &vis) override;
void accept_vis (HIRStmtVisitor &vis) override;
void accept_vis (HIRVisItemVisitor &vis) override;

Analysis::NodeMapping get_impl_mappings () const override
{
return get_mappings ();
return VisItem::get_mappings ();
};

std::vector<FunctionParam> &get_function_params () { return function_params; }
Expand Down Expand Up @@ -1246,6 +1283,11 @@ class Function : public VisItem, public ImplItem
{
return new Function (*this);
}

Function *clone_trait_item_impl () const override
{
return new Function (*this);
}
};

// Rust type alias (i.e. typedef) HIR node
Expand Down Expand Up @@ -2400,7 +2442,7 @@ class TraitItemFunc : public TraitItem
return decl.get_function_name ().as_string ();
}

TraitItemKind get_item_kind () const override final
TraitItemKind get_trait_item_kind () const override final
{
return TraitItemKind::FUNC;
}
Expand Down Expand Up @@ -2487,7 +2529,7 @@ class TraitItemConst : public TraitItem
return name.as_string ();
}

TraitItemKind get_item_kind () const override final
TraitItemKind get_trait_item_kind () const override final
{
return TraitItemKind::CONST;
}
Expand Down Expand Up @@ -2579,7 +2621,7 @@ class TraitItemType : public TraitItem
return name.as_string ();
}

TraitItemKind get_item_kind () const override final
TraitItemKind get_trait_item_kind () const override final
{
return TraitItemKind::TYPE;
}
Expand Down
Loading
Loading