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

derive(PartialEq): Add partial implementation (hehe) #3415

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ GRS_OBJS = \
rust/rust-derive-copy.o \
rust/rust-derive-debug.o \
rust/rust-derive-default.o \
rust/rust-derive-partial-eq.o \
rust/rust-derive-eq.o \
rust/rust-proc-macro.o \
rust/rust-macro-invoc-lexer.o \
rust/rust-proc-macro-invoc-lexer.o \
Expand Down
66 changes: 55 additions & 11 deletions gcc/rust/ast/rust-ast-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "rust-path.h"
#include "rust-item.h"
#include "rust-path.h"
#include "rust-pattern.h"
#include "rust-system.h"
#include "rust-token.h"
#include <memory>
Expand All @@ -39,6 +40,16 @@ Builder::literal_string (std::string &&content) const
PrimitiveCoreType::CORETYPE_STR, {}, loc));
}

std::unique_ptr<Expr>
Builder::literal_bool (bool b) const
{
auto str = b ? "true" : "false";

return std::unique_ptr<Expr> (
new AST::LiteralExpr (std::move (str), Literal::LitType::BOOL,
PrimitiveCoreType::CORETYPE_BOOL, {}, loc));
}

std::unique_ptr<Expr>
Builder::call (std::unique_ptr<Expr> &&path,
std::vector<std::unique_ptr<Expr>> &&args) const
Expand Down Expand Up @@ -279,23 +290,33 @@ Builder::path_in_expression (LangItem::Kind lang_item) const
return PathInExpression (lang_item, {}, loc);
}

std::unique_ptr<Expr>
Builder::block (std::unique_ptr<Stmt> &&stmt,
PathInExpression
Builder::variant_path (const std::string &enum_path,
const std::string &variant) const
{
return PathInExpression ({path_segment (enum_path), path_segment (variant)},
{}, loc, false);
}

std::unique_ptr<BlockExpr>
Builder::block (tl::optional<std::unique_ptr<Stmt>> &&stmt,
std::unique_ptr<Expr> &&tail_expr) const
{
auto stmts = std::vector<std::unique_ptr<Stmt>> ();
stmts.emplace_back (std::move (stmt));

if (stmt)
stmts.emplace_back (std::move (*stmt));

return block (std::move (stmts), std::move (tail_expr));
}

std::unique_ptr<Expr>
std::unique_ptr<BlockExpr>
Builder::block (std::vector<std::unique_ptr<Stmt>> &&stmts,
std::unique_ptr<Expr> &&tail_expr) const
{
return std::unique_ptr<Expr> (new BlockExpr (std::move (stmts),
std::move (tail_expr), {}, {},
LoopLabel::error (), loc, loc));
return std::unique_ptr<BlockExpr> (
new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {},
LoopLabel::error (), loc, loc));
}

std::unique_ptr<Expr>
Expand Down Expand Up @@ -329,6 +350,24 @@ Builder::deref (std::unique_ptr<Expr> &&of) const
return std::unique_ptr<Expr> (new DereferenceExpr (std::move (of), {}, loc));
}

std::unique_ptr<Expr>
Builder::comparison_expr (std::unique_ptr<Expr> &&lhs,
std::unique_ptr<Expr> &&rhs,
ComparisonOperator op) const
{
return std::make_unique<ComparisonExpr> (std::move (lhs), std::move (rhs), op,
loc);
}

std::unique_ptr<Expr>
Builder::boolean_operation (std::unique_ptr<Expr> &&lhs,
std::unique_ptr<Expr> &&rhs,
LazyBooleanOperator op) const
{
return std::make_unique<LazyBooleanExpr> (std::move (lhs), std::move (rhs),
op, loc);
}

std::unique_ptr<Stmt>
Builder::struct_struct (std::string struct_name,
std::vector<std::unique_ptr<GenericParam>> &&generics,
Expand Down Expand Up @@ -388,6 +427,13 @@ Builder::wildcard () const
return std::unique_ptr<Pattern> (new WildcardPattern (loc));
}

std::unique_ptr<Pattern>
Builder::ref_pattern (std::unique_ptr<Pattern> &&inner) const
{
return std::make_unique<ReferencePattern> (std::move (inner), false, false,
loc);
}

std::unique_ptr<Path>
Builder::lang_item_path (LangItem::Kind kind) const
{
Expand Down Expand Up @@ -421,11 +467,9 @@ Builder::match_case (std::unique_ptr<Pattern> &&pattern,
std::unique_ptr<Expr>
Builder::loop (std::vector<std::unique_ptr<Stmt>> &&stmts)
{
auto block = std::unique_ptr<BlockExpr> (
new BlockExpr (std::move (stmts), nullptr, {}, {}, LoopLabel::error (), loc,
loc));
auto block_expr = block (std::move (stmts), nullptr);

return std::unique_ptr<Expr> (new LoopExpr (std::move (block), loc));
return std::unique_ptr<Expr> (new LoopExpr (std::move (block_expr), loc));
}

std::unique_ptr<TypeParamBound>
Expand Down
32 changes: 26 additions & 6 deletions gcc/rust/ast/rust-ast-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "rust-expr.h"
#include "rust-ast.h"
#include "rust-item.h"
#include "rust-operators.h"

namespace Rust {
namespace AST {
Expand Down Expand Up @@ -62,6 +63,9 @@ class Builder
/* Create a string literal expression ("content") */
std::unique_ptr<Expr> literal_string (std::string &&content) const;

/* Create a boolean literal expression (true) */
std::unique_ptr<Expr> literal_bool (bool b) const;

/* Create an identifier expression (`variable`) */
std::unique_ptr<Expr> identifier (std::string name) const;
std::unique_ptr<Pattern> identifier_pattern (std::string name,
Expand All @@ -81,13 +85,23 @@ class Builder
/* Create a dereference of an expression (`*of`) */
std::unique_ptr<Expr> deref (std::unique_ptr<Expr> &&of) const;

/* Build a comparison expression (`lhs == rhs`) */
std::unique_ptr<Expr> comparison_expr (std::unique_ptr<Expr> &&lhs,
std::unique_ptr<Expr> &&rhs,
ComparisonOperator op) const;

/* Build a lazy boolean operator expression (`lhs && rhs`) */
std::unique_ptr<Expr> boolean_operation (std::unique_ptr<Expr> &&lhs,
std::unique_ptr<Expr> &&rhs,
LazyBooleanOperator op) const;

/* Create a block with an optional tail expression */
std::unique_ptr<Expr> block (std::vector<std::unique_ptr<Stmt>> &&stmts,
std::unique_ptr<Expr> &&tail_expr
= nullptr) const;
std::unique_ptr<Expr> block (std::unique_ptr<Stmt> &&stmt,
std::unique_ptr<Expr> &&tail_expr
= nullptr) const;
std::unique_ptr<BlockExpr> block (std::vector<std::unique_ptr<Stmt>> &&stmts,
std::unique_ptr<Expr> &&tail_expr
= nullptr) const;
std::unique_ptr<BlockExpr> block (tl::optional<std::unique_ptr<Stmt>> &&stmt,
std::unique_ptr<Expr> &&tail_expr
= nullptr) const;

/* Create an early return expression with an optional expression */
std::unique_ptr<Expr> return_expr (std::unique_ptr<Expr> &&to_return
Expand Down Expand Up @@ -191,6 +205,10 @@ class Builder
*/
PathInExpression path_in_expression (LangItem::Kind lang_item) const;

/* Create the path to an enum's variant (`Result::Ok`) */
PathInExpression variant_path (const std::string &enum_path,
const std::string &variant) const;

/* Create a new struct */
std::unique_ptr<Stmt>
struct_struct (std::string struct_name,
Expand Down Expand Up @@ -223,6 +241,8 @@ class Builder

/* Create a wildcard pattern (`_`) */
std::unique_ptr<Pattern> wildcard () const;
/* Create a reference pattern (`&pattern`) */
std::unique_ptr<Pattern> ref_pattern (std::unique_ptr<Pattern> &&inner) const;

/* Create a lang item path usable as a general path */
std::unique_ptr<Path> lang_item_path (LangItem::Kind) const;
Expand Down
34 changes: 12 additions & 22 deletions gcc/rust/expand/rust-derive-clone.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

#include "rust-derive-clone.h"
#include "rust-ast.h"
#include "rust-ast-dump.h"
#include "rust-expr.h"
#include "rust-item.h"
#include "rust-path.h"
Expand Down Expand Up @@ -169,21 +168,10 @@ DeriveClone::visit_struct (StructStruct &item)
item.get_generic_params ());
}

PathInExpression
DeriveClone::variant_match_path (Enum &item, const Identifier &variant)
{
return PathInExpression ({builder.path_segment (
item.get_identifier ().as_string ()),
builder.path_segment (variant.as_string ())},
{}, loc, false);
}

MatchCase
DeriveClone::clone_enum_identifier (Enum &item,
DeriveClone::clone_enum_identifier (PathInExpression variant_path,
const std::unique_ptr<EnumItem> &variant)
{
auto variant_path = variant_match_path (item, variant->get_identifier ());

auto pattern = std::unique_ptr<Pattern> (new ReferencePattern (
std::unique_ptr<Pattern> (new PathInExpression (variant_path)), false,
false, loc));
Expand All @@ -193,10 +181,9 @@ DeriveClone::clone_enum_identifier (Enum &item,
}

MatchCase
DeriveClone::clone_enum_tuple (Enum &item, const EnumItemTuple &variant)
DeriveClone::clone_enum_tuple (PathInExpression variant_path,
const EnumItemTuple &variant)
{
auto variant_path = variant_match_path (item, variant.get_identifier ());

auto patterns = std::vector<std::unique_ptr<Pattern>> ();
auto cloned_patterns = std::vector<std::unique_ptr<Expr>> ();

Expand Down Expand Up @@ -232,10 +219,9 @@ DeriveClone::clone_enum_tuple (Enum &item, const EnumItemTuple &variant)
}

MatchCase
DeriveClone::clone_enum_struct (Enum &item, const EnumItemStruct &variant)
DeriveClone::clone_enum_struct (PathInExpression variant_path,
const EnumItemStruct &variant)
{
auto variant_path = variant_match_path (item, variant.get_identifier ());

auto field_patterns = std::vector<std::unique_ptr<StructPatternField>> ();
auto cloned_fields = std::vector<std::unique_ptr<StructExprField>> ();

Expand Down Expand Up @@ -314,21 +300,25 @@ DeriveClone::visit_enum (Enum &item)

for (const auto &variant : item.get_variants ())
{
auto path
= builder.variant_path (item.get_identifier ().as_string (),
variant->get_identifier ().as_string ());

switch (variant->get_enum_item_kind ())
{
// Identifiers and discriminated variants are the same for a clone - we
// just return the same variant
case EnumItem::Kind::Identifier:
case EnumItem::Kind::Discriminant:
cases.emplace_back (clone_enum_identifier (item, variant));
cases.emplace_back (clone_enum_identifier (path, variant));
break;
case EnumItem::Kind::Tuple:
cases.emplace_back (
clone_enum_tuple (item, static_cast<EnumItemTuple &> (*variant)));
clone_enum_tuple (path, static_cast<EnumItemTuple &> (*variant)));
break;
case EnumItem::Kind::Struct:
cases.emplace_back (
clone_enum_struct (item, static_cast<EnumItemStruct &> (*variant)));
clone_enum_struct (path, static_cast<EnumItemStruct &> (*variant)));
break;
}
}
Expand Down
8 changes: 5 additions & 3 deletions gcc/rust/expand/rust-derive-clone.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,12 @@ class DeriveClone : DeriveVisitor
/**
* Implementation of clone for all possible variants of an enum
*/
MatchCase clone_enum_identifier (Enum &item,
MatchCase clone_enum_identifier (PathInExpression variant_path,
const std::unique_ptr<EnumItem> &variant);
MatchCase clone_enum_tuple (Enum &item, const EnumItemTuple &variant);
MatchCase clone_enum_struct (Enum &item, const EnumItemStruct &variant);
MatchCase clone_enum_tuple (PathInExpression variant_path,
const EnumItemTuple &variant);
MatchCase clone_enum_struct (PathInExpression variant_path,
const EnumItemStruct &variant);

virtual void visit_struct (StructStruct &item);
virtual void visit_tuple (TupleStruct &item);
Expand Down
Loading
Loading