aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/ast')
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc56
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc244
-rw-r--r--gcc/rust/ast/rust-ast-collector.h9
-rw-r--r--gcc/rust/ast/rust-ast-formatting.h3
-rw-r--r--gcc/rust/ast/rust-ast-fragment.cc42
-rw-r--r--gcc/rust/ast/rust-ast-fragment.h6
-rw-r--r--gcc/rust/ast/rust-ast-full-decls.h9
-rw-r--r--gcc/rust/ast/rust-ast-pointer-visitor.cc1475
-rw-r--r--gcc/rust/ast/rust-ast-pointer-visitor.h234
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc18
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h18
-rw-r--r--gcc/rust/ast/rust-ast.cc136
-rw-r--r--gcc/rust/ast/rust-ast.h120
-rw-r--r--gcc/rust/ast/rust-builtin-ast-nodes.h8
-rw-r--r--gcc/rust/ast/rust-collect-lang-items.cc14
-rw-r--r--gcc/rust/ast/rust-cond-compilation.h32
-rw-r--r--gcc/rust/ast/rust-desugar-apit.cc26
-rw-r--r--gcc/rust/ast/rust-desugar-for-loops.cc2
-rw-r--r--gcc/rust/ast/rust-desugar-question-mark.cc4
-rw-r--r--gcc/rust/ast/rust-expr.h257
-rw-r--r--gcc/rust/ast/rust-expression-yeast.cc47
-rw-r--r--gcc/rust/ast/rust-expression-yeast.h15
-rw-r--r--gcc/rust/ast/rust-fmt.cc38
-rw-r--r--gcc/rust/ast/rust-fmt.h228
-rw-r--r--gcc/rust/ast/rust-item.h145
-rw-r--r--gcc/rust/ast/rust-path.cc11
-rw-r--r--gcc/rust/ast/rust-path.h17
-rw-r--r--gcc/rust/ast/rust-pattern.cc20
-rw-r--r--gcc/rust/ast/rust-pattern.h229
-rw-r--r--gcc/rust/ast/rust-stmt.h6
-rw-r--r--gcc/rust/ast/rust-type.h32
31 files changed, 2815 insertions, 686 deletions
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index ed10ce7..632f945 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -554,12 +554,12 @@ std::unique_ptr<GenericParam>
Builder::new_lifetime_param (LifetimeParam &param)
{
Lifetime l = new_lifetime (param.get_lifetime ());
+
std::vector<Lifetime> lifetime_bounds;
+ lifetime_bounds.reserve (param.get_lifetime_bounds ().size ());
+
for (auto b : param.get_lifetime_bounds ())
- {
- Lifetime bl = new_lifetime (b);
- lifetime_bounds.push_back (bl);
- }
+ lifetime_bounds.emplace_back (new_lifetime (b));
auto p = new LifetimeParam (l, std::move (lifetime_bounds),
param.get_outer_attrs (), param.get_locus ());
@@ -605,11 +605,11 @@ Builder::new_type_param (
for (const auto &lifetime : tb.get_for_lifetimes ())
{
std::vector<Lifetime> lifetime_bounds;
+ lifetime_bounds.reserve (
+ lifetime.get_lifetime_bounds ().size ());
+
for (const auto &b : lifetime.get_lifetime_bounds ())
- {
- Lifetime bl = new_lifetime (b);
- lifetime_bounds.push_back (std::move (bl));
- }
+ lifetime_bounds.emplace_back (new_lifetime (b));
Lifetime nl = new_lifetime (lifetime.get_lifetime ());
LifetimeParam p (std::move (nl), std::move (lifetime_bounds),
@@ -626,12 +626,11 @@ Builder::new_type_param (
{
const TypePathSegment &segment
= (const TypePathSegment &) (*seg.get ());
- TypePathSegment *s = new TypePathSegment (
+
+ segments.emplace_back (new TypePathSegment (
segment.get_ident_segment (),
segment.get_separating_scope_resolution (),
- segment.get_locus ());
- std::unique_ptr<TypePathSegment> sg (s);
- segments.push_back (std::move (sg));
+ segment.get_locus ()));
}
break;
@@ -642,11 +641,10 @@ Builder::new_type_param (
GenericArgs args
= new_generic_args (generic.get_generic_args ());
- TypePathSegmentGeneric *s = new TypePathSegmentGeneric (
+
+ segments.emplace_back (new TypePathSegmentGeneric (
generic.get_ident_segment (), false, std::move (args),
- generic.get_locus ());
- std::unique_ptr<TypePathSegment> sg (s);
- segments.push_back (std::move (sg));
+ generic.get_locus ()));
}
break;
@@ -664,12 +662,9 @@ Builder::new_type_param (
TypePath p (std::move (segments), path.get_locus (),
path.has_opening_scope_resolution_op ());
- TraitBound *b = new TraitBound (std::move (p), tb.get_locus (),
- tb.is_in_parens (),
- tb.has_opening_question_mark (),
- std::move (for_lifetimes));
- std::unique_ptr<TypeParamBound> bound (b);
- type_param_bounds.push_back (std::move (bound));
+ type_param_bounds.emplace_back (new TraitBound (
+ std::move (p), tb.get_locus (), tb.is_in_parens (),
+ tb.has_opening_question_mark (), std::move (for_lifetimes)));
}
break;
@@ -677,10 +672,9 @@ Builder::new_type_param (
{
const Lifetime &l = (const Lifetime &) *b.get ();
- auto bl = new Lifetime (l.get_lifetime_type (),
- l.get_lifetime_name (), l.get_locus ());
- std::unique_ptr<TypeParamBound> bound (bl);
- type_param_bounds.push_back (std::move (bound));
+ type_param_bounds.emplace_back (
+ new Lifetime (l.get_lifetime_type (), l.get_lifetime_name (),
+ l.get_locus ()));
}
break;
}
@@ -709,18 +703,14 @@ Builder::new_generic_args (GenericArgs &args)
location_t locus = args.get_locus ();
for (const auto &lifetime : args.get_lifetime_args ())
- {
- Lifetime l = new_lifetime (lifetime);
- lifetime_args.push_back (std::move (l));
- }
+ lifetime_args.push_back (new_lifetime (lifetime));
for (auto &binding : args.get_binding_args ())
{
Type &t = *binding.get_type_ptr ().get ();
std::unique_ptr<Type> ty = t.reconstruct ();
- GenericArgsBinding b (binding.get_identifier (), std::move (ty),
- binding.get_locus ());
- binding_args.push_back (std::move (b));
+ binding_args.emplace_back (binding.get_identifier (), std::move (ty),
+ binding.get_locus ());
}
for (auto &arg : args.get_generic_args ())
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index 3d9ea78..721d274 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -76,13 +76,13 @@ TokenCollector::trailing_comma ()
void
TokenCollector::newline ()
{
- tokens.push_back ({CollectItem::Kind::Newline});
+ tokens.emplace_back (CollectItem::Kind::Newline);
}
void
TokenCollector::indentation ()
{
- tokens.push_back ({indent_level});
+ tokens.emplace_back (indent_level);
}
void
@@ -101,7 +101,7 @@ TokenCollector::decrement_indentation ()
void
TokenCollector::comment (std::string comment)
{
- tokens.push_back ({comment});
+ tokens.emplace_back (comment);
}
void
@@ -355,7 +355,8 @@ TokenCollector::visit (MaybeNamedParam &param)
void
TokenCollector::visit (Token &tok)
{
- std::string data = tok.get_tok_ptr ()->has_str () ? tok.get_str () : "";
+ std::string data
+ = tok.get_tok_ptr ()->should_have_str () ? tok.get_str () : "";
switch (tok.get_id ())
{
case IDENTIFIER:
@@ -2171,19 +2172,6 @@ TokenCollector::visit (SelfParam &param)
}
void
-TokenCollector::visit (TraitItemConst &item)
-{
- auto id = item.get_identifier ().as_string ();
- indentation ();
- push (Rust::Token::make (CONST, item.get_locus ()));
- push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
- push (Rust::Token::make (COLON, UNDEF_LOCATION));
- visit (item.get_type ());
- push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
- newline ();
-}
-
-void
TokenCollector::visit (TraitItemType &item)
{
visit_items_as_lines (item.get_outer_attrs ());
@@ -2632,7 +2620,7 @@ TokenCollector::visit (StructPattern &pattern)
if (elems.has_struct_pattern_fields ())
{
visit_items_joined_by_separator (elems.get_struct_pattern_fields ());
- if (elems.has_etc ())
+ if (elems.has_rest ())
{
push (Rust::Token::make (COMMA, UNDEF_LOCATION));
visit_items_as_lines (elems.get_etc_outer_attrs ());
@@ -2649,13 +2637,13 @@ TokenCollector::visit (StructPattern &pattern)
// void TokenCollector::visit(TupleStructItems& ){}
void
-TokenCollector::visit (TupleStructItemsNoRange &pattern)
+TokenCollector::visit (TupleStructItemsNoRest &pattern)
{
visit_items_joined_by_separator (pattern.get_patterns ());
}
void
-TokenCollector::visit (TupleStructItemsRange &pattern)
+TokenCollector::visit (TupleStructItemsHasRest &pattern)
{
for (auto &lower : pattern.get_lower_patterns ())
{
@@ -2682,13 +2670,13 @@ TokenCollector::visit (TupleStructPattern &pattern)
// {}
void
-TokenCollector::visit (TuplePatternItemsMultiple &pattern)
+TokenCollector::visit (TuplePatternItemsNoRest &pattern)
{
visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
}
void
-TokenCollector::visit (TuplePatternItemsRanged &pattern)
+TokenCollector::visit (TuplePatternItemsHasRest &pattern)
{
for (auto &lower : pattern.get_lower_patterns ())
{
@@ -3009,8 +2997,216 @@ TokenCollector::visit (BareFunctionType &type)
void
TokenCollector::visit (AST::FormatArgs &fmt)
{
- rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
- __FILE__, __LINE__);
+ push (Rust::Token::make_identifier (fmt.get_locus (), "format_args"));
+ push (Rust::Token::make (EXCLAM, fmt.get_locus ()));
+ push (Rust::Token::make (LEFT_PAREN, fmt.get_locus ()));
+
+ std::string reconstructed_template = "\"";
+ const auto &template_pieces = fmt.get_template ();
+
+ for (const auto &piece : template_pieces.get_pieces ())
+ {
+ if (piece.tag == Fmt::ffi::Piece::Tag::String)
+ {
+ std::string literal = piece.string._0.to_string ();
+ for (char c : literal)
+ {
+ if (c == '"' || c == '\\')
+ {
+ reconstructed_template += '\\';
+ }
+ else if (c == '\n')
+ {
+ reconstructed_template += "\\n";
+ continue;
+ }
+ else if (c == '\r')
+ {
+ reconstructed_template += "\\r";
+ continue;
+ }
+ else if (c == '\t')
+ {
+ reconstructed_template += "\\t";
+ continue;
+ }
+ reconstructed_template += c;
+ }
+ }
+ else if (piece.tag == Fmt::ffi::Piece::Tag::NextArgument)
+ {
+ reconstructed_template += "{";
+
+ const auto &argument = piece.next_argument._0;
+ const auto &position = argument.position;
+
+ switch (position.tag)
+ {
+ case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs:
+ break;
+ case Fmt::ffi::Position::Tag::ArgumentIs:
+ reconstructed_template
+ += std::to_string (position.argument_is._0);
+ break;
+ case Fmt::ffi::Position::Tag::ArgumentNamed:
+ reconstructed_template += position.argument_named._0.to_string ();
+ break;
+ }
+
+ // Add format specifiers if any (like :?, :x, etc.)
+ const auto &format_spec = argument.format;
+
+ bool has_format_spec = false;
+ std::string format_part;
+
+ // For now, skipping the complex format specifications that use FFIOpt
+ // since FFIOpt::get_opt() has a bug.
+
+ // Alignment
+ if (format_spec.align != Fmt::ffi::Alignment::AlignUnknown)
+ {
+ has_format_spec = true;
+ switch (format_spec.align)
+ {
+ case Fmt::ffi::Alignment::AlignLeft:
+ format_part += "<";
+ break;
+ case Fmt::ffi::Alignment::AlignRight:
+ format_part += ">";
+ break;
+ case Fmt::ffi::Alignment::AlignCenter:
+ format_part += "^";
+ break;
+ case Fmt::ffi::Alignment::AlignUnknown:
+ break;
+ }
+ }
+
+ // Alternate flag
+ if (format_spec.alternate)
+ {
+ has_format_spec = true;
+ format_part += "#";
+ }
+
+ // Zero pad flag
+ if (format_spec.zero_pad)
+ {
+ has_format_spec = true;
+ format_part += "0";
+ }
+
+ // Width
+ if (format_spec.width.tag != Fmt::ffi::Count::Tag::CountImplied)
+ {
+ has_format_spec = true;
+ switch (format_spec.width.tag)
+ {
+ case Fmt::ffi::Count::Tag::CountIs:
+ format_part += std::to_string (format_spec.width.count_is._0);
+ break;
+ case Fmt::ffi::Count::Tag::CountIsParam:
+ format_part
+ += std::to_string (format_spec.width.count_is_param._0)
+ + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsName:
+ format_part
+ += format_spec.width.count_is_name._0.to_string () + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsStar:
+ format_part += "*";
+ break;
+ case Fmt::ffi::Count::Tag::CountImplied:
+ break;
+ }
+ }
+
+ // Precision
+ if (format_spec.precision.tag != Fmt::ffi::Count::Tag::CountImplied)
+ {
+ has_format_spec = true;
+ format_part += ".";
+ switch (format_spec.precision.tag)
+ {
+ case Fmt::ffi::Count::Tag::CountIs:
+ format_part
+ += std::to_string (format_spec.precision.count_is._0);
+ break;
+ case Fmt::ffi::Count::Tag::CountIsParam:
+ format_part
+ += std::to_string (format_spec.precision.count_is_param._0)
+ + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsName:
+ format_part
+ += format_spec.precision.count_is_name._0.to_string ()
+ + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsStar:
+ format_part += "*";
+ break;
+ case Fmt::ffi::Count::Tag::CountImplied:
+ break;
+ }
+ }
+
+ // Type/trait (like ?, x, X, etc.)
+ std::string type_str = format_spec.ty.to_string ();
+ if (!type_str.empty ())
+ {
+ has_format_spec = true;
+ format_part += type_str;
+ }
+
+ // Add the format specification if any
+ if (has_format_spec)
+ {
+ reconstructed_template += ":";
+ reconstructed_template += format_part;
+ }
+
+ reconstructed_template += "}";
+ }
+ }
+ reconstructed_template += "\"";
+
+ push (Rust::Token::make_string (fmt.get_locus (), reconstructed_template));
+
+ // Visit format arguments if any exist
+ auto &arguments = fmt.get_arguments ();
+ if (!arguments.empty ())
+ {
+ push (Rust::Token::make (COMMA, fmt.get_locus ()));
+
+ auto &args = arguments.get_args ();
+ for (size_t i = 0; i < args.size (); ++i)
+ {
+ if (i > 0)
+ {
+ push (Rust::Token::make (COMMA, fmt.get_locus ()));
+ }
+
+ auto kind = args[i].get_kind ();
+
+ // Handle named arguments: name = expr
+ if (kind.kind == FormatArgumentKind::Kind::Named)
+ {
+ auto ident = kind.get_ident ().as_string ();
+ push (Rust::Token::make_identifier (fmt.get_locus (),
+ std::move (ident)));
+ push (Rust::Token::make (EQUAL, fmt.get_locus ()));
+ }
+ // Note: Captured arguments are handled implicitly in the template
+ // reconstruction They don't need explicit "name =" syntax in the
+ // reconstructed macro call
+
+ auto &expr = args[i].get_expr ();
+ expr.accept_vis (*this);
+ }
+ }
+
+ push (Rust::Token::make (RIGHT_PAREN, fmt.get_locus ()));
}
void
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index d3ab18a..3e33476 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -330,7 +330,6 @@ public:
void visit (ConstantItem &const_item);
void visit (StaticItem &static_item);
void visit (SelfParam &param);
- void visit (TraitItemConst &item);
void visit (TraitItemType &item);
void visit (Trait &trait);
void visit (InherentImpl &impl);
@@ -370,12 +369,12 @@ public:
void visit (StructPatternFieldIdent &field);
void visit (StructPattern &pattern);
// void visit(TupleStructItems& tuple_items);
- void visit (TupleStructItemsNoRange &tuple_items);
- void visit (TupleStructItemsRange &tuple_items);
+ void visit (TupleStructItemsNoRest &tuple_items);
+ void visit (TupleStructItemsHasRest &tuple_items);
void visit (TupleStructPattern &pattern);
// void visit(TuplePatternItems& tuple_items);
- void visit (TuplePatternItemsMultiple &tuple_items);
- void visit (TuplePatternItemsRanged &tuple_items);
+ void visit (TuplePatternItemsNoRest &tuple_items);
+ void visit (TuplePatternItemsHasRest &tuple_items);
void visit (TuplePattern &pattern);
void visit (GroupedPattern &pattern);
void visit (SlicePatternItemsNoRest &items);
diff --git a/gcc/rust/ast/rust-ast-formatting.h b/gcc/rust/ast/rust-ast-formatting.h
index aace93f..075c51c 100644
--- a/gcc/rust/ast/rust-ast-formatting.h
+++ b/gcc/rust/ast/rust-ast-formatting.h
@@ -19,6 +19,9 @@
#ifndef RUST_AST_FORMATTING_H
#define RUST_AST_FORMATTING_H
+#include "rust-ast.h"
+#include "rust-system.h"
+
namespace Rust {
namespace AST {
diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc
index 076cab3..8a547b4 100644
--- a/gcc/rust/ast/rust-ast-fragment.cc
+++ b/gcc/rust/ast/rust-ast-fragment.cc
@@ -107,29 +107,42 @@ Fragment::should_expand () const
bool
Fragment::is_expression_fragment () const
{
- return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION);
+ return is_single_fragment_of_kind (SingleASTNode::Kind::Expr);
}
bool
Fragment::is_type_fragment () const
{
- return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE);
+ return is_single_fragment_of_kind (SingleASTNode::Kind::Type);
+}
+
+bool
+Fragment::is_pattern_fragment () const
+{
+ return is_single_fragment_of_kind (SingleASTNode::Kind::Pattern);
}
std::unique_ptr<Expr>
Fragment::take_expression_fragment ()
{
- assert_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+ assert_single_fragment (SingleASTNode::Kind::Expr);
return nodes[0].take_expr ();
}
std::unique_ptr<Type>
Fragment::take_type_fragment ()
{
- assert_single_fragment (SingleASTNode::NodeType::TYPE);
+ assert_single_fragment (SingleASTNode::Kind::Type);
return nodes[0].take_type ();
}
+std::unique_ptr<Pattern>
+Fragment::take_pattern_fragment ()
+{
+ assert_single_fragment (SingleASTNode::Kind::Pattern);
+ return nodes[0].take_pattern ();
+}
+
void
Fragment::accept_vis (ASTVisitor &vis)
{
@@ -144,21 +157,22 @@ Fragment::is_single_fragment () const
}
bool
-Fragment::is_single_fragment_of_kind (SingleASTNode::NodeType expected) const
+Fragment::is_single_fragment_of_kind (SingleASTNode::Kind expected) const
{
return is_single_fragment () && nodes[0].get_kind () == expected;
}
void
-Fragment::assert_single_fragment (SingleASTNode::NodeType expected) const
-{
- static const std::map<SingleASTNode::NodeType, const char *> str_map = {
- {SingleASTNode::NodeType::ASSOC_ITEM, "associated item"},
- {SingleASTNode::NodeType::ITEM, "item"},
- {SingleASTNode::NodeType::TYPE, "type"},
- {SingleASTNode::NodeType::EXPRESSION, "expr"},
- {SingleASTNode::NodeType::STMT, "stmt"},
- {SingleASTNode::NodeType::EXTERN, "extern"},
+Fragment::assert_single_fragment (SingleASTNode::Kind expected) const
+{
+ static const std::map<SingleASTNode::Kind, const char *> str_map = {
+ {SingleASTNode::Kind::Assoc, "associated item"},
+ {SingleASTNode::Kind::Item, "item"},
+ {SingleASTNode::Kind::Type, "type"},
+ {SingleASTNode::Kind::Expr, "expr"},
+ {SingleASTNode::Kind::Stmt, "stmt"},
+ {SingleASTNode::Kind::Extern, "extern"},
+ {SingleASTNode::Kind::Pattern, "pattern"},
};
auto actual = nodes[0].get_kind ();
diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h
index 7d01fd7..23f26d3 100644
--- a/gcc/rust/ast/rust-ast-fragment.h
+++ b/gcc/rust/ast/rust-ast-fragment.h
@@ -86,9 +86,11 @@ public:
bool is_expression_fragment () const;
bool is_type_fragment () const;
+ bool is_pattern_fragment () const;
std::unique_ptr<Expr> take_expression_fragment ();
std::unique_ptr<Type> take_type_fragment ();
+ std::unique_ptr<Pattern> take_pattern_fragment ();
void accept_vis (ASTVisitor &vis);
@@ -119,8 +121,8 @@ private:
* one Node will be extracted from the `nodes` vector
*/
bool is_single_fragment () const;
- bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const;
- void assert_single_fragment (SingleASTNode::NodeType expected) const;
+ bool is_single_fragment_of_kind (SingleASTNode::Kind expected) const;
+ void assert_single_fragment (SingleASTNode::Kind expected) const;
};
enum class InvocKind
diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h
index 09706ce..2903ba7 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -195,7 +195,6 @@ class Enum;
class Union;
class ConstantItem;
class StaticItem;
-class TraitItemConst;
class TraitItemType;
class Trait;
class Impl;
@@ -240,12 +239,12 @@ class StructPatternFieldIdent;
class StructPatternElements;
class StructPattern;
class TupleStructItems;
-class TupleStructItemsNoRange;
-class TupleStructItemsRange;
+class TupleStructItemsNoRest;
+class TupleStructItemsHasRest;
class TupleStructPattern;
class TuplePatternItems;
-class TuplePatternItemsMultiple;
-class TuplePatternItemsRanged;
+class TuplePatternItemsNoRest;
+class TuplePatternItemsHasRest;
class TuplePattern;
class GroupedPattern;
class SlicePatternItemsNoRest;
diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.cc b/gcc/rust/ast/rust-ast-pointer-visitor.cc
new file mode 100644
index 0000000..ee1f001
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-pointer-visitor.cc
@@ -0,0 +1,1475 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-pointer-visitor.h"
+#include "rust-ast-visitor.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace AST {
+
+void
+PointerVisitor::visit (AST::Crate &crate)
+{
+ visit_inner_attrs (crate);
+ for (auto &item : crate.items)
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::AttrInputMetaItemContainer &input)
+{
+ // FIXME: I think we might actually have to reseat sub-items for macro
+ // invocations within attributes correct?
+
+ for (auto &item : input.get_items ())
+ visit (item);
+}
+
+void
+PointerVisitor::visit (AST::IdentifierExpr &ident_expr)
+{
+ visit_outer_attrs (ident_expr);
+}
+
+void
+PointerVisitor::visit (AST::LifetimeParam &lifetime_param)
+{
+ visit_outer_attrs (lifetime_param);
+
+ // Nothing to do for lifetimes right?
+}
+
+void
+PointerVisitor::visit (AST::ConstGenericParam &const_param)
+{
+ visit_outer_attrs (const_param);
+ if (const_param.has_type ())
+ reseat (const_param.get_type_ptr ());
+
+ if (const_param.has_default_value ())
+ visit (const_param.get_default_value_unchecked ());
+}
+
+void
+PointerVisitor::visit (AST::PathInExpression &path)
+{
+ visit_outer_attrs (path);
+
+ if (!path.is_lang_item ())
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (GenericArgsBinding &binding)
+{
+ reseat (binding.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TypePathSegmentGeneric &segment)
+{
+ if (segment.has_generic_args ())
+ visit (segment.get_generic_args ());
+}
+
+void
+PointerVisitor::visit (AST::TypePathFunction &tpf)
+{
+ for (auto &input : tpf.get_params ())
+ reseat (input);
+ if (tpf.has_return_type ())
+ reseat (tpf.get_return_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TypePathSegmentFunction &segment)
+{
+ // FIXME: No reseating here correct? No macros possible or desugar?
+ visit (segment.get_type_path_function ());
+ visit (segment.get_ident_segment ());
+}
+
+void
+PointerVisitor::visit (AST::GenericArgs &args)
+{
+ // Nothing to do for lifetimes?
+ // for (auto &lifetime : args.get_lifetime_args ())
+ // reseat (lifetime);
+
+ // FIXME: Actually this can probably be a macro invocation, so we need to
+ // reseat them?
+ for (auto &generic : args.get_generic_args ())
+ visit (generic);
+
+ for (auto &binding : args.get_binding_args ())
+ visit (binding);
+}
+
+void
+PointerVisitor::visit (AST::PathExprSegment &segment)
+{
+ visit (segment.get_ident_segment ());
+ if (segment.has_generic_args ())
+ visit (segment.get_generic_args ());
+}
+void
+PointerVisitor::visit (AST::TypePath &path)
+{
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::QualifiedPathInExpression &path)
+{
+ visit_outer_attrs (path);
+ visit (path.get_qualified_path_type ());
+
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::QualifiedPathType &path)
+{
+ reseat (path.get_type_ptr ());
+ if (path.has_as_clause ())
+ visit (path.get_as_type_path ());
+}
+
+void
+PointerVisitor::visit (AST::QualifiedPathInType &path)
+{
+ visit (path.get_qualified_path_type ());
+ visit (path.get_associated_segment ());
+
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::LiteralExpr &expr)
+{
+ visit_outer_attrs (expr);
+}
+
+void
+PointerVisitor::visit (AST::AttrInputLiteral &attr_input)
+{
+ visit (attr_input.get_literal ());
+}
+
+void
+PointerVisitor::visit (AST::AttrInputMacro &attr_input)
+{
+ visit (attr_input.get_macro ());
+}
+
+void
+PointerVisitor::visit (AST::MetaItemLitExpr &meta_item)
+{
+ visit (meta_item.get_literal ());
+}
+
+void
+PointerVisitor::visit (AST::SimplePath &path)
+{
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::MetaItemPathExpr &meta_item)
+{
+ visit (meta_item.get_path ());
+ reseat (meta_item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BorrowExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_borrowed_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::DereferenceExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_dereferenced_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ErrorPropagationExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_propagating_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::NegationExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_negated_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ComparisonExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::LazyBooleanExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TypeCastExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_casted_expr_ptr ());
+ reseat (expr.get_type_to_cast_to_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::AssignmentExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::CompoundAssignmentExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::GroupedExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ reseat (expr.get_expr_in_parens_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayElemsValues &elems)
+{
+ for (auto &value : elems.get_values ())
+ reseat (value);
+}
+
+void
+PointerVisitor::visit (AST::ArrayElemsCopied &elems)
+{
+ reseat (elems.get_elem_to_copy_ptr ());
+ reseat (elems.get_num_copies_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ visit (expr.get_array_elems ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayIndexExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_array_expr_ptr ());
+ reseat (expr.get_index_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TupleExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ for (auto &elem : expr.get_tuple_elems ())
+ reseat (elem);
+}
+
+void
+PointerVisitor::visit (AST::TupleIndexExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_tuple_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructExprStruct &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ visit (expr.get_struct_name ());
+}
+
+void
+PointerVisitor::visit (AST::StructExprFieldIdentifier &field)
+{}
+
+void
+PointerVisitor::visit (AST::StructExprFieldIdentifierValue &field)
+{
+ reseat (field.get_value_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructExprFieldIndexValue &field)
+{
+ reseat (field.get_value_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructBase &base)
+{
+ reseat (base.get_base_struct_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructExprStructFields &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ visit (expr.get_struct_name ());
+ if (expr.has_struct_base ())
+ visit (expr.get_struct_base ());
+ for (auto &field : expr.get_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::StructExprStructBase &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ visit (expr.get_struct_name ());
+ visit (expr.get_struct_base ());
+}
+
+void
+PointerVisitor::visit (AST::CallExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_function_expr_ptr ());
+ for (auto &param : expr.get_params ())
+ reseat (param);
+}
+
+void
+PointerVisitor::visit (AST::MethodCallExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_receiver_expr_ptr ());
+ visit (expr.get_method_name ());
+ for (auto &param : expr.get_params ())
+ reseat (param);
+}
+
+void
+PointerVisitor::visit (AST::FieldAccessExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_receiver_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ClosureExprInner &expr)
+{
+ visit_outer_attrs (expr);
+
+ // TODO: Actually we need to handle macro invocations as closure parameters so
+ // this needs to be a reseat
+ for (auto &param : expr.get_params ())
+ visit (param);
+
+ reseat (expr.get_definition_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BlockExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+
+ if (expr.has_label ())
+ visit (expr.get_label ());
+
+ for (auto &stmt : expr.get_statements ())
+ reseat (stmt);
+
+ if (expr.has_tail_expr ())
+ reseat (expr.get_tail_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ConstBlock &expr)
+{
+ visit (expr.get_const_expr ());
+}
+
+void
+PointerVisitor::visit (AST::AnonConst &expr)
+{
+ if (!expr.is_deferred ())
+ reseat (expr.get_inner_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ClosureExprInnerTyped &expr)
+{
+ visit_outer_attrs (expr);
+
+ // TODO: Same as ClosureExprInner
+ for (auto &param : expr.get_params ())
+ visit (param);
+
+ reseat (expr.get_return_type_ptr ());
+
+ reseat (expr.get_definition_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ClosureParam &param)
+{
+ visit_outer_attrs (param);
+ reseat (param.get_pattern_ptr ());
+ if (param.has_type_given ())
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ContinueExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_label ())
+ visit (expr.get_label_unchecked ());
+}
+
+void
+PointerVisitor::visit (AST::BreakExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_label ())
+ visit (expr.get_label_unchecked ());
+
+ if (expr.has_break_expr ())
+ reseat (expr.get_break_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeFromToExpr &expr)
+{
+ reseat (expr.get_from_expr_ptr ());
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeFromExpr &expr)
+{
+ reseat (expr.get_from_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeToExpr &expr)
+{
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeFullExpr &expr)
+{}
+
+void
+PointerVisitor::visit (AST::RangeFromToInclExpr &expr)
+{
+ reseat (expr.get_from_expr_ptr ());
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeToInclExpr &expr)
+{
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ReturnExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_returned_expr ())
+ reseat (expr.get_returned_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TryExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_block_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BoxExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_boxed_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::UnsafeBlockExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_block_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::LoopLabel &label)
+{
+ visit (label.get_lifetime ());
+}
+
+void
+PointerVisitor::visit (AST::LoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::WhileLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+ reseat (expr.get_predicate_expr_ptr ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::WhileLetLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ for (auto &pattern : expr.get_patterns ())
+ reseat (pattern);
+
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+
+ reseat (expr.get_scrutinee_expr_ptr ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ForLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_pattern_ptr ());
+ reseat (expr.get_iterator_expr_ptr ());
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::IfExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_condition_expr_ptr ());
+ visit (expr.get_if_block ());
+}
+
+void
+PointerVisitor::visit (AST::IfExprConseqElse &expr)
+{
+ visit (reinterpret_cast<AST::IfExpr &> (expr));
+ visit (expr.get_else_block ());
+}
+
+void
+PointerVisitor::visit (AST::IfLetExpr &expr)
+{
+ visit_outer_attrs (expr);
+ for (auto &pattern : expr.get_patterns ())
+ reseat (pattern);
+ reseat (expr.get_value_expr_ptr ());
+ visit (expr.get_if_block ());
+}
+
+void
+PointerVisitor::visit (AST::IfLetExprConseqElse &expr)
+{
+ visit (reinterpret_cast<AST::IfLetExpr &> (expr));
+ visit (expr.get_else_block ());
+}
+
+void
+PointerVisitor::visit (AST::MatchArm &arm)
+{
+ visit_outer_attrs (arm);
+ for (auto &pattern : arm.get_patterns ())
+ reseat (pattern);
+ if (arm.has_match_arm_guard ())
+ reseat (arm.get_guard_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::MatchCase &arm)
+{
+ visit (arm.get_arm ());
+ reseat (arm.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::MatchExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ reseat (expr.get_scrutinee_expr_ptr ());
+ for (auto &arm : expr.get_match_cases ())
+ visit (arm);
+}
+
+void
+PointerVisitor::visit (AST::AwaitExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_awaited_expr ());
+}
+
+void
+PointerVisitor::visit (AST::AsyncBlockExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_block_expr ());
+}
+
+void
+PointerVisitor::visit (AST::InlineAsm &expr)
+{
+ visit_outer_attrs (expr);
+ using RegisterType = AST::InlineAsmOperand::RegisterType;
+ for (auto &operand : expr.get_operands ())
+ {
+ switch (operand.get_register_type ())
+ {
+ case RegisterType::In:
+ {
+ reseat (operand.get_in ().expr);
+ break;
+ }
+ case RegisterType::Out:
+ {
+ reseat (operand.get_out ().expr);
+ break;
+ }
+ case RegisterType::InOut:
+ {
+ reseat (operand.get_in_out ().expr);
+ break;
+ }
+ case RegisterType::SplitInOut:
+ {
+ auto split = operand.get_split_in_out ();
+ reseat (split.in_expr);
+ reseat (split.out_expr);
+ break;
+ }
+ case RegisterType::Const:
+ {
+ reseat (operand.get_const ().anon_const.get_inner_expr_ptr ());
+ break;
+ }
+ case RegisterType::Sym:
+ {
+ reseat (operand.get_sym ().expr);
+ break;
+ }
+ case RegisterType::Label:
+ {
+ reseat (operand.get_label ().expr);
+ break;
+ }
+ }
+ }
+}
+
+void
+PointerVisitor::visit (AST::LlvmInlineAsm &expr)
+{
+ for (auto &output : expr.get_outputs ())
+ reseat (output.expr);
+
+ for (auto &input : expr.get_inputs ())
+ reseat (input.expr);
+}
+
+void
+PointerVisitor::visit (AST::TypeParam &param)
+{
+ visit_outer_attrs (param);
+ // FIXME: Can we do macro expansion here?
+ for (auto &bound : param.get_type_param_bounds ())
+ visit (bound);
+ if (param.has_type ())
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::LifetimeWhereClauseItem &item)
+{
+ visit (item.get_lifetime ());
+ for (auto &bound : item.get_lifetime_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::TypeBoundWhereClauseItem &item)
+{
+ for (auto &lifetime : item.get_for_lifetimes ())
+ visit (lifetime);
+ reseat (item.get_type_ptr ());
+ // FIXME: Likewise?
+ for (auto &param : item.get_type_param_bounds ())
+ visit (param);
+}
+
+void
+PointerVisitor::visit (AST::Visibility &vis)
+{
+ if (vis.has_path ())
+ visit (vis.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::WhereClause &where)
+{
+ for (auto &item : where.get_items ())
+ visit (item);
+}
+
+void
+PointerVisitor::visit (AST::FunctionParam &param)
+{
+ visit_outer_attrs (param);
+ if (param.has_name ())
+ reseat (param.get_pattern_ptr ());
+
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::SelfParam &param)
+{
+ visit_outer_attrs (param);
+
+ if (param.has_lifetime ())
+ visit (param.get_lifetime ());
+
+ if (param.has_type ())
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::Module &module)
+{
+ visit_outer_attrs (module);
+ visit (module.get_visibility ());
+ visit_inner_attrs (module);
+ for (auto &item : module.get_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::ExternCrate &crate)
+{
+ visit_outer_attrs (crate);
+ visit (crate.get_visibility ());
+}
+
+void
+PointerVisitor::visit (AST::UseTreeGlob &use_tree)
+{
+ visit (use_tree.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::UseTreeList &use_tree)
+{
+ visit (use_tree.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::UseTreeRebind &use_tree)
+{
+ visit (use_tree.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::UseDeclaration &use_decl)
+{
+ visit (use_decl.get_visibility ());
+ visit (use_decl.get_tree ());
+}
+
+void
+PointerVisitor::visit_function_params (AST::Function &function)
+{
+ for (auto &param : function.get_function_params ())
+ visit (param);
+}
+
+void
+PointerVisitor::visit (AST::Function &function)
+{
+ visit_outer_attrs (function);
+ visit (function.get_visibility ());
+ visit (function.get_qualifiers ());
+ for (auto &generic : function.get_generic_params ())
+ visit (generic);
+
+ visit_function_params (function);
+
+ if (function.has_return_type ())
+ reseat (function.get_return_type_ptr ());
+ if (function.has_where_clause ())
+ visit (function.get_where_clause ());
+ if (function.has_body ())
+ reseat (*function.get_definition ());
+}
+
+void
+PointerVisitor::visit (AST::TypeAlias &type_alias)
+{
+ visit_outer_attrs (type_alias);
+ visit (type_alias.get_visibility ());
+ for (auto &generic : type_alias.get_generic_params ())
+ visit (generic);
+ if (type_alias.has_where_clause ())
+ visit (type_alias.get_where_clause ());
+ reseat (type_alias.get_type_aliased_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructField &field)
+{
+ visit_outer_attrs (field);
+ visit (field.get_visibility ());
+ reseat (field.get_field_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructStruct &struct_item)
+{
+ visit_outer_attrs (struct_item);
+ visit (struct_item.get_visibility ());
+ for (auto &generic : struct_item.get_generic_params ())
+ visit (generic);
+ if (struct_item.has_where_clause ())
+ visit (struct_item.get_where_clause ());
+ for (auto &field : struct_item.get_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::TupleField &field)
+{
+ visit_outer_attrs (field);
+ visit (field.get_visibility ());
+ reseat (field.get_field_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TupleStruct &tuple_struct)
+{
+ visit_outer_attrs (tuple_struct);
+ visit (tuple_struct.get_visibility ());
+ for (auto &generic : tuple_struct.get_generic_params ())
+ visit (generic);
+ if (tuple_struct.has_where_clause ())
+ visit (tuple_struct.get_where_clause ());
+ for (auto &field : tuple_struct.get_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::EnumItem &item)
+{
+ visit_outer_attrs (item);
+ visit (item.get_visibility ());
+}
+
+void
+PointerVisitor::visit (AST::EnumItemTuple &item)
+{
+ PointerVisitor::visit (static_cast<EnumItem &> (item));
+ for (auto &field : item.get_tuple_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::EnumItemStruct &item)
+{
+ PointerVisitor::visit (static_cast<EnumItem &> (item));
+ for (auto &field : item.get_struct_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::EnumItemDiscriminant &item)
+{
+ PointerVisitor::visit (static_cast<EnumItem &> (item));
+ reseat (item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::Enum &enum_item)
+{
+ visit_outer_attrs (enum_item);
+ visit (enum_item.get_visibility ());
+ for (auto &generic : enum_item.get_generic_params ())
+ visit (generic);
+ if (enum_item.has_where_clause ())
+ visit (enum_item.get_where_clause ());
+ for (auto &item : enum_item.get_variants ())
+ visit (item);
+}
+
+void
+PointerVisitor::visit (AST::Union &union_item)
+{
+ visit_outer_attrs (union_item);
+ visit (union_item.get_visibility ());
+ for (auto &generic : union_item.get_generic_params ())
+ visit (generic);
+ if (union_item.has_where_clause ())
+ visit (union_item.get_where_clause ());
+ for (auto &variant : union_item.get_variants ())
+ visit (variant);
+}
+
+void
+PointerVisitor::visit (AST::ConstantItem &const_item)
+{
+ visit_outer_attrs (const_item);
+ visit (const_item.get_visibility ());
+ reseat (const_item.get_type_ptr ());
+ if (const_item.has_expr ())
+ reseat (const_item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StaticItem &static_item)
+{
+ visit_outer_attrs (static_item);
+ visit (static_item.get_visibility ());
+ reseat (static_item.get_type_ptr ());
+ reseat (static_item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TraitItemType &item)
+{
+ visit_outer_attrs (item);
+ for (auto &bound : item.get_type_param_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::Trait &trait)
+{
+ visit_outer_attrs (trait);
+ visit (trait.get_visibility ());
+
+ visit_inner_attrs (trait);
+
+ visit (trait.get_implicit_self ());
+
+ for (auto &generic : trait.get_generic_params ())
+ visit (generic);
+
+ if (trait.has_where_clause ())
+ visit (trait.get_where_clause ());
+
+ for (auto &bound : trait.get_type_param_bounds ())
+ visit (bound);
+
+ for (auto &item : trait.get_trait_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::InherentImpl &impl)
+{
+ visit_outer_attrs (impl);
+ visit (impl.get_visibility ());
+
+ for (auto &generic : impl.get_generic_params ())
+ visit (generic);
+ if (impl.has_where_clause ())
+ visit (impl.get_where_clause ());
+ reseat (impl.get_type_ptr ());
+ visit_inner_attrs (impl);
+ for (auto &item : impl.get_impl_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::TraitImpl &impl)
+{
+ visit_outer_attrs (impl);
+ visit (impl.get_visibility ());
+
+ for (auto &generic : impl.get_generic_params ())
+ visit (generic);
+ if (impl.has_where_clause ())
+ visit (impl.get_where_clause ());
+ reseat (impl.get_type_ptr ());
+ visit (impl.get_trait_path ());
+ visit_inner_attrs (impl);
+ for (auto &item : impl.get_impl_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::ExternalTypeItem &item)
+{
+ visit_outer_attrs (item);
+ visit (item.get_visibility ());
+}
+
+void
+PointerVisitor::visit (AST::ExternalStaticItem &item)
+{
+ visit_outer_attrs (item);
+ visit (item.get_visibility ());
+ reseat (item.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ExternBlock &block)
+{
+ visit_outer_attrs (block);
+ visit (block.get_visibility ());
+ visit_inner_attrs (block);
+ for (auto &item : block.get_extern_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::MacroMatchFragment &match)
+{}
+
+void
+PointerVisitor::visit (AST::MacroMatchRepetition &match)
+{
+ for (auto &m : match.get_matches ())
+ visit (m);
+}
+
+void
+PointerVisitor::visit (AST::MacroMatcher &matcher)
+{
+ for (auto &m : matcher.get_matches ())
+ visit (m);
+}
+
+void
+PointerVisitor::visit (AST::MacroTranscriber &transcriber)
+{
+ visit (transcriber.get_token_tree ());
+}
+
+void
+PointerVisitor::visit (AST::MacroRule &rule)
+{
+ visit (rule.get_matcher ());
+ visit (rule.get_transcriber ());
+}
+
+void
+PointerVisitor::visit (AST::MacroRulesDefinition &rules_def)
+{
+ visit_outer_attrs (rules_def);
+ for (auto &rule : rules_def.get_macro_rules ())
+ visit (rule);
+}
+
+void
+PointerVisitor::visit (AST::MacroInvocData &data)
+{
+ visit (data.get_path ());
+ visit (data.get_delim_tok_tree ());
+}
+
+void
+PointerVisitor::visit (AST::MacroInvocation &macro_invoc)
+{
+ visit_outer_attrs (macro_invoc);
+ visit (macro_invoc.get_invoc_data ());
+}
+
+void
+PointerVisitor::visit (AST::MetaItemPath &meta_item)
+{
+ visit (meta_item.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::MetaItemSeq &meta_item)
+{
+ visit (meta_item.get_path ());
+ for (auto &inner : meta_item.get_seq ())
+ visit (inner);
+}
+
+void
+PointerVisitor::visit (AST::MetaListPaths &meta_item)
+{
+ for (auto &path : meta_item.get_paths ())
+ visit (path);
+}
+
+void
+PointerVisitor::visit (AST::MetaListNameValueStr &meta_item)
+{
+ for (auto &str : meta_item.get_values ())
+ visit (str);
+}
+
+void
+PointerVisitor::visit (AST::IdentifierPattern &pattern)
+{
+ if (pattern.has_subpattern ())
+ reseat (pattern.get_subpattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangePatternBoundPath &bound)
+{
+ visit (bound.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::RangePatternBoundQualPath &bound)
+{
+ visit (bound.get_qualified_path ());
+}
+
+void
+PointerVisitor::visit (AST::RangePattern &pattern)
+{
+ // FIXME: So should this be reseat() instead? Can we have macro invocations as
+ // patterns in range patterns?
+ if (pattern.get_has_lower_bound ())
+ visit (pattern.get_lower_bound ());
+ if (pattern.get_has_upper_bound ())
+ visit (pattern.get_upper_bound ());
+}
+
+void
+PointerVisitor::visit (AST::ReferencePattern &pattern)
+{
+ reseat (pattern.get_referenced_pattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructPatternFieldTuplePat &field)
+{
+ visit_outer_attrs (field);
+ reseat (field.get_index_pattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructPatternFieldIdentPat &field)
+{
+ visit_outer_attrs (field);
+ reseat (field.get_ident_pattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructPatternFieldIdent &field)
+{
+ visit_outer_attrs (field);
+}
+
+void
+PointerVisitor::visit (AST::StructPatternElements &spe)
+{
+ for (auto &field : spe.get_struct_pattern_fields ())
+ visit (field);
+ for (auto &attribute : spe.get_etc_outer_attrs ())
+ visit (attribute);
+}
+
+void
+PointerVisitor::visit (AST::StructPattern &pattern)
+{
+ visit (pattern.get_path ());
+ visit (pattern.get_struct_pattern_elems ());
+}
+
+void
+PointerVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
+{
+ for (auto &pattern : tuple_items.get_patterns ())
+ reseat (pattern);
+}
+
+void
+PointerVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
+{
+ for (auto &lower : tuple_items.get_lower_patterns ())
+ reseat (lower);
+ for (auto &upper : tuple_items.get_upper_patterns ())
+ reseat (upper);
+}
+
+void
+PointerVisitor::visit (AST::TupleStructPattern &pattern)
+{
+ visit (pattern.get_path ());
+ visit (pattern.get_items ());
+}
+
+void
+PointerVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
+{
+ for (auto &pattern : tuple_items.get_patterns ())
+ reseat (pattern);
+}
+
+void
+PointerVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
+{
+ for (auto &lower : tuple_items.get_lower_patterns ())
+ reseat (lower);
+ for (auto &upper : tuple_items.get_upper_patterns ())
+ reseat (upper);
+}
+
+void
+PointerVisitor::visit (AST::TuplePattern &pattern)
+{
+ visit (pattern.get_items ());
+}
+
+void
+PointerVisitor::visit (AST::GroupedPattern &pattern)
+{
+ reseat (pattern.get_pattern_in_parens_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::SlicePatternItemsNoRest &items)
+{
+ for (auto &item : items.get_patterns ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::SlicePatternItemsHasRest &items)
+{
+ for (auto &item : items.get_lower_patterns ())
+ reseat (item);
+ for (auto &item : items.get_upper_patterns ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::SlicePattern &pattern)
+{
+ visit (pattern.get_items ());
+}
+
+void
+PointerVisitor::visit (AST::AltPattern &pattern)
+{
+ for (auto &alt : pattern.get_alts ())
+ reseat (alt);
+}
+
+void
+PointerVisitor::visit (AST::EmptyStmt &stmt)
+{}
+
+void
+PointerVisitor::visit (AST::LetStmt &stmt)
+{
+ visit_outer_attrs (stmt);
+ reseat (stmt.get_pattern_ptr ());
+ if (stmt.has_type ())
+ reseat (stmt.get_type_ptr ());
+ if (stmt.has_init_expr ())
+ reseat (stmt.get_init_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ExprStmt &stmt)
+{
+ reseat (stmt.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TraitBound &bound)
+{
+ for (auto &lifetime : bound.get_for_lifetimes ())
+ visit (lifetime);
+ visit (bound.get_type_path ());
+}
+
+void
+PointerVisitor::visit (AST::ImplTraitType &type)
+{
+ for (auto &bound : type.get_type_param_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::TraitObjectType &type)
+{
+ for (auto &bound : type.get_type_param_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::ParenthesisedType &type)
+{
+ reseat (type.get_type_in_parens ());
+}
+
+void
+PointerVisitor::visit (AST::ImplTraitTypeOneBound &type)
+{
+ // FIXME: Do we need to reseat here?
+ visit (type.get_trait_bound ());
+}
+
+void
+PointerVisitor::visit (AST::TraitObjectTypeOneBound &type)
+{
+ // FIXME: Do we need to reseat here?
+ visit (type.get_trait_bound ());
+}
+
+void
+PointerVisitor::visit (AST::TupleType &type)
+{
+ for (auto &elem : type.get_elems ())
+ reseat (elem);
+}
+
+void
+PointerVisitor::visit (AST::NeverType &type)
+{}
+
+void
+PointerVisitor::visit (AST::RawPointerType &type)
+{
+ reseat (type.get_type_pointed_to_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ReferenceType &type)
+{
+ visit (type.get_lifetime ());
+ reseat (type.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayType &type)
+{
+ reseat (type.get_elem_type_ptr ());
+ visit (type.get_size_expr ());
+}
+
+void
+PointerVisitor::visit (AST::SliceType &type)
+{
+ reseat (type.get_elem_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::InferredType &type)
+{}
+
+void
+PointerVisitor::visit (AST::MaybeNamedParam &param)
+{
+ visit_outer_attrs (param);
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BareFunctionType &type)
+{
+ for (auto &lifetime : type.get_for_lifetimes ())
+ visit (lifetime);
+ visit (type.get_function_qualifiers ());
+ for (auto &param : type.get_function_params ())
+ visit (param);
+ if (type.is_variadic ())
+ for (auto attr : type.get_variadic_attr ())
+ visit (attr);
+ if (type.has_return_type ())
+ reseat (type.get_return_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::FormatArgs &)
+{
+ // FIXME: Do we have anything to do? any subnodes to visit? Probably, right?
+}
+
+void
+PointerVisitor::visit (AST::OffsetOf &offset_of)
+{
+ reseat (offset_of.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::VariadicParam &param)
+{
+ if (param.has_pattern ())
+ reseat (param.get_pattern_ptr ());
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.h b/gcc/rust/ast/rust-ast-pointer-visitor.h
new file mode 100644
index 0000000..8c12b4e
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-pointer-visitor.h
@@ -0,0 +1,234 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_AST_POINTER_VISITOR_H
+#define RUST_AST_POINTER_VISITOR_H
+
+#include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-item.h"
+
+namespace Rust {
+namespace AST {
+
+/**
+ * Regular AST visitor which may reseat pointers when necessary.
+ */
+class PointerVisitor : public DefaultASTVisitor
+{
+public:
+ using DefaultASTVisitor::visit;
+
+ virtual void reseat (std::unique_ptr<AST::Expr> &ptr) { visit (ptr); }
+ virtual void reseat (std::unique_ptr<AST::BlockExpr> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Stmt> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Item> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::AssociatedItem> &ptr)
+ {
+ visit (ptr);
+ }
+
+ virtual void reseat (std::unique_ptr<AST::ExternalItem> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Type> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::TypeNoBounds> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Pattern> &ptr) { visit (ptr); }
+
+ void visit (AST::Crate &crate) override;
+ void visit (AST::AttrInputMetaItemContainer &input) override;
+ void visit (AST::IdentifierExpr &ident_expr) override;
+ void visit (AST::LifetimeParam &lifetime_param) override;
+ void visit (AST::ConstGenericParam &const_param) override;
+ void visit (AST::PathInExpression &path) override;
+ void visit (GenericArgsBinding &binding) override;
+ void visit (AST::TypePathSegmentGeneric &segment) override;
+ void visit (AST::TypePathFunction &tpf) override;
+ void visit (AST::TypePathSegmentFunction &segment) override;
+ void visit (AST::GenericArgs &args) override;
+ void visit (AST::PathExprSegment &segment) override;
+ void visit (AST::TypePath &path) override;
+ void visit (AST::QualifiedPathInExpression &path) override;
+ void visit (AST::QualifiedPathType &path) override;
+ void visit (AST::QualifiedPathInType &path) override;
+ void visit (AST::LiteralExpr &expr) override;
+ void visit (AST::AttrInputLiteral &attr_input) override;
+ void visit (AST::AttrInputMacro &attr_input) override;
+ void visit (AST::MetaItemLitExpr &meta_item) override;
+ void visit (AST::SimplePath &path) override;
+ void visit (AST::MetaItemPathExpr &meta_item) override;
+ void visit (AST::BorrowExpr &expr) override;
+ void visit (AST::DereferenceExpr &expr) override;
+ void visit (AST::ErrorPropagationExpr &expr) override;
+ void visit (AST::NegationExpr &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::ArrayElemsValues &elems) override;
+ void visit (AST::ArrayElemsCopied &elems) override;
+ void visit (AST::ArrayExpr &expr) override;
+ void visit (AST::ArrayIndexExpr &expr) override;
+ void visit (AST::TupleExpr &expr) override;
+ void visit (AST::TupleIndexExpr &expr) override;
+ void visit (AST::StructExprStruct &expr) override;
+ void visit (AST::StructExprFieldIdentifier &field) override;
+ void visit (AST::StructExprFieldIdentifierValue &field) override;
+ void visit (AST::StructExprFieldIndexValue &field) override;
+ void visit (AST::StructBase &base) override;
+ void visit (AST::StructExprStructFields &expr) override;
+ void visit (AST::StructExprStructBase &expr) override;
+ void visit (AST::CallExpr &expr) override;
+ void visit (AST::MethodCallExpr &expr) override;
+ void visit (AST::FieldAccessExpr &expr) override;
+ void visit (AST::ClosureExprInner &expr) override;
+ void visit (AST::BlockExpr &expr) override;
+ void visit (AST::ConstBlock &expr) override;
+ void visit (AST::AnonConst &expr) override;
+ void visit (AST::ClosureExprInnerTyped &expr) override;
+ void visit (AST::ClosureParam &param) override;
+ void visit (AST::ContinueExpr &expr) override;
+ void visit (AST::BreakExpr &expr) override;
+ void visit (AST::RangeFromToExpr &expr) override;
+ void visit (AST::RangeFromExpr &expr) override;
+ void visit (AST::RangeToExpr &expr) override;
+ void visit (AST::RangeFullExpr &expr) override;
+ void visit (AST::RangeFromToInclExpr &expr) override;
+ void visit (AST::RangeToInclExpr &expr) override;
+ void visit (AST::ReturnExpr &expr) override;
+ void visit (AST::TryExpr &expr) override;
+ void visit (AST::BoxExpr &expr) override;
+ void visit (AST::UnsafeBlockExpr &expr) override;
+ void visit (AST::LoopLabel &label) override;
+ void visit (AST::LoopExpr &expr) override;
+ void visit (AST::WhileLoopExpr &expr) override;
+ void visit (AST::WhileLetLoopExpr &expr) override;
+ void visit (AST::ForLoopExpr &expr) override;
+ void visit (AST::IfExpr &expr) override;
+ void visit (AST::IfExprConseqElse &expr) override;
+ void visit (AST::IfLetExpr &expr) override;
+ void visit (AST::IfLetExprConseqElse &expr) override;
+ void visit (AST::MatchArm &arm) override;
+ void visit (AST::MatchCase &arm) override;
+ void visit (AST::MatchExpr &expr) override;
+ void visit (AST::AwaitExpr &expr) override;
+ void visit (AST::AsyncBlockExpr &expr) override;
+ void visit (AST::InlineAsm &expr) override;
+ void visit (AST::LlvmInlineAsm &expr) override;
+ void visit (AST::TypeParam &param) override;
+ void visit (AST::LifetimeWhereClauseItem &item) override;
+ void visit (AST::TypeBoundWhereClauseItem &item) override;
+ void visit (AST::Visibility &vis) override;
+ void visit (AST::WhereClause &where) override;
+ void visit (AST::FunctionParam &param) override;
+ void visit (AST::SelfParam &param) override;
+ void visit (AST::Module &module) override;
+ void visit (AST::ExternCrate &crate) override;
+ void visit (AST::UseTreeGlob &use_tree) override;
+ void visit (AST::UseTreeList &use_tree) override;
+ void visit (AST::UseTreeRebind &use_tree) override;
+ void visit (AST::UseDeclaration &use_decl) override;
+ void visit_function_params (AST::Function &function) override;
+ void visit (AST::Function &function) override;
+ void visit (AST::TypeAlias &type_alias) override;
+ void visit (AST::StructField &field) override;
+ void visit (AST::StructStruct &struct_item) override;
+ void visit (AST::TupleField &field) override;
+ void visit (AST::TupleStruct &tuple_struct) override;
+ void visit (AST::EnumItem &item) override;
+ void visit (AST::EnumItemTuple &item) override;
+ void visit (AST::EnumItemStruct &item) override;
+ void visit (AST::EnumItemDiscriminant &item) override;
+ void visit (AST::Enum &enum_item) override;
+ void visit (AST::Union &union_item) override;
+ void visit (AST::ConstantItem &const_item) override;
+ void visit (AST::StaticItem &static_item) override;
+ void visit (AST::TraitItemType &item) override;
+ void visit (AST::Trait &trait) override;
+ void visit (AST::InherentImpl &impl) override;
+ void visit (AST::TraitImpl &impl) override;
+ void visit (AST::ExternalTypeItem &item) override;
+ void visit (AST::ExternalStaticItem &item) override;
+ void visit (AST::ExternBlock &block) override;
+ void visit (AST::MacroMatchFragment &match) override;
+ void visit (AST::MacroMatchRepetition &match) override;
+ void visit (AST::MacroMatcher &matcher) override;
+ void visit (AST::MacroTranscriber &transcriber) override;
+ void visit (AST::MacroRule &rule) override;
+ void visit (AST::MacroRulesDefinition &rules_def) override;
+ void visit (AST::MacroInvocData &data) override;
+ void visit (AST::MacroInvocation &macro_invoc) override;
+ void visit (AST::MetaItemPath &meta_item) override;
+ void visit (AST::MetaItemSeq &meta_item) override;
+ void visit (AST::MetaListPaths &meta_item) override;
+ void visit (AST::MetaListNameValueStr &meta_item) override;
+ void visit (AST::IdentifierPattern &pattern) override;
+ void visit (AST::RangePatternBoundPath &bound) override;
+ void visit (AST::RangePatternBoundQualPath &bound) override;
+ void visit (AST::RangePattern &pattern) override;
+ void visit (AST::ReferencePattern &pattern) override;
+ void visit (AST::StructPatternFieldTuplePat &field) override;
+ void visit (AST::StructPatternFieldIdentPat &field) override;
+ void visit (AST::StructPatternFieldIdent &field) override;
+ void visit (AST::StructPatternElements &spe) override;
+ void visit (AST::StructPattern &pattern) override;
+ void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ void visit (AST::TupleStructItemsHasRest &tuple_items) override;
+ void visit (AST::TupleStructPattern &pattern) override;
+ void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
+ void visit (AST::TuplePattern &pattern) override;
+ void visit (AST::GroupedPattern &pattern) override;
+ void visit (AST::SlicePatternItemsNoRest &items) override;
+ void visit (AST::SlicePatternItemsHasRest &items) override;
+ void visit (AST::SlicePattern &pattern) override;
+ void visit (AST::AltPattern &pattern) override;
+ void visit (AST::EmptyStmt &stmt) override;
+ void visit (AST::LetStmt &stmt) override;
+ void visit (AST::ExprStmt &stmt) override;
+ void visit (AST::TraitBound &bound) override;
+ void visit (AST::ImplTraitType &type) override;
+ void visit (AST::TraitObjectType &type) override;
+ void visit (AST::ParenthesisedType &type) override;
+ void visit (AST::ImplTraitTypeOneBound &type) override;
+ void visit (AST::TraitObjectTypeOneBound &type) override;
+ void visit (AST::TupleType &type) override;
+ void visit (AST::NeverType &type) override;
+ void visit (AST::RawPointerType &type) override;
+ void visit (AST::ReferenceType &type) override;
+ void visit (AST::ArrayType &type) override;
+ void visit (AST::SliceType &type) override;
+ void visit (AST::InferredType &type) override;
+ void visit (AST::MaybeNamedParam &param) override;
+ void visit (AST::BareFunctionType &type) override;
+ void visit (AST::FormatArgs &) override;
+ void visit (AST::OffsetOf &offset_of) override;
+ void visit (AST::VariadicParam &param) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index ab8cdbe..afdd2b1 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -248,6 +248,7 @@ void
DefaultASTVisitor::visit (AST::ErrorPropagationExpr &expr)
{
visit_outer_attrs (expr);
+ visit (expr.get_propagating_expr ());
}
void
@@ -1025,15 +1026,6 @@ DefaultASTVisitor::visit (AST::StaticItem &static_item)
}
void
-DefaultASTVisitor::visit (AST::TraitItemConst &item)
-{
- visit_outer_attrs (item);
- visit (item.get_type ());
- if (item.has_expr ())
- visit (item.get_expr ());
-}
-
-void
DefaultASTVisitor::visit (AST::TraitItemType &item)
{
visit_outer_attrs (item);
@@ -1296,14 +1288,14 @@ DefaultASTVisitor::visit (AST::StructPattern &pattern)
}
void
-DefaultASTVisitor::visit (AST::TupleStructItemsNoRange &tuple_items)
+DefaultASTVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
{
for (auto &pattern : tuple_items.get_patterns ())
visit (pattern);
}
void
-DefaultASTVisitor::visit (AST::TupleStructItemsRange &tuple_items)
+DefaultASTVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
{
for (auto &lower : tuple_items.get_lower_patterns ())
visit (lower);
@@ -1319,14 +1311,14 @@ DefaultASTVisitor::visit (AST::TupleStructPattern &pattern)
}
void
-DefaultASTVisitor::visit (AST::TuplePatternItemsMultiple &tuple_items)
+DefaultASTVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
{
for (auto &pattern : tuple_items.get_patterns ())
visit (pattern);
}
void
-DefaultASTVisitor::visit (AST::TuplePatternItemsRanged &tuple_items)
+DefaultASTVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
{
for (auto &lower : tuple_items.get_lower_patterns ())
visit (lower);
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 2d81aa1..a7a2ac4 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -164,7 +164,6 @@ public:
virtual void visit (Union &union_item) = 0;
virtual void visit (ConstantItem &const_item) = 0;
virtual void visit (StaticItem &static_item) = 0;
- virtual void visit (TraitItemConst &item) = 0;
virtual void visit (TraitItemType &item) = 0;
virtual void visit (Trait &trait) = 0;
virtual void visit (InherentImpl &impl) = 0;
@@ -204,12 +203,12 @@ public:
virtual void visit (StructPatternFieldIdent &field) = 0;
virtual void visit (StructPattern &pattern) = 0;
// virtual void visit(TupleStructItems& tuple_items) = 0;
- virtual void visit (TupleStructItemsNoRange &tuple_items) = 0;
- virtual void visit (TupleStructItemsRange &tuple_items) = 0;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) = 0;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) = 0;
virtual void visit (TupleStructPattern &pattern) = 0;
// virtual void visit(TuplePatternItems& tuple_items) = 0;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) = 0;
- virtual void visit (TuplePatternItemsRanged &tuple_items) = 0;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) = 0;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) = 0;
virtual void visit (TuplePattern &pattern) = 0;
virtual void visit (GroupedPattern &pattern) = 0;
virtual void visit (SlicePatternItemsNoRest &items) = 0;
@@ -349,7 +348,6 @@ public:
virtual void visit (AST::Union &union_item) override;
virtual void visit (AST::ConstantItem &const_item) override;
virtual void visit (AST::StaticItem &static_item) override;
- virtual void visit (AST::TraitItemConst &item) override;
virtual void visit (AST::TraitItemType &item) override;
virtual void visit (AST::Trait &trait) override;
virtual void visit (AST::InherentImpl &impl) override;
@@ -381,11 +379,11 @@ public:
virtual void visit (AST::StructPatternFieldIdentPat &field) override;
virtual void visit (AST::StructPatternFieldIdent &field) override;
virtual void visit (AST::StructPattern &pattern) override;
- virtual void visit (AST::TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (AST::TupleStructItemsRange &tuple_items) override;
+ virtual void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (AST::TupleStructItemsHasRest &tuple_items) override;
virtual void visit (AST::TupleStructPattern &pattern) override;
- virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (AST::TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (AST::TuplePattern &pattern) override;
virtual void visit (AST::GroupedPattern &pattern) override;
virtual void visit (AST::SlicePatternItemsNoRest &items) override;
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 8e856fb..337a338 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -48,29 +48,33 @@ SingleASTNode::SingleASTNode (SingleASTNode const &other)
kind = other.kind;
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
expr = other.expr->clone_expr ();
break;
- case ITEM:
+ case Kind::Item:
item = other.item->clone_item ();
break;
- case STMT:
+ case Kind::Stmt:
stmt = other.stmt->clone_stmt ();
break;
- case EXTERN:
+ case Kind::Extern:
external_item = other.external_item->clone_external_item ();
break;
- case ASSOC_ITEM:
+ case Kind::Assoc:
assoc_item = other.assoc_item->clone_associated_item ();
break;
- case TYPE:
+ case Kind::Type:
type = other.type->clone_type ();
break;
+
+ case Kind::Pattern:
+ pattern = other.pattern->clone_pattern ();
+ break;
}
}
@@ -80,29 +84,33 @@ SingleASTNode::operator= (SingleASTNode const &other)
kind = other.kind;
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
expr = other.expr->clone_expr ();
break;
- case ITEM:
+ case Kind::Item:
item = other.item->clone_item ();
break;
- case STMT:
+ case Kind::Stmt:
stmt = other.stmt->clone_stmt ();
break;
- case EXTERN:
+ case Kind::Extern:
external_item = other.external_item->clone_external_item ();
break;
- case ASSOC_ITEM:
+ case Kind::Assoc:
assoc_item = other.assoc_item->clone_associated_item ();
break;
- case TYPE:
+ case Kind::Type:
type = other.type->clone_type ();
break;
+
+ case Kind::Pattern:
+ pattern = other.pattern->clone_pattern ();
+ break;
}
return *this;
}
@@ -112,29 +120,33 @@ SingleASTNode::accept_vis (ASTVisitor &vis)
{
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
expr->accept_vis (vis);
break;
- case ITEM:
+ case Kind::Item:
item->accept_vis (vis);
break;
- case STMT:
+ case Kind::Stmt:
stmt->accept_vis (vis);
break;
- case EXTERN:
+ case Kind::Extern:
external_item->accept_vis (vis);
break;
- case ASSOC_ITEM:
+ case Kind::Assoc:
assoc_item->accept_vis (vis);
break;
- case TYPE:
+ case Kind::Type:
type->accept_vis (vis);
break;
+
+ case Kind::Pattern:
+ pattern->accept_vis (vis);
+ break;
}
}
@@ -143,18 +155,20 @@ SingleASTNode::is_error ()
{
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
return expr == nullptr;
- case ITEM:
+ case Kind::Item:
return item == nullptr;
- case STMT:
+ case Kind::Stmt:
return stmt == nullptr;
- case EXTERN:
+ case Kind::Extern:
return external_item == nullptr;
- case ASSOC_ITEM:
+ case Kind::Assoc:
return assoc_item == nullptr;
- case TYPE:
+ case Kind::Type:
return type == nullptr;
+ case Kind::Pattern:
+ return pattern == nullptr;
}
rust_unreachable ();
@@ -166,18 +180,20 @@ SingleASTNode::as_string () const
{
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
return "Expr: " + expr->as_string ();
- case ITEM:
+ case Kind::Item:
return "Item: " + item->as_string ();
- case STMT:
+ case Kind::Stmt:
return "Stmt: " + stmt->as_string ();
- case EXTERN:
+ case Kind::Extern:
return "External Item: " + external_item->as_string ();
- case ASSOC_ITEM:
+ case Kind::Assoc:
return "Associated Item: " + assoc_item->as_string ();
- case TYPE:
+ case Kind::Type:
return "Type: " + type->as_string ();
+ case Kind::Pattern:
+ return "Pattern: " + pattern->as_string ();
}
rust_unreachable ();
@@ -232,7 +248,7 @@ Attribute::as_string () const
bool
Attribute::is_derive () const
{
- return has_attr_input () && get_path () == "derive";
+ return has_attr_input () && get_path () == Values::Attributes::DERIVE;
}
/**
@@ -389,7 +405,7 @@ DelimTokenTree::as_string () const
std::string
Token::as_string () const
{
- if (tok_ref->has_str ())
+ if (tok_ref->should_have_str ())
{
std::string str = tok_ref->get_str ();
@@ -636,14 +652,8 @@ ConstantItem::as_string () const
}
str += "\n Type: " + type->as_string ();
- // DEBUG: null pointer check
- if (const_expr == nullptr)
- {
- rust_debug ("something really terrible has gone wrong - null "
- "pointer expr in const item.");
- return "NULL_POINTER_MARK";
- }
- str += "\n Expression: " + const_expr->as_string ();
+ if (has_expr ())
+ str += "\n Expression: " + const_expr->as_string ();
return str + "\n";
}
@@ -3034,20 +3044,6 @@ ExternalStaticItem::as_string () const
}
std::string
-TraitItemConst::as_string () const
-{
- // TODO: rewrite to work with non-linearisable exprs
- std::string str = append_attributes (outer_attrs, OUTER);
-
- str += "\nconst " + name.as_string () + " : " + type->as_string ();
-
- if (has_expression ())
- str += " = " + expr->as_string ();
-
- return str;
-}
-
-std::string
TraitItemType::as_string () const
{
std::string str = append_attributes (outer_attrs, OUTER);
@@ -3367,7 +3363,13 @@ void
Module::process_file_path ()
{
rust_assert (kind == Module::ModuleKind::UNLOADED);
- rust_assert (module_file.empty ());
+
+ if (!module_file.empty ())
+ {
+ rust_error_at (locus, "error handling module file for %qs",
+ module_name.as_string ().c_str ());
+ return;
+ }
// This corresponds to the path of the file 'including' the module. So the
// file that contains the 'mod <file>;' directive
@@ -4132,6 +4134,12 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const
for (auto it = items.begin () + 1; it != items.end (); ++it)
{
+ if ((*it)->get_kind () == MetaItemInner::Kind::MetaItem
+ && static_cast<MetaItem &> (**it).get_item_kind ()
+ == MetaItem::ItemKind::PathExpr
+ && !static_cast<MetaItemPathExpr &> (**it).get_expr ().is_literal ())
+ continue;
+
Attribute attr = (*it)->to_attribute ();
if (attr.is_empty ())
{
@@ -4149,11 +4157,12 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const
bool
Attribute::check_cfg_predicate (const Session &session) const
{
+ auto string_path = path.as_string ();
/* assume that cfg predicate actually can exist, i.e. attribute has cfg or
* cfg_attr path */
if (!has_attr_input ()
- || (path.as_string () != Values::Attributes::CFG
- && path.as_string () != Values::Attributes::CFG_ATTR))
+ || (string_path != Values::Attributes::CFG
+ && string_path != Values::Attributes::CFG_ATTR))
{
// DEBUG message
rust_debug (
@@ -4169,6 +4178,13 @@ Attribute::check_cfg_predicate (const Session &session) const
return false;
auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
+ if (meta_item.get_items ().empty ()
+ && string_path == Values::Attributes::CFG_ATTR)
+ {
+ rust_error_at (path.get_locus (),
+ "malformed %<cfg_attr%> attribute input");
+ return false;
+ }
return meta_item.get_items ().front ()->check_cfg_predicate (session);
}
@@ -4740,12 +4756,6 @@ StaticItem::accept_vis (ASTVisitor &vis)
}
void
-TraitItemConst::accept_vis (ASTVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
TraitItemType::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 2d2c5d0..8a7e618 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -184,17 +184,6 @@ class Token : public TokenTree, public MacroMatch
{
// A token is a kind of token tree (except delimiter tokens)
// A token is a kind of MacroMatch (except $ and delimiter tokens)
-#if 0
- // TODO: improve member variables - current ones are the same as lexer token
- // Token kind.
- TokenId token_id;
- // Token location.
- location_t locus;
- // Associated text (if any) of token.
- std::string str;
- // Token type hint (if any).
- PrimitiveCoreType type_hint;
-#endif
const_TokenPtr tok_ref;
@@ -209,53 +198,7 @@ public:
return std::unique_ptr<Token> (clone_token_impl ());
}
-#if 0
- /* constructor from general text - avoid using if lexer const_TokenPtr is
- * available */
- Token (TokenId token_id, location_t locus, std::string str,
- PrimitiveCoreType type_hint)
- : token_id (token_id), locus (locus), str (std::move (str)),
- type_hint (type_hint)
- {}
-#endif
- // not doable with new implementation - will have to make a const_TokenPtr
-
// Constructor from lexer const_TokenPtr
-#if 0
- /* TODO: find workaround for std::string being nullptr - probably have to
- * introduce new method in lexer Token, or maybe make conversion method
- * there */
- Token (const_TokenPtr lexer_token_ptr)
- : token_id (lexer_token_ptr->get_id ()),
- locus (lexer_token_ptr->get_locus ()), str (""),
- type_hint (lexer_token_ptr->get_type_hint ())
- {
- // FIXME: change to "should have str" later?
- if (lexer_token_ptr->has_str ())
- {
- str = lexer_token_ptr->get_str ();
-
- // DEBUG
- rust_debug ("ast token created with str '%s'", str.c_str ());
- }
- else
- {
- // FIXME: is this returning correct thing?
- str = lexer_token_ptr->get_token_description ();
-
- // DEBUG
- rust_debug ("ast token created with string '%s'", str.c_str ());
- }
-
- // DEBUG
- if (lexer_token_ptr->should_have_str () && !lexer_token_ptr->has_str ())
- {
- rust_debug (
- "BAD: for token '%s', should have string but does not!",
- lexer_token_ptr->get_token_description ());
- }
- }
-#endif
Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {}
bool is_string_lit () const
@@ -283,7 +226,7 @@ public:
std::vector<std::unique_ptr<Token>> to_token_stream () const override;
TokenId get_id () const { return tok_ref->get_id (); }
- bool has_str () const { return tok_ref->has_str (); }
+ bool should_have_str () const { return tok_ref->should_have_str (); }
const std::string &get_str () const { return tok_ref->get_str (); }
location_t get_locus () const { return tok_ref->get_locus (); }
@@ -1137,7 +1080,9 @@ public:
virtual void mark_for_strip () = 0;
virtual bool is_marked_for_strip () const = 0;
- NodeId get_node_id () const { return node_id; }
+
+ // TODO: put this in a virtual base class?
+ virtual NodeId get_node_id () const { return node_id; }
virtual Kind get_stmt_kind () = 0;
@@ -1536,7 +1481,8 @@ public:
virtual location_t get_locus () const = 0;
- NodeId get_node_id () const { return node_id; }
+ // TODO: put this in a virtual base class?
+ virtual NodeId get_node_id () const { return node_id; }
virtual Type *reconstruct_impl () const = 0;
protected:
@@ -1799,6 +1745,8 @@ public:
virtual bool is_marked_for_strip () const = 0;
virtual location_t get_locus () const = 0;
+
+ virtual NodeId get_node_id () const = 0;
};
// Item used in trait declarations - abstract base class
@@ -1829,7 +1777,7 @@ public:
return std::unique_ptr<TraitItem> (clone_associated_item_impl ());
}
- NodeId get_node_id () const { return node_id; }
+ NodeId get_node_id () const override { return node_id; }
location_t get_locus () const override { return locus; }
};
@@ -1957,18 +1905,19 @@ public:
class SingleASTNode : public Visitable
{
public:
- enum NodeType
- {
- EXPRESSION,
- ITEM,
- STMT,
- EXTERN,
- ASSOC_ITEM,
- TYPE,
+ enum class Kind
+ {
+ Expr,
+ Item,
+ Stmt,
+ Extern,
+ Assoc,
+ Type,
+ Pattern,
};
private:
- NodeType kind;
+ Kind kind;
// FIXME make this a union
std::unique_ptr<Expr> expr;
@@ -1977,30 +1926,35 @@ private:
std::unique_ptr<ExternalItem> external_item;
std::unique_ptr<AssociatedItem> assoc_item;
std::unique_ptr<Type> type;
+ std::unique_ptr<Pattern> pattern;
public:
SingleASTNode (std::unique_ptr<Expr> expr)
- : kind (EXPRESSION), expr (std::move (expr))
+ : kind (Kind::Expr), expr (std::move (expr))
{}
SingleASTNode (std::unique_ptr<Item> item)
- : kind (ITEM), item (std::move (item))
+ : kind (Kind::Item), item (std::move (item))
{}
SingleASTNode (std::unique_ptr<Stmt> stmt)
- : kind (STMT), stmt (std::move (stmt))
+ : kind (Kind::Stmt), stmt (std::move (stmt))
{}
SingleASTNode (std::unique_ptr<ExternalItem> item)
- : kind (EXTERN), external_item (std::move (item))
+ : kind (Kind::Extern), external_item (std::move (item))
{}
SingleASTNode (std::unique_ptr<AssociatedItem> item)
- : kind (ASSOC_ITEM), assoc_item (std::move (item))
+ : kind (Kind::Assoc), assoc_item (std::move (item))
{}
SingleASTNode (std::unique_ptr<Type> type)
- : kind (TYPE), type (std::move (type))
+ : kind (Kind::Type), type (std::move (type))
+ {}
+
+ SingleASTNode (std::unique_ptr<Pattern> pattern)
+ : kind (Kind::Pattern), pattern (std::move (pattern))
{}
SingleASTNode (SingleASTNode const &other);
@@ -2010,23 +1964,23 @@ public:
SingleASTNode (SingleASTNode &&other) = default;
SingleASTNode &operator= (SingleASTNode &&other) = default;
- NodeType get_kind () const { return kind; }
+ Kind get_kind () const { return kind; }
std::unique_ptr<Expr> &get_expr ()
{
- rust_assert (kind == EXPRESSION);
+ rust_assert (kind == Kind::Expr);
return expr;
}
std::unique_ptr<Item> &get_item ()
{
- rust_assert (kind == ITEM);
+ rust_assert (kind == Kind::Item);
return item;
}
std::unique_ptr<Stmt> &get_stmt ()
{
- rust_assert (kind == STMT);
+ rust_assert (kind == Kind::Stmt);
return stmt;
}
@@ -2071,6 +2025,12 @@ public:
return std::move (type);
}
+ std::unique_ptr<Pattern> take_pattern ()
+ {
+ rust_assert (!is_error ());
+ return std::move (pattern);
+ }
+
void accept_vis (ASTVisitor &vis) override;
bool is_error ();
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 2893e7b..c784ad6 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -134,6 +134,7 @@ public:
FormatArgumentKind get_kind () const { return kind; }
const Expr &get_expr () const { return *expr; }
+ Expr &get_expr () { return *expr; }
private:
FormatArgument (FormatArgumentKind::Kind kind, tl::optional<Identifier> ident,
@@ -164,6 +165,11 @@ public:
void push (FormatArgument &&elt) { args.emplace_back (std::move (elt)); }
const FormatArgument at (size_t idx) const { return args.at (idx); }
+ const std::vector<FormatArgument> &get_args () const { return args; }
+ std::vector<FormatArgument> &get_args () { return args; }
+ size_t size () const { return args.size (); }
+ bool empty () const { return args.empty (); }
+
private:
std::vector<FormatArgument> args;
};
@@ -200,6 +206,7 @@ public:
const Fmt::Pieces &get_template () const { return template_pieces; }
const FormatArguments &get_arguments () const { return arguments; }
+ FormatArguments &get_arguments () { return arguments; }
virtual location_t get_locus () const override;
Expr::Kind get_expr_kind () const override { return Expr::Kind::FormatArgs; }
@@ -255,6 +262,7 @@ public:
virtual location_t get_locus () const override { return loc; }
const Type &get_type () const { return *type; }
Type &get_type () { return *type; }
+ std::unique_ptr<Type> &get_type_ptr () { return type; }
const Identifier &get_field () const { return field; }
bool is_expr_without_block () const override { return false; }
diff --git a/gcc/rust/ast/rust-collect-lang-items.cc b/gcc/rust/ast/rust-collect-lang-items.cc
index 306c6f7..1efe26f 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -43,18 +43,16 @@ get_lang_item_attr (const T &maybe_lang_item)
continue;
}
- bool is_lang_item = str_path == Values::Attributes::LANG
- && attr.has_attr_input ()
- && attr.get_attr_input ().get_attr_input_type ()
- == AST::AttrInput::AttrInputType::LITERAL;
+ bool is_lang_item = str_path == Values::Attributes::LANG;
if (is_lang_item)
{
- auto &literal
- = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
- const auto &lang_item_type_str = literal.get_literal ().as_string ();
+ auto lang_item_type_str
+ = Analysis::Attributes::extract_string_literal (attr);
- return LangItem::Parse (lang_item_type_str);
+ rust_assert (lang_item_type_str.has_value ());
+
+ return LangItem::Parse (*lang_item_type_str);
}
}
diff --git a/gcc/rust/ast/rust-cond-compilation.h b/gcc/rust/ast/rust-cond-compilation.h
index 56a5646..5d5fba5 100644
--- a/gcc/rust/ast/rust-cond-compilation.h
+++ b/gcc/rust/ast/rust-cond-compilation.h
@@ -91,9 +91,13 @@ class ConfigurationAll : public ConfigurationPredicate
predicate_list; // inlined form
public:
+ ConfigurationAll (const ConfigurationAll &) = delete;
+
+ ConfigurationAll (ConfigurationAll &&) = default;
+
ConfigurationAll (
std::vector<std::unique_ptr<ConfigurationPredicate>> predicate_list)
- : predicate_list (predicate_list)
+ : predicate_list (std::move (predicate_list))
{}
void accept_vis (ASTVisitor &vis) override;
@@ -103,7 +107,14 @@ protected:
* than base */
ConfigurationAll *clone_configuration_predicate_impl () const override
{
- return new ConfigurationAll (*this);
+ decltype (predicate_list) predicate_list_clone = {};
+ predicate_list_clone.reserve (predicate_list.size ());
+
+ for (const auto &predicate : predicate_list)
+ predicate_list_clone.push_back (
+ predicate->clone_configuration_predicate ());
+
+ return new ConfigurationAll (std::move (predicate_list_clone));
}
};
@@ -114,9 +125,13 @@ class ConfigurationAny : public ConfigurationPredicate
predicate_list; // inlined form
public:
+ ConfigurationAny (const ConfigurationAny &) = delete;
+
+ ConfigurationAny (ConfigurationAny &&) = default;
+
ConfigurationAny (
std::vector<std::unique_ptr<ConfigurationPredicate>> predicate_list)
- : predicate_list (predicate_list)
+ : predicate_list (std::move (predicate_list))
{}
void accept_vis (ASTVisitor &vis) override;
@@ -126,7 +141,14 @@ protected:
* than base */
ConfigurationAny *clone_configuration_predicate_impl () const override
{
- return new ConfigurationAny (*this);
+ decltype (predicate_list) predicate_list_clone = {};
+ predicate_list_clone.reserve (predicate_list.size ());
+
+ for (const auto &predicate : predicate_list)
+ predicate_list_clone.push_back (
+ predicate->clone_configuration_predicate ());
+
+ return new ConfigurationAny (std::move (predicate_list_clone));
}
};
@@ -226,7 +248,7 @@ public:
CfgAttrAttribute (CfgAttrAttribute const &other)
: config_to_include (
other.config_to_include->clone_configuration_predicate ()),
- cfg_attrs (cfg_attrs)
+ cfg_attrs (other.cfg_attrs)
{}
// Overloaded assignment operator to clone
diff --git a/gcc/rust/ast/rust-desugar-apit.cc b/gcc/rust/ast/rust-desugar-apit.cc
index bca14ee..de34e15 100644
--- a/gcc/rust/ast/rust-desugar-apit.cc
+++ b/gcc/rust/ast/rust-desugar-apit.cc
@@ -188,9 +188,10 @@ public:
// Convert to TypePath by creating path segments
std::vector<std::unique_ptr<TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
- PathIdentSegment (ident.as_string (), type.get_locus ()), false,
- type.get_locus ())));
+ segments.emplace_back (
+ new TypePathSegment (PathIdentSegment (ident.as_string (),
+ type.get_locus ()),
+ false, type.get_locus ()));
// Create TypePath from segments
auto type_path
@@ -198,6 +199,8 @@ public:
// Convert bounds from impl trait to generic parameter bounds
std::vector<std::unique_ptr<TypeParamBound>> bounds;
+ bounds.reserve (type.get_type_param_bounds ().size ());
+
for (auto &bound : type.get_type_param_bounds ())
bounds.push_back (bound->clone_type_param_bound ());
@@ -228,9 +231,10 @@ public:
// Convert to TypePath by creating path segments
std::vector<std::unique_ptr<TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
- PathIdentSegment (ident.as_string (), type.get_locus ()), false,
- type.get_locus ())));
+ segments.emplace_back (
+ new TypePathSegment (PathIdentSegment (ident.as_string (),
+ type.get_locus ()),
+ false, type.get_locus ()));
// Create TypePath from segments
auto type_path
@@ -407,6 +411,9 @@ private:
std::vector<std::unique_ptr<TypeParamBound>>
type_param_bounds;
+ type_param_bounds.reserve (
+ tp.get_type_param_bounds ().size ());
+
for (auto &b : tp.get_type_param_bounds ())
type_param_bounds.push_back (std::move (b));
tp.get_type_param_bounds ().clear ();
@@ -459,9 +466,10 @@ private:
std::vector<SimplePathSegment> simple_segs = {simple_seg};
auto simple_path = SimplePath (simple_segs, false, ident.get_locus ());
std::vector<std::unique_ptr<TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
- PathIdentSegment (ident.as_string (), ident.get_locus ()), false,
- ident.get_locus ())));
+ segments.emplace_back (
+ new TypePathSegment (PathIdentSegment (ident.as_string (),
+ ident.get_locus ()),
+ false, ident.get_locus ()));
auto type_path = new TypePath (std::move (segments), ident.get_locus ());
return std::unique_ptr<Type> (type_path);
}
diff --git a/gcc/rust/ast/rust-desugar-for-loops.cc b/gcc/rust/ast/rust-desugar-for-loops.cc
index 5cc1c19..9a12423 100644
--- a/gcc/rust/ast/rust-desugar-for-loops.cc
+++ b/gcc/rust/ast/rust-desugar-for-loops.cc
@@ -51,7 +51,7 @@ DesugarForLoops::DesugarCtx::make_continue_arm ()
patterns.emplace_back (std::move (val));
auto pattern_item = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
builder.path_in_expression (LangItem::Kind::OPTION_SOME),
std::move (pattern_item)));
diff --git a/gcc/rust/ast/rust-desugar-question-mark.cc b/gcc/rust/ast/rust-desugar-question-mark.cc
index 01400d8..20a4903 100644
--- a/gcc/rust/ast/rust-desugar-question-mark.cc
+++ b/gcc/rust/ast/rust-desugar-question-mark.cc
@@ -55,7 +55,7 @@ ok_case (Builder &builder)
patterns.emplace_back (std::move (val));
auto pattern_item = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
builder.path_in_expression (LangItem::Kind::RESULT_OK),
std::move (pattern_item)));
@@ -82,7 +82,7 @@ err_case (Builder &builder)
patterns.emplace_back (std::move (val));
auto pattern_item = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
builder.path_in_expression (LangItem::Kind::RESULT_ERR),
std::move (pattern_item)));
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 7b0df25..3c36238 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -282,6 +282,8 @@ public:
Expr &get_expr () { return *expr; }
+ std::unique_ptr<Expr> &get_expr_ptr () { return expr; }
+
std::string as_string () const override
{
return path.as_string () + " = " + expr->as_string ();
@@ -296,7 +298,11 @@ public:
// we have no idea use which of them, just simply return UNKNOWN_LOCATION
// now.
// Maybe we will figure out when we really need the location in the future.
- location_t get_locus () const override { return UNKNOWN_LOCATION; }
+ location_t get_locus () const override
+ {
+ rust_unreachable ();
+ return UNKNOWN_LOCATION;
+ }
void accept_vis (ASTVisitor &vis) override;
@@ -414,6 +420,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_borrowed_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
bool has_borrow_expr () const { return main_or_left_expr != nullptr; }
bool get_is_mut () const { return mutability == Mutability::Mut; }
@@ -455,6 +467,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_dereferenced_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::Dereference; }
protected:
@@ -488,6 +506,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_propagating_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
Expr::Kind get_expr_kind () const override
{
return Expr::Kind::ErrorPropagation;
@@ -536,6 +560,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_negated_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::Negation; }
protected:
@@ -865,6 +895,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_casted_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
TypeNoBounds &get_type_to_cast_to ()
{
@@ -872,6 +908,12 @@ public:
return *type_to_convert_to;
}
+ std::unique_ptr<TypeNoBounds> &get_type_to_cast_to_ptr ()
+ {
+ rust_assert (type_to_convert_to != nullptr);
+ return type_to_convert_to;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; }
protected:
@@ -1282,6 +1324,12 @@ public:
return *elem_to_copy;
}
+ std::unique_ptr<Expr> &get_elem_to_copy_ptr ()
+ {
+ rust_assert (elem_to_copy != nullptr);
+ return elem_to_copy;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Expr &get_num_copies ()
{
@@ -1289,6 +1337,12 @@ public:
return *num_copies;
}
+ std::unique_ptr<Expr> &get_num_copies_ptr ()
+ {
+ rust_assert (num_copies != nullptr);
+ return num_copies;
+ }
+
protected:
ArrayElemsCopied *clone_array_elems_impl () const override
{
@@ -1468,6 +1522,12 @@ public:
return *array_expr;
}
+ std::unique_ptr<Expr> &get_array_expr_ptr ()
+ {
+ rust_assert (array_expr != nullptr);
+ return array_expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Expr &get_index_expr ()
{
@@ -1475,6 +1535,12 @@ public:
return *index_expr;
}
+ std::unique_ptr<Expr> &get_index_expr_ptr ()
+ {
+ rust_assert (index_expr != nullptr);
+ return index_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -1599,6 +1665,7 @@ class TupleIndexExpr : public ExprWithoutBlock
TupleIndex tuple_index;
location_t locus;
+ bool to_strip;
// i.e. pair.0
@@ -1610,13 +1677,15 @@ public:
TupleIndexExpr (std::unique_ptr<Expr> tuple_expr, TupleIndex index,
std::vector<Attribute> outer_attribs, location_t locus)
: outer_attrs (std::move (outer_attribs)),
- tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus)
+ tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus),
+ to_strip (false)
{}
// Copy constructor requires a clone for tuple_expr
TupleIndexExpr (TupleIndexExpr const &other)
: ExprWithoutBlock (other), outer_attrs (other.outer_attrs),
- tuple_index (other.tuple_index), locus (other.locus)
+ tuple_index (other.tuple_index), locus (other.locus),
+ to_strip (other.to_strip)
{
// guard to prevent null dereference (only required if error state)
if (other.tuple_expr != nullptr)
@@ -1630,6 +1699,7 @@ public:
tuple_index = other.tuple_index;
locus = other.locus;
outer_attrs = other.outer_attrs;
+ to_strip = other.to_strip;
// guard to prevent null dereference (only required if error state)
if (other.tuple_expr != nullptr)
@@ -1649,8 +1719,8 @@ public:
void accept_vis (ASTVisitor &vis) override;
// Invalid if tuple expr is null, so base stripping on that.
- void mark_for_strip () override { tuple_expr = nullptr; }
- bool is_marked_for_strip () const override { return tuple_expr == nullptr; }
+ void mark_for_strip () override { to_strip = true; }
+ bool is_marked_for_strip () const override { return to_strip; }
// TODO: is this better? Or is a "vis_block" better?
Expr &get_tuple_expr ()
@@ -1659,6 +1729,12 @@ public:
return *tuple_expr;
}
+ std::unique_ptr<Expr> &get_tuple_expr_ptr ()
+ {
+ rust_assert (tuple_expr != nullptr);
+ return tuple_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -1807,6 +1883,12 @@ public:
rust_assert (base_struct != nullptr);
return *base_struct;
}
+
+ std::unique_ptr<Expr> &get_base_struct_ptr ()
+ {
+ rust_assert (base_struct != nullptr);
+ return base_struct;
+ }
};
/* Base AST node for a single struct expression field (in struct instance
@@ -1923,6 +2005,12 @@ public:
rust_assert (value != nullptr);
return *value;
}
+
+ std::unique_ptr<Expr> &get_value_ptr ()
+ {
+ rust_assert (value != nullptr);
+ return value;
+ }
};
// Identifier and value variant of StructExprField AST node
@@ -2293,6 +2381,12 @@ public:
return *receiver;
}
+ std::unique_ptr<Expr> &get_receiver_expr_ptr ()
+ {
+ rust_assert (receiver != nullptr);
+ return receiver;
+ }
+
const PathExprSegment &get_method_name () const { return method_name; }
PathExprSegment &get_method_name () { return method_name; }
@@ -2381,6 +2475,12 @@ public:
return *receiver;
}
+ std::unique_ptr<Expr> &get_receiver_expr_ptr ()
+ {
+ rust_assert (receiver != nullptr);
+ return receiver;
+ }
+
Identifier get_field_name () const { return field; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
@@ -2480,6 +2580,12 @@ public:
return *pattern;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (pattern != nullptr);
+ return pattern;
+ }
+
Type &get_type ()
{
rust_assert (has_type_given ());
@@ -2532,6 +2638,7 @@ public:
Expr::Kind get_expr_kind () const override { return Expr::Kind::Closure; }
virtual Expr &get_definition_expr () = 0;
+ virtual std::unique_ptr<Expr> &get_definition_expr_ptr () = 0;
};
// Represents a non-type-specified closure expression AST node
@@ -2597,6 +2704,12 @@ public:
return *closure_inner;
}
+ std::unique_ptr<Expr> &get_definition_expr_ptr () override
+ {
+ rust_assert (closure_inner != nullptr);
+ return closure_inner;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2827,6 +2940,12 @@ public:
return *expr.value ();
}
+ std::unique_ptr<Expr> &get_inner_expr_ptr ()
+ {
+ rust_assert (expr.has_value ());
+ return expr.value ();
+ }
+
NodeId get_node_id () const override { return node_id; }
/* FIXME: AnonConst are always "internal" and should not have outer attributes
@@ -2922,8 +3041,7 @@ class ClosureExprInnerTyped : public ClosureExpr
{
// TODO: spec says typenobounds
std::unique_ptr<Type> return_type;
- std::unique_ptr<BlockExpr>
- expr; // only used because may be polymorphic in future
+ std::unique_ptr<Expr> expr; // only used because may be polymorphic in future
public:
std::string as_string () const override;
@@ -2947,7 +3065,7 @@ public:
{
// guard to prevent null dereference (only required if error state)
if (other.expr != nullptr)
- expr = other.expr->clone_block_expr ();
+ expr = other.expr->clone_expr ();
if (other.return_type != nullptr)
return_type = other.return_type->clone_type ();
}
@@ -2962,7 +3080,7 @@ public:
// guard to prevent null dereference (only required if error state)
if (other.expr != nullptr)
- expr = other.expr->clone_block_expr ();
+ expr = other.expr->clone_expr ();
else
expr = nullptr;
if (other.return_type != nullptr)
@@ -2985,12 +3103,19 @@ public:
bool is_marked_for_strip () const override { return expr == nullptr; }
// TODO: is this better? Or is a "vis_block" better?
- BlockExpr &get_definition_expr () override
+ Expr &get_definition_expr () override
{
rust_assert (expr != nullptr);
return *expr;
}
+ std::unique_ptr<Expr> &get_definition_expr_ptr () override
+ {
+ rust_assert (expr != nullptr);
+
+ return expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Type &get_return_type ()
{
@@ -3147,6 +3272,12 @@ public:
return *break_expr;
}
+ std::unique_ptr<Expr> &get_break_expr_ptr ()
+ {
+ rust_assert (has_break_expr ());
+ return break_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3274,6 +3405,18 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_from_expr_ptr ()
+ {
+ rust_assert (from != nullptr);
+ return from;
+ }
+
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3335,6 +3478,12 @@ public:
return *from;
}
+ std::unique_ptr<Expr> &get_from_expr_ptr ()
+ {
+ rust_assert (from != nullptr);
+ return from;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3397,6 +3546,12 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3510,6 +3665,18 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_from_expr_ptr ()
+ {
+ rust_assert (from != nullptr);
+ return from;
+ }
+
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3572,6 +3739,12 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3645,6 +3818,12 @@ public:
return *expr;
}
+ std::unique_ptr<Expr> &get_boxed_expr_ptr ()
+ {
+ rust_assert (expr != nullptr);
+ return expr;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::Box; }
protected:
@@ -3726,6 +3905,12 @@ public:
return *return_expr;
}
+ std::unique_ptr<Expr> &get_returned_expr_ptr ()
+ {
+ rust_assert (return_expr != nullptr);
+ return return_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3801,6 +3986,7 @@ public:
// TODO: is this better? Or is a "vis_block" better?
BlockExpr &get_block_expr () { return *block_expr; }
+ std::unique_ptr<BlockExpr> &get_block_expr_ptr () { return block_expr; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3886,6 +4072,12 @@ public:
return *expr;
}
+ std::unique_ptr<BlockExpr> &get_block_expr_ptr ()
+ {
+ rust_assert (expr != nullptr);
+ return expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3978,6 +4170,12 @@ public:
return *loop_block;
}
+ std::unique_ptr<BlockExpr> &get_loop_block_ptr ()
+ {
+ rust_assert (loop_block != nullptr);
+ return loop_block;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -4078,6 +4276,12 @@ public:
return *condition;
}
+ std::unique_ptr<Expr> &get_predicate_expr_ptr ()
+ {
+ rust_assert (condition != nullptr);
+ return condition;
+ }
+
BaseLoopExpr::Kind get_loop_kind () const override
{
return BaseLoopExpr::Kind::While;
@@ -4156,6 +4360,12 @@ public:
return *scrutinee;
}
+ std::unique_ptr<Expr> &get_scrutinee_expr_ptr ()
+ {
+ rust_assert (scrutinee != nullptr);
+ return scrutinee;
+ }
+
// TODO: this mutable getter seems really dodgy. Think up better way.
const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
{
@@ -4233,6 +4443,12 @@ public:
return *iterator_expr;
}
+ std::unique_ptr<Expr> &get_iterator_expr_ptr ()
+ {
+ rust_assert (iterator_expr != nullptr);
+ return iterator_expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Pattern &get_pattern ()
{
@@ -4240,6 +4456,12 @@ public:
return *pattern;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (pattern != nullptr);
+ return pattern;
+ }
+
BaseLoopExpr::Kind get_loop_kind () const override
{
return BaseLoopExpr::Kind::For;
@@ -4892,6 +5114,12 @@ public:
return *branch_value;
}
+ std::unique_ptr<Expr> &get_scrutinee_expr_ptr ()
+ {
+ rust_assert (branch_value != nullptr);
+ return branch_value;
+ }
+
const std::vector<MatchCase> &get_match_cases () const { return match_arms; }
std::vector<MatchCase> &get_match_cases () { return match_arms; }
@@ -5494,6 +5722,8 @@ struct InlineAsmTemplatePiece
struct TupleClobber
{
+ TupleClobber (std::string symbol, location_t loc) : symbol (symbol), loc (loc)
+ {}
// as gccrs still doesn't contain a symbol class I have put them as strings
std::string symbol;
location_t loc;
@@ -5667,6 +5897,10 @@ public:
}
std::vector<TupleTemplateStr> &get_templates () { return templates; }
+ const std::vector<TupleTemplateStr> &get_templates () const
+ {
+ return templates;
+ }
Expr::Kind get_expr_kind () const override
{
@@ -5685,9 +5919,12 @@ public:
void set_outputs (std::vector<LlvmOperand> operands) { outputs = operands; }
std::vector<LlvmOperand> &get_inputs () { return inputs; }
+ const std::vector<LlvmOperand> &get_inputs () const { return inputs; }
std::vector<LlvmOperand> &get_outputs () { return outputs; }
+ const std::vector<LlvmOperand> &get_outputs () const { return outputs; }
std::vector<TupleClobber> &get_clobbers () { return clobbers; }
+ const std::vector<TupleClobber> &get_clobbers () const { return clobbers; }
};
} // namespace AST
diff --git a/gcc/rust/ast/rust-expression-yeast.cc b/gcc/rust/ast/rust-expression-yeast.cc
index 9f6a62f..7626abc 100644
--- a/gcc/rust/ast/rust-expression-yeast.cc
+++ b/gcc/rust/ast/rust-expression-yeast.cc
@@ -21,10 +21,8 @@
#include "rust-desugar-question-mark.h"
#include "rust-desugar-try-block.h"
#include "rust-desugar-for-loops.h"
-#include "rust-ast-full.h"
#include "rust-desugar-while-let.h"
#include "rust-expr.h"
-#include "rust-stmt.h"
namespace Rust {
namespace AST {
@@ -32,7 +30,7 @@ namespace AST {
void
ExpressionYeast::go (AST::Crate &crate)
{
- DefaultASTVisitor::visit (crate);
+ PointerVisitor::visit (crate);
}
void
@@ -54,7 +52,7 @@ ExpressionYeast::dispatch_loops (std::unique_ptr<Expr> &loop_expr)
}
void
-ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr)
+ExpressionYeast::reseat (std::unique_ptr<Expr> &expr)
{
switch (expr->get_expr_kind ())
{
@@ -71,47 +69,8 @@ ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr)
default:
break;
}
-}
-
-void
-ExpressionYeast::visit (ExprStmt &stmt)
-{
- dispatch (stmt.get_expr_ptr ());
-
- DefaultASTVisitor::visit (stmt);
-}
-
-void
-ExpressionYeast::visit (CallExpr &call)
-{
- dispatch (call.get_function_expr_ptr ());
-
- for (auto &arg : call.get_params ())
- dispatch (arg);
-
- DefaultASTVisitor::visit (call);
-}
-
-void
-ExpressionYeast::visit (BlockExpr &block)
-{
- for (auto &stmt : block.get_statements ())
- if (stmt->get_stmt_kind () == Stmt::Kind::Expr)
- dispatch (static_cast<ExprStmt &> (*stmt).get_expr_ptr ());
-
- if (block.has_tail_expr ())
- dispatch (block.get_tail_expr_ptr ());
-
- DefaultASTVisitor::visit (block);
-}
-
-void
-ExpressionYeast::visit (LetStmt &stmt)
-{
- if (stmt.has_init_expr ())
- dispatch (stmt.get_init_expr_ptr ());
- DefaultASTVisitor::visit (stmt);
+ visit (expr);
}
} // namespace AST
diff --git a/gcc/rust/ast/rust-expression-yeast.h b/gcc/rust/ast/rust-expression-yeast.h
index 855918f..3f64b1d 100644
--- a/gcc/rust/ast/rust-expression-yeast.h
+++ b/gcc/rust/ast/rust-expression-yeast.h
@@ -19,7 +19,7 @@
#ifndef RUST_EXPRESSION_YEAST
#define RUST_EXPRESSION_YEAST
-#include "rust-ast-visitor.h"
+#include "rust-ast-pointer-visitor.h"
#include "rust-ast.h"
#include "rust-desugar-question-mark.h"
@@ -28,22 +28,19 @@ namespace AST {
// This visitor takes care of all the expression desugars: try-blocks,
// error-propagation, etc.
-class ExpressionYeast : public AST::DefaultASTVisitor
+class ExpressionYeast : public AST::PointerVisitor
{
- using AST::DefaultASTVisitor::visit;
+ using AST::PointerVisitor::reseat;
+ using AST::PointerVisitor::visit;
public:
void go (AST::Crate &);
private:
// Dispatch to the proper desugar
- void dispatch (std::unique_ptr<Expr> &expr);
- void dispatch_loops (std::unique_ptr<Expr> &loop_expr);
+ void reseat (std::unique_ptr<Expr> &expr) override;
- void visit (AST::ExprStmt &) override;
- void visit (AST::CallExpr &) override;
- void visit (AST::LetStmt &) override;
- void visit (AST::BlockExpr &) override;
+ void dispatch_loops (std::unique_ptr<Expr> &loop_expr);
};
} // namespace AST
diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index a29c820..21f4f03 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -32,41 +32,11 @@ Pieces
Pieces::collect (const std::string &to_parse, bool append_newline,
ffi::ParseMode parse_mode)
{
- auto handle
- = ffi::collect_pieces (to_parse.c_str (), append_newline, parse_mode);
-
- // this performs multiple copies, can we avoid them maybe?
- // TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we
- // should transform them into the proper C++ type which we can work with. so
- // transform all the strings into C++ strings? all the Option<T> into
- // tl::optional<T>?
- auto pieces_vector = std::vector<ffi::Piece> (handle.piece_slice.base_ptr,
- handle.piece_slice.base_ptr
- + handle.piece_slice.len);
-
- return Pieces (handle, std::move (pieces_vector));
-}
-
-Pieces::~Pieces () { ffi::destroy_pieces (handle); }
-
-Pieces::Pieces (const Pieces &other) : pieces_vector (other.pieces_vector)
-{
- handle = ffi::clone_pieces (other.handle);
+ Pieces ret (to_parse, ffi::FFIVec<ffi::Piece> ());
+ ret.data->second = ffi::collect_pieces (ffi::RustHamster (ret.data->first),
+ append_newline, parse_mode);
+ return ret;
}
-Pieces &
-Pieces::operator= (const Pieces &other)
-{
- handle = ffi::clone_pieces (other.handle);
- pieces_vector = other.pieces_vector;
-
- return *this;
-}
-
-Pieces::Pieces (Pieces &&other)
- : pieces_vector (std::move (other.pieces_vector)),
- handle (clone_pieces (other.handle))
-{}
-
} // namespace Fmt
} // namespace Rust
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 3722db2..e59bed3 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -20,20 +20,171 @@
#define RUST_FMT_H
#include "rust-system.h"
-
-// FIXME: How to encode Option?
+#include "optional.h"
namespace Rust {
namespace Fmt {
namespace ffi {
+extern "C" {
+
+unsigned char *rust_ffi_alloc (size_t count, size_t elem_size, size_t align);
+
+void rust_ffi_dealloc (unsigned char *data, size_t count, size_t elem_size,
+ size_t align);
+
+} // extern "C"
+
+template <typename T> class FFIVec
+{
+ T *data;
+ size_t len;
+ size_t cap;
+
+public:
+ FFIVec () : data ((T *) alignof (T)), len (0), cap (0) {}
+
+ FFIVec (const FFIVec &) = delete;
+ FFIVec &operator= (const FFIVec &) = delete;
+
+ FFIVec (FFIVec &&other) : data (other.data), len (other.len), cap (other.cap)
+ {
+ other.data = (T *) alignof (T);
+ other.len = 0;
+ other.cap = 0;
+ }
+
+ FFIVec &operator= (FFIVec &&other)
+ {
+ this->~FFIVec ();
+ new (this) FFIVec (std::move (other));
+ return *this;
+ }
+
+ ~FFIVec ()
+ {
+ // T can't be zero-sized
+ if (cap)
+ rust_ffi_dealloc ((unsigned char *) data, cap, sizeof (T), alignof (T));
+ }
+
+ size_t size () const { return len; }
+
+ const T &operator[] (size_t idx) const
+ {
+ rust_assert (idx <= len);
+ return data[idx];
+ }
+
+ T *begin () { return data; }
+ const T *begin () const { return data; }
+ T *end () { return data + len; }
+ const T *end () const { return data + len; }
+};
+
+// https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md
+template <typename T,
+ typename =
+ typename std::enable_if<std::is_standard_layout<T>::value>::type>
+class FFIOpt
+{
+public:
+ template <typename U>
+ FFIOpt (U &&val) : some{Some::KIND, std::forward<U> (val)}
+ {}
+
+ FFIOpt () : none{None::KIND} {}
+
+ FFIOpt (const FFIOpt &other)
+ {
+ if (other.has_value ())
+ new (&some) Some{Some::KIND, other.some.val};
+ else
+ new (&none) None{None::KIND};
+ }
+
+ FFIOpt (FFIOpt &&other)
+ {
+ if (other.has_value ())
+ new (&some) Some{Some::KIND, std::move (other.some.val)};
+ else
+ new (&none) None{None::KIND};
+ }
+
+ ~FFIOpt ()
+ {
+ if (has_value ())
+ some.~Some ();
+ else
+ none.~None ();
+ }
+
+ FFIOpt &operator= (const FFIOpt &other)
+ {
+ this->~FFIOpt ();
+ new (this) FFIOpt (other);
+ return *this;
+ }
+
+ FFIOpt &operator= (FFIOpt &&other)
+ {
+ this->~FFIOpt ();
+ new (this) FFIOpt (std::move (other));
+ return *this;
+ }
+
+ tl::optional<std::reference_wrapper<T>> get_opt ()
+ {
+ if (has_value ())
+ return std::ref (some.val);
+ else
+ return tl::nullopt;
+ }
+
+ tl::optional<std::reference_wrapper<const T>> get_opt () const
+ {
+ if (has_value ())
+ return std::ref (some.val);
+ else
+ return tl::nullopt;
+ }
+
+ bool has_value () const { return some.kind == Some::KIND; }
+
+ operator bool () const { return has_value (); }
+
+private:
+ struct Some
+ {
+ static constexpr uint8_t KIND = 0;
+ uint8_t kind;
+ T val;
+ };
+
+ struct None
+ {
+ static constexpr uint8_t KIND = 1;
+ uint8_t kind;
+ };
+
+ union
+ {
+ Some some;
+ None none;
+ };
+};
+
struct RustHamster
{
const char *ptr;
size_t len;
std::string to_string () const;
+
+ explicit RustHamster (const std::string &str)
+ : ptr (str.data ()), len (str.size ())
+ {}
};
/// Enum of alignments which are supported.
@@ -166,33 +317,33 @@ struct Count
struct FormatSpec
{
/// Optionally specified character to fill alignment with.
- const uint32_t *fill;
+ FFIOpt<uint32_t> fill;
/// Span of the optionally specified fill character.
- const InnerSpan *fill_span;
+ FFIOpt<InnerSpan> fill_span;
/// Optionally specified alignment.
Alignment align;
/// The `+` or `-` flag.
- const Sign *sign;
+ FFIOpt<Sign> sign;
/// The `#` flag.
bool alternate;
/// The `0` flag.
bool zero_pad;
/// The `x` or `X` flag. (Only for `Debug`.)
- const DebugHex *debug_hex;
+ FFIOpt<DebugHex> debug_hex;
/// The integer precision to use.
Count precision;
/// The span of the precision formatting flag (for diagnostics).
- const InnerSpan *precision_span;
+ FFIOpt<InnerSpan> precision_span;
/// The string width requested for the resulting format.
Count width;
/// The span of the width formatting flag (for diagnostics).
- const InnerSpan *width_span;
+ FFIOpt<InnerSpan> width_span;
/// The descriptor string representing the name of the format desired for
/// this argument, this can be empty or any number of characters, although
/// it is required to be one word.
RustHamster ty;
/// The span of the descriptor string (for diagnostics).
- const InnerSpan *ty_span;
+ FFIOpt<InnerSpan> ty_span;
};
/// Representation of an argument specification.
@@ -238,26 +389,6 @@ struct Piece
};
};
-struct PieceSlice
-{
- const Piece *base_ptr;
- size_t len;
- size_t cap;
-};
-
-struct RustString
-{
- const unsigned char *ptr;
- size_t len;
- size_t cap;
-};
-
-struct FormatArgsHandle
-{
- PieceSlice piece_slice;
- RustString rust_string;
-};
-
enum ParseMode
{
Format = 0,
@@ -266,12 +397,10 @@ enum ParseMode
extern "C" {
-FormatArgsHandle collect_pieces (const char *input, bool append_newline,
- ParseMode parse_mode);
+FFIVec<Piece> collect_pieces (RustHamster input, bool append_newline,
+ ParseMode parse_mode);
-FormatArgsHandle clone_pieces (const FormatArgsHandle &);
-
-void destroy_pieces (FormatArgsHandle);
+FFIVec<Piece> clone_pieces (const FFIVec<Piece> &);
} // extern "C"
@@ -281,33 +410,20 @@ struct Pieces
{
static Pieces collect (const std::string &to_parse, bool append_newline,
ffi::ParseMode parse_mode);
- ~Pieces ();
-
- Pieces (const Pieces &other);
- Pieces &operator= (const Pieces &other);
- Pieces (Pieces &&other);
-
- const std::vector<ffi::Piece> &get_pieces () const { return pieces_vector; }
-
- // {
- // slice = clone_pieces (&other.slice);
- // to_parse = other.to_parse;
-
- // return *this;
- // }
+ const ffi::FFIVec<ffi::Piece> &get_pieces () const { return data->second; }
private:
- Pieces (ffi::FormatArgsHandle handle, std::vector<ffi::Piece> &&pieces_vector)
- : pieces_vector (std::move (pieces_vector)), handle (handle)
+ Pieces (std::string str, ffi::FFIVec<ffi::Piece> pieces)
+ : data (
+ std::make_shared<decltype (data)::element_type> (std::move (str),
+ std::move (pieces)))
{}
- std::vector<ffi::Piece> pieces_vector;
-
- // this memory is held for FFI reasons - it needs to be released and cloned
- // precisely, so try to not access it/modify it if possible. you should
- // instead work with `pieces_vector`
- ffi::FormatArgsHandle handle;
+ // makes copying simpler
+ // also, we'd need to keep the parsed string in a shared_ptr anyways
+ // since we store pointers into the parsed string
+ std::shared_ptr<std::pair<std::string, ffi::FFIVec<ffi::Piece>>> data;
};
} // namespace Fmt
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index d11eed7..7aea763 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -631,6 +631,12 @@ public:
return *param_name;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (param_name != nullptr);
+ return param_name;
+ }
+
const Pattern &get_pattern () const
{
rust_assert (param_name != nullptr);
@@ -714,6 +720,12 @@ public:
return *param_name;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (param_name != nullptr);
+ return param_name;
+ }
+
bool has_name () const { return param_name != nullptr; }
// TODO: is this better? Or is a "vis_block" better?
@@ -1567,6 +1579,9 @@ public:
location_t get_locus () const override final { return locus; }
+ // needed to override AssociatedItem::get_node_id
+ NodeId get_node_id () const override final { return VisItem::get_node_id (); }
+
void accept_vis (ASTVisitor &vis) override;
// Invalid if existing type is null, so base stripping on that.
@@ -1595,6 +1610,12 @@ public:
return *existing_type;
}
+ std::unique_ptr<Type> &get_type_aliased_ptr ()
+ {
+ rust_assert (existing_type != nullptr);
+ return existing_type;
+ }
+
Identifier get_new_type_name () const { return new_type_name; }
Item::Kind get_item_kind () const override { return Item::Kind::TypeAlias; }
@@ -2515,9 +2536,12 @@ public:
location_t get_locus () const override final { return locus; }
+ // needed to override AssociatedItem::get_node_id
+ NodeId get_node_id () const override final { return VisItem::get_node_id (); }
+
void accept_vis (ASTVisitor &vis) override;
- // Invalid if type or expression are null, so base stripping on that.
+ // Invalid if type and expression are null, so base stripping on that.
void mark_for_strip () override
{
type = nullptr;
@@ -2528,7 +2552,7 @@ public:
return type == nullptr && const_expr == nullptr;
}
- bool has_expr () { return const_expr != nullptr; }
+ bool has_expr () const { return const_expr != nullptr; }
// TODO: is this better? Or is a "vis_block" better?
Expr &get_expr ()
@@ -2695,123 +2719,6 @@ protected:
}
};
-// Constant item within traits
-class TraitItemConst : public TraitItem
-{
- std::vector<Attribute> outer_attrs;
- Identifier name;
- std::unique_ptr<Type> type;
-
- // bool has_expression;
- std::unique_ptr<Expr> expr;
-
-public:
- // Whether the constant item has an associated expression.
- bool has_expression () const { return expr != nullptr; }
-
- TraitItemConst (Identifier name, std::unique_ptr<Type> type,
- std::unique_ptr<Expr> expr,
- std::vector<Attribute> outer_attrs, location_t locus)
- : TraitItem (locus), outer_attrs (std::move (outer_attrs)),
- name (std::move (name)), type (std::move (type)), expr (std::move (expr))
- {}
-
- // Copy constructor with clones
- TraitItemConst (TraitItemConst const &other)
- : TraitItem (other.locus), outer_attrs (other.outer_attrs),
- name (other.name)
- {
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.expr != nullptr)
- expr = other.expr->clone_expr ();
-
- // guard to prevent null dereference (only for error state)
- if (other.type != nullptr)
- type = other.type->clone_type ();
- }
-
- // Overloaded assignment operator to clone
- TraitItemConst &operator= (TraitItemConst const &other)
- {
- TraitItem::operator= (other);
- outer_attrs = other.outer_attrs;
- name = other.name;
- locus = other.locus;
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.expr != nullptr)
- expr = other.expr->clone_expr ();
- else
- expr = nullptr;
-
- // guard to prevent null dereference (only for error state)
- if (other.type != nullptr)
- type = other.type->clone_type ();
- else
- type = nullptr;
-
- return *this;
- }
-
- // move constructors
- TraitItemConst (TraitItemConst &&other) = default;
- TraitItemConst &operator= (TraitItemConst &&other) = default;
-
- std::string as_string () const override;
-
- location_t get_locus () const override { return locus; }
-
- void accept_vis (ASTVisitor &vis) override;
-
- // Invalid if type is null, so base stripping on that.
- void mark_for_strip () override { type = nullptr; }
- bool is_marked_for_strip () const override { return type == nullptr; }
-
- // TODO: this mutable getter seems really dodgy. Think up better way.
- std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
- const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
-
- bool has_expr () const { return expr != nullptr; }
-
- // TODO: is this better? Or is a "vis_block" better?
- Expr &get_expr ()
- {
- rust_assert (has_expr ());
- return *expr;
- }
-
- std::unique_ptr<Expr> &get_expr_ptr ()
- {
- rust_assert (has_expr ());
- return expr;
- }
-
- // TODO: is this better? Or is a "vis_block" better?
- Type &get_type ()
- {
- rust_assert (type != nullptr);
- return *type;
- }
-
- std::unique_ptr<Type> &get_type_ptr ()
- {
- rust_assert (type != nullptr);
- return type;
- }
-
- Identifier get_identifier () const { return name; }
-
-protected:
- // Clone function implementation as (not pure) virtual method
- TraitItemConst *clone_associated_item_impl () const override
- {
- return new TraitItemConst (*this);
- }
-};
-
// Type items within traits
class TraitItemType : public TraitItem
{
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 793423a..068e364 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -167,14 +167,13 @@ Path::convert_to_simple_path (bool with_opening_scope_resolution) const
for (const auto &segment : segments)
{
// return empty path if doesn't meet simple path segment requirements
- if (segment.is_error () || segment.has_generic_args ()
- || segment.as_string () == "Self")
+ if (segment.is_error () || segment.has_generic_args ())
return SimplePath::create_empty ();
// create segment and add to vector
std::string segment_str = segment.as_string ();
- simple_segments.push_back (
- SimplePathSegment (std::move (segment_str), segment.get_locus ()));
+ simple_segments.emplace_back (std::move (segment_str),
+ segment.get_locus ());
}
// kind of a HACK to get locus depending on opening scope resolution
@@ -258,8 +257,8 @@ TypePath::as_simple_path () const
// create segment and add to vector
std::string segment_str = segment->as_string ();
- simple_segments.push_back (
- SimplePathSegment (std::move (segment_str), segment->get_locus ()));
+ simple_segments.emplace_back (std::move (segment_str),
+ segment->get_locus ());
}
return SimplePath (std::move (simple_segments), has_opening_scope_resolution,
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index a1b19d5..be04882 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -377,6 +377,13 @@ public:
return *type;
}
+ std::unique_ptr<AST::Type> &get_type_ptr ()
+ {
+ rust_assert (has_type ());
+
+ return type;
+ }
+
GenericArg &get_default_value_unchecked ()
{
rust_assert (has_default_value ());
@@ -448,9 +455,7 @@ public:
generic_args.clear ();
generic_args.reserve (other.generic_args.size ());
for (const auto &arg : other.generic_args)
- {
- generic_args.push_back (GenericArg (arg));
- }
+ generic_args.emplace_back (arg);
}
~GenericArgs () = default;
@@ -465,9 +470,7 @@ public:
generic_args.clear ();
generic_args.reserve (other.generic_args.size ());
for (const auto &arg : other.generic_args)
- {
- generic_args.push_back (GenericArg (arg));
- }
+ generic_args.emplace_back (arg);
return *this;
}
@@ -1252,7 +1255,7 @@ public:
TraitBound *to_trait_bound (bool in_parens) const override;
location_t get_locus () const override final { return locus; }
- NodeId get_node_id () const { return node_id; }
+ NodeId get_node_id () const override { return node_id; }
void mark_for_strip () override {}
bool is_marked_for_strip () const override { return false; }
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index 15ab0b7..a2fe5d5 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -186,8 +186,8 @@ StructPatternElements::as_string () const
str += "\n " + field->as_string ();
}
- str += "\n Etc: ";
- if (has_struct_pattern_etc)
+ str += "\n Has rest: ";
+ if (has_rest_pattern)
str += "true";
else
str += "false";
@@ -212,7 +212,7 @@ StructPattern::as_string () const
}
std::string
-TupleStructItemsNoRange::as_string () const
+TupleStructItemsNoRest::as_string () const
{
std::string str;
@@ -223,7 +223,7 @@ TupleStructItemsNoRange::as_string () const
}
std::string
-TupleStructItemsRange::as_string () const
+TupleStructItemsHasRest::as_string () const
{
std::string str ("\n Lower patterns: ");
@@ -264,7 +264,7 @@ TupleStructPattern::as_string () const
}
std::string
-TuplePatternItemsMultiple::as_string () const
+TuplePatternItemsNoRest::as_string () const
{
std::string str;
@@ -275,7 +275,7 @@ TuplePatternItemsMultiple::as_string () const
}
std::string
-TuplePatternItemsRanged::as_string () const
+TuplePatternItemsHasRest::as_string () const
{
std::string str;
@@ -421,7 +421,7 @@ SlicePattern::accept_vis (ASTVisitor &vis)
}
void
-TuplePatternItemsRanged::accept_vis (ASTVisitor &vis)
+TuplePatternItemsHasRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
@@ -433,7 +433,7 @@ TuplePattern::accept_vis (ASTVisitor &vis)
}
void
-TuplePatternItemsMultiple::accept_vis (ASTVisitor &vis)
+TuplePatternItemsNoRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
@@ -517,13 +517,13 @@ StructPattern::accept_vis (ASTVisitor &vis)
}
void
-TupleStructItemsNoRange::accept_vis (ASTVisitor &vis)
+TupleStructItemsNoRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
void
-TupleStructItemsRange::accept_vis (ASTVisitor &vis)
+TupleStructItemsHasRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 4945ec4..0da1981 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -20,6 +20,7 @@
#define RUST_AST_PATTERN_H
#include "rust-ast.h"
+#include "rust-path.h"
namespace Rust {
namespace AST {
@@ -143,6 +144,12 @@ public:
return *subpattern;
}
+ std::unique_ptr<Pattern> &get_subpattern_ptr ()
+ {
+ rust_assert (has_subpattern ());
+ return subpattern;
+ }
+
Identifier get_ident () const { return variable_ident; }
bool get_is_mut () const { return is_mut; }
@@ -518,6 +525,12 @@ public:
return *pattern;
}
+ std::unique_ptr<Pattern> &get_referenced_pattern_ptr ()
+ {
+ rust_assert (pattern != nullptr);
+ return pattern;
+ }
+
bool is_double_reference () const { return has_two_amps; }
bool get_is_mut () const { return is_mut; }
@@ -681,6 +694,12 @@ public:
return *tuple_pattern;
}
+ std::unique_ptr<Pattern> &get_index_pattern_ptr ()
+ {
+ rust_assert (tuple_pattern != nullptr);
+ return tuple_pattern;
+ }
+
ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
protected:
@@ -761,6 +780,12 @@ public:
return *ident_pattern;
}
+ std::unique_ptr<Pattern> &get_ident_pattern_ptr ()
+ {
+ rust_assert (ident_pattern != nullptr);
+ return ident_pattern;
+ }
+
ItemType get_item_type () const override final { return ItemType::IDENT_PAT; }
protected:
@@ -818,7 +843,7 @@ class StructPatternElements
// bool has_struct_pattern_fields;
std::vector<std::unique_ptr<StructPatternField>> fields;
- bool has_struct_pattern_etc;
+ bool has_rest_pattern;
std::vector<Attribute> struct_pattern_etc_attrs;
// StructPatternEtc etc;
@@ -834,29 +859,29 @@ public:
* no etc). */
bool is_empty () const
{
- return !has_struct_pattern_fields () && !has_struct_pattern_etc;
+ return !has_struct_pattern_fields () && !has_rest_pattern;
}
- bool has_etc () const { return has_struct_pattern_etc; }
+ bool has_rest () const { return has_rest_pattern; }
// Constructor for StructPatternElements with both (potentially)
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields,
std::vector<Attribute> etc_attrs)
- : fields (std::move (fields)), has_struct_pattern_etc (true),
+ : fields (std::move (fields)), has_rest_pattern (true),
struct_pattern_etc_attrs (std::move (etc_attrs))
{}
// Constructor for StructPatternElements with no StructPatternEtc
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields)
- : fields (std::move (fields)), has_struct_pattern_etc (false),
+ : fields (std::move (fields)), has_rest_pattern (false),
struct_pattern_etc_attrs ()
{}
// Copy constructor with vector clone
StructPatternElements (StructPatternElements const &other)
- : has_struct_pattern_etc (other.has_struct_pattern_etc),
+ : has_rest_pattern (other.has_rest_pattern),
struct_pattern_etc_attrs (other.struct_pattern_etc_attrs)
{
fields.reserve (other.fields.size ());
@@ -868,7 +893,7 @@ public:
StructPatternElements &operator= (StructPatternElements const &other)
{
struct_pattern_etc_attrs = other.struct_pattern_etc_attrs;
- has_struct_pattern_etc = other.has_struct_pattern_etc;
+ has_rest_pattern = other.has_rest_pattern;
fields.clear ();
fields.reserve (other.fields.size ());
@@ -913,7 +938,7 @@ public:
void strip_etc ()
{
- has_struct_pattern_etc = false;
+ has_rest_pattern = false;
struct_pattern_etc_attrs.clear ();
struct_pattern_etc_attrs.shrink_to_fit ();
}
@@ -975,49 +1000,62 @@ protected:
}
};
-// Base abstract class for patterns used in TupleStructPattern
-class TupleStructItems
+// Base abstract class for TupleStructItems, TuplePatternItems &
+// SlicePatternItems
+class PatternItems
{
public:
enum ItemType
{
- RANGE,
- NO_RANGE
+ NO_REST,
+ HAS_REST,
};
- virtual ~TupleStructItems () {}
+ virtual ~PatternItems () {}
// TODO: should this store location data?
// Unique pointer custom clone function
- std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
+ std::unique_ptr<PatternItems> clone_pattern_items () const
{
- return std::unique_ptr<TupleStructItems> (clone_tuple_struct_items_impl ());
+ return std::unique_ptr<PatternItems> (clone_pattern_items_impl ());
}
virtual std::string as_string () const = 0;
-
+ virtual ItemType get_item_type () const = 0;
virtual void accept_vis (ASTVisitor &vis) = 0;
- virtual ItemType get_item_type () const = 0;
+protected:
+ virtual PatternItems *clone_pattern_items_impl () const = 0;
+};
+
+// Base abstract class for patterns used in TupleStructPattern
+class TupleStructItems : public PatternItems
+{
+public:
+ // Unique pointer custom clone function
+ std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
+ {
+ return std::unique_ptr<TupleStructItems> (clone_pattern_items_impl ());
+ }
protected:
// pure virtual clone implementation
- virtual TupleStructItems *clone_tuple_struct_items_impl () const = 0;
+ virtual TupleStructItems *clone_pattern_items_impl () const = 0;
};
// Class for non-ranged tuple struct pattern patterns
-class TupleStructItemsNoRange : public TupleStructItems
+class TupleStructItemsNoRest : public TupleStructItems
{
std::vector<std::unique_ptr<Pattern>> patterns;
public:
- TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern>> patterns)
+ TupleStructItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
: patterns (std::move (patterns))
{}
// Copy constructor with vector clone
- TupleStructItemsNoRange (TupleStructItemsNoRange const &other)
+ TupleStructItemsNoRest (TupleStructItemsNoRest const &other)
{
patterns.reserve (other.patterns.size ());
for (const auto &e : other.patterns)
@@ -1025,7 +1063,7 @@ public:
}
// Overloaded assignment operator with vector clone
- TupleStructItemsNoRange &operator= (TupleStructItemsNoRange const &other)
+ TupleStructItemsNoRest &operator= (TupleStructItemsNoRest const &other)
{
patterns.clear ();
patterns.reserve (other.patterns.size ());
@@ -1036,9 +1074,8 @@ public:
}
// move constructors
- TupleStructItemsNoRange (TupleStructItemsNoRange &&other) = default;
- TupleStructItemsNoRange &operator= (TupleStructItemsNoRange &&other)
- = default;
+ TupleStructItemsNoRest (TupleStructItemsNoRest &&other) = default;
+ TupleStructItemsNoRest &operator= (TupleStructItemsNoRest &&other) = default;
std::string as_string () const override;
@@ -1051,32 +1088,32 @@ public:
return patterns;
}
- ItemType get_item_type () const override final { return ItemType::NO_RANGE; }
+ ItemType get_item_type () const override final { return ItemType::NO_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TupleStructItemsNoRange *clone_tuple_struct_items_impl () const override
+ TupleStructItemsNoRest *clone_pattern_items_impl () const override
{
- return new TupleStructItemsNoRange (*this);
+ return new TupleStructItemsNoRest (*this);
}
};
// Class for ranged tuple struct pattern patterns
-class TupleStructItemsRange : public TupleStructItems
+class TupleStructItemsHasRest : public TupleStructItems
{
std::vector<std::unique_ptr<Pattern>> lower_patterns;
std::vector<std::unique_ptr<Pattern>> upper_patterns;
public:
- TupleStructItemsRange (std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ TupleStructItemsHasRest (std::vector<std::unique_ptr<Pattern>> lower_patterns,
+ std::vector<std::unique_ptr<Pattern>> upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
// Copy constructor with vector clone
- TupleStructItemsRange (TupleStructItemsRange const &other)
+ TupleStructItemsHasRest (TupleStructItemsHasRest const &other)
{
lower_patterns.reserve (other.lower_patterns.size ());
for (const auto &e : other.lower_patterns)
@@ -1088,7 +1125,7 @@ public:
}
// Overloaded assignment operator to clone
- TupleStructItemsRange &operator= (TupleStructItemsRange const &other)
+ TupleStructItemsHasRest &operator= (TupleStructItemsHasRest const &other)
{
lower_patterns.clear ();
lower_patterns.reserve (other.lower_patterns.size ());
@@ -1104,8 +1141,9 @@ public:
}
// move constructors
- TupleStructItemsRange (TupleStructItemsRange &&other) = default;
- TupleStructItemsRange &operator= (TupleStructItemsRange &&other) = default;
+ TupleStructItemsHasRest (TupleStructItemsHasRest &&other) = default;
+ TupleStructItemsHasRest &operator= (TupleStructItemsHasRest &&other)
+ = default;
std::string as_string () const override;
@@ -1131,14 +1169,14 @@ public:
return upper_patterns;
}
- ItemType get_item_type () const override final { return ItemType::RANGE; }
+ ItemType get_item_type () const override final { return ItemType::HAS_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TupleStructItemsRange *clone_tuple_struct_items_impl () const override
+ TupleStructItemsHasRest *clone_pattern_items_impl () const override
{
- return new TupleStructItemsRange (*this);
+ return new TupleStructItemsHasRest (*this);
}
};
@@ -1221,49 +1259,32 @@ protected:
};
// Base abstract class representing TuplePattern patterns
-class TuplePatternItems
+class TuplePatternItems : public PatternItems
{
public:
- enum TuplePatternItemType
- {
- MULTIPLE,
- RANGED,
- };
-
- virtual ~TuplePatternItems () {}
-
- // TODO: should this store location data?
-
// Unique pointer custom clone function
std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
{
- return std::unique_ptr<TuplePatternItems> (
- clone_tuple_pattern_items_impl ());
+ return std::unique_ptr<TuplePatternItems> (clone_pattern_items_impl ());
}
- virtual std::string as_string () const = 0;
-
- virtual void accept_vis (ASTVisitor &vis) = 0;
-
- virtual TuplePatternItemType get_pattern_type () const = 0;
-
protected:
// pure virtual clone implementation
- virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
+ virtual TuplePatternItems *clone_pattern_items_impl () const = 0;
};
-// Class representing TuplePattern patterns where there are multiple patterns
-class TuplePatternItemsMultiple : public TuplePatternItems
+// Class representing TuplePattern patterns which contains no rest pattern
+class TuplePatternItemsNoRest : public TuplePatternItems
{
std::vector<std::unique_ptr<Pattern>> patterns;
public:
- TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern>> patterns)
+ TuplePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
: patterns (std::move (patterns))
{}
// Copy constructor with vector clone
- TuplePatternItemsMultiple (TuplePatternItemsMultiple const &other)
+ TuplePatternItemsNoRest (TuplePatternItemsNoRest const &other)
{
patterns.reserve (other.patterns.size ());
for (const auto &e : other.patterns)
@@ -1271,7 +1292,7 @@ public:
}
// Overloaded assignment operator to vector clone
- TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple const &other)
+ TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest const &other)
{
patterns.clear ();
patterns.reserve (other.patterns.size ());
@@ -1282,8 +1303,8 @@ public:
}
// move constructors
- TuplePatternItemsMultiple (TuplePatternItemsMultiple &&other) = default;
- TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple &&other)
+ TuplePatternItemsNoRest (TuplePatternItemsNoRest &&other) = default;
+ TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest &&other)
= default;
std::string as_string () const override;
@@ -1297,35 +1318,33 @@ public:
return patterns;
}
- TuplePatternItemType get_pattern_type () const override
- {
- return TuplePatternItemType::MULTIPLE;
- }
+ ItemType get_item_type () const override { return ItemType::NO_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TuplePatternItemsMultiple *clone_tuple_pattern_items_impl () const override
+ TuplePatternItemsNoRest *clone_pattern_items_impl () const override
{
- return new TuplePatternItemsMultiple (*this);
+ return new TuplePatternItemsNoRest (*this);
}
};
-// Class representing TuplePattern patterns where there are a range of patterns
-class TuplePatternItemsRanged : public TuplePatternItems
+// Class representing TuplePattern patterns which contains a rest pattern
+class TuplePatternItemsHasRest : public TuplePatternItems
{
std::vector<std::unique_ptr<Pattern>> lower_patterns;
std::vector<std::unique_ptr<Pattern>> upper_patterns;
public:
- TuplePatternItemsRanged (std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ TuplePatternItemsHasRest (
+ std::vector<std::unique_ptr<Pattern>> lower_patterns,
+ std::vector<std::unique_ptr<Pattern>> upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
// Copy constructor with vector clone
- TuplePatternItemsRanged (TuplePatternItemsRanged const &other)
+ TuplePatternItemsHasRest (TuplePatternItemsHasRest const &other)
{
lower_patterns.reserve (other.lower_patterns.size ());
for (const auto &e : other.lower_patterns)
@@ -1337,7 +1356,7 @@ public:
}
// Overloaded assignment operator to clone
- TuplePatternItemsRanged &operator= (TuplePatternItemsRanged const &other)
+ TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest const &other)
{
lower_patterns.clear ();
lower_patterns.reserve (other.lower_patterns.size ());
@@ -1353,8 +1372,8 @@ public:
}
// move constructors
- TuplePatternItemsRanged (TuplePatternItemsRanged &&other) = default;
- TuplePatternItemsRanged &operator= (TuplePatternItemsRanged &&other)
+ TuplePatternItemsHasRest (TuplePatternItemsHasRest &&other) = default;
+ TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest &&other)
= default;
std::string as_string () const override;
@@ -1381,17 +1400,14 @@ public:
return upper_patterns;
}
- TuplePatternItemType get_pattern_type () const override
- {
- return TuplePatternItemType::RANGED;
- }
+ ItemType get_item_type () const override { return ItemType::HAS_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TuplePatternItemsRanged *clone_tuple_pattern_items_impl () const override
+ TuplePatternItemsHasRest *clone_pattern_items_impl () const override
{
- return new TuplePatternItemsRanged (*this);
+ return new TuplePatternItemsHasRest (*this);
}
};
@@ -1508,6 +1524,12 @@ public:
return *pattern_in_parens;
}
+ std::unique_ptr<Pattern> &get_pattern_in_parens_ptr ()
+ {
+ rust_assert (pattern_in_parens != nullptr);
+ return pattern_in_parens;
+ }
+
NodeId get_node_id () const override { return node_id; }
Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Grouped; }
@@ -1522,35 +1544,18 @@ protected:
};
// Base abstract class representing patterns in a SlicePattern
-class SlicePatternItems
+class SlicePatternItems : public PatternItems
{
public:
- enum SlicePatternItemType
- {
- NO_REST,
- HAS_REST,
- };
-
- virtual ~SlicePatternItems () {}
-
- // TODO: should this store location data?
-
// Unique pointer custom clone function
std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const
{
- return std::unique_ptr<SlicePatternItems> (
- clone_slice_pattern_items_impl ());
+ return std::unique_ptr<SlicePatternItems> (clone_pattern_items_impl ());
}
- virtual std::string as_string () const = 0;
-
- virtual void accept_vis (ASTVisitor &vis) = 0;
-
- virtual SlicePatternItemType get_pattern_type () const = 0;
-
protected:
// pure virtual clone implementation
- virtual SlicePatternItems *clone_slice_pattern_items_impl () const = 0;
+ virtual SlicePatternItems *clone_pattern_items_impl () const = 0;
};
// Class representing the patterns in a SlicePattern without `..`
@@ -1598,15 +1603,12 @@ public:
return patterns;
}
- SlicePatternItemType get_pattern_type () const override
- {
- return SlicePatternItemType::NO_REST;
- }
+ ItemType get_item_type () const override { return ItemType::NO_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- SlicePatternItemsNoRest *clone_slice_pattern_items_impl () const override
+ SlicePatternItemsNoRest *clone_pattern_items_impl () const override
{
return new SlicePatternItemsNoRest (*this);
}
@@ -1683,15 +1685,12 @@ public:
return upper_patterns;
}
- SlicePatternItemType get_pattern_type () const override
- {
- return SlicePatternItemType::HAS_REST;
- }
+ ItemType get_item_type () const override { return ItemType::HAS_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- SlicePatternItemsHasRest *clone_slice_pattern_items_impl () const override
+ SlicePatternItemsHasRest *clone_pattern_items_impl () const override
{
return new SlicePatternItemsHasRest (*this);
}
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index f843a79..5fb00ef 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -201,6 +201,12 @@ public:
return *variables_pattern;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (variables_pattern != nullptr);
+ return variables_pattern;
+ }
+
Type &get_type ()
{
rust_assert (has_type ());
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 2a3496b..014963f 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -571,6 +571,12 @@ public:
return *type;
}
+ std::unique_ptr<TypeNoBounds> &get_type_pointed_to_ptr ()
+ {
+ rust_assert (type != nullptr);
+ return type;
+ }
+
// Getter for direct access to the type unique_ptr
std::unique_ptr<TypeNoBounds> &get_type_ptr () { return type; }
@@ -646,6 +652,12 @@ public:
return *type;
}
+ std::unique_ptr<TypeNoBounds> &get_type_referenced_ptr ()
+ {
+ rust_assert (type != nullptr);
+ return type;
+ }
+
bool get_has_mut () const { return has_mut; }
Lifetime &get_lifetime () { return lifetime.value (); }
@@ -720,6 +732,12 @@ public:
return *elem_type;
}
+ std::unique_ptr<Type> &get_elem_type_ptr ()
+ {
+ rust_assert (elem_type != nullptr);
+ return elem_type;
+ }
+
// TODO: would a "vis_expr" be better?
AnonConst &get_size_expr ()
{
@@ -986,7 +1004,7 @@ public:
return_type (std::move (type)), locus (locus)
{
if (!variadic_attrs.empty ())
- is_variadic = true;
+ _is_variadic = true;
}
// Copy constructor with clone
@@ -1044,14 +1062,24 @@ public:
return *return_type;
}
+ std::unique_ptr<TypeNoBounds> &get_return_type_ptr ()
+ {
+ rust_assert (has_return_type ());
+ return return_type;
+ }
+
FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
BareFunctionType *reconstruct_impl () const override
{
+ std::unique_ptr<TypeNoBounds> ret_type = nullptr;
+ if (return_type != nullptr)
+ ret_type = return_type->reconstruct ();
+
return new BareFunctionType (
for_lifetimes, function_qualifiers, params,
/* FIXME: Should params be reconstruct() as well? */
- _is_variadic, variadic_attrs, return_type->reconstruct (), locus);
+ _is_variadic, variadic_attrs, std::move (ret_type), locus);
}
protected: