aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/expand
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/expand')
-rw-r--r--gcc/rust/expand/rust-cfg-strip.cc53
-rw-r--r--gcc/rust/expand/rust-cfg-strip.h23
-rw-r--r--gcc/rust/expand/rust-derive-clone.cc9
-rw-r--r--gcc/rust/expand/rust-derive-cmp-common.cc8
-rw-r--r--gcc/rust/expand/rust-derive-eq.cc6
-rw-r--r--gcc/rust/expand/rust-derive-hash.cc2
-rw-r--r--gcc/rust/expand/rust-derive-ord.cc2
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.cc10
-rw-r--r--gcc/rust/expand/rust-derive.h11
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc184
-rw-r--r--gcc/rust/expand/rust-expand-visitor.h67
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.cc30
-rw-r--r--gcc/rust/expand/rust-macro-builtins-format-args.cc78
-rw-r--r--gcc/rust/expand/rust-macro-builtins-helpers.h1
-rw-r--r--gcc/rust/expand/rust-macro-builtins-offset-of.cc2
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc1
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc49
-rw-r--r--gcc/rust/expand/rust-macro-expand.h2
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.cc19
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.h6
20 files changed, 368 insertions, 195 deletions
diff --git a/gcc/rust/expand/rust-cfg-strip.cc b/gcc/rust/expand/rust-cfg-strip.cc
index 58d8071..3c5e74e 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -22,6 +22,7 @@
#include "rust-path.h"
#include "rust-session-manager.h"
#include "rust-attribute-values.h"
+#include "rust-macro-expand.h"
namespace Rust {
@@ -30,7 +31,7 @@ namespace Rust {
* should be stripped. Note that attributes must be expanded before calling.
*/
bool
-fails_cfg (const AST::AttrVec &attrs)
+CfgStrip::fails_cfg (const AST::AttrVec &attrs) const
{
auto &session = Session::get_instance ();
@@ -39,6 +40,9 @@ fails_cfg (const AST::AttrVec &attrs)
if (attr.get_path () == Values::Attributes::CFG
&& !attr.check_cfg_predicate (session))
return true;
+ else if (!expansion_cfg.should_test
+ && attr.get_path () == Values::Attributes::TEST)
+ return true;
}
return false;
}
@@ -48,7 +52,7 @@ fails_cfg (const AST::AttrVec &attrs)
* should be stripped. Will expand attributes as well.
*/
bool
-fails_cfg_with_expand (AST::AttrVec &attrs)
+CfgStrip::fails_cfg_with_expand (AST::AttrVec &attrs) const
{
auto &session = Session::get_instance ();
@@ -85,6 +89,9 @@ fails_cfg_with_expand (AST::AttrVec &attrs)
attr.as_string ().c_str ());
}
}
+ else if (!expansion_cfg.should_test
+ && attr.get_path () == Values::Attributes::TEST)
+ return true;
}
return false;
}
@@ -2062,38 +2069,6 @@ CfgStrip::visit (AST::StaticItem &static_item)
}
void
-CfgStrip::visit (AST::TraitItemConst &item)
-{
- // initial test based on outer attrs
- expand_cfg_attrs (item.get_outer_attrs ());
- if (fails_cfg_with_expand (item.get_outer_attrs ()))
- {
- item.mark_for_strip ();
- return;
- }
-
- AST::DefaultASTVisitor::visit (item);
-
- // strip any sub-types
- auto &type = item.get_type ();
-
- if (type.is_marked_for_strip ())
- rust_error_at (type.get_locus (), "cannot strip type in this position");
-
- /* strip any internal sub-expressions - expression itself isn't
- * allowed to have external attributes in this position so can't be
- * stripped */
- if (item.has_expression ())
- {
- auto &expr = item.get_expr ();
- if (expr.is_marked_for_strip ())
- rust_error_at (expr.get_locus (),
- "cannot strip expression in this position - outer "
- "attributes not allowed");
- }
-}
-
-void
CfgStrip::visit (AST::TraitItemType &item)
{
// initial test based on outer attrs
@@ -2374,7 +2349,7 @@ CfgStrip::visit (AST::StructPattern &pattern)
maybe_strip_pointer_allow_strip (elems.get_struct_pattern_fields ());
// assuming you can strip the ".." part
- if (elems.has_etc ())
+ if (elems.has_rest ())
{
expand_cfg_attrs (elems.get_etc_outer_attrs ());
if (fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
@@ -2383,7 +2358,7 @@ CfgStrip::visit (AST::StructPattern &pattern)
}
void
-CfgStrip::visit (AST::TupleStructItemsNoRange &tuple_items)
+CfgStrip::visit (AST::TupleStructItemsNoRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
// can't strip individual patterns, only sub-patterns
@@ -2396,7 +2371,7 @@ CfgStrip::visit (AST::TupleStructItemsNoRange &tuple_items)
}
}
void
-CfgStrip::visit (AST::TupleStructItemsRange &tuple_items)
+CfgStrip::visit (AST::TupleStructItemsHasRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
// can't strip individual patterns, only sub-patterns
@@ -2429,7 +2404,7 @@ CfgStrip::visit (AST::TupleStructPattern &pattern)
}
void
-CfgStrip::visit (AST::TuplePatternItemsMultiple &tuple_items)
+CfgStrip::visit (AST::TuplePatternItemsNoRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
@@ -2444,7 +2419,7 @@ CfgStrip::visit (AST::TuplePatternItemsMultiple &tuple_items)
}
void
-CfgStrip::visit (AST::TuplePatternItemsRanged &tuple_items)
+CfgStrip::visit (AST::TuplePatternItemsHasRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index 767cf28..42cd266 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -23,14 +23,23 @@
#include "rust-item.h"
namespace Rust {
+
+// forward declare
+struct ExpansionCfg;
+
// Visitor used to maybe_strip attributes.
class CfgStrip : public AST::DefaultASTVisitor
{
private:
+ bool fails_cfg (const AST::AttrVec &attrs) const;
+
+ bool fails_cfg_with_expand (AST::AttrVec &attrs) const;
+
public:
using DefaultASTVisitor::visit;
- CfgStrip () {}
+ CfgStrip (const ExpansionCfg &expansion_cfg) : expansion_cfg (expansion_cfg)
+ {}
/* Run the AttrVisitor on an entire crate */
void go (AST::Crate &crate);
@@ -147,7 +156,6 @@ public:
void visit (AST::Union &union_item) override;
void visit (AST::ConstantItem &const_item) override;
void visit (AST::StaticItem &static_item) override;
- void visit (AST::TraitItemConst &item) override;
void visit (AST::TraitItemType &item) override;
void visit (AST::Trait &trait) override;
void visit (AST::InherentImpl &impl) override;
@@ -166,11 +174,11 @@ public:
void visit (AST::StructPatternFieldIdentPat &field) override;
void visit (AST::StructPatternFieldIdent &field) override;
void visit (AST::StructPattern &pattern) override;
- void visit (AST::TupleStructItemsNoRange &tuple_items) override;
- void visit (AST::TupleStructItemsRange &tuple_items) override;
+ void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ void visit (AST::TupleStructItemsHasRest &tuple_items) override;
void visit (AST::TupleStructPattern &pattern) override;
- void visit (AST::TuplePatternItemsMultiple &tuple_items) override;
- void visit (AST::TuplePatternItemsRanged &tuple_items) override;
+ void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
void visit (AST::GroupedPattern &pattern) override;
void visit (AST::SlicePatternItemsNoRest &items) override;
void visit (AST::SlicePatternItemsHasRest &items) override;
@@ -194,6 +202,9 @@ public:
{
DefaultASTVisitor::visit (item);
}
+
+private:
+ const ExpansionCfg &expansion_cfg;
};
} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc
index 321fa00..27dcc66 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -64,11 +64,10 @@ DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr)
new BlockExpr ({}, std::move (clone_expr), {}, {}, tl::nullopt, loc, loc));
auto big_self_type = builder.single_type_path ("Self");
- std::unique_ptr<SelfParam> self (new SelfParam (tl::nullopt,
- /* is_mut */ false, loc));
-
std::vector<std::unique_ptr<Param>> params;
- params.push_back (std::move (self));
+
+ params.emplace_back (new SelfParam (tl::nullopt,
+ /* is_mut */ false, loc));
return std::unique_ptr<AssociatedItem> (
new Function ({"clone"}, builder.fn_qualifiers (), /* generics */ {},
@@ -211,7 +210,7 @@ DeriveClone::clone_enum_tuple (PathInExpression variant_path,
}
auto pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new ReferencePattern (
std::unique_ptr<Pattern> (new TupleStructPattern (
diff --git a/gcc/rust/expand/rust-derive-cmp-common.cc b/gcc/rust/expand/rust-derive-cmp-common.cc
index 22ca16f..9890bb7 100644
--- a/gcc/rust/expand/rust-derive-cmp-common.cc
+++ b/gcc/rust/expand/rust-derive-cmp-common.cc
@@ -101,9 +101,9 @@ EnumMatchBuilder::tuple (EnumItem &variant_raw)
auto other_variant_path = builder.variant_path (enum_path, variant_path);
auto self_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (self_patterns)));
+ new TupleStructItemsNoRest (std::move (self_patterns)));
auto other_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (other_patterns)));
+ new TupleStructItemsNoRest (std::move (other_patterns)));
auto self_pattern = std::unique_ptr<Pattern> (
new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
@@ -114,7 +114,7 @@ EnumMatchBuilder::tuple (EnumItem &variant_raw)
other_variant_path, std::move (other_pattern_items))),
false, false, builder.loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern
@@ -176,7 +176,7 @@ EnumMatchBuilder::strukt (EnumItem &variant_raw)
std::move (other_elts))),
false, false, builder.loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern
diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc
index 7da137f..17332a4 100644
--- a/gcc/rust/expand/rust-derive-eq.cc
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -128,9 +128,13 @@ DeriveEq::eq_impls (
auto eq_impl = builder.trait_impl (eq, std::move (eq_generics.self_type),
std::move (trait_items),
std::move (eq_generics.impl));
+
+ // StructuralEq is a marker trait
+ decltype (trait_items) steq_trait_items = {};
+
auto steq_impl
= builder.trait_impl (steq, std::move (steq_generics.self_type),
- std::move (trait_items),
+ std::move (steq_trait_items),
std::move (steq_generics.impl));
return vec (std::move (eq_impl), std::move (steq_impl));
diff --git a/gcc/rust/expand/rust-derive-hash.cc b/gcc/rust/expand/rust-derive-hash.cc
index 94aede2..616bfdb 100644
--- a/gcc/rust/expand/rust-derive-hash.cc
+++ b/gcc/rust/expand/rust-derive-hash.cc
@@ -151,7 +151,7 @@ DeriveHash::match_enum_tuple (PathInExpression variant_path,
}
auto patterns_elts = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (self_patterns)));
+ new TupleStructItemsNoRest (std::move (self_patterns)));
auto pattern = std::unique_ptr<Pattern> (
new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
variant_path, std::move (patterns_elts))),
diff --git a/gcc/rust/expand/rust-derive-ord.cc b/gcc/rust/expand/rust-derive-ord.cc
index afc4b71..6f3981f 100644
--- a/gcc/rust/expand/rust-derive-ord.cc
+++ b/gcc/rust/expand/rust-derive-ord.cc
@@ -120,7 +120,7 @@ DeriveOrd::make_equal ()
if (ordering == Ordering::Partial)
{
auto pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (vec (std::move (equal))));
+ new TupleStructItemsNoRest (vec (std::move (equal))));
equal
= std::make_unique<TupleStructPattern> (builder.path_in_expression (
diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc b/gcc/rust/expand/rust-derive-partial-eq.cc
index a0bf87a..287d8a7 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.cc
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -146,7 +146,7 @@ DerivePartialEq::match_enum_identifier (
builder.ref_pattern (
std::unique_ptr<Pattern> (new PathInExpression (variant_path))));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
std::move (inner_ref_patterns));
auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
@@ -186,9 +186,9 @@ DerivePartialEq::match_enum_tuple (PathInExpression variant_path,
}
auto self_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (self_patterns)));
+ new TupleStructItemsNoRest (std::move (self_patterns)));
auto other_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (other_patterns)));
+ new TupleStructItemsNoRest (std::move (other_patterns)));
auto self_pattern = std::unique_ptr<Pattern> (
new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
@@ -199,7 +199,7 @@ DerivePartialEq::match_enum_tuple (PathInExpression variant_path,
variant_path, std::move (other_pattern_items))),
false, false, loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
@@ -254,7 +254,7 @@ DerivePartialEq::match_enum_struct (PathInExpression variant_path,
variant_path, loc, std::move (other_elts))),
false, false, loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index 10c146c..d28bba9 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -192,7 +192,6 @@ private:
virtual void visit (EnumItemDiscriminant &item) override final{};
virtual void visit (ConstantItem &const_item) override final{};
virtual void visit (StaticItem &static_item) override final{};
- virtual void visit (TraitItemConst &item) override final{};
virtual void visit (TraitItemType &item) override final{};
virtual void visit (Trait &trait) override final{};
virtual void visit (InherentImpl &impl) override final{};
@@ -224,11 +223,11 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override final{};
virtual void visit (StructPatternFieldIdent &field) override final{};
virtual void visit (StructPattern &pattern) override final{};
- virtual void visit (TupleStructItemsNoRange &tuple_items) override final{};
- virtual void visit (TupleStructItemsRange &tuple_items) override final{};
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override final{};
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override final{};
virtual void visit (TupleStructPattern &pattern) override final{};
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override final{};
- virtual void visit (TuplePatternItemsRanged &tuple_items) override final{};
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override final{};
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override final{};
virtual void visit (TuplePattern &pattern) override final{};
virtual void visit (GroupedPattern &pattern) override final{};
virtual void visit (SlicePatternItemsNoRest &items) override final{};
@@ -262,4 +261,4 @@ private:
} // namespace AST
} // namespace Rust
-#endif // DERIVE_VISITOR_H
+#endif // DERIVE_VISITOR_H \ No newline at end of file
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index 8f6e7fa..4593cc3 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -18,6 +18,7 @@
#include "rust-expand-visitor.h"
#include "rust-ast-fragment.h"
+#include "rust-item.h"
#include "rust-proc-macro.h"
#include "rust-attributes.h"
#include "rust-ast.h"
@@ -62,7 +63,7 @@ derive_item (AST::Item &item, AST::SimplePath &to_derive,
{
switch (node.get_kind ())
{
- case AST::SingleASTNode::ITEM:
+ case AST::SingleASTNode::Kind::Item:
result.push_back (node.take_item ());
break;
default:
@@ -85,7 +86,7 @@ expand_item_attribute (AST::Item &item, AST::SimplePath &name,
{
switch (node.get_kind ())
{
- case AST::SingleASTNode::ITEM:
+ case AST::SingleASTNode::Kind::Item:
result.push_back (node.take_item ());
break;
default:
@@ -114,7 +115,7 @@ expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
{
switch (node.get_kind ())
{
- case AST::SingleASTNode::STMT:
+ case AST::SingleASTNode::Kind::Stmt:
result.push_back (node.take_stmt ());
break;
default:
@@ -329,10 +330,15 @@ ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
void
ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
{
+ NodeId old_expect = expr->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+
expander.push_context (MacroExpander::ContextType::EXPR);
expr->accept_vis (*this);
expander.pop_context ();
+ std::swap (macro_invoc_expect_id, old_expect);
+
auto final_fragment = expander.take_expanded_fragment ();
if (final_fragment.should_expand ()
&& final_fragment.is_expression_fragment ())
@@ -342,14 +348,54 @@ ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
void
ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
{
- expander.push_context (MacroExpander::ContextType::TYPE);
+ NodeId old_expect = type->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+ expander.push_context (MacroExpander::ContextType::TYPE);
type->accept_vis (*this);
+ expander.pop_context ();
+
+ std::swap (macro_invoc_expect_id, old_expect);
+
auto final_fragment = expander.take_expanded_fragment ();
if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
type = final_fragment.take_type_fragment ();
+}
+
+// HACK: maybe we shouldn't have TypeNoBounds as a base class
+void
+ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
+{
+ NodeId old_expect = type->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+ expander.push_context (MacroExpander::ContextType::TYPE);
+ type->accept_vis (*this);
expander.pop_context ();
+
+ std::swap (macro_invoc_expect_id, old_expect);
+
+ auto final_fragment = expander.take_expanded_fragment ();
+ if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
+ type = std::make_unique<AST::ParenthesisedType> (
+ final_fragment.take_type_fragment (), BUILTINS_LOCATION);
+}
+
+void
+ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
+{
+ NodeId old_expect = pattern->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+
+ expander.push_context (MacroExpander::ContextType::PATTERN);
+ pattern->accept_vis (*this);
+ expander.pop_context ();
+
+ std::swap (macro_invoc_expect_id, old_expect);
+
+ auto final_fragment = expander.take_expanded_fragment ();
+ if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
+ pattern = final_fragment.take_pattern_fragment ();
}
// FIXME: Can this be refactored into a `scoped` method? Which takes a
@@ -424,6 +470,8 @@ ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
{
for (auto &param : params)
{
+ maybe_expand_pattern (param.get_pattern_ptr ());
+
if (param.has_type_given ())
maybe_expand_type (param.get_type_ptr ());
}
@@ -465,6 +513,14 @@ ExpandVisitor::visit (AST::ConstGenericParam &)
void
ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
{
+ if (macro_invoc_expect_id != macro_invoc.get_node_id ())
+ {
+ rust_internal_error_at (
+ macro_invoc.get_locus (),
+ "attempting to expand node with id %d into position with node id %d",
+ (int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
+ }
+
// TODO: Can we do the AST fragment replacing here? Probably not, right?
expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
? AST::InvocKind::Semicoloned
@@ -542,12 +598,6 @@ ExpandVisitor::visit (AST::MetaItemPathExpr &)
{}
void
-ExpandVisitor::visit (AST::ErrorPropagationExpr &expr)
-{
- visit (expr.get_propagating_expr ());
-}
-
-void
ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
{
maybe_expand_expr (expr.get_left_expr_ptr ());
@@ -569,6 +619,13 @@ ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
}
void
+ExpandVisitor::visit (AST::TypeCastExpr &expr)
+{
+ maybe_expand_expr (expr.get_casted_expr_ptr ());
+ maybe_expand_type (expr.get_type_to_cast_to_ptr ());
+}
+
+void
ExpandVisitor::visit (AST::AssignmentExpr &expr)
{
maybe_expand_expr (expr.get_left_expr_ptr ());
@@ -602,20 +659,11 @@ ExpandVisitor::visit (AST::CallExpr &expr)
}
void
-ExpandVisitor::visit (AST::MethodCallExpr &expr)
-{
- visit (expr.get_receiver_expr ());
-
- for (auto &param : expr.get_params ())
- maybe_expand_expr (param);
-}
-
-void
ExpandVisitor::visit (AST::ClosureExprInner &expr)
{
expand_closure_params (expr.get_params ());
- visit (expr.get_definition_expr ());
+ maybe_expand_expr (expr.get_definition_expr_ptr ());
}
void
@@ -677,22 +725,10 @@ ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
}
void
-ExpandVisitor::visit (AST::MatchExpr &expr)
+ExpandVisitor::visit (AST::TupleExpr &expr)
{
- visit (expr.get_scrutinee_expr ());
-
- for (auto &match_case : expr.get_match_cases ())
- {
- auto &arm = match_case.get_arm ();
-
- for (auto &pattern : arm.get_patterns ())
- visit (pattern);
-
- if (arm.has_match_arm_guard ())
- maybe_expand_expr (arm.get_guard_expr_ptr ());
-
- maybe_expand_expr (match_case.get_expr_ptr ());
- }
+ for (auto &sub : expr.get_tuple_elems ())
+ maybe_expand_expr (sub);
}
void
@@ -838,15 +874,6 @@ ExpandVisitor::visit (AST::StaticItem &static_item)
}
void
-ExpandVisitor::visit (AST::TraitItemConst &const_item)
-{
- maybe_expand_type (const_item.get_type_ptr ());
-
- if (const_item.has_expr ())
- maybe_expand_expr (const_item.get_expr_ptr ());
-}
-
-void
ExpandVisitor::visit (AST::Trait &trait)
{
for (auto &generic : trait.get_generic_params ())
@@ -970,13 +997,70 @@ ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
void
ExpandVisitor::visit (AST::GroupedPattern &pattern)
{
- visit (pattern.get_pattern_in_parens ());
+ maybe_expand_pattern (pattern.get_pattern_in_parens_ptr ());
+}
+
+void
+ExpandVisitor::visit (AST::SlicePatternItemsNoRest &items)
+{
+ for (auto &sub : items.get_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::SlicePatternItemsHasRest &items)
+{
+ for (auto &sub : items.get_lower_patterns ())
+ maybe_expand_pattern (sub);
+ for (auto &sub : items.get_upper_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::AltPattern &pattern)
+{
+ for (auto &alt : pattern.get_alts ())
+ maybe_expand_pattern (alt);
+}
+
+void
+ExpandVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_lower_patterns ())
+ maybe_expand_pattern (sub);
+
+ for (auto &sub : tuple_items.get_upper_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_lower_patterns ())
+ maybe_expand_pattern (sub);
+
+ for (auto &sub : tuple_items.get_upper_patterns ())
+ maybe_expand_pattern (sub);
}
void
ExpandVisitor::visit (AST::LetStmt &stmt)
{
- visit (stmt.get_pattern ());
+ maybe_expand_pattern (stmt.get_pattern_ptr ());
if (stmt.has_type ())
maybe_expand_type (stmt.get_type_ptr ());
@@ -1006,10 +1090,18 @@ ExpandVisitor::visit (AST::BareFunctionType &type)
void
ExpandVisitor::visit (AST::FunctionParam &param)
{
+ maybe_expand_pattern (param.get_pattern_ptr ());
maybe_expand_type (param.get_type_ptr ());
}
void
+ExpandVisitor::visit (AST::VariadicParam &param)
+{
+ if (param.has_pattern ())
+ maybe_expand_pattern (param.get_pattern_ptr ());
+}
+
+void
ExpandVisitor::visit (AST::SelfParam &param)
{
/* TODO: maybe check for invariants being violated - e.g. both type and
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index 845e10c..b79eb66 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -19,7 +19,9 @@
#ifndef RUST_EXPAND_VISITOR_H
#define RUST_EXPAND_VISITOR_H
+#include "rust-ast-pointer-visitor.h"
#include "rust-ast-visitor.h"
+#include "rust-item.h"
#include "rust-macro-expand.h"
#include "rust-proc-macro.h"
@@ -35,27 +37,48 @@ bool is_derive (AST::Attribute &attr);
*/
bool is_builtin (AST::Attribute &attr);
-class ExpandVisitor : public AST::DefaultASTVisitor
+class ExpandVisitor : public AST::PointerVisitor
{
public:
- ExpandVisitor (MacroExpander &expander) : expander (expander) {}
+ ExpandVisitor (MacroExpander &expander)
+ : expander (expander), macro_invoc_expect_id (UNKNOWN_NODEID)
+ {}
/* Expand all of the macro invocations currently contained in a crate */
void go (AST::Crate &crate);
- using AST::DefaultASTVisitor::visit;
+ using AST::PointerVisitor::reseat;
+ using AST::PointerVisitor::visit;
- /*
- Maybe expand a macro invocation in lieu of an expression
- expr : Core guidelines R33, this function reseat the pointer.
- */
- void maybe_expand_expr (std::unique_ptr<AST::Expr> &expr);
+ void reseat (std::unique_ptr<AST::Expr> &ptr) override
+ {
+ maybe_expand_expr (ptr);
+ }
- /*
- Maybe expand a macro invocation in lieu of a type
- type : Core guidelines R33, this function reseat the pointer.
+ void reseat (std::unique_ptr<AST::Type> &ptr) override
+ {
+ maybe_expand_type (ptr);
+ }
+
+ void reseat (std::unique_ptr<AST::TypeNoBounds> &ptr) override
+ {
+ maybe_expand_type (ptr);
+ }
+
+ void reseat (std::unique_ptr<AST::Pattern> &ptr) override
+ {
+ maybe_expand_pattern (ptr);
+ }
+
+ /**
+ * Maybe expand a macro invocation in lieu of an expression, type or pattern.
+ *
+ * @ptr Core guidelines R33, this function reseats the pointer.
*/
- void maybe_expand_type (std::unique_ptr<AST::Type> &type);
+ void maybe_expand_expr (std::unique_ptr<AST::Expr> &ptr);
+ void maybe_expand_type (std::unique_ptr<AST::Type> &ptr);
+ void maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type);
+ void maybe_expand_pattern (std::unique_ptr<AST::Pattern> &ptr);
/**
* Expand all macro invocations in lieu of types within a vector of struct
@@ -128,7 +151,10 @@ public:
auto &value = *it;
// Perform expansion
+ NodeId old_expect = value->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
value->accept_vis (*this);
+ std::swap (macro_invoc_expect_id, old_expect);
auto final_fragment = expander.take_expanded_fragment ();
@@ -210,17 +236,16 @@ public:
void visit (AST::AttrInputMacro &) override;
void visit (AST::MetaItemLitExpr &) override;
void visit (AST::MetaItemPathExpr &) override;
- void visit (AST::ErrorPropagationExpr &expr) override;
void visit (AST::ArithmeticOrLogicalExpr &expr) override;
void visit (AST::ComparisonExpr &expr) override;
void visit (AST::LazyBooleanExpr &expr) override;
+ void visit (AST::TypeCastExpr &expr) override;
void visit (AST::AssignmentExpr &expr) override;
void visit (AST::CompoundAssignmentExpr &expr) override;
void visit (AST::GroupedExpr &expr) override;
void visit (AST::StructExprStruct &expr) override;
void visit (AST::CallExpr &expr) override;
- void visit (AST::MethodCallExpr &expr) override;
void visit (AST::ClosureExprInner &expr) override;
void visit (AST::BlockExpr &expr) override;
@@ -231,7 +256,7 @@ public:
void visit (AST::IfExprConseqElse &expr) override;
void visit (AST::IfLetExpr &expr) override;
void visit (AST::IfLetExprConseqElse &expr) override;
- void visit (AST::MatchExpr &expr) override;
+ void visit (AST::TupleExpr &expr) override;
void visit (AST::TypeParam &param) override;
void visit (AST::LifetimeWhereClauseItem &) override;
void visit (AST::TypeBoundWhereClauseItem &item) override;
@@ -251,7 +276,6 @@ public:
void visit (AST::Union &union_item) override;
void visit (AST::ConstantItem &const_item) override;
void visit (AST::StaticItem &static_item) override;
- void visit (AST::TraitItemConst &item) override;
void visit (AST::Trait &trait) override;
void visit (AST::InherentImpl &impl) override;
void visit (AST::TraitImpl &impl) override;
@@ -269,12 +293,20 @@ public:
void visit (AST::MetaListNameValueStr &) override;
void visit (AST::StructPatternFieldIdent &field) override;
void visit (AST::GroupedPattern &pattern) override;
+ void visit (AST::SlicePatternItemsNoRest &items) override;
+ void visit (AST::SlicePatternItemsHasRest &items) override;
+ void visit (AST::AltPattern &pattern) override;
+ void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ void visit (AST::TupleStructItemsHasRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
void visit (AST::LetStmt &stmt) override;
void visit (AST::ExprStmt &stmt) override;
void visit (AST::BareFunctionType &type) override;
- void visit (AST::FunctionParam &type) override;
+ void visit (AST::FunctionParam &param) override;
+ void visit (AST::VariadicParam &param) override;
void visit (AST::SelfParam &type) override;
template <typename T>
@@ -287,6 +319,7 @@ public:
private:
MacroExpander &expander;
+ NodeId macro_invoc_expect_id;
};
} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 61222db..c991ca7 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -101,7 +101,7 @@ parse_clobber_abi (InlineAsmContext inline_asm_ctx)
if (token->get_id () == STRING_LITERAL)
{
// TODO: Caring for span in here.
- new_abis.push_back ({token->as_string (), token->get_locus ()});
+ new_abis.emplace_back (token->as_string (), token->get_locus ());
}
else
{
@@ -787,12 +787,12 @@ expand_inline_asm_strings (InlineAsmContext inline_asm_ctx)
auto pieces = Fmt::Pieces::collect (template_str.symbol, false,
Fmt::ffi::ParseMode::InlineAsm);
- auto pieces_vec = pieces.get_pieces ();
+ auto &pieces_vec = pieces.get_pieces ();
std::string transformed_template_str = "";
for (size_t i = 0; i < pieces_vec.size (); i++)
{
- auto piece = pieces_vec[i];
+ auto &piece = pieces_vec[i];
if (piece.tag == Fmt::ffi::Piece::Tag::String)
{
transformed_template_str += piece.string._0.to_string ();
@@ -880,7 +880,8 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
// context.
if (resulting_context)
{
- auto node = (*resulting_context).inline_asm.clone_expr_without_block ();
+ auto resulting_ctx = resulting_context.value ();
+ auto node = resulting_ctx.inline_asm.clone_expr_without_block ();
std::vector<AST::SingleASTNode> single_vec = {};
@@ -1124,8 +1125,11 @@ parse_llvm_clobbers (LlvmAsmContext &ctx)
{
ctx.llvm_asm.get_clobbers ().push_back (
{strip_double_quotes (token->as_string ()), token->get_locus ()});
+
+ parser.skip_token (STRING_LITERAL);
}
- parser.skip_token (STRING_LITERAL);
+
+ parser.maybe_skip_token (COMMA);
token = parser.peek_current_token ();
}
}
@@ -1177,12 +1181,13 @@ parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
auto asm_ctx = LlvmAsmContext (llvm_asm, parser, last_token_id);
- auto resulting_context
+ tl::optional<LlvmAsmContext> resulting_context
= parse_llvm_templates (asm_ctx).and_then (parse_llvm_arguments);
if (resulting_context)
{
- auto node = (*resulting_context).llvm_asm.clone_expr_without_block ();
+ auto resulting_ctx = resulting_context.value ();
+ auto node = resulting_ctx.llvm_asm.clone_expr_without_block ();
std::vector<AST::SingleASTNode> single_vec = {};
@@ -1190,12 +1195,13 @@ parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
// need to make it a statement. This way, it will be expanded
// properly.
if (semicolon == AST::InvocKind::Semicoloned)
- single_vec.emplace_back (AST::SingleASTNode (
- std::make_unique<AST::ExprStmt> (std::move (node), invoc_locus,
- semicolon
- == AST::InvocKind::Semicoloned)));
+ {
+ single_vec.emplace_back (
+ std::make_unique<AST::ExprStmt> (std::move (node), invoc_locus,
+ true /* has semicolon */));
+ }
else
- single_vec.emplace_back (AST::SingleASTNode (std::move (node)));
+ single_vec.emplace_back (std::move (node));
AST::Fragment fragment_ast
= AST::Fragment (single_vec,
diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc b/gcc/rust/expand/rust-macro-builtins-format-args.cc
index b20c849..eb2a1cc 100644
--- a/gcc/rust/expand/rust-macro-builtins-format-args.cc
+++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc
@@ -37,39 +37,42 @@ struct FormatArgsParseError
} kind;
};
-static tl::expected<FormatArgsInput, FormatArgsParseError>
-format_args_parse_arguments (AST::MacroInvocData &invoc)
+static inline tl::expected<std::string, AST::Fragment>
+format_args_parse_expr (location_t invoc_locus, AST::MacroInvocData &invoc,
+ Parser<MacroInvocLexer> &parser,
+ BuiltinMacro macro_kind)
{
- MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
- Parser<MacroInvocLexer> parser (lex);
-
- // TODO: check if EOF - return that format_args!() requires at least one
- // argument
-
- auto args = AST::FormatArguments ();
- auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
- std::unique_ptr<AST::Expr> format_expr = nullptr;
+ std::unique_ptr<AST::Expr> format_expr = parser.parse_expr ();
+ rust_assert (format_expr);
- // TODO: Handle the case where we're not parsing a string literal (macro
- // invocation for e.g.)
- switch (parser.peek_current_token ()->get_id ())
+ if (format_expr->get_expr_kind () == AST::Expr::Kind::MacroInvocation)
{
- case STRING_LITERAL:
- case RAW_STRING_LITERAL:
- format_expr = parser.parse_literal_expr ();
- default:
- // do nothing
- ;
+ std::vector<std::unique_ptr<AST::MacroInvocation>> pending;
+ pending.emplace_back (
+ static_cast<AST::MacroInvocation *> (format_expr.release ()));
+ return tl::unexpected<AST::Fragment> (
+ make_eager_builtin_invocation (macro_kind, invoc_locus,
+ invoc.get_delim_tok_tree (),
+ std::move (pending)));
}
- rust_assert (format_expr);
-
// TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
// macro invocation, what do we do here? return a tl::unexpected?
- auto format_str = static_cast<AST::LiteralExpr &> (*format_expr)
- .get_literal ()
- .as_string ();
+ rust_assert (format_expr->is_literal ());
+ return static_cast<AST::LiteralExpr &> (*format_expr)
+ .get_literal ()
+ .as_string ();
+}
+
+static inline tl::expected<AST::FormatArguments, FormatArgsParseError>
+format_args_parse_arguments (AST::MacroInvocData &invoc,
+ Parser<MacroInvocLexer> &parser,
+ TokenId last_token_id)
+{
+ // TODO: check if EOF - return that format_args!() requires at least one
+ // argument
+ auto args = AST::FormatArguments ();
// TODO: Allow implicit captures ONLY if the the first arg is a string literal
// and not a macro invocation
@@ -126,7 +129,7 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
// we need to skip commas, don't we?
}
- return FormatArgsInput{std::move (format_str), std::move (args)};
+ return args;
}
tl::optional<AST::Fragment>
@@ -135,9 +138,24 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
AST::InvocKind semicolon,
AST::FormatArgs::Newline nl)
{
- auto input = format_args_parse_arguments (invoc);
+ MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
+ Parser<MacroInvocLexer> parser (lex);
+
+ auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
+
+ auto format_str = format_args_parse_expr (invoc_locus, invoc, parser,
+ nl == AST::FormatArgs::Newline::Yes
+ ? BuiltinMacro::FormatArgsNl
+ : BuiltinMacro::FormatArgs);
+
+ if (!format_str)
+ {
+ return std::move (format_str.error ());
+ }
+
+ auto args = format_args_parse_arguments (invoc, parser, last_token_id);
- if (!input)
+ if (!args)
{
rust_error_at (invoc_locus,
"could not parse arguments to %<format_args!()%>");
@@ -173,7 +191,7 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
bool append_newline = nl == AST::FormatArgs::Newline::Yes;
- auto fmt_str = std::move (input->format_str);
+ auto fmt_str = std::move (format_str.value ());
if (append_newline)
fmt_str += '\n';
@@ -189,7 +207,7 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
// for creating the `template`
auto fmt_args_node = AST::FormatArgs (invoc_locus, std::move (pieces),
- std::move (input->args));
+ std::move (args.value ()));
auto expanded
= Fmt::expand_format_args (fmt_args_node,
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.h b/gcc/rust/expand/rust-macro-builtins-helpers.h
index 32cf58f..ce63017 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.h
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.h
@@ -22,7 +22,6 @@
#include "rust-ast.h"
#include "rust-cfg-strip.h"
#include "rust-diagnostics.h"
-#include "rust-early-name-resolver.h"
#include "rust-expr.h"
#include "rust-lex.h"
#include "rust-macro-builtins.h"
diff --git a/gcc/rust/expand/rust-macro-builtins-offset-of.cc b/gcc/rust/expand/rust-macro-builtins-offset-of.cc
index 53efe74..02c637b 100644
--- a/gcc/rust/expand/rust-macro-builtins-offset-of.cc
+++ b/gcc/rust/expand/rust-macro-builtins-offset-of.cc
@@ -56,7 +56,7 @@ MacroBuiltin::offset_of_handler (location_t invoc_locus,
parser.skip_token (COMMA);
auto field_tok = parser.parse_identifier_or_keyword_token ();
- auto invalid_field = !field_tok || !field_tok->has_str ();
+ auto invalid_field = !field_tok || !field_tok->should_have_str ();
if (invalid_field)
rust_error_at (invoc_locus, "could not parse field argument for %qs",
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index a7ae220..948f389 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -29,7 +29,6 @@
#include "rust-ast.h"
#include "rust-cfg-strip.h"
#include "rust-diagnostics.h"
-#include "rust-early-name-resolver.h"
#include "rust-expr.h"
#include "rust-lex.h"
#include "rust-macro-invoc-lexer.h"
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 4c54cef..52f8e2b 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -27,7 +27,6 @@
#include "rust-macro.h"
#include "rust-parse.h"
#include "rust-cfg-strip.h"
-#include "rust-early-name-resolver.h"
#include "rust-proc-macro.h"
#include "rust-token-tree-desugar.h"
@@ -961,9 +960,14 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
auto &lexer = parser.get_token_source ();
auto start = lexer.get_offs ();
- auto expr = parser.parse_expr ();
+ auto attrs = parser.parse_outer_attributes ();
+ auto expr = parser.parse_expr (std::move (attrs));
if (expr == nullptr)
- return AST::Fragment::create_error ();
+ {
+ for (auto error : parser.get_errors ())
+ error.emit ();
+ return AST::Fragment::create_error ();
+ }
// FIXME: make this an error for some edititons
if (parser.peek_current_token ()->get_id () == SEMICOLON)
@@ -999,6 +1003,27 @@ transcribe_type (Parser<MacroInvocLexer> &parser)
return AST::Fragment ({std::move (type)}, lexer.get_token_slice (start, end));
}
+/**
+ * Transcribe one pattern from a macro invocation
+ *
+ * @param parser Parser to extract statements from
+ */
+static AST::Fragment
+transcribe_pattern (Parser<MacroInvocLexer> &parser)
+{
+ auto &lexer = parser.get_token_source ();
+ auto start = lexer.get_offs ();
+
+ auto pattern = parser.parse_pattern ();
+ for (auto err : parser.get_errors ())
+ err.emit ();
+
+ auto end = lexer.get_offs ();
+
+ return AST::Fragment ({std::move (pattern)},
+ lexer.get_token_slice (start, end));
+}
+
static AST::Fragment
transcribe_context (MacroExpander::ContextType ctx,
Parser<MacroInvocLexer> &parser, bool semicolon,
@@ -1011,6 +1036,7 @@ transcribe_context (MacroExpander::ContextType ctx,
// -- Trait --> parser.parse_trait_item();
// -- Impl --> parser.parse_impl_item();
// -- Extern --> parser.parse_extern_item();
+ // -- Pattern --> parser.parse_pattern();
// -- None --> [has semicolon?]
// -- Yes --> parser.parse_stmt();
// -- No --> [switch invocation.delimiter()]
@@ -1039,6 +1065,8 @@ transcribe_context (MacroExpander::ContextType ctx,
break;
case MacroExpander::ContextType::TYPE:
return transcribe_type (parser);
+ case MacroExpander::ContextType::PATTERN:
+ return transcribe_pattern (parser);
break;
case MacroExpander::ContextType::STMT:
return transcribe_many_stmts (parser, last_token_id, semicolon);
@@ -1080,8 +1108,9 @@ MacroExpander::transcribe_rule (
auto invoc_stream = invoc_token_tree.to_token_stream ();
auto macro_rule_tokens = transcribe_tree.to_token_stream ();
- auto substitute_context = SubstituteCtx (invoc_stream, macro_rule_tokens,
- matched_fragments, definition);
+ auto substitute_context
+ = SubstituteCtx (invoc_stream, macro_rule_tokens, matched_fragments,
+ definition, invoc_token_tree.get_locus ());
std::vector<std::unique_ptr<AST::Token>> substituted_tokens
= substitute_context.substitute_tokens ();
@@ -1128,11 +1157,7 @@ MacroExpander::transcribe_rule (
// emit any errors
if (parser.has_errors ())
- {
- for (auto &err : parser.get_errors ())
- rust_error_at (err.locus, "%s", err.message.c_str ());
- return AST::Fragment::create_error ();
- }
+ return AST::Fragment::create_error ();
// are all the tokens used?
bool did_delimit = parser.skip_token (last_token_id);
@@ -1165,7 +1190,7 @@ MacroExpander::parse_proc_macro_output (ProcMacro::TokenStream ts)
auto result = parser.parse_item (false);
if (result == nullptr)
break;
- nodes.push_back ({std::move (result)});
+ nodes.emplace_back (std::move (result));
}
break;
case ContextType::STMT:
@@ -1174,7 +1199,7 @@ MacroExpander::parse_proc_macro_output (ProcMacro::TokenStream ts)
auto result = parser.parse_stmt ();
if (result == nullptr)
break;
- nodes.push_back ({std::move (result)});
+ nodes.emplace_back (std::move (result));
}
break;
case ContextType::TRAIT:
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 360294c..c3d5e7d 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -27,7 +27,6 @@
#include "rust-ast.h"
#include "rust-macro.h"
#include "rust-hir-map.h"
-#include "rust-early-name-resolver.h"
#include "rust-name-resolver.h"
#include "rust-macro-invoc-lexer.h"
#include "rust-proc-macro-invoc-lexer.h"
@@ -291,6 +290,7 @@ struct MacroExpander
TRAIT,
IMPL,
TRAIT_IMPL,
+ PATTERN,
};
ExpansionCfg cfg;
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc
index ac36ed8..36bae5b 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.cc
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc
@@ -40,7 +40,7 @@ SubstituteCtx::substitute_dollar_crate (
if (*def_crate == current_crate)
{
expanded.push_back (std::make_unique<AST::Token> (
- Rust::Token::make_identifier (UNKNOWN_LOCATION, "crate")));
+ Rust::Token::make_identifier (origin, "crate")));
}
else
{
@@ -49,9 +49,9 @@ SubstituteCtx::substitute_dollar_crate (
rust_assert (name);
expanded.push_back (std::make_unique<AST::Token> (
- Rust::Token::make (SCOPE_RESOLUTION, UNKNOWN_LOCATION)));
+ Rust::Token::make (SCOPE_RESOLUTION, origin)));
expanded.push_back (std::make_unique<AST::Token> (
- Rust::Token::make_identifier (UNKNOWN_LOCATION, std::string (*name))));
+ Rust::Token::make_identifier (origin, std::string (*name))));
}
return true;
@@ -108,6 +108,12 @@ SubstituteCtx::substitute_metavar (
return true;
}
+static bool
+is_builtin_metavariable (AST::Token &token)
+{
+ return token.get_id () == CRATE;
+}
+
bool
SubstituteCtx::check_repetition_amount (size_t pattern_start,
size_t pattern_end,
@@ -125,6 +131,10 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
|| frag_token->get_id () == IDENTIFIER)
{
auto it = fragments.find (frag_token->get_str ());
+
+ if (is_builtin_metavariable (*frag_token))
+ continue;
+
if (it == fragments.end ())
{
// If the repetition is not anything we know (ie no declared
@@ -136,6 +146,7 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
frag_token->get_str ().c_str ());
is_valid = false;
+ continue;
}
auto &fragment = *it->second;
@@ -226,7 +237,7 @@ SubstituteCtx::substitute_repetition (
}
auto substitute_context
- = SubstituteCtx (input, new_macro, sub_map, definition);
+ = SubstituteCtx (input, new_macro, sub_map, definition, origin);
auto new_tokens = substitute_context.substitute_tokens ();
// Skip the first repetition, but add the separator to the expanded
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.h b/gcc/rust/expand/rust-macro-substitute-ctx.h
index c5c4956..3829a5a 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.h
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.h
@@ -27,6 +27,8 @@ class SubstituteCtx
std::vector<std::unique_ptr<AST::Token>> &macro;
std::map<std::string, MatchedFragmentContainer *> &fragments;
AST::MacroRulesDefinition &definition;
+ // Macro invocation location
+ location_t origin;
/**
* Find the repetition amount to use when expanding a repetition, and
@@ -43,9 +45,9 @@ public:
SubstituteCtx (std::vector<std::unique_ptr<AST::Token>> &input,
std::vector<std::unique_ptr<AST::Token>> &macro,
std::map<std::string, MatchedFragmentContainer *> &fragments,
- AST::MacroRulesDefinition &definition)
+ AST::MacroRulesDefinition &definition, location_t origin)
: input (input), macro (macro), fragments (fragments),
- definition (definition)
+ definition (definition), origin (origin)
{}
/**