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

Finish derive(Clone) for enums #3343

Draft
wants to merge 28 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
51848ba
ast: Fix warning about copy elision for moved expr
CohenArthur Dec 26, 2024
efe3dc6
attributes: Add #[derive] as a built-in attribute
CohenArthur Jan 3, 2025
c8b7a72
collect-lang-items: Display attribute upon error finding it
CohenArthur Jan 3, 2025
8bb9315
ast: Refactor how lang item paths are handled.
CohenArthur Dec 26, 2024
27914e5
tychk: resolve lang item type paths properly
CohenArthur Jan 2, 2025
2a58b98
lower: Properly lower non-generic lang item type path segments.
CohenArthur Jan 2, 2025
9bbe79e
lang-items: Collect struct lang items.
CohenArthur Dec 26, 2024
34996c6
lang-item: Add LangItem::PrettyString
CohenArthur Dec 26, 2024
edbafa5
mappings: Add get_lang_item_node
CohenArthur Dec 26, 2024
d883a74
ast-collector: Adapt to lang item type path segments
CohenArthur Dec 31, 2024
0b105fc
ast-collector: Fix tuple struct pattern collection
CohenArthur Jan 3, 2025
ae05501
ast: Refactor how lang item paths are handled.
CohenArthur Dec 26, 2024
5c592fe
lang-items: Collect struct lang items.
CohenArthur Dec 26, 2024
13f8c66
lang-items: Mark Clone trait as a lang item in testsuite
CohenArthur Jan 3, 2025
dba7a14
builder: Allow generating struct statements
CohenArthur Dec 26, 2024
90bca41
derive(Clone): Manually generate AssertParamIsCopy struct for unions
CohenArthur Dec 26, 2024
3dcc24e
derive(Clone): Mark PhantomData as a lang item
CohenArthur Dec 26, 2024
5db4518
derive(Copy): Use copy lang item when deriving Copy.
CohenArthur Dec 26, 2024
09b4f29
ast-builder: Add new methods around type paths.
CohenArthur Dec 26, 2024
42fdc01
derive(Clone): Use lang item for PhantomData in Clone
CohenArthur Dec 26, 2024
4ab9ae4
derive(Clone): Add note about Clone::clone()
CohenArthur Jan 2, 2025
46ab99e
derive(Clone): Improve existing testcase
CohenArthur Jan 2, 2025
a849165
derive(Clone): Add deriving of simple enum variants
CohenArthur Jan 2, 2025
7edd272
ast-builder: Add new methods for building structs
CohenArthur Jan 3, 2025
6a60ed1
derive(Clone): Implement clone for enum tuple variants
CohenArthur Jan 3, 2025
6199042
derive(Clone): Implement derive clone for enum struct variants
CohenArthur Jan 3, 2025
73498e0
derive(Clone): Add lang item typepaths failure testcases to nr2 exclude
CohenArthur Jan 15, 2025
edaebb7
nr2.0: late: Better format PathInExpression resolution
CohenArthur Jan 15, 2025
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
104 changes: 81 additions & 23 deletions gcc/rust/ast/rust-ast-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@

#include "rust-ast-builder.h"
#include "rust-ast-builder-type.h"
#include "rust-ast.h"
#include "rust-common.h"
#include "rust-expr.h"
#include "rust-path.h"
#include "rust-item.h"
#include "rust-path.h"
#include "rust-system.h"
#include "rust-token.h"

namespace Rust {
Expand All @@ -42,15 +46,6 @@ Builder::call (std::unique_ptr<Expr> &&path,
new CallExpr (std::move (path), std::move (args), {}, loc));
}

std::unique_ptr<Expr>
Builder::call (std::unique_ptr<Path> &&path,
std::vector<std::unique_ptr<Expr>> &&args) const
{
return call (std::unique_ptr<Expr> (
new PathInExpression (std::move (path), {}, loc)),
std::move (args));
}

std::unique_ptr<Expr>
Builder::call (std::unique_ptr<Expr> &&path, std::unique_ptr<Expr> &&arg) const
{
Expand All @@ -60,15 +55,6 @@ Builder::call (std::unique_ptr<Expr> &&path, std::unique_ptr<Expr> &&arg) const
return call (std::move (path), std::move (args));
}

std::unique_ptr<Expr>
Builder::call (std::unique_ptr<Path> &&path, std::unique_ptr<Expr> &&arg) const
{
auto args = std::vector<std::unique_ptr<Expr>> ();
args.emplace_back (std::move (arg));

return call (std::move (path), std::move (args));
}

std::unique_ptr<Expr>
Builder::array (std::vector<std::unique_ptr<Expr>> &&members) const
{
Expand Down Expand Up @@ -117,12 +103,27 @@ Builder::type_path_segment (std::string seg) const
}

std::unique_ptr<TypePathSegment>
Builder::generic_type_path_segment (std::string seg, GenericArgs args) const
Builder::type_path_segment (LangItem::Kind lang_item) const
{
return std::unique_ptr<TypePathSegment> (
new TypePathSegment (lang_item, loc));
}

std::unique_ptr<TypePathSegment>
Builder::type_path_segment_generic (std::string seg, GenericArgs args) const
{
return std::unique_ptr<TypePathSegment> (
new TypePathSegmentGeneric (PathIdentSegment (seg, loc), false, args, loc));
}

std::unique_ptr<TypePathSegment>
Builder::type_path_segment_generic (LangItem::Kind lang_item,
GenericArgs args) const
{
return std::unique_ptr<TypePathSegment> (
new TypePathSegmentGeneric (lang_item, args, loc));
}

std::unique_ptr<Type>
Builder::single_type_path (std::string type) const
{
Expand All @@ -132,15 +133,52 @@ Builder::single_type_path (std::string type) const
return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
}

std::unique_ptr<Type>
Builder::single_type_path (LangItem::Kind lang_item) const
{
return std::unique_ptr<Type> (new TypePath (lang_item, {}, loc));
}

std::unique_ptr<Type>
Builder::single_generic_type_path (std::string type, GenericArgs args) const
{
auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
segments.emplace_back (generic_type_path_segment (type, args));
segments.emplace_back (type_path_segment_generic (type, args));

return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
}

std::unique_ptr<Type>
Builder::single_generic_type_path (LangItem::Kind lang_item,
GenericArgs args) const
{
auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
segments.emplace_back (type_path_segment_generic (lang_item, args));

return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
}

TypePath
Builder::type_path (std::unique_ptr<TypePathSegment> &&segment) const
{
auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
segments.emplace_back (std::move (segment));

return TypePath (std::move (segments), loc);
}

TypePath
Builder::type_path (std::string type) const
{
return type_path (type_path_segment (type));
}

TypePath
Builder::type_path (LangItem::Kind lang_item) const
{
return type_path (type_path_segment (lang_item));
}

PathInExpression
Builder::path_in_expression (std::vector<std::string> &&segments) const
{
Expand Down Expand Up @@ -200,6 +238,19 @@ Builder::deref (std::unique_ptr<Expr> &&of) const
return std::unique_ptr<Expr> (new DereferenceExpr (std::move (of), {}, loc));
}

std::unique_ptr<Stmt>
Builder::struct_struct (std::string struct_name,
std::vector<std::unique_ptr<GenericParam>> &&generics,
std::vector<StructField> &&fields)
{
auto is_unit = fields.empty ();

return std::unique_ptr<Stmt> (
new StructStruct (std::move (fields), struct_name, std::move (generics),
WhereClause::create_empty (), is_unit,
Visibility::create_private (), {}, loc));
}

std::unique_ptr<Expr>
Builder::struct_expr_struct (std::string struct_name) const
{
Expand All @@ -211,10 +262,17 @@ std::unique_ptr<Expr>
Builder::struct_expr (
std::string struct_name,
std::vector<std::unique_ptr<StructExprField>> &&fields) const
{
return struct_expr (path_in_expression ({struct_name}), std::move (fields));
}

std::unique_ptr<Expr>
Builder::struct_expr (
PathInExpression struct_name,
std::vector<std::unique_ptr<StructExprField>> &&fields) const
{
return std::unique_ptr<Expr> (
new StructExprStructFields (path_in_expression ({struct_name}),
std::move (fields), loc));
new StructExprStructFields (struct_name, std::move (fields), loc));
}

std::unique_ptr<StructExprField>
Expand Down Expand Up @@ -242,7 +300,7 @@ Builder::wildcard () const
std::unique_ptr<Path>
Builder::lang_item_path (LangItem::Kind kind) const
{
return std::unique_ptr<Path> (new LangItemPath (kind, loc));
return std::unique_ptr<Path> (new PathInExpression (kind, {}, loc));
}

std::unique_ptr<Expr>
Expand Down
53 changes: 48 additions & 5 deletions gcc/rust/ast/rust-ast-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,35 @@

#include "rust-ast-full.h"
#include "rust-expr.h"
#include "rust-ast.h"
#include "rust-item.h"

namespace Rust {
namespace AST {

template <typename T>
std::vector<std::unique_ptr<T>>
vec (std::unique_ptr<T> &&t)
{
auto v = std::vector<std::unique_ptr<T>> ();

v.emplace_back (std::move (t));

return v;
}

template <typename T>
std::vector<std::unique_ptr<T>>
vec (std::unique_ptr<T> &&t1, std::unique_ptr<T> &&t2)
{
auto v = std::vector<std::unique_ptr<T>> ();

v.emplace_back (std::move (t1));
v.emplace_back (std::move (t2));

return v;
}

// TODO: Use this builder when expanding regular macros
/* Builder class with helper methods to create AST nodes. This builder is
* tailored towards generating multiple AST nodes from a single location, and
Expand Down Expand Up @@ -72,12 +97,8 @@ class Builder
*/
std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
std::vector<std::unique_ptr<Expr>> &&args) const;
std::unique_ptr<Expr> call (std::unique_ptr<Path> &&path,
std::vector<std::unique_ptr<Expr>> &&args) const;
std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
std::unique_ptr<Expr> &&arg) const;
std::unique_ptr<Expr> call (std::unique_ptr<Path> &&path,
std::unique_ptr<Expr> &&arg) const;

/**
* Create an array expression (`[member0, member1, member2]`)
Expand All @@ -93,16 +114,27 @@ class Builder

/* And similarly for type path segments */
std::unique_ptr<TypePathSegment> type_path_segment (std::string seg) const;
std::unique_ptr<TypePathSegment>
type_path_segment (LangItem::Kind lang_item) const;

std::unique_ptr<TypePathSegment>
generic_type_path_segment (std::string seg, GenericArgs args) const;
type_path_segment_generic (std::string seg, GenericArgs args) const;
std::unique_ptr<TypePathSegment>
type_path_segment_generic (LangItem::Kind lang_item, GenericArgs args) const;

/* Create a Type from a single string - the most basic kind of type in our AST
*/
std::unique_ptr<Type> single_type_path (std::string type) const;
std::unique_ptr<Type> single_type_path (LangItem::Kind lang_item) const;

std::unique_ptr<Type> single_generic_type_path (std::string type,
GenericArgs args) const;
std::unique_ptr<Type> single_generic_type_path (LangItem::Kind lang_item,
GenericArgs args) const;

TypePath type_path (std::unique_ptr<TypePathSegment> &&segment) const;
TypePath type_path (std::string type) const;
TypePath type_path (LangItem::Kind lang_item) const;

/**
* Create a path in expression from multiple segments (`Clone::clone`). You
Expand All @@ -117,15 +149,26 @@ class Builder
*/
PathInExpression path_in_expression (LangItem::Kind lang_item) const;

/* Create a new struct */
std::unique_ptr<Stmt>
struct_struct (std::string struct_name,
std::vector<std::unique_ptr<GenericParam>> &&generics,
std::vector<StructField> &&fields);

/* Create a struct expression for unit structs (`S`) */
std::unique_ptr<Expr> struct_expr_struct (std::string struct_name) const;

/**
* Create an expression for struct instantiation with fields (`S { a, b: c }`)
* Tuple expressions are call expressions and can thus be constructed with
* `call`
*/
std::unique_ptr<Expr>
struct_expr (std::string struct_name,
std::vector<std::unique_ptr<StructExprField>> &&fields) const;
std::unique_ptr<Expr>
struct_expr (PathInExpression struct_name,
std::vector<std::unique_ptr<StructExprField>> &&fields) const;

/* Create a field expression for struct instantiation (`field_name: value`) */
std::unique_ptr<StructExprField>
Expand Down
41 changes: 16 additions & 25 deletions gcc/rust/ast/rust-ast-collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -538,28 +538,19 @@ TokenCollector::visit (PathInExpression &path)
visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
}

void
TokenCollector::visit (RegularPath &path)
{
// FIXME: We probably want to have a proper implementation here, and call this
// function from things like the PathInExpression visitor
}

void
TokenCollector::visit (LangItemPath &path)
{
// TODO: Implement proper token collection for lang item paths
}

void
TokenCollector::visit (TypePathSegment &segment)
{
// Syntax:
// PathIdentSegment
auto ident_segment = segment.get_ident_segment ();
auto id = ident_segment.as_string ();
push (
Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));

auto locus = segment.is_lang_item ()
? segment.get_locus ()
: segment.get_ident_segment ().get_locus ();
auto segment_string = segment.is_lang_item ()
? LangItem::PrettyString (segment.get_lang_item ())
: segment.get_ident_segment ().as_string ();
push (Rust::Token::make_identifier (locus, std::move (segment_string)));
}

void
Expand All @@ -571,10 +562,13 @@ TokenCollector::visit (TypePathSegmentGeneric &segment)
// `<` `>`
// | `<` ( GenericArg `,` )* GenericArg `,`? `>`

auto ident_segment = segment.get_ident_segment ();
auto id = ident_segment.as_string ();
push (
Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
auto locus = segment.is_lang_item ()
? segment.get_locus ()
: segment.get_ident_segment ().get_locus ();
auto segment_string = segment.is_lang_item ()
? LangItem::PrettyString (segment.get_lang_item ())
: segment.get_ident_segment ().as_string ();
push (Rust::Token::make_identifier (locus, std::move (segment_string)));

if (segment.get_separating_scope_resolution ())
push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
Expand Down Expand Up @@ -2476,10 +2470,7 @@ TokenCollector::visit (StructPattern &pattern)
void
TokenCollector::visit (TupleStructItemsNoRange &pattern)
{
for (auto &pat : pattern.get_patterns ())
{
visit (pat);
}
visit_items_joined_by_separator (pattern.get_patterns ());
}

void
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/ast/rust-ast-collector.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,6 @@ class TokenCollector : public ASTVisitor
void visit (PathExprSegment &segment);
void visit (PathIdentSegment &segment);
void visit (PathInExpression &path);
void visit (RegularPath &path);
void visit (LangItemPath &path);
void visit (TypePathSegment &segment);
void visit (TypePathSegmentGeneric &segment);
void visit (TypePathSegmentFunction &segment);
Expand Down
11 changes: 0 additions & 11 deletions gcc/rust/ast/rust-ast-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,6 @@ DefaultASTVisitor::visit (AST::ConstGenericParam &const_param)
visit (const_param.get_default_value ());
}

void
DefaultASTVisitor::visit (AST::RegularPath &path)
{
for (auto &segment : path.get_segments ())
visit (segment);
}

void
DefaultASTVisitor::visit (AST::LangItemPath &path)
{}

void
DefaultASTVisitor::visit (AST::PathInExpression &path)
{
Expand Down
4 changes: 0 additions & 4 deletions gcc/rust/ast/rust-ast-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ class ASTVisitor
// virtual void visit(TraitImplItem& trait_impl_item) = 0;

// rust-path.h
virtual void visit (RegularPath &path) = 0;
virtual void visit (LangItemPath &path) = 0;
virtual void visit (PathInExpression &path) = 0;
virtual void visit (TypePathSegment &segment) = 0;
virtual void visit (TypePathSegmentGeneric &segment) = 0;
Expand Down Expand Up @@ -252,8 +250,6 @@ class DefaultASTVisitor : public ASTVisitor
virtual void visit (AST::Lifetime &lifetime) override;
virtual void visit (AST::LifetimeParam &lifetime_param) override;
virtual void visit (AST::ConstGenericParam &const_param) override;
virtual void visit (AST::RegularPath &path) override;
virtual void visit (AST::LangItemPath &path) override;
virtual void visit (AST::PathInExpression &path) override;
virtual void visit (AST::TypePathSegment &segment) override;
virtual void visit (AST::TypePathSegmentGeneric &segment) override;
Expand Down
Loading
Loading