Skip to content

Commit 1bb9a29

Browse files
Merge #1029
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 <[email protected]>
2 parents 1a14348 + a7ef6f9 commit 1bb9a29

13 files changed

+432
-94
lines changed

gcc/rust/ast/rust-ast.h

Lines changed: 131 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,18 +1511,51 @@ class SingleASTNode
15111511
EXPRESSION,
15121512
ITEM,
15131513
STMT,
1514+
EXTERN,
1515+
TRAIT,
1516+
IMPL,
1517+
TRAIT_IMPL,
15141518
};
15151519

1520+
private:
1521+
NodeType kind;
1522+
1523+
// FIXME make this a union
1524+
std::unique_ptr<Expr> expr;
1525+
std::unique_ptr<Item> item;
1526+
std::unique_ptr<Stmt> stmt;
1527+
std::unique_ptr<ExternalItem> external_item;
1528+
std::unique_ptr<TraitItem> trait_item;
1529+
std::unique_ptr<InherentImplItem> impl_item;
1530+
std::unique_ptr<TraitImplItem> trait_impl_item;
1531+
1532+
public:
15161533
SingleASTNode (std::unique_ptr<Expr> expr)
1517-
: kind (EXPRESSION), expr (std::move (expr)), item (nullptr), stmt (nullptr)
1534+
: kind (EXPRESSION), expr (std::move (expr))
15181535
{}
15191536

15201537
SingleASTNode (std::unique_ptr<Item> item)
1521-
: kind (ITEM), expr (nullptr), item (std::move (item)), stmt (nullptr)
1538+
: kind (ITEM), item (std::move (item))
15221539
{}
15231540

15241541
SingleASTNode (std::unique_ptr<Stmt> stmt)
1525-
: kind (STMT), expr (nullptr), item (nullptr), stmt (std::move (stmt))
1542+
: kind (STMT), stmt (std::move (stmt))
1543+
{}
1544+
1545+
SingleASTNode (std::unique_ptr<ExternalItem> item)
1546+
: kind (EXTERN), external_item (std::move (item))
1547+
{}
1548+
1549+
SingleASTNode (std::unique_ptr<TraitItem> item)
1550+
: kind (TRAIT), trait_item (std::move (item))
1551+
{}
1552+
1553+
SingleASTNode (std::unique_ptr<InherentImplItem> item)
1554+
: kind (IMPL), impl_item (std::move (item))
1555+
{}
1556+
1557+
SingleASTNode (std::unique_ptr<TraitImplItem> trait_impl_item)
1558+
: kind (TRAIT_IMPL), trait_impl_item (std::move (trait_impl_item))
15261559
{}
15271560

15281561
SingleASTNode (SingleASTNode const &other)
@@ -1541,6 +1574,22 @@ class SingleASTNode
15411574
case STMT:
15421575
stmt = other.stmt->clone_stmt ();
15431576
break;
1577+
1578+
case EXTERN:
1579+
external_item = other.external_item->clone_external_item ();
1580+
break;
1581+
1582+
case TRAIT:
1583+
trait_item = other.trait_item->clone_trait_item ();
1584+
break;
1585+
1586+
case IMPL:
1587+
impl_item = other.impl_item->clone_inherent_impl_item ();
1588+
break;
1589+
1590+
case TRAIT_IMPL:
1591+
trait_impl_item = other.trait_impl_item->clone_trait_impl_item ();
1592+
break;
15441593
}
15451594
}
15461595

@@ -1560,6 +1609,22 @@ class SingleASTNode
15601609
case STMT:
15611610
stmt = other.stmt->clone_stmt ();
15621611
break;
1612+
1613+
case EXTERN:
1614+
external_item = other.external_item->clone_external_item ();
1615+
break;
1616+
1617+
case TRAIT:
1618+
trait_item = other.trait_item->clone_trait_item ();
1619+
break;
1620+
1621+
case IMPL:
1622+
impl_item = other.impl_item->clone_inherent_impl_item ();
1623+
break;
1624+
1625+
case TRAIT_IMPL:
1626+
trait_impl_item = other.trait_impl_item->clone_trait_impl_item ();
1627+
break;
15631628
}
15641629
return *this;
15651630
}
@@ -1569,7 +1634,7 @@ class SingleASTNode
15691634

15701635
NodeType get_kind () const { return kind; }
15711636

1572-
std::unique_ptr<Expr> &get_inner ()
1637+
std::unique_ptr<Expr> &get_expr ()
15731638
{
15741639
rust_assert (kind == EXPRESSION);
15751640
return expr;
@@ -1610,6 +1675,30 @@ class SingleASTNode
16101675
return std::move (item);
16111676
}
16121677

1678+
std::unique_ptr<TraitItem> take_trait_item ()
1679+
{
1680+
rust_assert (!is_error ());
1681+
return std::move (trait_item);
1682+
}
1683+
1684+
std::unique_ptr<ExternalItem> take_external_item ()
1685+
{
1686+
rust_assert (!is_error ());
1687+
return std::move (external_item);
1688+
}
1689+
1690+
std::unique_ptr<InherentImplItem> take_impl_item ()
1691+
{
1692+
rust_assert (!is_error ());
1693+
return std::move (impl_item);
1694+
}
1695+
1696+
std::unique_ptr<TraitImplItem> take_trait_impl_item ()
1697+
{
1698+
rust_assert (!is_error ());
1699+
return std::move (trait_impl_item);
1700+
}
1701+
16131702
void accept_vis (ASTVisitor &vis)
16141703
{
16151704
switch (kind)
@@ -1625,6 +1714,22 @@ class SingleASTNode
16251714
case STMT:
16261715
stmt->accept_vis (vis);
16271716
break;
1717+
1718+
case EXTERN:
1719+
external_item->accept_vis (vis);
1720+
break;
1721+
1722+
case TRAIT:
1723+
trait_item->accept_vis (vis);
1724+
break;
1725+
1726+
case IMPL:
1727+
impl_item->accept_vis (vis);
1728+
break;
1729+
1730+
case TRAIT_IMPL:
1731+
trait_impl_item->accept_vis (vis);
1732+
break;
16281733
}
16291734
}
16301735

@@ -1638,9 +1743,18 @@ class SingleASTNode
16381743
return item == nullptr;
16391744
case STMT:
16401745
return stmt == nullptr;
1641-
default:
1642-
return true;
1746+
case EXTERN:
1747+
return external_item == nullptr;
1748+
case TRAIT:
1749+
return trait_item == nullptr;
1750+
case IMPL:
1751+
return impl_item == nullptr;
1752+
case TRAIT_IMPL:
1753+
return trait_impl_item == nullptr;
16431754
}
1755+
1756+
gcc_unreachable ();
1757+
return true;
16441758
}
16451759

16461760
std::string as_string ()
@@ -1653,18 +1767,19 @@ class SingleASTNode
16531767
return "Item: " + item->as_string ();
16541768
case STMT:
16551769
return "Stmt: " + stmt->as_string ();
1656-
default:
1657-
return "";
1770+
case EXTERN:
1771+
return "External Item: " + external_item->as_string ();
1772+
case TRAIT:
1773+
return "Trait Item: " + trait_item->as_string ();
1774+
case IMPL:
1775+
return "Impl Item: " + impl_item->as_string ();
1776+
case TRAIT_IMPL:
1777+
return "Trait Impl Item: " + impl_item->as_string ();
16581778
}
1659-
}
16601779

1661-
private:
1662-
NodeType kind;
1663-
1664-
// FIXME make this a union
1665-
std::unique_ptr<Expr> expr;
1666-
std::unique_ptr<Item> item;
1667-
std::unique_ptr<Stmt> stmt;
1780+
gcc_unreachable ();
1781+
return "";
1782+
}
16681783
};
16691784

16701785
/* Basically, a "fragment" that can be incorporated into the AST, created as

gcc/rust/ast/rust-macro.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ class MacroInvocation : public TypeNoBounds,
460460
public TraitItem,
461461
public TraitImplItem,
462462
public InherentImplItem,
463+
public ExternalItem,
463464
public ExprWithoutBlock
464465
{
465466
std::vector<Attribute> outer_attrs;
@@ -537,6 +538,11 @@ class MacroInvocation : public TypeNoBounds,
537538
return clone_macro_invocation_impl ();
538539
}
539540

541+
MacroInvocation *clone_external_item_impl () const final override
542+
{
543+
return clone_macro_invocation_impl ();
544+
}
545+
540546
/*virtual*/ MacroInvocation *clone_macro_invocation_impl () const
541547
{
542548
return new MacroInvocation (*this);

gcc/rust/expand/rust-attribute-visitor.cc

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,6 @@ AttrVisitor::visit (AST::ClosureExprInner &expr)
11141114
void
11151115
AttrVisitor::visit (AST::BlockExpr &expr)
11161116
{
1117-
expander.push_context (MacroExpander::BLOCK);
1118-
11191117
// initial strip test based on outer attrs
11201118
expander.expand_cfg_attrs (expr.get_outer_attrs ());
11211119
if (expander.fails_cfg_with_expand (expr.get_outer_attrs ()))
@@ -1135,31 +1133,13 @@ AttrVisitor::visit (AST::BlockExpr &expr)
11351133
return;
11361134
}
11371135

1138-
// strip all statements
1139-
auto &stmts = expr.get_statements ();
1140-
for (auto it = stmts.begin (); it != stmts.end ();)
1141-
{
1142-
auto &stmt = *it;
1143-
1144-
stmt->accept_vis (*this);
1136+
std::function<std::unique_ptr<AST::Stmt> (AST::SingleASTNode)> extractor
1137+
= [] (AST::SingleASTNode node) { return node.take_stmt (); };
11451138

1146-
auto fragment = expander.take_expanded_fragment (*this);
1147-
if (fragment.should_expand ())
1148-
{
1149-
// Remove the current expanded invocation
1150-
it = stmts.erase (it);
1151-
for (auto &node : fragment.get_nodes ())
1152-
{
1153-
it = stmts.insert (it, node.take_stmt ());
1154-
it++;
1155-
}
1156-
}
1139+
expand_macro_children (MacroExpander::BLOCK, expr.get_statements (),
1140+
extractor);
11571141

1158-
else if (stmt->is_marked_for_strip ())
1159-
it = stmts.erase (it);
1160-
else
1161-
it++;
1162-
}
1142+
expander.push_context (MacroExpander::BLOCK);
11631143

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

2492-
// strip trait items if required
2493-
expand_pointer_allow_strip (trait.get_trait_items ());
2472+
std::function<std::unique_ptr<AST::TraitItem> (AST::SingleASTNode)> extractor
2473+
= [] (AST::SingleASTNode node) { return node.take_trait_item (); };
2474+
2475+
expand_macro_children (MacroExpander::TRAIT, trait.get_trait_items (),
2476+
extractor);
24942477
}
24952478
void
24962479
AttrVisitor::visit (AST::InherentImpl &impl)
@@ -2523,8 +2506,11 @@ AttrVisitor::visit (AST::InherentImpl &impl)
25232506
if (impl.has_where_clause ())
25242507
expand_where_clause (impl.get_where_clause ());
25252508

2526-
// strip inherent impl items if required
2527-
expand_pointer_allow_strip (impl.get_impl_items ());
2509+
std::function<std::unique_ptr<AST::InherentImplItem> (AST::SingleASTNode)>
2510+
extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); };
2511+
2512+
expand_macro_children (MacroExpander::IMPL, impl.get_impl_items (),
2513+
extractor);
25282514
}
25292515
void
25302516
AttrVisitor::visit (AST::TraitImpl &impl)
@@ -2563,8 +2549,12 @@ AttrVisitor::visit (AST::TraitImpl &impl)
25632549
if (impl.has_where_clause ())
25642550
expand_where_clause (impl.get_where_clause ());
25652551

2566-
// strip trait impl items if required
2567-
expand_pointer_allow_strip (impl.get_impl_items ());
2552+
std::function<std::unique_ptr<AST::TraitImplItem> (AST::SingleASTNode)>
2553+
extractor
2554+
= [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
2555+
2556+
expand_macro_children (MacroExpander::TRAIT_IMPL, impl.get_impl_items (),
2557+
extractor);
25682558
}
25692559
void
25702560
AttrVisitor::visit (AST::ExternalStaticItem &item)
@@ -2659,8 +2649,12 @@ AttrVisitor::visit (AST::ExternBlock &block)
26592649
return;
26602650
}
26612651

2662-
// strip external items if required
2663-
expand_pointer_allow_strip (block.get_extern_items ());
2652+
std::function<std::unique_ptr<AST::ExternalItem> (AST::SingleASTNode)>
2653+
extractor
2654+
= [] (AST::SingleASTNode node) { return node.take_external_item (); };
2655+
2656+
expand_macro_children (MacroExpander::EXTERN, block.get_extern_items (),
2657+
extractor);
26642658
}
26652659

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

0 commit comments

Comments
 (0)