Skip to content

Commit

Permalink
Merge #1029
Browse files Browse the repository at this point in the history
1029: Macro in trait impl r=CohenArthur a=CohenArthur

Needs #1028 

You can just review the last commit to avoid reviewing twice. Sorry about that!

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
  • Loading branch information
bors[bot] and CohenArthur committed Mar 17, 2022
2 parents 1a14348 + a7ef6f9 commit 1bb9a29
Show file tree
Hide file tree
Showing 13 changed files with 432 additions and 94 deletions.
147 changes: 131 additions & 16 deletions gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1511,18 +1511,51 @@ class SingleASTNode
EXPRESSION,
ITEM,
STMT,
EXTERN,
TRAIT,
IMPL,
TRAIT_IMPL,
};

private:
NodeType kind;

// FIXME make this a union
std::unique_ptr<Expr> expr;
std::unique_ptr<Item> item;
std::unique_ptr<Stmt> stmt;
std::unique_ptr<ExternalItem> external_item;
std::unique_ptr<TraitItem> trait_item;
std::unique_ptr<InherentImplItem> impl_item;
std::unique_ptr<TraitImplItem> trait_impl_item;

public:
SingleASTNode (std::unique_ptr<Expr> expr)
: kind (EXPRESSION), expr (std::move (expr)), item (nullptr), stmt (nullptr)
: kind (EXPRESSION), expr (std::move (expr))
{}

SingleASTNode (std::unique_ptr<Item> item)
: kind (ITEM), expr (nullptr), item (std::move (item)), stmt (nullptr)
: kind (ITEM), item (std::move (item))
{}

SingleASTNode (std::unique_ptr<Stmt> stmt)
: kind (STMT), expr (nullptr), item (nullptr), stmt (std::move (stmt))
: kind (STMT), stmt (std::move (stmt))
{}

SingleASTNode (std::unique_ptr<ExternalItem> item)
: kind (EXTERN), external_item (std::move (item))
{}

SingleASTNode (std::unique_ptr<TraitItem> item)
: kind (TRAIT), trait_item (std::move (item))
{}

SingleASTNode (std::unique_ptr<InherentImplItem> item)
: kind (IMPL), impl_item (std::move (item))
{}

SingleASTNode (std::unique_ptr<TraitImplItem> trait_impl_item)
: kind (TRAIT_IMPL), trait_impl_item (std::move (trait_impl_item))
{}

SingleASTNode (SingleASTNode const &other)
Expand All @@ -1541,6 +1574,22 @@ class SingleASTNode
case STMT:
stmt = other.stmt->clone_stmt ();
break;

case EXTERN:
external_item = other.external_item->clone_external_item ();
break;

case TRAIT:
trait_item = other.trait_item->clone_trait_item ();
break;

case IMPL:
impl_item = other.impl_item->clone_inherent_impl_item ();
break;

case TRAIT_IMPL:
trait_impl_item = other.trait_impl_item->clone_trait_impl_item ();
break;
}
}

Expand All @@ -1560,6 +1609,22 @@ class SingleASTNode
case STMT:
stmt = other.stmt->clone_stmt ();
break;

case EXTERN:
external_item = other.external_item->clone_external_item ();
break;

case TRAIT:
trait_item = other.trait_item->clone_trait_item ();
break;

case IMPL:
impl_item = other.impl_item->clone_inherent_impl_item ();
break;

case TRAIT_IMPL:
trait_impl_item = other.trait_impl_item->clone_trait_impl_item ();
break;
}
return *this;
}
Expand All @@ -1569,7 +1634,7 @@ class SingleASTNode

NodeType get_kind () const { return kind; }

std::unique_ptr<Expr> &get_inner ()
std::unique_ptr<Expr> &get_expr ()
{
rust_assert (kind == EXPRESSION);
return expr;
Expand Down Expand Up @@ -1610,6 +1675,30 @@ class SingleASTNode
return std::move (item);
}

std::unique_ptr<TraitItem> take_trait_item ()
{
rust_assert (!is_error ());
return std::move (trait_item);
}

std::unique_ptr<ExternalItem> take_external_item ()
{
rust_assert (!is_error ());
return std::move (external_item);
}

std::unique_ptr<InherentImplItem> take_impl_item ()
{
rust_assert (!is_error ());
return std::move (impl_item);
}

std::unique_ptr<TraitImplItem> take_trait_impl_item ()
{
rust_assert (!is_error ());
return std::move (trait_impl_item);
}

void accept_vis (ASTVisitor &vis)
{
switch (kind)
Expand All @@ -1625,6 +1714,22 @@ class SingleASTNode
case STMT:
stmt->accept_vis (vis);
break;

case EXTERN:
external_item->accept_vis (vis);
break;

case TRAIT:
trait_item->accept_vis (vis);
break;

case IMPL:
impl_item->accept_vis (vis);
break;

case TRAIT_IMPL:
trait_impl_item->accept_vis (vis);
break;
}
}

Expand All @@ -1638,9 +1743,18 @@ class SingleASTNode
return item == nullptr;
case STMT:
return stmt == nullptr;
default:
return true;
case EXTERN:
return external_item == nullptr;
case TRAIT:
return trait_item == nullptr;
case IMPL:
return impl_item == nullptr;
case TRAIT_IMPL:
return trait_impl_item == nullptr;
}

gcc_unreachable ();
return true;
}

std::string as_string ()
Expand All @@ -1653,18 +1767,19 @@ class SingleASTNode
return "Item: " + item->as_string ();
case STMT:
return "Stmt: " + stmt->as_string ();
default:
return "";
case EXTERN:
return "External Item: " + external_item->as_string ();
case TRAIT:
return "Trait Item: " + trait_item->as_string ();
case IMPL:
return "Impl Item: " + impl_item->as_string ();
case TRAIT_IMPL:
return "Trait Impl Item: " + impl_item->as_string ();
}
}

private:
NodeType kind;

// FIXME make this a union
std::unique_ptr<Expr> expr;
std::unique_ptr<Item> item;
std::unique_ptr<Stmt> stmt;
gcc_unreachable ();
return "";
}
};

/* Basically, a "fragment" that can be incorporated into the AST, created as
Expand Down
6 changes: 6 additions & 0 deletions gcc/rust/ast/rust-macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ class MacroInvocation : public TypeNoBounds,
public TraitItem,
public TraitImplItem,
public InherentImplItem,
public ExternalItem,
public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
Expand Down Expand Up @@ -537,6 +538,11 @@ class MacroInvocation : public TypeNoBounds,
return clone_macro_invocation_impl ();
}

MacroInvocation *clone_external_item_impl () const final override
{
return clone_macro_invocation_impl ();
}

/*virtual*/ MacroInvocation *clone_macro_invocation_impl () const
{
return new MacroInvocation (*this);
Expand Down
60 changes: 27 additions & 33 deletions gcc/rust/expand/rust-attribute-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1114,8 +1114,6 @@ AttrVisitor::visit (AST::ClosureExprInner &expr)
void
AttrVisitor::visit (AST::BlockExpr &expr)
{
expander.push_context (MacroExpander::BLOCK);

// initial strip test based on outer attrs
expander.expand_cfg_attrs (expr.get_outer_attrs ());
if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
Expand All @@ -1135,31 +1133,13 @@ AttrVisitor::visit (AST::BlockExpr &expr)
return;
}

// strip all statements
auto &stmts = expr.get_statements ();
for (auto it = stmts.begin (); it != stmts.end ();)
{
auto &stmt = *it;

stmt->accept_vis (*this);
std::function<std::unique_ptr<AST::Stmt> (AST::SingleASTNode)> extractor
= [] (AST::SingleASTNode node) { return node.take_stmt (); };

auto fragment = expander.take_expanded_fragment (*this);
if (fragment.should_expand ())
{
// Remove the current expanded invocation
it = stmts.erase (it);
for (auto &node : fragment.get_nodes ())
{
it = stmts.insert (it, node.take_stmt ());
it++;
}
}
expand_macro_children (MacroExpander::BLOCK, expr.get_statements (),
extractor);

else if (stmt->is_marked_for_strip ())
it = stmts.erase (it);
else
it++;
}
expander.push_context (MacroExpander::BLOCK);

// strip tail expression if exists - can actually fully remove it
if (expr.has_tail_expr ())
Expand Down Expand Up @@ -2489,8 +2469,11 @@ AttrVisitor::visit (AST::Trait &trait)
if (trait.has_where_clause ())
expand_where_clause (trait.get_where_clause ());

// strip trait items if required
expand_pointer_allow_strip (trait.get_trait_items ());
std::function<std::unique_ptr<AST::TraitItem> (AST::SingleASTNode)> extractor
= [] (AST::SingleASTNode node) { return node.take_trait_item (); };

expand_macro_children (MacroExpander::TRAIT, trait.get_trait_items (),
extractor);
}
void
AttrVisitor::visit (AST::InherentImpl &impl)
Expand Down Expand Up @@ -2523,8 +2506,11 @@ AttrVisitor::visit (AST::InherentImpl &impl)
if (impl.has_where_clause ())
expand_where_clause (impl.get_where_clause ());

// strip inherent impl items if required
expand_pointer_allow_strip (impl.get_impl_items ());
std::function<std::unique_ptr<AST::InherentImplItem> (AST::SingleASTNode)>
extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); };

expand_macro_children (MacroExpander::IMPL, impl.get_impl_items (),
extractor);
}
void
AttrVisitor::visit (AST::TraitImpl &impl)
Expand Down Expand Up @@ -2563,8 +2549,12 @@ AttrVisitor::visit (AST::TraitImpl &impl)
if (impl.has_where_clause ())
expand_where_clause (impl.get_where_clause ());

// strip trait impl items if required
expand_pointer_allow_strip (impl.get_impl_items ());
std::function<std::unique_ptr<AST::TraitImplItem> (AST::SingleASTNode)>
extractor
= [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };

expand_macro_children (MacroExpander::TRAIT_IMPL, impl.get_impl_items (),
extractor);
}
void
AttrVisitor::visit (AST::ExternalStaticItem &item)
Expand Down Expand Up @@ -2659,8 +2649,12 @@ AttrVisitor::visit (AST::ExternBlock &block)
return;
}

// strip external items if required
expand_pointer_allow_strip (block.get_extern_items ());
std::function<std::unique_ptr<AST::ExternalItem> (AST::SingleASTNode)>
extractor
= [] (AST::SingleASTNode node) { return node.take_external_item (); };

expand_macro_children (MacroExpander::EXTERN, block.get_extern_items (),
extractor);
}

// I don't think it would be possible to strip macros without expansion
Expand Down

0 comments on commit 1bb9a29

Please sign in to comment.