diff options
Diffstat (limited to 'gcc/rust/expand')
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> ¶ms)  {    for (auto ¶m : 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 ¯o_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 ¶m : 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 ¶m)  { +  maybe_expand_pattern (param.get_pattern_ptr ());    maybe_expand_type (param.get_type_ptr ());  }  void +ExpandVisitor::visit (AST::VariadicParam ¶m) +{ +  if (param.has_pattern ()) +    maybe_expand_pattern (param.get_pattern_ptr ()); +} + +void  ExpandVisitor::visit (AST::SelfParam ¶m)  {    /* 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 ¶m) 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 ¶m) override; +  void visit (AST::VariadicParam ¶m) 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>> ¯o;    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>> ¯o,  		 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)    {}    /**  | 
