Skip to content

Commit

Permalink
WIP: Remove self parameter from functions
Browse files Browse the repository at this point in the history
Self can now be represented as a standard parameter and is thus no longer
required as a separate function attribute.

gcc/rust/ChangeLog:

	* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit):
	* ast/rust-ast.cc (Function::Function):
	(Function::operator=):
	(TraitMethodDecl::as_string):
	* ast/rust-item.h (class Function):
	(class TraitMethodDecl):
	* checks/errors/rust-ast-validation.cc (ASTValidation::visit):
	* expand/rust-cfg-strip.cc (CfgStrip::maybe_strip_self_param):
	(CfgStrip::maybe_strip_trait_method_decl):
	(CfgStrip::visit):
	* expand/rust-derive-clone.cc (DeriveClone::clone_fn):
	* expand/rust-expand-visitor.cc (ExpandVisitor::expand_self_param):
	(ExpandVisitor::expand_trait_method_decl):
	(ExpandVisitor::visit):
	* expand/rust-expand-visitor.h:
	* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self):
	* hir/rust-ast-lower-base.h:
	* parse/rust-parse-impl.h (Parser::parse_function):
	(Parser::parse_trait_item):
	(Parser::parse_self_param):
	* parse/rust-parse.h:
	* resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit):
	(ResolveItem::visit):
	* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit):
  • Loading branch information
P-E-P committed Nov 13, 2023
1 parent 55836bc commit 9ead3de
Show file tree
Hide file tree
Showing 14 changed files with 199 additions and 267 deletions.
10 changes: 7 additions & 3 deletions gcc/rust/ast/rust-ast-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,8 @@ DefaultASTVisitor::visit (AST::SelfParam &param)
if (param.has_lifetime ())
visit (param.get_lifetime ());

visit (param.get_type ());
if (param.has_type ())
visit (param.get_type ());
}

void
Expand Down Expand Up @@ -1443,8 +1444,11 @@ DefaultASTVisitor::visit (AST::BareFunctionType &type)
}

void
DefaultASTVisitor::visit (AST::VariadicParam &)
{}
DefaultASTVisitor::visit (AST::VariadicParam &param)
{
if (param.has_pattern ())
visit (param.get_pattern ());
}

void
ContextualASTVisitor::visit (AST::Crate &crate)
Expand Down
8 changes: 2 additions & 6 deletions gcc/rust/ast/rust-ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1092,9 +1092,8 @@ Union::as_string () const

Function::Function (Function const &other)
: VisItem (other), qualifiers (other.qualifiers),
function_name (other.function_name), self_param (other.self_param),
where_clause (other.where_clause), locus (other.locus),
is_default (other.is_default)
function_name (other.function_name), where_clause (other.where_clause),
locus (other.locus), is_default (other.is_default)
{
// guard to prevent null dereference (always required)
if (other.return_type != nullptr)
Expand All @@ -1119,7 +1118,6 @@ Function::operator= (Function const &other)
VisItem::operator= (other);
function_name = other.function_name;
qualifiers = other.qualifiers;
self_param = other.self_param;
where_clause = other.where_clause;
// visibility = other.visibility->clone_visibility();
// outer_attrs = other.outer_attrs;
Expand Down Expand Up @@ -3269,8 +3267,6 @@ TraitMethodDecl::as_string () const
}
}

str += "\n Self param: " + self_param.as_string ();

str += "\n Function params: ";
if (has_params ())
{
Expand Down
40 changes: 24 additions & 16 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,6 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem
FunctionQualifiers qualifiers;
Identifier function_name;
std::vector<std::unique_ptr<GenericParam>> generic_params;
tl::optional<SelfParam> self_param;
std::vector<std::unique_ptr<Param>> function_params;
std::unique_ptr<Type> return_type;
WhereClause where_clause;
Expand All @@ -1304,12 +1303,14 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem
// Returns whether function has a where clause.
bool has_where_clause () const { return !where_clause.is_empty (); }

bool has_self_param () const { return self_param.has_value (); }
bool has_self_param () const
{
return function_params.size () > 0 && function_params[0]->is_self ();
}

// Mega-constructor with all possible fields
Function (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
tl::optional<SelfParam> self_param,
std::vector<std::unique_ptr<Param>> function_params,
std::unique_ptr<Type> return_type, WhereClause where_clause,
std::unique_ptr<BlockExpr> function_body, Visibility vis,
Expand All @@ -1319,7 +1320,6 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem
qualifiers (std::move (qualifiers)),
function_name (std::move (function_name)),
generic_params (std::move (generic_params)),
self_param (std::move (self_param)),
function_params (std::move (function_params)),
return_type (std::move (return_type)),
where_clause (std::move (where_clause)),
Expand Down Expand Up @@ -1397,15 +1397,15 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem
return return_type;
}

SelfParam &get_self_param ()
std::unique_ptr<Param> &get_self_param ()
{
rust_assert (has_self_param ());
return self_param.value ();
return function_params[0];
}
const SelfParam &get_self_param () const
const std::unique_ptr<Param> &get_self_param () const
{
rust_assert (has_self_param ());
return self_param.value ();
return function_params[0];
}

protected:
Expand Down Expand Up @@ -2726,8 +2726,6 @@ class TraitMethodDecl
// Generics generic_params;
std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined

SelfParam self_param;

// bool has_params;
// FunctionParams function_params;
std::vector<std::unique_ptr<Param>> function_params; // inlined
Expand Down Expand Up @@ -2758,13 +2756,11 @@ class TraitMethodDecl
// Mega-constructor
TraitMethodDecl (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
SelfParam self_param,
std::vector<std::unique_ptr<Param>> function_params,
std::unique_ptr<Type> return_type, WhereClause where_clause)
: qualifiers (std::move (qualifiers)),
function_name (std::move (function_name)),
generic_params (std::move (generic_params)),
self_param (std::move (self_param)),
function_params (std::move (function_params)),
return_type (std::move (return_type)),
where_clause (std::move (where_clause))
Expand All @@ -2773,7 +2769,7 @@ class TraitMethodDecl
// Copy constructor with clone
TraitMethodDecl (TraitMethodDecl const &other)
: qualifiers (other.qualifiers), function_name (other.function_name),
self_param (other.self_param), where_clause (other.where_clause)
where_clause (other.where_clause)
{
// guard to prevent nullptr dereference
if (other.return_type != nullptr)
Expand All @@ -2795,7 +2791,6 @@ class TraitMethodDecl
{
function_name = other.function_name;
qualifiers = other.qualifiers;
self_param = other.self_param;
where_clause = other.where_clause;

// guard to prevent nullptr dereference
Expand Down Expand Up @@ -2850,8 +2845,21 @@ class TraitMethodDecl
// TODO: is this better? Or is a "vis_block" better?
WhereClause &get_where_clause () { return where_clause; }

SelfParam &get_self_param () { return self_param; }
const SelfParam &get_self_param () const { return self_param; }
bool has_self () const
{
return !function_params.empty () && function_params[0]->is_self ();
}

std::unique_ptr<Param> &get_self_param ()
{
rust_assert (has_self ());
return function_params[0];
}
const std::unique_ptr<Param> &get_self_param () const
{
rust_assert (has_self ());
return function_params[0];
}

FunctionQualifiers get_qualifiers () const { return qualifiers; }

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 @@ -90,7 +90,7 @@ ASTValidation::visit (AST::Function &function)
if (valid_context.find (context.back ()) == valid_context.end ()
&& function.has_self_param ())
rust_error_at (
function.get_self_param ().get_locus (),
function.get_self_param ()->get_locus (),
"%<self%> parameter is only allowed in associated functions");

AST::ContextualASTVisitor::visit (function);
Expand Down
44 changes: 14 additions & 30 deletions gcc/rust/expand/rust-cfg-strip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -363,22 +363,6 @@ CfgStrip::CfgStrip::maybe_strip_closure_params (
}
}

void
CfgStrip::maybe_strip_self_param (AST::SelfParam &self_param)
{
if (self_param.has_type ())
{
auto &type = self_param.get_type ();
type->accept_vis (*this);

if (type->is_marked_for_strip ())
rust_error_at (type->get_locus (),
"cannot strip type in this position");
}
/* TODO: maybe check for invariants being violated - e.g. both type and
* lifetime? */
}

void
CfgStrip::maybe_strip_where_clause (AST::WhereClause &where_clause)
{
Expand Down Expand Up @@ -419,11 +403,6 @@ CfgStrip::maybe_strip_trait_method_decl (AST::TraitMethodDecl &decl)
for (auto &param : decl.get_generic_params ())
param->accept_vis (*this);

/* assuming you can't strip self param - wouldn't be a method
* anymore. spec allows outer attrs on self param, but doesn't
* specify whether cfg is used. */
maybe_strip_self_param (decl.get_self_param ());

/* strip function parameters if required - this is specifically
* allowed by spec */
maybe_strip_function_params (decl.get_function_params ());
Expand Down Expand Up @@ -2033,13 +2012,6 @@ CfgStrip::visit (AST::Function &function)
for (auto &param : function.get_generic_params ())
param->accept_vis (*this);

/* assuming you can't strip self param - wouldn't be a method
* anymore. spec allows outer attrs on self param, but doesn't
* specify whether cfg is used. */
// TODO: verify this
if (function.has_self_param ())
maybe_strip_self_param (function.get_self_param ());

/* strip function parameters if required - this is specifically
* allowed by spec */
maybe_strip_function_params (function.get_function_params ());
Expand Down Expand Up @@ -3180,7 +3152,19 @@ CfgStrip::visit (AST::FunctionParam &type)
{}

void
CfgStrip::visit (AST::SelfParam &type)
{}
CfgStrip::visit (AST::SelfParam &param)
{
if (param.has_type ())
{
auto &type = param.get_type ();
type->accept_vis (*this);

if (type->is_marked_for_strip ())
rust_error_at (type->get_locus (),
"cannot strip type in this position");
}
/* TODO: maybe check for invariants being violated - e.g. both type and
* lifetime? */
}

} // namespace Rust
15 changes: 10 additions & 5 deletions gcc/rust/expand/rust-derive-clone.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.

#include "rust-derive-clone.h"
#include "rust-item.h"

namespace Rust {
namespace AST {
Expand Down Expand Up @@ -50,13 +51,17 @@ DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr)
loc, loc));
auto big_self_type = builder.single_type_path ("Self");

std::unique_ptr<SelfParam> self (new SelfParam (Lifetime::error (),
/* is_mut */ false, loc));

std::vector<std::unique_ptr<Param>> params;
params.push_back (std::move (self));

return std::unique_ptr<TraitImplItem> (
new Function ({"clone"}, builder.fn_qualifiers (), /* generics */ {},
tl::optional<SelfParam> (tl::in_place, Lifetime::error (),
/* is_mut */ false, loc),
/* function params */ {}, std::move (big_self_type),
WhereClause::create_empty (), std::move (block),
Visibility::create_private (), {}, loc));
/* function params */ std::move (params),
std::move (big_self_type), WhereClause::create_empty (),
std::move (block), Visibility::create_private (), {}, loc));
}

/**
Expand Down
47 changes: 13 additions & 34 deletions gcc/rust/expand/rust-expand-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -378,18 +378,7 @@ ExpandVisitor::expand_function_params (
{
for (auto &p : params)
{
if (p->is_variadic ())
continue;
else if (p->is_self ())
{
auto param = static_cast<AST::SelfParam *> (p.get ());
maybe_expand_type (param->get_type ());
}
else
{
auto param = static_cast<AST::FunctionParam *> (p.get ());
maybe_expand_type (param->get_type ());
}
visit (p);
}
}

Expand Down Expand Up @@ -443,16 +432,6 @@ ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
}
}

void
ExpandVisitor::expand_self_param (AST::SelfParam &self_param)
{
if (self_param.has_type ())
maybe_expand_type (self_param.get_type ());

/* TODO: maybe check for invariants being violated - e.g. both type and
* lifetime? */
}

void
ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
{
Expand Down Expand Up @@ -484,11 +463,6 @@ ExpandVisitor::expand_trait_method_decl (AST::TraitMethodDecl &decl)
for (auto &param : decl.get_generic_params ())
visit (param);

/* assuming you can't strip self param - wouldn't be a method
* anymore. spec allows outer attrs on self param, but doesn't
* specify whether cfg is used. */
expand_self_param (decl.get_self_param ());

/* strip function parameters if required - this is specifically
* allowed by spec */
expand_function_params (decl.get_function_params ());
Expand Down Expand Up @@ -1034,8 +1008,6 @@ ExpandVisitor::visit (AST::Function &function)
for (auto &param : function.get_generic_params ())
visit (param);

if (function.has_self_param ())
expand_self_param (function.get_self_param ());
expand_function_params (function.get_function_params ());

if (function.has_return_type ())
Expand Down Expand Up @@ -1579,16 +1551,23 @@ ExpandVisitor::visit (AST::BareFunctionType &type)
}

void
ExpandVisitor::visit (AST::VariadicParam &type)
ExpandVisitor::visit (AST::VariadicParam &param)
{}

void
ExpandVisitor::visit (AST::FunctionParam &type)
{}
ExpandVisitor::visit (AST::FunctionParam &param)
{
maybe_expand_type (param.get_type ());
}

void
ExpandVisitor::visit (AST::SelfParam &type)
{}
ExpandVisitor::visit (AST::SelfParam &param)
{
/* TODO: maybe check for invariants being violated - e.g. both type and
* lifetime? */
if (param.has_type ())
maybe_expand_type (param.get_type ());
}

template <typename T>
void
Expand Down
1 change: 0 additions & 1 deletion gcc/rust/expand/rust-expand-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ class ExpandVisitor : public AST::ASTVisitor

// FIXME: Add documentation
void expand_closure_params (std::vector<AST::ClosureParam> &params);
void expand_self_param (AST::SelfParam &self_param);
void expand_where_clause (AST::WhereClause &where_clause);
void expand_trait_function_decl (AST::TraitFunctionDecl &decl);
void expand_trait_method_decl (AST::TraitMethodDecl &decl);
Expand Down
Loading

0 comments on commit 9ead3de

Please sign in to comment.