public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
* Rust front-end update
@ 2023-02-21 12:00 arthur.cohen
  2023-02-21 12:00 ` [committed 001/103] gccrs: Fix missing dead code analysis ICE on local enum definition arthur.cohen
                   ` (102 more replies)
  0 siblings, 103 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust

Hi everyone,

This series contain the majority of gccrs commits which were present on
our GitHub repository but did not have a Changelog entry yet. We have
cleaned, rebased, tested and fixed all of these to contain proper
Changelog entries as well as DCO signoff for big contributions.

All of these commits bootstrap and pass our testsuite on x86_64.

Sorry for the amount of commits pushed, but since the project is
starting to receive more and more contributions, we thought it was
important for GCC contributors to hack on the most recent version of the
frontend as well.

Since then, we have started enforcing DCO-signoff and Changelog checks on
our repository, so such a large push will not happen again. As it stands,
there are only 21 commits left in the entire repository which do not have
a Changelog entry, and which I'll upstream in the coming days.

All the best,

Arthur



^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 001/103] gccrs: Fix missing dead code analysis ICE on local enum definition
  2023-02-21 12:00 Rust front-end update arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:00 ` [committed 002/103] gccrs: visibility: Rename get_public_vis_type -> get_vis_type arthur.cohen
                   ` (101 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

When resolving local enum's within a Block the name resolution info is
not at the top of the stack so this patch introduces a new mappings class
for miscellaneous name resolutions which can be used during path analaysis.

Fixes #1272

gcc/rust/ChangeLog:

	* resolve/rust-name-resolver.h: Add miscellenaous item mappings.
	* resolve/rust-name-resolver.cc (Resolver::insert_resolved_misc): Use
	new mappings.
	(Resolver::lookup_resolved_misc): Likewise.
	* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments):
	Adapt function to insert into miscelleanous mappings.
	* checks/lints/rust-lint-marklive.cc (MarkLive::find_ref_node_id):
	Allow lookup in miscelleanous mappings in mark-live phase.

gcc/testsuite/ChangeLog:

	* rust/compile/issue-1272.rs: New test.
---
 gcc/rust/checks/lints/rust-lint-marklive.cc   |  7 +++++--
 gcc/rust/resolve/rust-name-resolver.cc        | 20 +++++++++++++++++++
 gcc/rust/resolve/rust-name-resolver.h         |  6 ++++++
 .../typecheck/rust-hir-type-check-path.cc     |  5 +++++
 gcc/testsuite/rust/compile/issue-1272.rs      |  8 ++++++++
 5 files changed, 44 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-1272.rs

diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 14115c86f26..c914b549257 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -273,8 +273,11 @@ MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id)
 {
   if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
     {
-      bool ok = resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
-      rust_assert (ok);
+      if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+	{
+	  bool ok = resolver->lookup_resolved_misc (ast_node_id, &ref_node_id);
+	  rust_assert (ok);
+	}
     }
 }
 
diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc
index 77d98d5f364..b94713d3c30 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -499,5 +499,25 @@ Resolver::lookup_resolved_macro (NodeId refId, NodeId *defId)
   return true;
 }
 
+void
+Resolver::insert_resolved_misc (NodeId refId, NodeId defId)
+{
+  auto it = misc_resolved_items.find (refId);
+  rust_assert (it == misc_resolved_items.end ());
+
+  misc_resolved_items[refId] = defId;
+}
+
+bool
+Resolver::lookup_resolved_misc (NodeId refId, NodeId *defId)
+{
+  auto it = misc_resolved_items.find (refId);
+  if (it == misc_resolved_items.end ())
+    return false;
+
+  *defId = it->second;
+  return true;
+}
+
 } // namespace Resolver
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 6f4dda06a5c..302b0de15cc 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -126,6 +126,9 @@ public:
   void insert_resolved_macro (NodeId refId, NodeId defId);
   bool lookup_resolved_macro (NodeId refId, NodeId *defId);
 
+  void insert_resolved_misc (NodeId refId, NodeId defId);
+  bool lookup_resolved_misc (NodeId refId, NodeId *defId);
+
   // proxy for scoping
   Scope &get_name_scope () { return name_scope; }
   Scope &get_type_scope () { return type_scope; }
@@ -202,6 +205,9 @@ private:
   std::map<NodeId, NodeId> resolved_labels;
   std::map<NodeId, NodeId> resolved_macros;
 
+  // misc
+  std::map<NodeId, NodeId> misc_resolved_items;
+
   // keep track of the current module scope ids
   std::vector<NodeId> current_module_stack;
 };
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index f404ea64bcc..305d73f76f9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -462,6 +462,11 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
       resolver->insert_resolved_type (expr_mappings.get_nodeid (),
 				      resolved_node_id);
     }
+  else
+    {
+      resolver->insert_resolved_misc (expr_mappings.get_nodeid (),
+				      resolved_node_id);
+    }
 
   infered = tyseg;
 }
diff --git a/gcc/testsuite/rust/compile/issue-1272.rs b/gcc/testsuite/rust/compile/issue-1272.rs
new file mode 100644
index 00000000000..08adaaf944b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1272.rs
@@ -0,0 +1,8 @@
+fn main() -> i32 {
+    enum E {
+        X(u8),
+    }
+    let _v = E::X(4);
+
+    0
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 002/103] gccrs: visibility: Rename get_public_vis_type -> get_vis_type
  2023-02-21 12:00 Rust front-end update arthur.cohen
  2023-02-21 12:00 ` [committed 001/103] gccrs: Fix missing dead code analysis ICE on local enum definition arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:00 ` [committed 003/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
                   ` (100 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-item.h: Rename get_public_vis_type.
	* hir/rust-ast-lower.cc (translate_visibility): Use new name.
---
 gcc/rust/ast/rust-item.h       | 2 +-
 gcc/rust/hir/rust-ast-lower.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 93497a391ce..d66dd615319 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -634,7 +634,7 @@ public:
     : vis_type (vis_type), in_path (std::move (in_path))
   {}
 
-  VisType get_public_vis_type () const { return vis_type; }
+  VisType get_vis_type () const { return vis_type; }
 
   // Returns whether visibility is in an error state.
   bool is_error () const
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index d88c343f9ef..4f1bfd1f0c1 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -36,7 +36,7 @@ translate_visibility (const AST::Visibility &vis)
   if (vis.is_error ())
     return Visibility::create_error ();
 
-  switch (vis.get_public_vis_type ())
+  switch (vis.get_vis_type ())
     {
     case AST::Visibility::PUB:
       return Visibility (Visibility::VisType::PUBLIC);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 003/103] gccrs: dump: Emit visibility when dumping items
  2023-02-21 12:00 Rust front-end update arthur.cohen
  2023-02-21 12:00 ` [committed 001/103] gccrs: Fix missing dead code analysis ICE on local enum definition arthur.cohen
  2023-02-21 12:00 ` [committed 002/103] gccrs: visibility: Rename get_public_vis_type -> get_vis_type arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:53   ` Update copyright years. (was: [committed 003/103] gccrs: dump: Emit visibility when dumping items) Thomas Schwinge
  2023-02-21 12:00 ` [committed 004/103] gccrs: Add catch for recusive type queries arthur.cohen
                   ` (99 subsequent siblings)
  102 siblings, 1 reply; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::emit_visibility): New function.
	(Dump::visit): Call into `emit_visibility`.
	(Dump::format_function_common): Likewise.
	* ast/rust-ast-dump.h: Declare `emit_visibility`.
---
 gcc/rust/ast/rust-ast-dump.cc | 142 +++++++++++++++++++++++++---------
 gcc/rust/ast/rust-ast-dump.h  |  17 +++-
 2 files changed, 123 insertions(+), 36 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 0b2dac9b2ff..3d1b42d70e3 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2023 Free Software Foundation, Inc.
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-ast-dump.h"
+#include "rust-diagnostics.h"
 
 namespace Rust {
 namespace AST {
@@ -51,7 +52,7 @@ Dump::go (AST::Crate &crate)
     {
       stream << indentation;
       item->accept_vis (*this);
-      stream << "\n";
+      stream << '\n';
     }
 }
 
@@ -72,8 +73,7 @@ Dump::format_function_param (FunctionParam &param)
 void
 Dump::emit_attrib (const Attribute &attrib)
 {
-  stream << "#";
-  stream << "[";
+  stream << "#[";
 
   for (size_t i = 0; i < attrib.get_path ().get_segments ().size (); i++)
     {
@@ -108,6 +108,38 @@ Dump::emit_attrib (const Attribute &attrib)
   stream << "]";
 }
 
+void
+Dump::emit_visibility (const Visibility &vis)
+{
+  switch (vis.get_vis_type ())
+    {
+    case Visibility::PUB:
+      stream << "pub ";
+      break;
+    case Visibility::PUB_CRATE:
+      stream << "pub(crate) ";
+      break;
+    case Visibility::PUB_SELF:
+      stream << "pub(self) ";
+      break;
+    case Visibility::PUB_SUPER:
+      stream << "pub(super) ";
+      break;
+    case Visibility::PUB_IN_PATH:
+      stream << "pub(in " << vis.get_path ().as_string () << ") ";
+      break;
+    case Visibility::PRIV:
+      break;
+    }
+}
+
+std::ostream &
+Dump::emit_indented_string (const std::string &value,
+			    const std::string &comment)
+{
+  return stream << indentation << value << comment;
+}
+
 void
 Dump::visit (Token &tok)
 {}
@@ -141,7 +173,9 @@ Dump::visit (ConstGenericParam &lifetime_param)
 // rust-path.h
 void
 Dump::visit (PathInExpression &path)
-{}
+{
+  stream << path.as_string ();
+}
 
 void
 Dump::visit (TypePathSegment &segment)
@@ -163,7 +197,9 @@ Dump::visit (TypePath &path)
 
 void
 Dump::visit (QualifiedPathInExpression &path)
-{}
+{
+  stream << path.as_string ();
+}
 
 void
 Dump::visit (QualifiedPathInType &path)
@@ -207,53 +243,52 @@ Dump::visit (NegationExpr &expr)
 void
 Dump::visit (ArithmeticOrLogicalExpr &expr)
 {
-  expr.get_left_expr ()->accept_vis (*this);
-  stream << " ";
-
+  auto op = "";
   switch (expr.get_expr_type ())
     {
     case ArithmeticOrLogicalOperator::ADD:
-      stream << "+";
+      op = "+";
       break;
 
     case ArithmeticOrLogicalOperator::SUBTRACT:
-      stream << "-";
+      op = "-";
       break;
 
     case ArithmeticOrLogicalOperator::MULTIPLY:
-      stream << "*";
+      op = "*";
       break;
 
     case ArithmeticOrLogicalOperator::DIVIDE:
-      stream << "/";
+      op = "/";
       break;
 
     case ArithmeticOrLogicalOperator::MODULUS:
-      stream << "%";
+      op = "%";
       break;
 
     case ArithmeticOrLogicalOperator::BITWISE_AND:
-      stream << "&";
+      op = "&";
       break;
 
     case ArithmeticOrLogicalOperator::BITWISE_OR:
-      stream << "|";
+      op = "|";
       break;
 
     case ArithmeticOrLogicalOperator::BITWISE_XOR:
-      stream << "^";
+      op = "^";
       break;
 
     case ArithmeticOrLogicalOperator::LEFT_SHIFT:
-      stream << "<<";
+      op = "<<";
       break;
 
     case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
-      stream << ">>";
+      op = ">>";
       break;
     }
 
-  stream << " ";
+  expr.get_left_expr ()->accept_vis (*this);
+  stream << " " << op << " ";
   expr.get_right_expr ()->accept_vis (*this);
 }
 
@@ -331,7 +366,23 @@ Dump::visit (StructExprStructBase &expr)
 
 void
 Dump::visit (CallExpr &expr)
-{}
+{
+  expr.get_function_expr ()->accept_vis (*this);
+  stream << '(';
+
+  indentation.increment ();
+
+  for (auto &arg : expr.get_params ())
+    {
+      stream << '\n' << indentation;
+      arg->accept_vis (*this);
+      stream << ',';
+    }
+
+  indentation.decrement ();
+
+  stream << '\n' << indentation << ')';
+}
 
 void
 Dump::visit (MethodCallExpr &expr)
@@ -355,13 +406,14 @@ Dump::visit (BlockExpr &expr)
     {
       stream << indentation;
       stmt->accept_vis (*this);
-      stream << ";\n";
+      stream << "; /* stmt */\n";
     }
 
   if (expr.has_tail_expr ())
     {
       stream << indentation;
       expr.get_tail_expr ()->accept_vis (*this);
+      stream << " /* tail expr */";
     }
 
   indentation.decrement ();
@@ -495,7 +547,10 @@ Dump::visit (TypeBoundWhereClauseItem &item)
 void
 Dump::visit (Method &method)
 {
-  stream << indentation << "fn " << method.get_method_name () << '(';
+  // FIXME: Do we really need to dump the indentation here?
+  stream << indentation;
+  emit_visibility (method.get_visibility ());
+  stream << "fn " << method.get_method_name () << '(';
 
   auto &self = method.get_self_param ();
   stream << self.as_string ();
@@ -552,6 +607,7 @@ Dump::visit (UseDeclaration &use_decl)
 void
 Dump::visit (Function &function)
 {
+  emit_visibility (function.get_visibility ());
   stream << "fn " << function.get_function_name ();
 
   if (function.has_generics ())
@@ -647,6 +703,7 @@ void
 Dump::format_function_common (std::unique_ptr<Type> &return_type,
 			      std::unique_ptr<BlockExpr> &block)
 {
+  // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
   if (return_type)
     {
       stream << "-> ";
@@ -656,8 +713,10 @@ Dump::format_function_common (std::unique_ptr<Type> &return_type,
   if (block)
     {
       if (return_type)
-	stream << ' ';
-      block->accept_vis (*this);
+	{
+	  stream << ' ';
+	  block->accept_vis (*this);
+	}
     }
   else
     stream << ";\n";
@@ -685,7 +744,13 @@ void
 Dump::visit (TraitItemMethod &item)
 {
   auto method = item.get_trait_method_decl ();
-  stream << indentation << "fn " << method.get_identifier () << '(';
+
+  // FIXME: Do we really need to dump the indentation here?
+  stream << indentation;
+
+  // FIXME: Can we have visibility here?
+  // emit_visibility (method.get_visibility ());
+  stream << "fn " << method.get_identifier () << '(';
 
   auto &self = method.get_self_param ();
   stream << self.as_string ();
@@ -725,6 +790,8 @@ Dump::visit (Trait &trait)
       stream << "\n" << indentation;
     }
 
+  emit_visibility (trait.get_visibility ());
+
   stream << "trait " << trait.get_identifier ();
 
   // Traits actually have an implicit Self thrown at the start so we must expect
@@ -784,12 +851,15 @@ Dump::visit (TraitImpl &impl)
   impl.get_trait_path ().accept_vis (*this);
   stream << " for ";
   impl.get_type ()->accept_vis (*this);
-
   stream << " {\n";
+
   indentation.increment ();
 
   for (auto &item : impl.get_impl_items ())
-    item->accept_vis (*this);
+    {
+      stream << indentation;
+      item->accept_vis (*this);
+    }
 
   indentation.decrement ();
   stream << "\n}\n";
@@ -802,6 +872,8 @@ Dump::visit (ExternalStaticItem &item)
 void
 Dump::visit (ExternalFunctionItem &function)
 {
+  emit_visibility (function.get_visibility ());
+
   stream << "fn " << function.get_identifier () << '(';
 
   for (size_t i = 0; i < function.get_function_params ().size (); i++)
@@ -830,11 +902,7 @@ Dump::visit (ExternBlock &block)
   stream << "extern ";
 
   if (block.has_abi ())
-    {
-      stream << "\"";
-      stream << block.get_abi ();
-      stream << "\" ";
-    }
+    stream << "\"" << block.get_abi () << "\" ";
 
   stream << "{\n";
   indentation.increment ();
@@ -1014,11 +1082,15 @@ Dump::visit (LetStmt &stmt)
 
 void
 Dump::visit (ExprStmtWithoutBlock &stmt)
-{}
+{
+  stmt.get_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (ExprStmtWithBlock &stmt)
-{}
+{
+  stmt.get_expr ()->accept_vis (*this);
+}
 
 // rust-type.h
 void
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 955dbc0bebc..a5a99f2b03e 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2023 Free Software Foundation, Inc.
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
@@ -80,8 +80,23 @@ private:
    * Format a function's definition parameter
    */
   void format_function_param (FunctionParam &param);
+
+  /**
+   * Emit an attribute
+   */
   void emit_attrib (const Attribute &attrib);
 
+  /**
+   * Emit an item's visibility
+   */
+  void emit_visibility (const Visibility &vis);
+
+  /**
+   * Emit an indented string with an optional extra comment
+   */
+  std::ostream &emit_indented_string (const std::string &value,
+				      const std::string &comment = "");
+
   // rust-ast.h
   void visit (Token &tok);
   void visit (DelimTokenTree &delim_tok_tree);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 004/103] gccrs: Add catch for recusive type queries
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (2 preceding siblings ...)
  2023-02-21 12:00 ` [committed 003/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:00 ` [committed 005/103] gccrs: testing: try loop in const function arthur.cohen
                   ` (98 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

When we have a type query where by generic substitution occurs we can hit
the case where we need to Probe the bounds of the substited item to
determine whether the the bounds are compatible this can cause us to
end up querying the same type recursively.

Fixes #1550

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-base.cc (TypeCheckBase::query_type):
	Check for recursive queries.
	* typecheck/rust-hir-type-check.h: New functions: `query_completed`,
	`query_in_progress`, `insert_query`.
	* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Use `query_type` API.
---
 gcc/rust/typecheck/rust-hir-type-check-base.cc | 10 ++++++++++
 gcc/rust/typecheck/rust-hir-type-check.h       | 12 ++++++++++++
 gcc/rust/typecheck/rust-tyty-bounds.cc         |  5 +++--
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index cf496d3eb19..85826aec8fe 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -495,14 +495,20 @@ TypeCheckBase::resolve_generic_params (
 bool
 TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
 {
+  if (context->query_in_progress (reference))
+    return false;
+
   if (context->lookup_type (reference, result))
     return true;
 
+  context->insert_query (reference);
+
   HIR::Item *item = mappings->lookup_hir_item (reference);
   if (item != nullptr)
     {
       rust_debug_loc (item->get_locus (), "resolved item {%u} to", reference);
       *result = TypeCheckItem::Resolve (*item);
+      context->query_completed (reference);
       return true;
     }
 
@@ -520,6 +526,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
 		      reference);
 
       *result = TypeCheckItem::ResolveImplItem (*impl_block, *impl_item);
+      context->query_completed (reference);
       return true;
     }
 
@@ -530,6 +537,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
   if (found_impl_block_type)
     {
       *result = TypeCheckItem::ResolveImplBlockSelf (*impl_block_by_type);
+      context->query_completed (reference);
       return true;
     }
 
@@ -544,6 +552,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
       rust_assert (block != nullptr);
 
       *result = TypeCheckTopLevelExternItem::Resolve (extern_item, *block);
+      context->query_completed (reference);
       return true;
     }
 
@@ -551,6 +560,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
   Location possible_locus = mappings->lookup_location (reference);
   rust_debug_loc (possible_locus, "query system failed to resolve: [%u]",
 		  reference);
+  context->query_completed (reference);
 
   return false;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 3e9c9c4d21a..a1dd8052246 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -372,6 +372,15 @@ public:
     return true;
   }
 
+  void insert_query (HirId id) { querys_in_progress.insert (id); }
+
+  void query_completed (HirId id) { querys_in_progress.erase (id); }
+
+  bool query_in_progress (HirId id) const
+  {
+    return querys_in_progress.find (id) != querys_in_progress.end ();
+  }
+
 private:
   TypeCheckContext ();
 
@@ -406,6 +415,9 @@ private:
 
   // predicates
   std::map<HirId, TyTy::TypeBoundPredicate> predicates;
+
+  // query context lookups
+  std::set<HirId> querys_in_progress;
 };
 
 class TypeResolution
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 5b5ff751e2b..1a2ed3b7422 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -34,8 +34,9 @@ TypeBoundsProbe::scan ()
       if (!impl->has_trait_ref ())
 	return true;
 
-      TyTy::BaseType *impl_type = TypeCheckItem::ResolveImplBlockSelf (*impl);
-      if (impl_type->get_kind () == TyTy::TypeKind::ERROR)
+      HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
+      TyTy::BaseType *impl_type = nullptr;
+      if (!query_type (impl_ty_id, &impl_type))
 	return true;
 
       if (!receiver->can_eq (impl_type, false))
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 005/103] gccrs: testing: try loop in const function
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (3 preceding siblings ...)
  2023-02-21 12:00 ` [committed 004/103] gccrs: Add catch for recusive type queries arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:00 ` [committed 006/103] gccrs: ast: dump assignment and compound assignment expr arthur.cohen
                   ` (97 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Faisal Abbas, Faisal Abbas

From: Faisal Abbas <faisal.abbas@elastica.co>

Signed-off-by: Faisal Abbas <90.abbasfaisal@gmail.com>

gcc/testsuite/ChangeLog:

	* rust/compile/const9.rs: New test.

Signed-off-by: Faisal Abbas <faisal.abbas@elastica.co>
---
 gcc/testsuite/rust/compile/const9.rs | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/const9.rs

diff --git a/gcc/testsuite/rust/compile/const9.rs b/gcc/testsuite/rust/compile/const9.rs
new file mode 100644
index 00000000000..e71a62a33b1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const9.rs
@@ -0,0 +1,18 @@
+// { dg-options "-w -O0 -fdump-tree-gimple" }
+const fn test(mut x: i32) -> i32 {
+    loop {
+        if x == 10 {
+            break;
+        }
+
+        x = x + 1;
+    }
+    return x;
+}
+
+const X: i32 = test(0);
+
+fn main() {
+    // { dg-final { scan-tree-dump-times {x = 10} 1 gimple } }
+    let x = X;
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 006/103] gccrs: ast: dump assignment and compound assignment expr
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (4 preceding siblings ...)
  2023-02-21 12:00 ` [committed 005/103] gccrs: testing: try loop in const function arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:00 ` [committed 007/103] gccrs: ast: dump If expressions arthur.cohen
                   ` (96 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Dump assignment and compound
	assignment expressions.
---
 gcc/rust/ast/rust-ast-dump.cc | 56 +++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 3d1b42d70e3..f3d0e2d9974 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -306,11 +306,63 @@ Dump::visit (TypeCastExpr &expr)
 
 void
 Dump::visit (AssignmentExpr &expr)
-{}
+{
+  expr.visit_lhs (*this);
+  stream << " = ";
+  expr.visit_rhs (*this);
+}
 
 void
 Dump::visit (CompoundAssignmentExpr &expr)
-{}
+{
+  auto op = "";
+  switch (expr.get_expr_type ())
+    {
+    case CompoundAssignmentOperator::ADD:
+      op = "+";
+      break;
+
+    case CompoundAssignmentOperator::SUBTRACT:
+      op = "-";
+      break;
+
+    case CompoundAssignmentOperator::MULTIPLY:
+      op = "*";
+      break;
+
+    case CompoundAssignmentOperator::DIVIDE:
+      op = "/";
+      break;
+
+    case CompoundAssignmentOperator::MODULUS:
+      op = "%";
+      break;
+
+    case CompoundAssignmentOperator::BITWISE_AND:
+      op = "&";
+      break;
+
+    case CompoundAssignmentOperator::BITWISE_OR:
+      op = "|";
+      break;
+
+    case CompoundAssignmentOperator::BITWISE_XOR:
+      op = "^";
+      break;
+
+    case CompoundAssignmentOperator::LEFT_SHIFT:
+      op = "<<";
+      break;
+
+    case CompoundAssignmentOperator::RIGHT_SHIFT:
+      op = ">>";
+      break;
+    }
+
+  expr.get_left_expr ()->accept_vis (*this);
+  stream << " " << op << "= ";
+  expr.get_right_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (GroupedExpr &expr)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 007/103] gccrs: ast: dump If expressions
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (5 preceding siblings ...)
  2023-02-21 12:00 ` [committed 006/103] gccrs: ast: dump assignment and compound assignment expr arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:00 ` [committed 008/103] gccrs: builtins: Move implementation into source file arthur.cohen
                   ` (95 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Implement visitor for If
	expressions.
---
 gcc/rust/ast/rust-ast-dump.cc | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index f3d0e2d9974..bc4f7a3a5c1 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -534,15 +534,31 @@ Dump::visit (ForLoopExpr &expr)
 
 void
 Dump::visit (IfExpr &expr)
-{}
+{
+  stream << "if ";
+  expr.vis_if_condition (*this);
+  expr.vis_if_block (*this);
+}
 
 void
 Dump::visit (IfExprConseqElse &expr)
-{}
+{
+  stream << "if ";
+  expr.vis_if_condition (*this);
+  expr.vis_if_block (*this);
+  stream << indentation << "else ";
+  expr.vis_else_block (*this);
+}
 
 void
 Dump::visit (IfExprConseqIf &expr)
-{}
+{
+  stream << "if ";
+  expr.vis_if_condition (*this);
+  expr.vis_if_block (*this);
+  stream << indentation << "else if ";
+  expr.vis_conseq_if_expr (*this);
+}
 
 void
 Dump::visit (IfExprConseqIfLet &expr)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 008/103] gccrs: builtins: Move implementation into source file
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (6 preceding siblings ...)
  2023-02-21 12:00 ` [committed 007/103] gccrs: ast: dump If expressions arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:00 ` [committed 009/103] gccrs: Track DefId on ADT variants arthur.cohen
                   ` (94 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* Make-lang.in: Add `rust-builtins.o` as target
	* backend/rust-builtins.h: Refactor to new file.
	* backend/rust-builtins.cc: New file.
---
 gcc/rust/Make-lang.in             |   1 +
 gcc/rust/backend/rust-builtins.cc | 143 ++++++++++++++++++++++++++++++
 gcc/rust/backend/rust-builtins.h  | 120 +++----------------------
 3 files changed, 156 insertions(+), 108 deletions(-)
 create mode 100644 gcc/rust/backend/rust-builtins.cc

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 7dad27a5dcd..a24025cb31c 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -156,6 +156,7 @@ GRS_OBJS = \
     rust/rust-imports.o \
     rust/rust-import-archive.o \
     rust/rust-extern-crate.o \
+    rust/rust-builtins.o \
     $(END)
 # removed object files from here
 
diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
new file mode 100644
index 00000000000..14dc037edac
--- /dev/null
+++ b/gcc/rust/backend/rust-builtins.cc
@@ -0,0 +1,143 @@
+// 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-builtins.h"
+
+namespace Rust {
+namespace Compile {
+
+static const int builtin_const = 1 << 0;
+static const int builtin_noreturn = 1 << 1;
+static const int builtin_novops = 1 << 2;
+
+BuiltinsContext &
+BuiltinsContext::get ()
+{
+  static BuiltinsContext instance;
+  return instance;
+}
+
+bool
+BuiltinsContext::lookup_simple_builtin (const std::string &name, tree *builtin)
+{
+  auto it = rust_intrinsic_to_gcc_builtin.find (name);
+  if (it == rust_intrinsic_to_gcc_builtin.end ())
+    return false;
+
+  return lookup_gcc_builtin (it->second, builtin);
+}
+
+BuiltinsContext::BuiltinsContext () { setup (); }
+
+void
+BuiltinsContext::setup_overflow_fns ()
+{
+  tree overflow_type
+    = build_varargs_function_type_list (boolean_type_node, NULL_TREE);
+
+  define_builtin ("add_overflow", BUILT_IN_ADD_OVERFLOW,
+		  "__builtin_add_overflow", "add_overflow", overflow_type, 0);
+  define_builtin ("sub_overflow", BUILT_IN_SUB_OVERFLOW,
+		  "__builtin_sub_overflow", "sub_overflow", overflow_type, 0);
+  define_builtin ("mul_overflow", BUILT_IN_MUL_OVERFLOW,
+		  "__builtin_mul_overflow", "mul_overflow", overflow_type, 0);
+}
+
+void
+BuiltinsContext::setup_math_fns ()
+{
+  tree math_function_type_f32
+    = build_function_type_list (float_type_node, float_type_node, NULL_TREE);
+
+  define_builtin ("sinf32", BUILT_IN_SINF, "__builtin_sinf", "sinf",
+		  math_function_type_f32, builtin_const);
+  define_builtin ("sqrtf32", BUILT_IN_SQRTF, "__builtin_sqrtf", "sqrtf",
+		  math_function_type_f32, builtin_const);
+}
+
+void
+BuiltinsContext::setup ()
+{
+  setup_math_fns ();
+  setup_overflow_fns ();
+
+  define_builtin ("unreachable", BUILT_IN_UNREACHABLE, "__builtin_unreachable",
+		  NULL, build_function_type (void_type_node, void_list_node),
+		  builtin_const | builtin_noreturn);
+
+  define_builtin ("abort", BUILT_IN_ABORT, "__builtin_abort", "abort",
+		  build_function_type (void_type_node, void_list_node),
+		  builtin_const | builtin_noreturn);
+
+  define_builtin ("breakpoint", BUILT_IN_TRAP, "__builtin_trap", "breakpoint",
+		  build_function_type (void_type_node, void_list_node),
+		  builtin_const | builtin_noreturn);
+
+  define_builtin ("memcpy", BUILT_IN_MEMCPY, "__builtin_memcpy", "memcpy",
+		  build_function_type_list (build_pointer_type (void_type_node),
+					    build_pointer_type (void_type_node),
+					    build_pointer_type (void_type_node),
+					    size_type_node, NULL_TREE),
+		  0);
+}
+
+static void
+handle_flags (tree decl, int flags)
+{
+  if (flags & builtin_const)
+    TREE_READONLY (decl) = 1;
+  if (flags & builtin_noreturn)
+    TREE_READONLY (decl) = 1;
+  if (flags & builtin_novops)
+    DECL_IS_NOVOPS (decl) = 1;
+}
+
+void
+BuiltinsContext::define_builtin (const std::string rust_name,
+				 built_in_function bcode, const char *name,
+				 const char *libname, tree fntype, int flags)
+{
+  tree decl = add_builtin_function (name, fntype, bcode, BUILT_IN_NORMAL,
+				    libname, NULL_TREE);
+  handle_flags (decl, flags);
+  set_builtin_decl (bcode, decl, true);
+
+  this->builtin_functions_[name] = decl;
+  if (libname != NULL)
+    {
+      decl = add_builtin_function (libname, fntype, bcode, BUILT_IN_NORMAL,
+				   NULL, NULL_TREE);
+      handle_flags (decl, flags);
+
+      this->builtin_functions_[libname] = decl;
+    }
+
+  rust_intrinsic_to_gcc_builtin[rust_name] = name;
+}
+
+bool
+BuiltinsContext::lookup_gcc_builtin (const std::string &name, tree *builtin)
+{
+  auto it = builtin_functions_.find (name);
+  if (it == builtin_functions_.end ())
+    return false;
+
+  *builtin = it->second;
+  return true;
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-builtins.h b/gcc/rust/backend/rust-builtins.h
index 5cd84010723..e421fa43755 100644
--- a/gcc/rust/backend/rust-builtins.h
+++ b/gcc/rust/backend/rust-builtins.h
@@ -78,88 +78,18 @@ namespace Compile {
 class BuiltinsContext
 {
 public:
-  static BuiltinsContext &get ()
-  {
-    static BuiltinsContext instance;
-    return instance;
-  }
+  static BuiltinsContext &get ();
 
-  bool lookup_simple_builtin (const std::string &name, tree *builtin)
-  {
-    auto it = rust_intrinsic_to_gcc_builtin.find (name);
-    if (it == rust_intrinsic_to_gcc_builtin.end ())
-      return false;
-
-    return lookup_gcc_builtin (it->second, builtin);
-  }
+  bool lookup_simple_builtin (const std::string &name, tree *builtin);
 
 private:
-  static const int builtin_const = 1 << 0;
-  static const int builtin_noreturn = 1 << 1;
-  static const int builtin_novops = 1 << 2;
-
-  BuiltinsContext () { setup (); }
-
-  void setup_overflow_fns ()
-  {
-    tree overflow_type
-      = build_varargs_function_type_list (boolean_type_node, NULL_TREE);
-
-    define_builtin ("add_overflow", BUILT_IN_ADD_OVERFLOW,
-		    "__builtin_add_overflow", "add_overflow", overflow_type, 0);
-    define_builtin ("sub_overflow", BUILT_IN_SUB_OVERFLOW,
-		    "__builtin_sub_overflow", "sub_overflow", overflow_type, 0);
-    define_builtin ("mul_overflow", BUILT_IN_MUL_OVERFLOW,
-		    "__builtin_mul_overflow", "mul_overflow", overflow_type, 0);
-  }
-
-  void setup_math_fns ()
-  {
-    tree math_function_type_f32
-      = build_function_type_list (float_type_node, float_type_node, NULL_TREE);
-
-    define_builtin ("sinf32", BUILT_IN_SINF, "__builtin_sinf", "sinf",
-		    math_function_type_f32, builtin_const);
-    define_builtin ("sqrtf32", BUILT_IN_SQRTF, "__builtin_sqrtf", "sqrtf",
-		    math_function_type_f32, builtin_const);
-  }
-
-  void setup ()
-  {
-    setup_math_fns ();
-    setup_overflow_fns ();
-
-    define_builtin ("unreachable", BUILT_IN_UNREACHABLE,
-		    "__builtin_unreachable", NULL,
-		    build_function_type (void_type_node, void_list_node),
-		    builtin_const | builtin_noreturn);
-
-    define_builtin ("abort", BUILT_IN_ABORT, "__builtin_abort", "abort",
-		    build_function_type (void_type_node, void_list_node),
-		    builtin_const | builtin_noreturn);
-
-    define_builtin ("breakpoint", BUILT_IN_TRAP, "__builtin_trap", "breakpoint",
-		    build_function_type (void_type_node, void_list_node),
-		    builtin_const | builtin_noreturn);
-
-    define_builtin (
-      "memcpy", BUILT_IN_MEMCPY, "__builtin_memcpy", "memcpy",
-      build_function_type_list (build_pointer_type (void_type_node),
-				build_pointer_type (void_type_node),
-				build_pointer_type (void_type_node),
-				size_type_node, NULL_TREE),
-      0);
-  }
-
-  static void handle_flags (tree decl, int flags)
-  {
-    if (flags & builtin_const)
-      TREE_READONLY (decl) = 1;
-    if (flags & builtin_noreturn)
-      TREE_READONLY (decl) = 1;
-    if (flags & builtin_novops)
-      DECL_IS_NOVOPS (decl) = 1;
-  }
+  BuiltinsContext ();
+
+  void setup_overflow_fns ();
+
+  void setup_math_fns ();
+
+  void setup ();
 
   // Define a builtin function.  BCODE is the builtin function code
   // defined by builtins.def.  NAME is the name of the builtin function.
@@ -169,35 +99,9 @@ private:
   // NORETURN_P is true if the function has the noreturn attribute.
   void define_builtin (const std::string rust_name, built_in_function bcode,
 		       const char *name, const char *libname, tree fntype,
-		       int flags)
-  {
-    tree decl = add_builtin_function (name, fntype, bcode, BUILT_IN_NORMAL,
-				      libname, NULL_TREE);
-    handle_flags (decl, flags);
-    set_builtin_decl (bcode, decl, true);
-
-    this->builtin_functions_[name] = decl;
-    if (libname != NULL)
-      {
-	decl = add_builtin_function (libname, fntype, bcode, BUILT_IN_NORMAL,
-				     NULL, NULL_TREE);
-	handle_flags (decl, flags);
-
-	this->builtin_functions_[libname] = decl;
-      }
-
-    rust_intrinsic_to_gcc_builtin[rust_name] = name;
-  }
-
-  bool lookup_gcc_builtin (const std::string &name, tree *builtin)
-  {
-    auto it = builtin_functions_.find (name);
-    if (it == builtin_functions_.end ())
-      return false;
-
-    *builtin = it->second;
-    return true;
-  }
+		       int flags);
+
+  bool lookup_gcc_builtin (const std::string &name, tree *builtin);
 
   // A mapping of the GCC built-ins exposed to GCC Rust.
   std::map<std::string, tree> builtin_functions_;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 009/103] gccrs: Track DefId on ADT variants
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (7 preceding siblings ...)
  2023-02-21 12:00 ` [committed 008/103] gccrs: builtins: Move implementation into source file arthur.cohen
@ 2023-02-21 12:00 ` arthur.cohen
  2023-02-21 12:01 ` [committed 010/103] gccrs: Ensure uniqueness on Path probe's arthur.cohen
                   ` (93 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

We must track the DefID on variants for algebraic data types as this will
allow us to enforce unique'ness on path queries relating to this.

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-enumitem.cc
	(TypeCheckEnumItem::visit): Adjust VariantDef ctor calls with
	DefID.
	* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit):
	Likewise.
	* typecheck/rust-tyty.h (VariantDef): Add defid parameter to ctor.
---
 .../typecheck/rust-hir-type-check-enumitem.cc |  4 ++++
 .../typecheck/rust-hir-type-check-item.cc     |  9 +++++---
 gcc/rust/typecheck/rust-tyty.h                | 22 ++++++++++---------
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index dd3cb12d17b..30db967f4e0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -82,6 +82,7 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+				  item.get_mappings ().get_defid (),
 				  item.get_identifier (), ident, discim_expr);
 }
 
@@ -111,6 +112,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+				  item.get_mappings ().get_defid (),
 				  item.get_identifier (), ident,
 				  item.get_discriminant_expression ().get ());
 }
@@ -159,6 +161,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+				  item.get_mappings ().get_defid (),
 				  item.get_identifier (), ident,
 				  TyTy::VariantDef::VariantType::TUPLE,
 				  discim_expr, fields);
@@ -206,6 +209,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+				  item.get_mappings ().get_defid (),
 				  item.get_identifier (), ident,
 				  TyTy::VariantDef::VariantType::STRUCT,
 				  discrim_expr, fields);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index e39dd537d6e..af1e39670ce 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -125,7 +125,8 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
   // its a single variant ADT
   std::vector<TyTy::VariantDef *> variants;
   variants.push_back (new TyTy::VariantDef (
-    struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
+    struct_decl.get_mappings ().get_hirid (),
+    struct_decl.get_mappings ().get_defid (), struct_decl.get_identifier (),
     ident, TyTy::VariantDef::VariantType::TUPLE, nullptr, std::move (fields)));
 
   // Process #[repr(X)] attribute, if any
@@ -179,7 +180,8 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   // its a single variant ADT
   std::vector<TyTy::VariantDef *> variants;
   variants.push_back (new TyTy::VariantDef (
-    struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
+    struct_decl.get_mappings ().get_hirid (),
+    struct_decl.get_mappings ().get_defid (), struct_decl.get_identifier (),
     ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
 
   // Process #[repr(X)] attribute, if any
@@ -273,7 +275,8 @@ TypeCheckItem::visit (HIR::Union &union_decl)
   // there is only a single variant
   std::vector<TyTy::VariantDef *> variants;
   variants.push_back (new TyTy::VariantDef (
-    union_decl.get_mappings ().get_hirid (), union_decl.get_identifier (),
+    union_decl.get_mappings ().get_hirid (),
+    union_decl.get_mappings ().get_defid (), union_decl.get_identifier (),
     ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
 
   TyTy::BaseType *type
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index e3cf4d667c7..a033fcad6c9 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1063,9 +1063,9 @@ public:
     return "";
   }
 
-  VariantDef (HirId id, std::string identifier, RustIdent ident,
+  VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
 	      HIR::Expr *discriminant)
-    : id (id), identifier (identifier), ident (ident),
+    : id (id), defid (defid), identifier (identifier), ident (ident),
       discriminant (discriminant)
 
   {
@@ -1073,11 +1073,11 @@ public:
     fields = {};
   }
 
-  VariantDef (HirId id, std::string identifier, RustIdent ident,
+  VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
 	      VariantType type, HIR::Expr *discriminant,
 	      std::vector<StructFieldType *> fields)
-    : id (id), identifier (identifier), ident (ident), type (type),
-      discriminant (discriminant), fields (fields)
+    : id (id), defid (defid), identifier (identifier), ident (ident),
+      type (type), discriminant (discriminant), fields (fields)
   {
     rust_assert (
       (type == VariantType::NUM && fields.empty ())
@@ -1085,8 +1085,8 @@ public:
   }
 
   VariantDef (const VariantDef &other)
-    : id (other.id), identifier (other.identifier), ident (other.ident),
-      type (other.type), discriminant (other.discriminant),
+    : id (other.id), defid (other.defid), identifier (other.identifier),
+      ident (other.ident), type (other.type), discriminant (other.discriminant),
       fields (other.fields)
   {}
 
@@ -1105,7 +1105,7 @@ public:
   static VariantDef &get_error_node ()
   {
     static VariantDef node
-      = VariantDef (UNKNOWN_HIRID, "",
+      = VariantDef (UNKNOWN_HIRID, UNKNOWN_DEFID, "",
 		    {Resolver::CanonicalPath::create_empty (),
 		     Linemap::unknown_location ()},
 		    nullptr);
@@ -1116,6 +1116,7 @@ public:
   bool is_error () const { return get_id () == UNKNOWN_HIRID; }
 
   HirId get_id () const { return id; }
+  DefId get_defid () const { return defid; }
 
   VariantType get_variant_type () const { return type; }
   bool is_data_variant () const { return type != VariantType::NUM; }
@@ -1211,7 +1212,7 @@ public:
     for (auto &f : fields)
       cloned_fields.push_back ((StructFieldType *) f->clone ());
 
-    return new VariantDef (id, identifier, ident, type, discriminant,
+    return new VariantDef (id, defid, identifier, ident, type, discriminant,
 			   cloned_fields);
   }
 
@@ -1221,7 +1222,7 @@ public:
     for (auto &f : fields)
       cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
 
-    return new VariantDef (id, identifier, ident, type, discriminant,
+    return new VariantDef (id, defid, identifier, ident, type, discriminant,
 			   cloned_fields);
   }
 
@@ -1229,6 +1230,7 @@ public:
 
 private:
   HirId id;
+  DefId defid;
   std::string identifier;
   RustIdent ident;
   VariantType type;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 010/103] gccrs: Ensure uniqueness on Path probe's
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (8 preceding siblings ...)
  2023-02-21 12:00 ` [committed 009/103] gccrs: Track DefId on ADT variants arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 011/103] gccrs: Support looking up super traits for trait items arthur.cohen
                   ` (92 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

When we lookup names in paths such as Foo::bar, foo is a type we resolve
and then we lookup 'bar' based on what type Foo is which includes probing
relevant bounds of this type. We currently return a vector of possible
candidates and this patch changes it so that we return a set of unique
items based on DefId.

Addresses #1555

gcc/rust/ChangeLog:

	* backend/rust-compile-expr.cc
	(CompileExpr::resolve_method_address): Use auto and minor change
	in candidate init.
	* typecheck/rust-hir-type-check-path.cc
	(TypeCheckExpr::resolve_segments): Likewise.
	* typecheck/rust-hir-type-check-type.cc: Likewise.
	* backend/rust-compile-resolve-path.cc
	(HIRCompileBase::query_compile): Likewise. Removecall to
	set_ty_ref.
	* typecheck/rust-hir-path-probe.h (struct PathProbeCandidate): Add
	locus initializer in ctor, implement get_defid.
	(class PathProbeType::Probe): return a set instead of vector.
	Adjust class impl.
	(class ReportMultipleCandidateError): Do not inherit from
	HIRImplVisitor anymore and remove corresponding impl. Adjust for
	change in Probe. Simplify Report handling.
	(class PathProbeImplTrait::Probe): Adjust return type.
---
 gcc/rust/backend/rust-compile-expr.cc         |   4 +-
 gcc/rust/backend/rust-compile-resolve-path.cc |   8 +-
 gcc/rust/typecheck/rust-hir-path-probe.h      | 108 ++++++++----------
 .../typecheck/rust-hir-type-check-path.cc     |   2 +-
 .../typecheck/rust-hir-type-check-type.cc     |   2 +-
 5 files changed, 58 insertions(+), 66 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index d58e2258947..ddf914f6736 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1982,7 +1982,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
   // trait-impl-item's definition
 
   auto root = receiver->get_root ();
-  std::vector<Resolver::PathProbeCandidate> candidates
+  auto candidates
     = Resolver::PathProbeType::Probe (root, segment, true /* probe_impls */,
 				      false /* probe_bounds */,
 				      true /* ignore_mandatory_trait_items */);
@@ -2011,7 +2011,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
       // implementation and we should just return error_mark_node
 
       rust_assert (candidates.size () == 1);
-      auto &candidate = candidates.at (0);
+      auto &candidate = *candidates.begin ();
       rust_assert (candidate.is_impl_candidate ());
       rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF);
       TyTy::FnType *candidate_call = static_cast<TyTy::FnType *> (candidate.ty);
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 2cc9505692a..ab8e628c75c 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -251,7 +251,7 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
 	  // item so its up to us to figure out if this path should resolve
 	  // to an trait-impl-block-item or if it can be defaulted to the
 	  // trait-impl-item's definition
-	  std::vector<Resolver::PathProbeCandidate> candidates
+	  auto candidates
 	    = Resolver::PathProbeImplTrait::Probe (receiver, final_segment,
 						   trait_ref);
 	  if (candidates.size () == 0)
@@ -270,7 +270,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
 	    }
 	  else
 	    {
-	      Resolver::PathProbeCandidate &candidate = candidates.at (0);
+	      rust_assert (candidates.size () == 1);
+
+	      auto candidate = *candidates.begin ();
 	      rust_assert (candidate.is_impl_candidate ());
 
 	      HIR::ImplBlock *impl = candidate.item.impl.parent;
@@ -288,8 +290,6 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
 	      else
 		return CompileInherentImplItem::Compile (impl_item, ctx, lookup,
 							 true, expr_locus);
-
-	      lookup->set_ty_ref (impl_item->get_impl_mappings ().get_hirid ());
 	    }
 	}
     }
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index c957487dd2a..6d6bcf8e7cd 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -80,17 +80,17 @@ struct PathProbeCandidate
 
   PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
 		      EnumItemCandidate enum_field)
-    : type (type), ty (ty), item (enum_field)
+    : type (type), ty (ty), locus (locus), item (enum_field)
   {}
 
   PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
 		      ImplItemCandidate impl)
-    : type (type), ty (ty), item (impl)
+    : type (type), ty (ty), locus (locus), item (impl)
   {}
 
   PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
 		      TraitItemCandidate trait)
-    : type (type), ty (ty), item (trait)
+    : type (type), ty (ty), locus (locus), item (trait)
   {}
 
   std::string as_string () const
@@ -123,12 +123,45 @@ struct PathProbeCandidate
   }
 
   bool is_error () const { return type == ERROR; }
+
+  DefId get_defid () const
+  {
+    switch (type)
+      {
+      case ENUM_VARIANT:
+	return item.enum_field.variant->get_defid ();
+	break;
+
+      case IMPL_CONST:
+      case IMPL_TYPE_ALIAS:
+      case IMPL_FUNC:
+	return item.impl.impl_item->get_impl_mappings ().get_defid ();
+	break;
+
+      case TRAIT_ITEM_CONST:
+      case TRAIT_TYPE_ALIAS:
+      case TRAIT_FUNC:
+	return item.trait.item_ref->get_mappings ().get_defid ();
+	break;
+
+      case ERROR:
+      default:
+	return UNKNOWN_DEFID;
+      }
+
+    return UNKNOWN_DEFID;
+  }
+
+  bool operator< (const PathProbeCandidate &c) const
+  {
+    return get_defid () < c.get_defid ();
+  }
 };
 
 class PathProbeType : public TypeCheckBase, public HIR::HIRImplVisitor
 {
 public:
-  static std::vector<PathProbeCandidate>
+  static std::set<PathProbeCandidate>
   Probe (const TyTy::BaseType *receiver,
 	 const HIR::PathIdentSegment &segment_name, bool probe_impls,
 	 bool probe_bounds, bool ignore_mandatory_trait_items,
@@ -203,7 +236,7 @@ public:
 	PathProbeCandidate candidate{
 	  PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS, ty,
 	  alias.get_locus (), impl_item_candidate};
-	candidates.push_back (std::move (candidate));
+	candidates.insert (std::move (candidate));
       }
   }
 
@@ -222,7 +255,7 @@ public:
 	PathProbeCandidate candidate{
 	  PathProbeCandidate::CandidateType::IMPL_CONST, ty,
 	  constant.get_locus (), impl_item_candidate};
-	candidates.push_back (std::move (candidate));
+	candidates.insert (std::move (candidate));
       }
   }
 
@@ -241,7 +274,7 @@ public:
 	PathProbeCandidate candidate{
 	  PathProbeCandidate::CandidateType::IMPL_FUNC, ty,
 	  function.get_locus (), impl_item_candidate};
-	candidates.push_back (std::move (candidate));
+	candidates.insert (std::move (candidate));
       }
   }
 
@@ -259,7 +292,7 @@ protected:
     PathProbeCandidate candidate{
       PathProbeCandidate::CandidateType::ENUM_VARIANT, receiver->clone (),
       mappings->lookup_location (adt->get_ty_ref ()), enum_item_candidate};
-    candidates.push_back (std::move (candidate));
+    candidates.insert (std::move (candidate));
   }
 
   void process_impl_items_for_candidates ()
@@ -338,8 +371,9 @@ protected:
 								impl};
 
     PathProbeCandidate candidate{candidate_type, trait_item_tyty,
-				 trait_ref->get_locus (), trait_item_candidate};
-    candidates.push_back (std::move (candidate));
+				 trait_item_ref->get_locus (),
+				 trait_item_candidate};
+    candidates.insert (std::move (candidate));
   }
 
   void
@@ -383,7 +417,7 @@ protected:
     PathProbeCandidate candidate{candidate_type, trait_item_tyty,
 				 trait_item_ref->get_locus (),
 				 trait_item_candidate};
-    candidates.push_back (std::move (candidate));
+    candidates.insert (std::move (candidate));
   }
 
 protected:
@@ -428,72 +462,30 @@ protected:
 
   const TyTy::BaseType *receiver;
   const HIR::PathIdentSegment &search;
-  std::vector<PathProbeCandidate> candidates;
+  std::set<PathProbeCandidate> candidates;
   HIR::ImplBlock *current_impl;
   DefId specific_trait_id;
 };
 
-class ReportMultipleCandidateError : private TypeCheckBase,
-				     private HIR::HIRImplVisitor
+class ReportMultipleCandidateError : private TypeCheckBase
 {
 public:
-  static void Report (std::vector<PathProbeCandidate> &candidates,
+  static void Report (std::set<PathProbeCandidate> &candidates,
 		      const HIR::PathIdentSegment &query, Location query_locus)
   {
     RichLocation r (query_locus);
-    ReportMultipleCandidateError visitor (r);
     for (auto &c : candidates)
-      {
-	switch (c.type)
-	  {
-	  case PathProbeCandidate::CandidateType::ERROR:
-	  case PathProbeCandidate::CandidateType::ENUM_VARIANT:
-	    gcc_unreachable ();
-	    break;
-
-	  case PathProbeCandidate::CandidateType::IMPL_CONST:
-	  case PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS:
-	  case PathProbeCandidate::CandidateType::IMPL_FUNC:
-	    c.item.impl.impl_item->accept_vis (visitor);
-	    break;
-
-	  case PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST:
-	  case PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS:
-	  case PathProbeCandidate::CandidateType::TRAIT_FUNC:
-	    r.add_range (c.item.trait.item_ref->get_locus ());
-	    break;
-	  }
-      }
+      r.add_range (c.locus);
 
     rust_error_at (r, "multiple applicable items in scope for: %s",
 		   query.as_string ().c_str ());
   }
-
-  void visit (HIR::TypeAlias &alias) override
-  {
-    r.add_range (alias.get_locus ());
-  }
-
-  void visit (HIR::ConstantItem &constant) override
-  {
-    r.add_range (constant.get_locus ());
-  }
-
-  void visit (HIR::Function &function) override
-  {
-    r.add_range (function.get_locus ());
-  }
-
-private:
-  ReportMultipleCandidateError (RichLocation &r) : TypeCheckBase (), r (r) {}
-
-  RichLocation &r;
 };
 
 class PathProbeImplTrait : public PathProbeType
 {
 public:
-  static std::vector<PathProbeCandidate>
+  static std::set<PathProbeCandidate>
   Probe (const TyTy::BaseType *receiver,
 	 const HIR::PathIdentSegment &segment_name,
 	 const TraitReference *trait_reference)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 305d73f76f9..6f1fd416c19 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -337,7 +337,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 	  return;
 	}
 
-      auto &candidate = candidates.at (0);
+      auto &candidate = *candidates.begin ();
       prev_segment = tyseg;
       tyseg = candidate.ty;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 5a6d00a0e9d..a91d15c8e2c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -462,7 +462,7 @@ TypeCheckType::resolve_segments (
 	  return new TyTy::ErrorType (expr_id);
 	}
 
-      auto &candidate = candidates.at (0);
+      auto &candidate = *candidates.begin ();
       prev_segment = tyseg;
       tyseg = candidate.ty;
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 011/103] gccrs: Support looking up super traits for trait items
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (9 preceding siblings ...)
  2023-02-21 12:01 ` [committed 010/103] gccrs: Ensure uniqueness on Path probe's arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 012/103] gccrs: ast: dump: add emit_generic_params helper arthur.cohen
                   ` (91 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

When supporting calls to super traits we need to allow lookups based on
the super traits as specified on the TraitReferences.

Fixes #1555

gcc/rust/ChangeLog:

	* typecheck/rust-hir-trait-ref.h (lookup_trait_item): Add lookup
	in super_trait.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/issue-1555.rs: New test.
---
 gcc/rust/typecheck/rust-hir-trait-ref.h       | 19 ++++++++
 .../rust/compile/torture/issue-1555.rs        | 48 +++++++++++++++++++
 2 files changed, 67 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/torture/issue-1555.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h
index f6a3328c5f6..7eeb3300387 100644
--- a/gcc/rust/typecheck/rust-hir-trait-ref.h
+++ b/gcc/rust/typecheck/rust-hir-trait-ref.h
@@ -336,6 +336,15 @@ public:
 	    return true;
 	  }
       }
+
+    // lookup super traits
+    for (const auto &super_trait : super_traits)
+      {
+	bool found = super_trait->lookup_trait_item (ident, ref);
+	if (found)
+	  return true;
+      }
+
     return false;
   }
 
@@ -351,6 +360,16 @@ public:
 	if (ident.compare (item.get_identifier ()) == 0)
 	  return &item;
       }
+
+    // lookup super traits
+    for (const auto &super_trait : super_traits)
+      {
+	const TraitItemReference *res
+	  = super_trait->lookup_trait_item (ident, type);
+	if (!res->is_error ())
+	  return res;
+      }
+
     return &TraitItemReference::error_node ();
   }
 
diff --git a/gcc/testsuite/rust/compile/torture/issue-1555.rs b/gcc/testsuite/rust/compile/torture/issue-1555.rs
new file mode 100644
index 00000000000..adb48911648
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1555.rs
@@ -0,0 +1,48 @@
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+}
+
+trait Baz: Bar {
+    fn qux(&self);
+}
+
+impl Bar for Foo {
+    fn baz(&self) {
+        unsafe {
+            let a = "baz %i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+impl Baz for Foo {
+    fn qux(&self) {
+        unsafe {
+            let a = "qux %i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+fn static_dispatch<T: Baz>(t: &T) {
+    t.baz();
+    t.qux();
+}
+
+pub fn main() {
+    let a;
+    a = &Foo(123);
+
+    static_dispatch(a);
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 012/103] gccrs: ast: dump: add emit_generic_params helper
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (10 preceding siblings ...)
  2023-02-21 12:01 ` [committed 011/103] gccrs: Support looking up super traits for trait items arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 013/103] gccrs: ast: dump: add format_{tuple,struct}_field helpers arthur.cohen
                   ` (90 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): move generic params dump ...
	(Dump::emit_generic_params): ... here.
	* ast/rust-ast-dump.h (emit_generic_params): New.
---
 gcc/rust/ast/rust-ast-dump.cc | 30 +++++++++++++++++-------------
 gcc/rust/ast/rust-ast-dump.h  |  3 +++
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index bc4f7a3a5c1..b192556647c 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -140,6 +140,22 @@ Dump::emit_indented_string (const std::string &value,
   return stream << indentation << value << comment;
 }
 
+void
+Dump::emit_generic_params (std::vector<std::unique_ptr<GenericParam>> &params)
+{
+  stream << "<";
+  for (size_t i = 0; i < params.size (); i++)
+    {
+      auto &param = params.at (i);
+      param->accept_vis (*this);
+
+      bool has_next = (i + 1) < params.size ();
+      if (has_next)
+	stream << ", ";
+    }
+  stream << ">";
+}
+
 void
 Dump::visit (Token &tok)
 {}
@@ -679,19 +695,7 @@ Dump::visit (Function &function)
   stream << "fn " << function.get_function_name ();
 
   if (function.has_generics ())
-    {
-      stream << "<";
-      for (size_t i = 0; i < function.get_generic_params ().size (); i++)
-	{
-	  auto &param = function.get_generic_params ().at (i);
-	  param->accept_vis (*this);
-
-	  bool has_next = (i + 1) < function.get_generic_params ().size ();
-	  if (has_next)
-	    stream << ", ";
-	}
-      stream << ">";
-    }
+    emit_generic_params (function.get_generic_params ());
 
   stream << '(';
   auto &params = function.get_function_params ();
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index a5a99f2b03e..1bbefb38454 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -97,6 +97,9 @@ private:
   std::ostream &emit_indented_string (const std::string &value,
 				      const std::string &comment = "");
 
+  // Emit formatted string for generic parameters.
+  void emit_generic_params (std::vector<std::unique_ptr<GenericParam>> &params);
+
   // rust-ast.h
   void visit (Token &tok);
   void visit (DelimTokenTree &delim_tok_tree);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 013/103] gccrs: ast: dump: add format_{tuple,struct}_field helpers
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (11 preceding siblings ...)
  2023-02-21 12:01 ` [committed 012/103] gccrs: ast: dump: add emit_generic_params helper arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 014/103] gccrs: ast: dump structs, enums and unions arthur.cohen
                   ` (89 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::format_tuple_field): New.
	(Dump::format_struct_field): New.
	* ast/rust-ast-dump.h (format_tuple_field): New.
	(format_struct_field): New.
---
 gcc/rust/ast/rust-ast-dump.cc | 17 +++++++++++++++++
 gcc/rust/ast/rust-ast-dump.h  |  6 ++++++
 2 files changed, 23 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index b192556647c..6f2f81630b0 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -156,6 +156,23 @@ Dump::emit_generic_params (std::vector<std::unique_ptr<GenericParam>> &params)
   stream << ">";
 }
 
+void
+Dump::format_tuple_field (TupleField &field)
+{
+  // TODO: do we need to emit outer attrs here?
+  emit_visibility (field.get_visibility ());
+  field.get_field_type ()->accept_vis (*this);
+}
+
+void
+Dump::format_struct_field (StructField &field)
+{
+  // TODO: do we need to emit outer attrs here?
+  emit_visibility (field.get_visibility ());
+  stream << field.get_field_name () << ": ";
+  field.get_field_type ()->accept_vis (*this);
+}
+
 void
 Dump::visit (Token &tok)
 {}
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 1bbefb38454..2da2736c95b 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -100,6 +100,12 @@ private:
   // Emit formatted string for generic parameters.
   void emit_generic_params (std::vector<std::unique_ptr<GenericParam>> &params);
 
+  // Format a single field of a tuple.
+  void format_tuple_field (TupleField &field);
+
+  // Format a single field of a struct.
+  void format_struct_field (StructField &field);
+
   // rust-ast.h
   void visit (Token &tok);
   void visit (DelimTokenTree &delim_tok_tree);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 014/103] gccrs: ast: dump structs, enums and unions
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (12 preceding siblings ...)
  2023-02-21 12:01 ` [committed 013/103] gccrs: ast: dump: add format_{tuple,struct}_field helpers arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 015/103] gccrs: intrinsics: Add data prefetching intrinsics arthur.cohen
                   ` (88 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Fill empty functions for
	structs, enums and unions.
---
 gcc/rust/ast/rust-ast-dump.cc | 135 ++++++++++++++++++++++++++++++++--
 1 file changed, 127 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 6f2f81630b0..7cbdfa21fcb 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -750,35 +750,154 @@ Dump::visit (TypeAlias &type_alias)
 
 void
 Dump::visit (StructStruct &struct_item)
-{}
+{
+  stream << "struct " << struct_item.get_identifier ();
+  if (struct_item.has_generics ())
+    emit_generic_params (struct_item.get_generic_params ());
+
+  // FIXME: where-clause
+
+  stream << " {";
+
+  auto &fields = struct_item.get_fields ();
+
+  indentation.increment ();
+  for (auto &field : fields)
+    {
+      stream << '\n' << indentation;
+      format_struct_field (field);
+      stream << ',';
+    }
+  indentation.decrement ();
+
+  if (fields.size () > 0)
+    stream << '\n' << indentation;
+  stream << "}\n";
+}
 
 void
 Dump::visit (TupleStruct &tuple_struct)
-{}
+{
+  stream << "struct " << tuple_struct.get_identifier ();
+  if (tuple_struct.has_generics ())
+    emit_generic_params (tuple_struct.get_generic_params ());
+
+  // FIXME: where-clause
+
+  stream << '(';
+
+  auto &fields = tuple_struct.get_fields ();
+  if (fields.size () >= 1)
+    {
+      format_tuple_field (fields[0]);
+      for (size_t i = 1; i < fields.size (); i++)
+	{
+	  stream << ", ";
+	  format_tuple_field (fields[i]);
+	}
+    }
+  stream << ");\n";
+}
 
 void
 Dump::visit (EnumItem &item)
-{}
+{
+  stream << item.get_identifier ();
+}
 
 void
 Dump::visit (EnumItemTuple &item)
-{}
+{
+  stream << item.get_identifier () << '(';
+  auto &fields = item.get_tuple_fields ();
+  if (fields.size () >= 1)
+    {
+      format_tuple_field (fields[0]);
+      for (size_t i = 1; i < fields.size (); i++)
+	{
+	  stream << ", ";
+	  format_tuple_field (fields[i]);
+	}
+    }
+  stream << ')';
+}
 
 void
 Dump::visit (EnumItemStruct &item)
-{}
+{
+  stream << item.get_identifier () << " {";
+
+  auto &fields = item.get_struct_fields ();
+
+  indentation.increment ();
+  for (auto &field : fields)
+    {
+      stream << '\n' << indentation;
+      format_struct_field (field);
+      stream << ',';
+    }
+  indentation.decrement ();
+
+  if (fields.size () > 0)
+    stream << '\n' << indentation;
+  stream << '}';
+}
 
 void
 Dump::visit (EnumItemDiscriminant &item)
-{}
+{
+  stream << item.get_identifier () << " = ";
+  item.get_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (Enum &enum_item)
-{}
+{
+  stream << "enum " << enum_item.get_identifier ();
+  if (enum_item.has_generics ())
+    emit_generic_params (enum_item.get_generic_params ());
+
+  // FIXME: where-clause
+
+  stream << " {";
+  auto &variants = enum_item.get_variants ();
+  if (variants.size () >= 1)
+    {
+      stream << '\n';
+      indentation.increment ();
+      for (auto &var : variants)
+	{
+	  stream << indentation;
+	  var->accept_vis (*this);
+	  stream << ",\n";
+	}
+      indentation.decrement ();
+    }
+
+  stream << "}\n";
+}
 
 void
 Dump::visit (Union &union_item)
-{}
+{
+  stream << "union " << union_item.get_identifier ();
+  if (union_item.has_generics ())
+    emit_generic_params (union_item.get_generic_params ());
+
+  // FIXME: where-clause
+
+  stream << " {";
+  indentation.increment ();
+  for (auto &field : union_item.get_variants ())
+    {
+      stream << '\n' << indentation;
+      format_struct_field (field);
+      stream << ',';
+    }
+  indentation.decrement ();
+
+  stream << '\n' << indentation << "}\n";
+}
 
 void
 Dump::visit (ConstantItem &const_item)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 015/103] gccrs: intrinsics: Add data prefetching intrinsics
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (13 preceding siblings ...)
  2023-02-21 12:01 ` [committed 014/103] gccrs: ast: dump structs, enums and unions arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 016/103] gccrs: fix ICE on missing closing paren arthur.cohen
                   ` (87 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-builtins.cc (BuiltinsContext::setup): Declare prefetch
	intrinsics.
	* backend/rust-compile-intrinsic.cc (enum class Prefetch): Add kinds of
	prefetch intrinsics.
	(prefetch_data_handler): New function.
	(prefetch_read_data): Likewise.
	(prefetch_write_data): Likewise.

gcc/testsuite/ChangeLog:

	* rust/execute/torture/prefetch_data.rs: New test.
---
 gcc/rust/backend/rust-builtins.cc             |  6 ++
 gcc/rust/backend/rust-compile-intrinsic.cc    | 97 +++++++++++++++++--
 .../rust/execute/torture/prefetch_data.rs     | 17 ++++
 3 files changed, 111 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/prefetch_data.rs

diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
index 14dc037edac..d6f8cb6f495 100644
--- a/gcc/rust/backend/rust-builtins.cc
+++ b/gcc/rust/backend/rust-builtins.cc
@@ -92,6 +92,12 @@ BuiltinsContext::setup ()
 					    build_pointer_type (void_type_node),
 					    size_type_node, NULL_TREE),
 		  0);
+
+  define_builtin ("prefetch", BUILT_IN_PREFETCH, "__builtin_prefetch",
+		  "prefetch",
+		  build_varargs_function_type_list (
+		    build_pointer_type (const_ptr_type_node), NULL_TREE),
+		  builtin_const);
 }
 
 static void
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 616919677c9..a418b863210 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -17,6 +17,7 @@
 #include "rust-compile-intrinsic.h"
 #include "rust-compile-context.h"
 #include "rust-compile-type.h"
+#include "rust-compile-expr.h"
 #include "rust-compile-fnparam.h"
 #include "rust-builtins.h"
 #include "rust-diagnostics.h"
@@ -28,6 +29,8 @@
 #include "fold-const.h"
 #include "langhooks.h"
 
+#include "print-tree.h"
+
 namespace Rust {
 namespace Compile {
 
@@ -44,6 +47,15 @@ wrapping_op_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
 static tree
 copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype);
 
+enum class Prefetch
+{
+  Read,
+  Write
+};
+
+static tree
+prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind);
+
 static inline tree
 rotate_left_handler (Context *ctx, TyTy::FnType *fntype)
 {
@@ -70,18 +82,32 @@ wrapping_mul_handler (Context *ctx, TyTy::FnType *fntype)
 {
   return wrapping_op_handler (ctx, fntype, MULT_EXPR);
 }
+static inline tree
+prefetch_read_data (Context *ctx, TyTy::FnType *fntype)
+{
+  return prefetch_data_handler (ctx, fntype, Prefetch::Read);
+}
+static inline tree
+prefetch_write_data (Context *ctx, TyTy::FnType *fntype)
+{
+  return prefetch_data_handler (ctx, fntype, Prefetch::Write);
+}
 
 static const std::map<std::string,
 		      std::function<tree (Context *, TyTy::FnType *)>>
-  generic_intrinsics = {{"offset", &offset_handler},
-			{"size_of", &sizeof_handler},
-			{"transmute", &transmute_handler},
-			{"rotate_left", &rotate_left_handler},
-			{"rotate_right", &rotate_right_handler},
-			{"wrapping_add", &wrapping_add_handler},
-			{"wrapping_sub", &wrapping_sub_handler},
-			{"wrapping_mul", &wrapping_mul_handler},
-			{"copy_nonoverlapping", &copy_nonoverlapping_handler}};
+  generic_intrinsics = {
+    {"offset", &offset_handler},
+    {"size_of", &sizeof_handler},
+    {"transmute", &transmute_handler},
+    {"rotate_left", &rotate_left_handler},
+    {"rotate_right", &rotate_right_handler},
+    {"wrapping_add", &wrapping_add_handler},
+    {"wrapping_sub", &wrapping_sub_handler},
+    {"wrapping_mul", &wrapping_mul_handler},
+    {"copy_nonoverlapping", &copy_nonoverlapping_handler},
+    {"prefetch_read_data", &prefetch_read_data},
+    {"prefetch_write_data", &prefetch_write_data},
+};
 
 Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
 
@@ -515,5 +541,58 @@ copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype)
   return fndecl;
 }
 
+static tree
+prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
+{
+  rust_assert (fntype->get_params ().size () == 2);
+
+  tree lookup = NULL_TREE;
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
+
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+  // prefetching isn't pure and shouldn't be discarded after GIMPLE
+  TREE_READONLY (fndecl) = 0;
+  TREE_SIDE_EFFECTS (fndecl) = 1;
+
+  std::vector<Bvariable *> args;
+  compile_fn_params (ctx, fntype, fndecl, &args);
+
+  if (!ctx->get_backend ()->function_set_parameters (fndecl, args))
+    return error_mark_node;
+
+  enter_intrinsic_block (ctx, fndecl);
+
+  auto addr = ctx->get_backend ()->var_expression (args[0], Location ());
+  auto locality = ctx->get_backend ()->var_expression (args[1], Location ());
+
+  mpz_t zero;
+  mpz_t one;
+  mpz_init_set_ui (zero, 0);
+  mpz_init_set_ui (one, 1);
+
+  auto rw_flag_value = kind == Prefetch::Write ? one : zero;
+  auto rw_flag
+    = ctx->get_backend ()->integer_constant_expression (integer_type_node,
+							rw_flag_value);
+  auto prefetch_raw = NULL_TREE;
+  auto ok
+    = BuiltinsContext::get ().lookup_simple_builtin ("prefetch", &prefetch_raw);
+  rust_assert (ok);
+  auto prefetch
+    = build_fold_addr_expr_loc (Location ().gcc_location (), prefetch_raw);
+
+  auto prefetch_call
+    = ctx->get_backend ()->call_expression (prefetch, {addr, rw_flag, locality},
+					    nullptr, Location ());
+
+  ctx->add_statement (prefetch_call);
+
+  finalize_intrinsic_block (ctx, fndecl);
+
+  return fndecl;
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/testsuite/rust/execute/torture/prefetch_data.rs b/gcc/testsuite/rust/execute/torture/prefetch_data.rs
new file mode 100644
index 00000000000..dc049b136dd
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/prefetch_data.rs
@@ -0,0 +1,17 @@
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    fn prefetch_read_data<T>(addr: *const T, locality: i32);
+    fn prefetch_write_data<T>(addr: *const T, locality: i32);
+}
+
+fn main() -> i32 {
+    let a = [1, 2, 3, 4];
+
+    unsafe {
+        prefetch_read_data(&a, 3);
+        prefetch_write_data(&a[0], 3);
+    }
+
+    0
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 016/103] gccrs: fix ICE on missing closing paren
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (14 preceding siblings ...)
  2023-02-21 12:01 ` [committed 015/103] gccrs: intrinsics: Add data prefetching intrinsics arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 017/103] gccrs: mappings: Add MacroInvocation -> MacroRulesDef mappings arthur.cohen
                   ` (86 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Marc Poulhiès

From: Marc Poulhiès <dkm@kataplop.net>

Fix crash (segfault) on a missing closing parenthesis when parsing the
expressions in a block. The returned `expr` was missing a check before being
used.

Add corresponding test.

Signed-off-by: Marc Poulhiès <dkm@kataplop.net>

gcc/rust/ChangeLog:

	* parse/rust-parse-impl.h (Parser::parse_stmt_or_expr_without_block):
	Check if `expr` is valid after parsing it.

gcc/testsuite/ChangeLog:

	* rust/compile/missing_closing_paren.rs: New test.
---
 gcc/rust/parse/rust-parse-impl.h                  | 15 +++++++++++----
 .../rust/compile/missing_closing_paren.rs         |  3 +++
 2 files changed, 14 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/missing_closing_paren.rs

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 72207a1bc22..a4a912f8c1d 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -11738,10 +11738,17 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_without_block ()
 	    // must be expression statement
 	    lexer.skip_token ();
 
-	    std::unique_ptr<AST::ExprStmtWithoutBlock> stmt (
-	      new AST::ExprStmtWithoutBlock (std::move (expr),
-					     t->get_locus ()));
-	    return ExprOrStmt (std::move (stmt));
+	    if (expr)
+	      {
+		std::unique_ptr<AST::ExprStmtWithoutBlock> stmt (
+		  new AST::ExprStmtWithoutBlock (std::move (expr),
+						 t->get_locus ()));
+		return ExprOrStmt (std::move (stmt));
+	      }
+	    else
+	      {
+		return ExprOrStmt::create_error ();
+	      }
 	  }
 
 	// return expression
diff --git a/gcc/testsuite/rust/compile/missing_closing_paren.rs b/gcc/testsuite/rust/compile/missing_closing_paren.rs
new file mode 100644
index 00000000000..895c3133c3b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_closing_paren.rs
@@ -0,0 +1,3 @@
+fn foo() {
+    (""; // { dg-error "unexpected token .*" }
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 017/103] gccrs: mappings: Add MacroInvocation -> MacroRulesDef mappings
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (15 preceding siblings ...)
  2023-02-21 12:01 ` [committed 016/103] gccrs: fix ICE on missing closing paren arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 018/103] gccrs: rust-ast-resolve-item: Add note about resolving glob uses arthur.cohen
                   ` (85 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* util/rust-hir-map.h: Add new mappings.
	* util/rust-hir-map.cc (Mappings::insert_macro_invocation): Add insertion
	function into mappings.
	(Mappings::lookup_macro_invocation): Add lookup function for mappings.
---
 gcc/rust/util/rust-hir-map.cc | 22 ++++++++++++++++++++++
 gcc/rust/util/rust-hir-map.h  |  6 ++++++
 2 files changed, 28 insertions(+)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 80434489fcd..7ea782ed4c4 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -866,6 +866,28 @@ Mappings::lookup_macro_def (NodeId id, AST::MacroRulesDefinition **def)
   return true;
 }
 
+void
+Mappings::insert_macro_invocation (AST::MacroInvocation &invoc,
+				   AST::MacroRulesDefinition *def)
+{
+  auto it = macroInvocations.find (invoc.get_macro_node_id ());
+  rust_assert (it == macroInvocations.end ());
+
+  macroInvocations[invoc.get_macro_node_id ()] = def;
+}
+
+bool
+Mappings::lookup_macro_invocation (AST::MacroInvocation &invoc,
+				   AST::MacroRulesDefinition **def)
+{
+  auto it = macroInvocations.find (invoc.get_macro_node_id ());
+  if (it == macroInvocations.end ())
+    return false;
+
+  *def = it->second;
+  return true;
+}
+
 void
 Mappings::insert_visibility (NodeId id, Privacy::ModuleVisibility visibility)
 {
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 474bd5fa229..addd9efc3b0 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -269,6 +269,11 @@ public:
 
   bool lookup_macro_def (NodeId id, AST::MacroRulesDefinition **def);
 
+  void insert_macro_invocation (AST::MacroInvocation &invoc,
+				AST::MacroRulesDefinition *def);
+  bool lookup_macro_invocation (AST::MacroInvocation &invoc,
+				AST::MacroRulesDefinition **def);
+
   void insert_visibility (NodeId id, Privacy::ModuleVisibility visibility);
   bool lookup_visibility (NodeId id, Privacy::ModuleVisibility &def);
 
@@ -334,6 +339,7 @@ private:
 
   // macros
   std::map<NodeId, AST::MacroRulesDefinition *> macroMappings;
+  std::map<NodeId, AST::MacroRulesDefinition *> macroInvocations;
 
   // crate names
   std::map<CrateNum, std::string> crate_names;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 018/103] gccrs: rust-ast-resolve-item: Add note about resolving glob uses
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (16 preceding siblings ...)
  2023-02-21 12:01 ` [committed 017/103] gccrs: mappings: Add MacroInvocation -> MacroRulesDef mappings arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 019/103] gccrs: ast: Add accept_vis() method to `GenericArg` arthur.cohen
                   ` (84 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Add note for
	glob import resolving.
---
 gcc/rust/resolve/rust-ast-resolve-item.cc | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index e5eb6e491e3..193e6834334 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -968,6 +968,14 @@ ResolveItem::visit (AST::UseDeclaration &use_item)
 {
   auto to_resolve = flatten_use_dec_to_paths (use_item);
 
+  // FIXME: I think this does not actually resolve glob use-decls and is going
+  // the wrong way about it. RFC #1560 specifies the following:
+  //
+  // > When we find a glob import, we have to record a 'back link', so that when
+  // a public name is added for the supplying module, we can add it for the
+  // importing module.
+  //
+  // Which is the opposite of what we're doing if I understand correctly?
   for (auto &path : to_resolve)
     ResolvePath::go (&path);
 }
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 019/103] gccrs: ast: Add accept_vis() method to `GenericArg`
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (17 preceding siblings ...)
  2023-02-21 12:01 ` [committed 018/103] gccrs: rust-ast-resolve-item: Add note about resolving glob uses arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 020/103] gccrs: early-name-resolver: Add simple macro name resolution arthur.cohen
                   ` (83 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-path.h: Add `accept_vis` method to `GenericArg` class.
---
 gcc/rust/ast/rust-path.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index b12e4c2bafa..9683ad6ad68 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -207,6 +207,23 @@ public:
   Kind get_kind () const { return kind; }
   const Location &get_locus () const { return locus; }
 
+  void accept_vis (AST::ASTVisitor &visitor)
+  {
+    switch (get_kind ())
+      {
+      case Kind::Const:
+	get_expression ()->accept_vis (visitor);
+	break;
+      case Kind::Type:
+	get_type ()->accept_vis (visitor);
+	break;
+      case Kind::Either:
+	break;
+      case Kind::Error:
+	gcc_unreachable ();
+      }
+  }
+
   std::unique_ptr<Expr> &get_expression ()
   {
     rust_assert (kind == Kind::Const);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 020/103] gccrs: early-name-resolver: Add simple macro name resolution
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (18 preceding siblings ...)
  2023-02-21 12:01 ` [committed 019/103] gccrs: ast: Add accept_vis() method to `GenericArg` arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 021/103] gccrs: Support type resolution on super traits on dyn objects arthur.cohen
                   ` (82 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

This name resolver performs the same macro name resolution as what was
previously done by the AttrVisitor visitor and macro expander.

It also resolves macro expressions in builtin-macros properly, as well
as expanded AST nodes when necessary.

gcc/rust/ChangeLog:

	* Make-lang.in: Compile early name resolver.
	* expand/rust-attribute-visitor.cc (AttrVisitor::visit): Move macro
	name resolution.
	* expand/rust-macro-builtins.cc (try_expand_macro_expression): Run ENR
	when recursively expanding macros.
	* expand/rust-macro-expand.cc (MacroExpander::expand_invoc): No longer
	perform name resolution in `expand_invoc`.
	* expand/rust-macro-expand.h (struct MacroExpander): Keep ENR within
	MacroExpander.
	* rust-session-manager.cc (Session::expansion): Run ENR.
	* resolve/rust-early-name-resolver.cc: New file.
	* resolve/rust-early-name-resolver.h: New file.
---
 gcc/rust/Make-lang.in                        |    1 +
 gcc/rust/expand/rust-attribute-visitor.cc    |   10 -
 gcc/rust/expand/rust-macro-builtins.cc       |    9 +-
 gcc/rust/expand/rust-macro-expand.cc         |   30 +-
 gcc/rust/expand/rust-macro-expand.h          |    4 +
 gcc/rust/resolve/rust-early-name-resolver.cc | 1087 ++++++++++++++++++
 gcc/rust/resolve/rust-early-name-resolver.h  |  210 ++++
 gcc/rust/rust-session-manager.cc             |    4 +
 8 files changed, 1320 insertions(+), 35 deletions(-)
 create mode 100644 gcc/rust/resolve/rust-early-name-resolver.cc
 create mode 100644 gcc/rust/resolve/rust-early-name-resolver.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index a24025cb31c..a906516bd33 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -93,6 +93,7 @@ GRS_OBJS = \
     rust/rust-ast-lower-base.o \
     rust/rust-ast-lower-pattern.o \
     rust/rust-ast-lower-item.o \
+    rust/rust-early-name-resolver.o \
     rust/rust-name-resolver.o \
     rust/rust-ast-resolve.o \
     rust/rust-ast-resolve-base.o \
diff --git a/gcc/rust/expand/rust-attribute-visitor.cc b/gcc/rust/expand/rust-attribute-visitor.cc
index 673f0432a30..a1895749b82 100644
--- a/gcc/rust/expand/rust-attribute-visitor.cc
+++ b/gcc/rust/expand/rust-attribute-visitor.cc
@@ -2877,16 +2877,6 @@ AttrVisitor::visit (AST::MacroRulesDefinition &rules_def)
       rules_def.mark_for_strip ();
       return;
     }
-
-  // I don't think any macro rules can be stripped in any way
-
-  auto path = Resolver::CanonicalPath::new_seg (rules_def.get_node_id (),
-						rules_def.get_rule_name ());
-  expander.resolver->get_macro_scope ().insert (path, rules_def.get_node_id (),
-						rules_def.get_locus ());
-  expander.mappings->insert_macro_def (&rules_def);
-  rust_debug_loc (rules_def.get_locus (), "inserting macro def: [%s]",
-		  path.get ().c_str ());
 }
 
 void
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 606f33c65bc..a230ad9f2d8 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -24,6 +24,7 @@
 #include "rust-macro-invoc-lexer.h"
 #include "rust-lex.h"
 #include "rust-parse.h"
+#include "rust-early-name-resolver.h"
 #include "rust-attribute-visitor.h"
 
 namespace Rust {
@@ -70,9 +71,11 @@ try_expand_macro_expression (AST::Expr *expr, MacroExpander *expander)
 {
   rust_assert (expander);
 
-  auto vis = Rust::AttrVisitor (*expander);
-  expr->accept_vis (vis);
-  return expander->take_expanded_fragment (vis);
+  auto attr_visitor = Rust::AttrVisitor (*expander);
+  auto early_name_resolver = Resolver::EarlyNameResolver ();
+  expr->accept_vis (early_name_resolver);
+  expr->accept_vis (attr_visitor);
+  return expander->take_expanded_fragment (attr_visitor);
 }
 
 /* Expand and then extract a string literal from the macro */
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index fbf33209c5f..d94cd118700 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -23,6 +23,7 @@
 #include "rust-diagnostics.h"
 #include "rust-parse.h"
 #include "rust-attribute-visitor.h"
+#include "rust-early-name-resolver.h"
 
 namespace Rust {
 AST::ASTFragment
@@ -138,32 +139,17 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon)
   //      - else is unreachable
   //  - derive container macro - unreachable
 
-  // lookup the rules for this macro
-  NodeId resolved_node = UNKNOWN_NODEID;
-  NodeId source_node = UNKNOWN_NODEID;
-  if (has_semicolon)
-    source_node = invoc.get_macro_node_id ();
-  else
-    source_node = invoc.get_pattern_node_id ();
-  auto seg
-    = Resolver::CanonicalPath::new_seg (source_node,
-					invoc_data.get_path ().as_string ());
-
-  bool found = resolver->get_macro_scope ().lookup (seg, &resolved_node);
-  if (!found)
-    {
-      rust_error_at (invoc.get_locus (), "unknown macro: [%s]",
-		     seg.get ().c_str ());
-      return;
-    }
+  auto fragment = AST::ASTFragment::create_error ();
+  invoc_data.set_expander (this);
 
   // lookup the rules
   AST::MacroRulesDefinition *rules_def = nullptr;
-  bool ok = mappings->lookup_macro_def (resolved_node, &rules_def);
-  rust_assert (ok);
+  bool ok = mappings->lookup_macro_invocation (invoc, &rules_def);
 
-  auto fragment = AST::ASTFragment::create_error ();
-  invoc_data.set_expander (this);
+  // If there's no rule associated with the invocation, we can simply return
+  // early. The early name resolver will have already emitted an error.
+  if (!ok)
+    return;
 
   if (rules_def->is_builtin ())
     fragment
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index bef140236b3..187d79f9a28 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -25,6 +25,7 @@
 #include "rust-ast.h"
 #include "rust-macro.h"
 #include "rust-hir-map.h"
+#include "rust-early-name-resolver.h"
 #include "rust-name-resolver.h"
 #include "rust-macro-invoc-lexer.h"
 
@@ -323,10 +324,13 @@ struct MacroExpander
     AST::ASTFragment old_fragment = std::move (expanded_fragment);
     auto accumulator = std::vector<AST::SingleASTNode> ();
     expanded_fragment = AST::ASTFragment::create_error ();
+    auto early_name_resolver = Resolver::EarlyNameResolver ();
 
     for (auto &node : old_fragment.get_nodes ())
       {
 	expansion_depth++;
+
+	node.accept_vis (early_name_resolver);
 	node.accept_vis (vis);
 	// we'll decide the next move according to the outcome of the macro
 	// expansion
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc
new file mode 100644
index 00000000000..6b1f1e9c52f
--- /dev/null
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -0,0 +1,1087 @@
+// Copyright (C) 2020-2022 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-early-name-resolver.h"
+#include "rust-ast-full.h"
+#include "rust-name-resolver.h"
+
+namespace Rust {
+namespace Resolver {
+
+EarlyNameResolver::EarlyNameResolver ()
+  : resolver (*Resolver::get ()), mappings (*Analysis::Mappings::get ())
+{}
+
+void
+EarlyNameResolver::go (AST::Crate &crate)
+{
+  // FIXME: Is that valid? Why is the regular name resolution doing
+  // mappings->get_next_node_id()?
+  resolver.get_macro_scope ().push (crate.get_node_id ());
+
+  for (auto &item : crate.items)
+    item->accept_vis (*this);
+
+  // FIXME: Should we pop the macro scope?
+}
+
+void
+EarlyNameResolver::resolve_generic_args (AST::GenericArgs &generic_args)
+{
+  for (auto &arg : generic_args.get_generic_args ())
+    arg.accept_vis (*this);
+
+  for (auto &arg : generic_args.get_binding_args ())
+    arg.get_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::resolve_qualified_path_type (AST::QualifiedPathType &path)
+{
+  path.get_type ()->accept_vis (*this);
+
+  if (path.has_as_clause ())
+    path.get_as_type_path ().accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::Token &tok)
+{}
+
+void
+EarlyNameResolver::visit (AST::DelimTokenTree &delim_tok_tree)
+{}
+
+void
+EarlyNameResolver::visit (AST::AttrInputMetaItemContainer &input)
+{}
+
+void
+EarlyNameResolver::visit (AST::IdentifierExpr &ident_expr)
+{}
+
+void
+EarlyNameResolver::visit (AST::Lifetime &lifetime)
+{}
+
+void
+EarlyNameResolver::visit (AST::LifetimeParam &lifetime_param)
+{}
+
+void
+EarlyNameResolver::visit (AST::ConstGenericParam &const_param)
+{}
+
+// FIXME: ARTHUR: Do we need to perform macro resolution for paths as well?
+// std::arch::asm!()?
+void
+EarlyNameResolver::visit (AST::PathInExpression &path)
+{
+  for (auto &segment : path.get_segments ())
+    if (segment.has_generic_args ())
+      resolve_generic_args (segment.get_generic_args ());
+}
+
+void
+EarlyNameResolver::visit (AST::TypePathSegment &segment)
+{}
+
+void
+EarlyNameResolver::visit (AST::TypePathSegmentGeneric &segment)
+{
+  if (segment.has_generic_args ())
+    resolve_generic_args (segment.get_generic_args ());
+}
+
+void
+EarlyNameResolver::visit (AST::TypePathSegmentFunction &segment)
+{
+  for (auto &type : segment.get_type_path_function ().get_params ())
+    type->accept_vis (*this);
+
+  segment.get_type_path_function ().get_return_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TypePath &path)
+{
+  for (auto &seg : path.get_segments ())
+    seg->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::QualifiedPathInExpression &path)
+{
+  resolve_qualified_path_type (path.get_qualified_path_type ());
+
+  for (auto &segment : path.get_segments ())
+    if (segment.has_generic_args ())
+      resolve_generic_args (segment.get_generic_args ());
+}
+
+void
+EarlyNameResolver::visit (AST::QualifiedPathInType &path)
+{
+  resolve_qualified_path_type (path.get_qualified_path_type ());
+
+  for (auto &segment : path.get_segments ())
+    segment->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::LiteralExpr &expr)
+{}
+
+void
+EarlyNameResolver::visit (AST::AttrInputLiteral &attr_input)
+{}
+
+void
+EarlyNameResolver::visit (AST::MetaItemLitExpr &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::MetaItemPathLit &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::BorrowExpr &expr)
+{
+  expr.get_borrowed_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::DereferenceExpr &expr)
+{
+  expr.get_dereferenced_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ErrorPropagationExpr &expr)
+{
+  expr.get_propagating_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::NegationExpr &expr)
+{
+  expr.get_negated_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ArithmeticOrLogicalExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ComparisonExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::LazyBooleanExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TypeCastExpr &expr)
+{
+  expr.get_casted_expr ()->accept_vis (*this);
+  expr.get_type_to_cast_to ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::AssignmentExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::CompoundAssignmentExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::GroupedExpr &expr)
+{
+  expr.get_expr_in_parens ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ArrayElemsValues &elems)
+{
+  for (auto &expr : elems.get_values ())
+    expr->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ArrayElemsCopied &elems)
+{
+  elems.get_elem_to_copy ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ArrayExpr &expr)
+{
+  expr.get_array_elems ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ArrayIndexExpr &expr)
+{
+  expr.get_array_expr ()->accept_vis (*this);
+  expr.get_index_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TupleExpr &expr)
+{
+  for (auto &elem : expr.get_tuple_elems ())
+    elem->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TupleIndexExpr &expr)
+{
+  expr.get_tuple_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructExprStruct &expr)
+{}
+
+void
+EarlyNameResolver::visit (AST::StructExprFieldIdentifier &field)
+{}
+
+void
+EarlyNameResolver::visit (AST::StructExprFieldIdentifierValue &field)
+{
+  field.get_value ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructExprFieldIndexValue &field)
+{
+  field.get_value ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructExprStructFields &expr)
+{
+  for (auto &field : expr.get_fields ())
+    field->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructExprStructBase &expr)
+{}
+
+void
+EarlyNameResolver::visit (AST::CallExpr &expr)
+{
+  expr.get_function_expr ()->accept_vis (*this);
+  for (auto &param : expr.get_params ())
+    param->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::MethodCallExpr &expr)
+{
+  expr.get_receiver_expr ()->accept_vis (*this);
+  for (auto &param : expr.get_params ())
+    param->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::FieldAccessExpr &expr)
+{
+  expr.get_receiver_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ClosureExprInner &expr)
+{
+  expr.get_definition_expr ()->accept_vis (*this);
+
+  for (auto &param : expr.get_params ())
+    param.get_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::BlockExpr &expr)
+{
+  for (auto &stmt : expr.get_statements ())
+    stmt->accept_vis (*this);
+
+  if (expr.has_tail_expr ())
+    expr.get_tail_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ClosureExprInnerTyped &expr)
+{
+  expr.get_definition_block ()->accept_vis (*this);
+
+  for (auto &param : expr.get_params ())
+    param.get_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ContinueExpr &expr)
+{}
+
+void
+EarlyNameResolver::visit (AST::BreakExpr &expr)
+{
+  if (expr.has_break_expr ())
+    expr.get_break_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::RangeFromToExpr &expr)
+{
+  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_to_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::RangeFromExpr &expr)
+{
+  expr.get_from_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::RangeToExpr &expr)
+{
+  expr.get_to_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::RangeFullExpr &expr)
+{}
+
+void
+EarlyNameResolver::visit (AST::RangeFromToInclExpr &expr)
+{
+  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_to_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::RangeToInclExpr &expr)
+{
+  expr.get_to_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ReturnExpr &expr)
+{
+  if (expr.has_returned_expr ())
+    expr.get_returned_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::UnsafeBlockExpr &expr)
+{
+  expr.get_block_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::LoopExpr &expr)
+{
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::WhileLoopExpr &expr)
+{
+  expr.get_predicate_expr ()->accept_vis (*this);
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::WhileLetLoopExpr &expr)
+{
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ForLoopExpr &expr)
+{
+  expr.get_iterator_expr ()->accept_vis (*this);
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfExpr &expr)
+{
+  expr.get_condition_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfExprConseqElse &expr)
+{
+  expr.get_condition_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_else_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfExprConseqIf &expr)
+{
+  expr.get_condition_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_conseq_if_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfExprConseqIfLet &expr)
+{
+  expr.get_condition_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_conseq_if_let_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfLetExpr &expr)
+{
+  expr.get_value_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfLetExprConseqElse &expr)
+{
+  expr.get_value_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_else_block ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfLetExprConseqIf &expr)
+{
+  expr.get_value_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_conseq_if_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::IfLetExprConseqIfLet &expr)
+{
+  expr.get_value_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_conseq_if_let_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::MatchExpr &expr)
+{
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+  for (auto &match_arm : expr.get_match_cases ())
+    {
+      if (match_arm.get_arm ().has_match_arm_guard ())
+	match_arm.get_arm ().get_guard_expr ()->accept_vis (*this);
+
+      for (auto &pattern : match_arm.get_arm ().get_patterns ())
+	pattern->accept_vis (*this);
+
+      match_arm.get_expr ()->accept_vis (*this);
+    }
+}
+
+void
+EarlyNameResolver::visit (AST::AwaitExpr &expr)
+{
+  expr.get_awaited_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::AsyncBlockExpr &expr)
+{
+  expr.get_block_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TypeParam &param)
+{
+  for (auto &bound : param.get_type_param_bounds ())
+    bound->accept_vis (*this);
+
+  if (param.has_type ())
+    param.get_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::LifetimeWhereClauseItem &item)
+{}
+
+void
+EarlyNameResolver::visit (AST::TypeBoundWhereClauseItem &item)
+{
+  for (auto &bound : item.get_type_param_bounds ())
+    bound->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::Method &method)
+{
+  if (method.has_generics ())
+    for (auto &generic : method.get_generic_params ())
+      generic->accept_vis (*this);
+
+  if (method.get_self_param ().has_type ())
+    method.get_self_param ().get_type ()->accept_vis (*this);
+
+  for (auto &param : method.get_function_params ())
+    param.get_type ()->accept_vis (*this);
+
+  if (method.has_return_type ())
+    method.get_return_type ()->accept_vis (*this);
+
+  method.get_definition ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::Module &module)
+{
+  for (auto &item : module.get_items ())
+    item->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ExternCrate &crate)
+{}
+
+void
+EarlyNameResolver::visit (AST::UseTreeGlob &use_tree)
+{}
+
+void
+EarlyNameResolver::visit (AST::UseTreeList &use_tree)
+{}
+
+void
+EarlyNameResolver::visit (AST::UseTreeRebind &use_tree)
+{}
+
+void
+EarlyNameResolver::visit (AST::UseDeclaration &use_decl)
+{}
+
+void
+EarlyNameResolver::visit (AST::Function &function)
+{
+  if (function.has_generics ())
+    for (auto &generic : function.get_generic_params ())
+      generic->accept_vis (*this);
+
+  for (auto &param : function.get_function_params ())
+    param.get_type ()->accept_vis (*this);
+
+  if (function.has_return_type ())
+    function.get_return_type ()->accept_vis (*this);
+
+  function.get_definition ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TypeAlias &type_alias)
+{
+  type_alias.get_type_aliased ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructStruct &struct_item)
+{
+  for (auto &field : struct_item.get_fields ())
+    field.get_field_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TupleStruct &tuple_struct)
+{
+  for (auto &field : tuple_struct.get_fields ())
+    field.get_field_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::EnumItem &item)
+{}
+
+void
+EarlyNameResolver::visit (AST::EnumItemTuple &item)
+{}
+
+void
+EarlyNameResolver::visit (AST::EnumItemStruct &item)
+{}
+
+void
+EarlyNameResolver::visit (AST::EnumItemDiscriminant &item)
+{}
+
+void
+EarlyNameResolver::visit (AST::Enum &enum_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::Union &union_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::ConstantItem &const_item)
+{
+  const_item.get_type ()->accept_vis (*this);
+  const_item.get_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StaticItem &static_item)
+{
+  static_item.get_type ()->accept_vis (*this);
+  static_item.get_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TraitItemFunc &item)
+{
+  auto &decl = item.get_trait_function_decl ();
+
+  if (decl.has_return_type ())
+    decl.get_return_type ()->accept_vis (*this);
+
+  for (auto &generic : decl.get_generic_params ())
+    generic->accept_vis (*this);
+
+  for (auto &param : decl.get_function_params ())
+    param.get_type ()->accept_vis (*this);
+
+  if (item.has_definition ())
+    item.get_definition ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TraitItemMethod &item)
+{
+  // FIXME: Can we factor this with the above function?
+  auto &decl = item.get_trait_method_decl ();
+
+  if (decl.has_return_type ())
+    decl.get_return_type ()->accept_vis (*this);
+
+  for (auto &generic : decl.get_generic_params ())
+    generic->accept_vis (*this);
+
+  for (auto &param : decl.get_function_params ())
+    param.get_type ()->accept_vis (*this);
+
+  if (item.has_definition ())
+    item.get_definition ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TraitItemConst &item)
+{
+  item.get_type ()->accept_vis (*this);
+
+  if (item.has_expr ())
+    item.get_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TraitItemType &item)
+{}
+
+void
+EarlyNameResolver::visit (AST::Trait &trait)
+{
+  for (auto &item : trait.get_trait_items ())
+    item->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::InherentImpl &impl)
+{
+  impl.get_type ()->accept_vis (*this);
+
+  for (auto &generic : impl.get_generic_params ())
+    generic->accept_vis (*this);
+
+  for (auto &item : impl.get_impl_items ())
+    item->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TraitImpl &impl)
+{
+  impl.get_type ()->accept_vis (*this);
+
+  for (auto &generic : impl.get_generic_params ())
+    generic->accept_vis (*this);
+
+  for (auto &item : impl.get_impl_items ())
+    item->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ExternalStaticItem &item)
+{
+  item.get_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ExternalFunctionItem &item)
+{
+  for (auto &generic : item.get_generic_params ())
+    generic->accept_vis (*this);
+
+  for (auto &param : item.get_function_params ())
+    param.get_type ()->accept_vis (*this);
+
+  if (item.has_return_type ())
+    item.get_return_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ExternBlock &block)
+{
+  for (auto &item : block.get_extern_items ())
+    item->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::MacroMatchFragment &match)
+{}
+
+void
+EarlyNameResolver::visit (AST::MacroMatchRepetition &match)
+{}
+
+void
+EarlyNameResolver::visit (AST::MacroMatcher &matcher)
+{}
+
+void
+EarlyNameResolver::visit (AST::MacroRulesDefinition &rules_def)
+{
+  auto path = CanonicalPath::new_seg (rules_def.get_node_id (),
+				      rules_def.get_rule_name ());
+  resolver.get_macro_scope ().insert (path, rules_def.get_node_id (),
+				      rules_def.get_locus ());
+  mappings.insert_macro_def (&rules_def);
+  rust_debug_loc (rules_def.get_locus (), "inserting macro def: [%s]",
+		  path.get ().c_str ());
+}
+
+void
+EarlyNameResolver::visit (AST::MacroInvocation &invoc)
+{
+  auto &invoc_data = invoc.get_invoc_data ();
+  auto has_semicolon = invoc.has_semicolon ();
+
+  // ??
+  // switch on type of macro:
+  //  - '!' syntax macro (inner switch)
+  //      - procedural macro - "A token-based function-like macro"
+  //      - 'macro_rules' (by example/pattern-match) macro? or not? "an
+  // AST-based function-like macro"
+  //      - else is unreachable
+  //  - attribute syntax macro (inner switch)
+  //  - procedural macro attribute syntax - "A token-based attribute
+  // macro"
+  //      - legacy macro attribute syntax? - "an AST-based attribute macro"
+  //      - non-macro attribute: mark known
+  //      - else is unreachable
+  //  - derive macro (inner switch)
+  //      - derive or legacy derive - "token-based" vs "AST-based"
+  //      - else is unreachable
+  //  - derive container macro - unreachable
+
+  // lookup the rules for this macro
+  NodeId resolved_node = UNKNOWN_NODEID;
+  NodeId source_node = UNKNOWN_NODEID;
+  if (has_semicolon)
+    source_node = invoc.get_macro_node_id ();
+  else
+    source_node = invoc.get_pattern_node_id ();
+  auto seg
+    = CanonicalPath::new_seg (source_node, invoc_data.get_path ().as_string ());
+
+  bool found = resolver.get_macro_scope ().lookup (seg, &resolved_node);
+  if (!found)
+    {
+      rust_error_at (invoc.get_locus (), "unknown macro: [%s]",
+		     seg.get ().c_str ());
+      return;
+    }
+
+  // lookup the rules
+  AST::MacroRulesDefinition *rules_def = nullptr;
+  bool ok = mappings.lookup_macro_def (resolved_node, &rules_def);
+  rust_assert (ok);
+
+  mappings.insert_macro_invocation (invoc, rules_def);
+}
+
+// FIXME: ARTHUR: Do we need to resolve these as well here?
+
+void
+EarlyNameResolver::visit (AST::MetaItemPath &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::MetaItemSeq &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::MetaWord &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::MetaNameValueStr &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::MetaListPaths &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::MetaListNameValueStr &meta_item)
+{}
+
+void
+EarlyNameResolver::visit (AST::LiteralPattern &pattern)
+{}
+
+void
+EarlyNameResolver::visit (AST::IdentifierPattern &pattern)
+{
+  if (pattern.has_pattern_to_bind ())
+    pattern.get_pattern_to_bind ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::WildcardPattern &pattern)
+{}
+
+void
+EarlyNameResolver::visit (AST::RangePatternBoundLiteral &bound)
+{}
+
+void
+EarlyNameResolver::visit (AST::RangePatternBoundPath &bound)
+{}
+
+void
+EarlyNameResolver::visit (AST::RangePatternBoundQualPath &bound)
+{}
+
+void
+EarlyNameResolver::visit (AST::RangePattern &pattern)
+{
+  pattern.get_lower_bound ()->accept_vis (*this);
+  pattern.get_upper_bound ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ReferencePattern &pattern)
+{
+  pattern.get_referenced_pattern ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructPatternFieldTuplePat &field)
+{
+  field.get_index_pattern ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructPatternFieldIdentPat &field)
+{
+  field.get_ident_pattern ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::StructPatternFieldIdent &field)
+{}
+
+void
+EarlyNameResolver::visit (AST::StructPattern &pattern)
+{}
+
+void
+EarlyNameResolver::visit (AST::TupleStructItemsNoRange &tuple_items)
+{
+  for (auto &pattern : tuple_items.get_patterns ())
+    pattern->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TupleStructItemsRange &tuple_items)
+{
+  for (auto &pattern : tuple_items.get_lower_patterns ())
+    pattern->accept_vis (*this);
+  for (auto &pattern : tuple_items.get_upper_patterns ())
+    pattern->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TupleStructPattern &pattern)
+{
+  pattern.get_items ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TuplePatternItemsMultiple &tuple_items)
+{
+  for (auto &pattern : tuple_items.get_patterns ())
+    pattern->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TuplePatternItemsRanged &tuple_items)
+{
+  for (auto &pattern : tuple_items.get_lower_patterns ())
+    pattern->accept_vis (*this);
+  for (auto &pattern : tuple_items.get_upper_patterns ())
+    pattern->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TuplePattern &pattern)
+{
+  pattern.get_items ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::GroupedPattern &pattern)
+{
+  pattern.get_pattern_in_parens ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::SlicePattern &pattern)
+{
+  for (auto &item : pattern.get_items ())
+    item->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::EmptyStmt &stmt)
+{}
+
+void
+EarlyNameResolver::visit (AST::LetStmt &stmt)
+{
+  if (stmt.has_type ())
+    stmt.get_type ()->accept_vis (*this);
+
+  if (stmt.has_init_expr ())
+    stmt.get_init_expr ()->accept_vis (*this);
+
+  stmt.get_pattern ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ExprStmtWithoutBlock &stmt)
+{
+  stmt.get_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::ExprStmtWithBlock &stmt)
+{
+  stmt.get_expr ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::TraitBound &bound)
+{}
+
+void
+EarlyNameResolver::visit (AST::ImplTraitType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::TraitObjectType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::ParenthesisedType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::ImplTraitTypeOneBound &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::TraitObjectTypeOneBound &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::TupleType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::NeverType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::RawPointerType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::ReferenceType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::ArrayType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::SliceType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::InferredType &type)
+{}
+
+void
+EarlyNameResolver::visit (AST::BareFunctionType &type)
+{
+  for (auto &param : type.get_function_params ())
+    param.get_type ()->accept_vis (*this);
+
+  if (type.has_return_type ())
+    type.get_return_type ()->accept_vis (*this);
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-early-name-resolver.h b/gcc/rust/resolve/rust-early-name-resolver.h
new file mode 100644
index 00000000000..c53ab9f3d6a
--- /dev/null
+++ b/gcc/rust/resolve/rust-early-name-resolver.h
@@ -0,0 +1,210 @@
+// Copyright (C) 2020-2022 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_EARLY_NAME_RESOLVER_H
+#define RUST_EARLY_NAME_RESOLVER_H
+
+#include "rust-name-resolver.h"
+#include "rust-system.h"
+#include "rust-ast.h"
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+namespace Resolver {
+
+class EarlyNameResolver : public AST::ASTVisitor
+{
+public:
+  EarlyNameResolver ();
+
+  void go (AST::Crate &crate);
+
+private:
+  Resolver &resolver;
+  Analysis::Mappings &mappings;
+
+  /**
+   * Early name-resolve generic args, which can be macro invocations
+   */
+  void resolve_generic_args (AST::GenericArgs &generic_args);
+
+  /**
+   * Early name-resolve a qualified path type, which can contain macro
+   * invocations
+   */
+  void resolve_qualified_path_type (AST::QualifiedPathType &path);
+
+  virtual void visit (AST::Token &tok);
+  virtual void visit (AST::DelimTokenTree &delim_tok_tree);
+  virtual void visit (AST::AttrInputMetaItemContainer &input);
+  virtual void visit (AST::IdentifierExpr &ident_expr);
+  virtual void visit (AST::Lifetime &lifetime);
+  virtual void visit (AST::LifetimeParam &lifetime_param);
+  virtual void visit (AST::ConstGenericParam &const_param);
+  virtual void visit (AST::PathInExpression &path);
+  virtual void visit (AST::TypePathSegment &segment);
+  virtual void visit (AST::TypePathSegmentGeneric &segment);
+  virtual void visit (AST::TypePathSegmentFunction &segment);
+  virtual void visit (AST::TypePath &path);
+  virtual void visit (AST::QualifiedPathInExpression &path);
+  virtual void visit (AST::QualifiedPathInType &path);
+  virtual void visit (AST::LiteralExpr &expr);
+  virtual void visit (AST::AttrInputLiteral &attr_input);
+  virtual void visit (AST::MetaItemLitExpr &meta_item);
+  virtual void visit (AST::MetaItemPathLit &meta_item);
+  virtual void visit (AST::BorrowExpr &expr);
+  virtual void visit (AST::DereferenceExpr &expr);
+  virtual void visit (AST::ErrorPropagationExpr &expr);
+  virtual void visit (AST::NegationExpr &expr);
+  virtual void visit (AST::ArithmeticOrLogicalExpr &expr);
+  virtual void visit (AST::ComparisonExpr &expr);
+  virtual void visit (AST::LazyBooleanExpr &expr);
+  virtual void visit (AST::TypeCastExpr &expr);
+  virtual void visit (AST::AssignmentExpr &expr);
+  virtual void visit (AST::CompoundAssignmentExpr &expr);
+  virtual void visit (AST::GroupedExpr &expr);
+  virtual void visit (AST::ArrayElemsValues &elems);
+  virtual void visit (AST::ArrayElemsCopied &elems);
+  virtual void visit (AST::ArrayExpr &expr);
+  virtual void visit (AST::ArrayIndexExpr &expr);
+  virtual void visit (AST::TupleExpr &expr);
+  virtual void visit (AST::TupleIndexExpr &expr);
+  virtual void visit (AST::StructExprStruct &expr);
+  virtual void visit (AST::StructExprFieldIdentifier &field);
+  virtual void visit (AST::StructExprFieldIdentifierValue &field);
+  virtual void visit (AST::StructExprFieldIndexValue &field);
+  virtual void visit (AST::StructExprStructFields &expr);
+  virtual void visit (AST::StructExprStructBase &expr);
+  virtual void visit (AST::CallExpr &expr);
+  virtual void visit (AST::MethodCallExpr &expr);
+  virtual void visit (AST::FieldAccessExpr &expr);
+  virtual void visit (AST::ClosureExprInner &expr);
+  virtual void visit (AST::BlockExpr &expr);
+  virtual void visit (AST::ClosureExprInnerTyped &expr);
+  virtual void visit (AST::ContinueExpr &expr);
+  virtual void visit (AST::BreakExpr &expr);
+  virtual void visit (AST::RangeFromToExpr &expr);
+  virtual void visit (AST::RangeFromExpr &expr);
+  virtual void visit (AST::RangeToExpr &expr);
+  virtual void visit (AST::RangeFullExpr &expr);
+  virtual void visit (AST::RangeFromToInclExpr &expr);
+  virtual void visit (AST::RangeToInclExpr &expr);
+  virtual void visit (AST::ReturnExpr &expr);
+  virtual void visit (AST::UnsafeBlockExpr &expr);
+  virtual void visit (AST::LoopExpr &expr);
+  virtual void visit (AST::WhileLoopExpr &expr);
+  virtual void visit (AST::WhileLetLoopExpr &expr);
+  virtual void visit (AST::ForLoopExpr &expr);
+  virtual void visit (AST::IfExpr &expr);
+  virtual void visit (AST::IfExprConseqElse &expr);
+  virtual void visit (AST::IfExprConseqIf &expr);
+  virtual void visit (AST::IfExprConseqIfLet &expr);
+  virtual void visit (AST::IfLetExpr &expr);
+  virtual void visit (AST::IfLetExprConseqElse &expr);
+  virtual void visit (AST::IfLetExprConseqIf &expr);
+  virtual void visit (AST::IfLetExprConseqIfLet &expr);
+  virtual void visit (AST::MatchExpr &expr);
+  virtual void visit (AST::AwaitExpr &expr);
+  virtual void visit (AST::AsyncBlockExpr &expr);
+  virtual void visit (AST::TypeParam &param);
+  virtual void visit (AST::LifetimeWhereClauseItem &item);
+  virtual void visit (AST::TypeBoundWhereClauseItem &item);
+  virtual void visit (AST::Method &method);
+  virtual void visit (AST::Module &module);
+  virtual void visit (AST::ExternCrate &crate);
+  virtual void visit (AST::UseTreeGlob &use_tree);
+  virtual void visit (AST::UseTreeList &use_tree);
+  virtual void visit (AST::UseTreeRebind &use_tree);
+  virtual void visit (AST::UseDeclaration &use_decl);
+  virtual void visit (AST::Function &function);
+  virtual void visit (AST::TypeAlias &type_alias);
+  virtual void visit (AST::StructStruct &struct_item);
+  virtual void visit (AST::TupleStruct &tuple_struct);
+  virtual void visit (AST::EnumItem &item);
+  virtual void visit (AST::EnumItemTuple &item);
+  virtual void visit (AST::EnumItemStruct &item);
+  virtual void visit (AST::EnumItemDiscriminant &item);
+  virtual void visit (AST::Enum &enum_item);
+  virtual void visit (AST::Union &union_item);
+  virtual void visit (AST::ConstantItem &const_item);
+  virtual void visit (AST::StaticItem &static_item);
+  virtual void visit (AST::TraitItemFunc &item);
+  virtual void visit (AST::TraitItemMethod &item);
+  virtual void visit (AST::TraitItemConst &item);
+  virtual void visit (AST::TraitItemType &item);
+  virtual void visit (AST::Trait &trait);
+  virtual void visit (AST::InherentImpl &impl);
+  virtual void visit (AST::TraitImpl &impl);
+  virtual void visit (AST::ExternalStaticItem &item);
+  virtual void visit (AST::ExternalFunctionItem &item);
+  virtual void visit (AST::ExternBlock &block);
+  virtual void visit (AST::MacroMatchFragment &match);
+  virtual void visit (AST::MacroMatchRepetition &match);
+  virtual void visit (AST::MacroMatcher &matcher);
+  virtual void visit (AST::MacroRulesDefinition &rules_def);
+  virtual void visit (AST::MacroInvocation &macro_invoc);
+  virtual void visit (AST::MetaItemPath &meta_item);
+  virtual void visit (AST::MetaItemSeq &meta_item);
+  virtual void visit (AST::MetaWord &meta_item);
+  virtual void visit (AST::MetaNameValueStr &meta_item);
+  virtual void visit (AST::MetaListPaths &meta_item);
+  virtual void visit (AST::MetaListNameValueStr &meta_item);
+  virtual void visit (AST::LiteralPattern &pattern);
+  virtual void visit (AST::IdentifierPattern &pattern);
+  virtual void visit (AST::WildcardPattern &pattern);
+  virtual void visit (AST::RangePatternBoundLiteral &bound);
+  virtual void visit (AST::RangePatternBoundPath &bound);
+  virtual void visit (AST::RangePatternBoundQualPath &bound);
+  virtual void visit (AST::RangePattern &pattern);
+  virtual void visit (AST::ReferencePattern &pattern);
+  virtual void visit (AST::StructPatternFieldTuplePat &field);
+  virtual void visit (AST::StructPatternFieldIdentPat &field);
+  virtual void visit (AST::StructPatternFieldIdent &field);
+  virtual void visit (AST::StructPattern &pattern);
+  virtual void visit (AST::TupleStructItemsNoRange &tuple_items);
+  virtual void visit (AST::TupleStructItemsRange &tuple_items);
+  virtual void visit (AST::TupleStructPattern &pattern);
+  virtual void visit (AST::TuplePatternItemsMultiple &tuple_items);
+  virtual void visit (AST::TuplePatternItemsRanged &tuple_items);
+  virtual void visit (AST::TuplePattern &pattern);
+  virtual void visit (AST::GroupedPattern &pattern);
+  virtual void visit (AST::SlicePattern &pattern);
+  virtual void visit (AST::EmptyStmt &stmt);
+  virtual void visit (AST::LetStmt &stmt);
+  virtual void visit (AST::ExprStmtWithoutBlock &stmt);
+  virtual void visit (AST::ExprStmtWithBlock &stmt);
+  virtual void visit (AST::TraitBound &bound);
+  virtual void visit (AST::ImplTraitType &type);
+  virtual void visit (AST::TraitObjectType &type);
+  virtual void visit (AST::ParenthesisedType &type);
+  virtual void visit (AST::ImplTraitTypeOneBound &type);
+  virtual void visit (AST::TraitObjectTypeOneBound &type);
+  virtual void visit (AST::TupleType &type);
+  virtual void visit (AST::NeverType &type);
+  virtual void visit (AST::RawPointerType &type);
+  virtual void visit (AST::ReferenceType &type);
+  virtual void visit (AST::ArrayType &type);
+  virtual void visit (AST::SliceType &type);
+  virtual void visit (AST::InferredType &type);
+  virtual void visit (AST::BareFunctionType &type);
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_EARLY_NAME_RESOLVER_H
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 4ee7175b48b..6f51bd2e5a1 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -38,6 +38,7 @@
 #include "rust-imports.h"
 #include "rust-extern-crate.h"
 #include "rust-attributes.h"
+#include "rust-early-name-resolver.h"
 
 #include "diagnostic.h"
 #include "input.h"
@@ -805,6 +806,9 @@ Session::injection (AST::Crate &crate)
 void
 Session::expansion (AST::Crate &crate)
 {
+  /* We need to name resolve macros and imports here */
+  Resolver::EarlyNameResolver ().go (crate);
+
   rust_debug ("started expansion");
 
   /* rustc has a modification to windows PATH temporarily here, which may end
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 021/103] gccrs: Support type resolution on super traits on dyn objects
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (19 preceding siblings ...)
  2023-02-21 12:01 ` [committed 020/103] gccrs: early-name-resolver: Add simple macro name resolution arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 022/103] gccrs: Add mappings for fn_once lang item arthur.cohen
                   ` (81 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

When checking if specified bounds satisfy other bounds we must lookup the
super traits. To finish the support for super traits we need to redo the
computation of method addresses to support super traits.

Addresses #914

gcc/rust/ChangeLog:

	* backend/rust-compile.cc: Add note about missing support for super
	traits.
	* typecheck/rust-tyty.cc (BaseType::satisfies_bound): New function.
	(BaseType::bounds_compatible): New function.
	(DynamicObjectType::get_object_items): New function.
	* typecheck/rust-hir-trait-ref.h: Use new API to perform type resolution
	on dyn objects.
---
 gcc/rust/backend/rust-compile.cc        |  2 ++
 gcc/rust/typecheck/rust-hir-trait-ref.h | 24 +++++++++++++++++
 gcc/rust/typecheck/rust-tyty.cc         | 35 ++++++++-----------------
 3 files changed, 37 insertions(+), 24 deletions(-)

diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 13f42438b56..db08b3d595b 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -247,6 +247,8 @@ HIRCompileBase::compute_address_for_trait_item (
   // Algo:
   // check if there is an impl-item for this trait-item-ref first
   // else assert that the trait-item-ref has an implementation
+  //
+  // FIXME this does not support super traits
 
   TyTy::TypeBoundPredicateItem predicate_item
     = predicate->lookup_associated_item (ref->get_identifier ());
diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h
index 7eeb3300387..0df35265959 100644
--- a/gcc/rust/typecheck/rust-hir-trait-ref.h
+++ b/gcc/rust/typecheck/rust-hir-trait-ref.h
@@ -380,6 +380,16 @@ public:
     return item_refs;
   }
 
+  void get_trait_items_and_supers (
+    std::vector<const TraitItemReference *> &result) const
+  {
+    for (const auto &item : item_refs)
+      result.push_back (&item);
+
+    for (const auto &super_trait : super_traits)
+      super_trait->get_trait_items_and_supers (result);
+  }
+
   void on_resolved ()
   {
     for (auto &item : item_refs)
@@ -451,6 +461,20 @@ public:
     return trait_substs;
   }
 
+  bool satisfies_bound (const TraitReference &reference) const
+  {
+    if (is_equal (reference))
+      return true;
+
+    for (const auto &super_trait : super_traits)
+      {
+	if (super_trait->satisfies_bound (reference))
+	  return true;
+      }
+
+    return false;
+  }
+
 private:
   const HIR::Trait *hir_trait_ref;
   std::vector<TraitItemReference> item_refs;
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 64fe0f6cfb0..e2f79971337 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -136,22 +136,18 @@ bool
 BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const
 {
   const Resolver::TraitReference *query = predicate.get ();
-  for (auto &bound : specified_bounds)
+  for (const auto &bound : specified_bounds)
     {
       const Resolver::TraitReference *item = bound.get ();
-      bool found = item->get_mappings ().get_defid ()
-		   == query->get_mappings ().get_defid ();
-      if (found)
+      if (item->satisfies_bound (*query))
 	return true;
     }
 
   auto probed = Resolver::TypeBoundsProbe::Probe (this);
-  for (auto &b : probed)
+  for (const auto &b : probed)
     {
       const Resolver::TraitReference *bound = b.first;
-      bool found = bound->get_mappings ().get_defid ()
-		   == query->get_mappings ().get_defid ();
-      if (found)
+      if (bound->satisfies_bound (*query))
 	return true;
     }
 
@@ -191,7 +187,6 @@ BaseType::bounds_compatible (const BaseType &other, Location locus,
 	  rust_error_at (r,
 			 "bounds not satisfied for %s %<%s%> is not satisfied",
 			 other.get_name ().c_str (), missing_preds.c_str ());
-	  // rust_assert (!emit_error);
 	}
     }
 
@@ -2956,23 +2951,15 @@ DynamicObjectType::get_object_items () const
   for (auto &bound : get_specified_bounds ())
     {
       const Resolver::TraitReference *trait = bound.get ();
-      for (auto &item : trait->get_trait_items ())
-	{
-	  if (item.get_trait_item_type ()
-		== Resolver::TraitItemReference::TraitItemType::FN
-	      && item.is_object_safe ())
-	    items.push_back ({&item, &bound});
-	}
+      std::vector<const Resolver::TraitItemReference *> trait_items;
+      trait->get_trait_items_and_supers (trait_items);
 
-      for (auto &super_trait : trait->get_super_traits ())
+      for (auto &item : trait_items)
 	{
-	  for (auto &item : super_trait->get_trait_items ())
-	    {
-	      if (item.get_trait_item_type ()
-		    == Resolver::TraitItemReference::TraitItemType::FN
-		  && item.is_object_safe ())
-		items.push_back ({&item, &bound});
-	    }
+	  if (item->get_trait_item_type ()
+		== Resolver::TraitItemReference::TraitItemType::FN
+	      && item->is_object_safe ())
+	    items.push_back ({item, &bound});
 	}
     }
   return items;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 022/103] gccrs: Add mappings for fn_once lang item
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (20 preceding siblings ...)
  2023-02-21 12:01 ` [committed 021/103] gccrs: Support type resolution on super traits on dyn objects arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 023/103] gccrs: Add ABI mappings for rust-call to map to ABI::RUST arthur.cohen
                   ` (80 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* util/rust-lang-item.h: Add `fn_once` lang item.
---
 gcc/rust/util/rust-lang-item.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 4d9dc8a3d3a..c7e0e5c811d 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -73,6 +73,9 @@ public:
     MUT_PTR,
     CONST_SLICE_PTR,
 
+    // functions
+    FN_ONCE,
+
     UNKNOWN,
   };
 
@@ -218,6 +221,10 @@ public:
       {
 	return ItemType::CONST_SLICE_PTR;
       }
+    else if (item.compare ("fn_once") == 0)
+      {
+	return ItemType::FN_ONCE;
+      }
 
     return ItemType::UNKNOWN;
   }
@@ -296,6 +303,8 @@ public:
 	return "mut_ptr";
       case CONST_SLICE_PTR:
 	return "const_slice_ptr";
+      case FN_ONCE:
+	return "fn_once";
 
       case UNKNOWN:
 	return "<UNKNOWN>";
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 023/103] gccrs: Add ABI mappings for rust-call to map to ABI::RUST
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (21 preceding siblings ...)
  2023-02-21 12:01 ` [committed 022/103] gccrs: Add mappings for fn_once lang item arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 024/103] gccrs: Method resolution must support multiple candidates arthur.cohen
                   ` (79 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* util/rust-abi.cc (get_abi_from_string): Add missing "rust-call"
	possibility for ABI variant.
---
 gcc/rust/util/rust-abi.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/util/rust-abi.cc b/gcc/rust/util/rust-abi.cc
index 6477c3790af..36abb21520d 100644
--- a/gcc/rust/util/rust-abi.cc
+++ b/gcc/rust/util/rust-abi.cc
@@ -23,6 +23,8 @@ get_abi_from_string (const std::string &abi)
 {
   if (abi.compare ("rust") == 0)
     return Rust::ABI::RUST;
+  else if (abi.compare ("rust-call") == 0)
+    return Rust::ABI::RUST;
   else if (abi.compare ("rust-intrinsic") == 0)
     return Rust::ABI::INTRINSIC;
   else if (abi.compare ("C") == 0)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 024/103] gccrs: Method resolution must support multiple candidates
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (22 preceding siblings ...)
  2023-02-21 12:01 ` [committed 023/103] gccrs: Add ABI mappings for rust-call to map to ABI::RUST arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 025/103] gccrs: ast: dump: fix extra newline in block without tail arthur.cohen
                   ` (78 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

This patch fixes bad method resolution in our operator_overload_9 case.
When we have a &mut reference to something and we deref we must resolve to
the mutable reference impl block. The interface we are using to resolve
methods is the can_eq interface which allows for permissive mutability
which means allowing for mutable reference being unified with an immutable
one. This meant we actual match against both the immutable and mutable
version leading to multiple candidate error.

The fix here adds a method resolution flag to the can_eq interface so that
we enforce mutability equality. The other hack is that we do not allow
can_eq of ParamTypes to generic Slices. I think there is some subtle thing
going on for that case. The Rustc method resolver actually filters the
impl blocks for reference types based looking up the relevant lang items
we need to do this as well but is a much larger refactor to our method
resolver which should be done seperately.

Fixes #1588

gcc/rust/ChangeLog:

	* typecheck/rust-autoderef.cc: Add support for multiple resolution candidates.
	* typecheck/rust-hir-dot-operator.cc (MethodResolver::MethodResolver): Edit
	`try_result` field and change constructor.
	(MethodResolver::Probe): Return set of candidates instead of singular candidate.
	(MethodResolver::select): Add better implementation to account for multiple
	candidates.
	* typecheck/rust-hir-dot-operator.h (struct MethodCandidate): Overload comparison
	operator in order to store them in `std::set`.
	* typecheck/rust-hir-inherent-impl-overlap.h: Do not fail assertion on missing type.
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Adapt code to use
	multiple candidates.
	* typecheck/rust-tyty.cc (set_cmp_autoderef_mode): Add code to handle automatic
	derefs properly.
	(reset_cmp_autoderef_mode): Add helper function to reset said mode.
	* typecheck/rust-tyty.h (set_cmp_autoderef_mode): Declare function.
	(reset_cmp_autoderef_mode): Likewise.
	* typecheck/rust-tyty-cmp.h: Add handling of `autoderef_cmp_flag`

gcc/testsuite/ChangeLog:

	* rust/compile/generics7.rs: Fix test with missing assertion.
	* rust/execute/torture/operator_overload_9.rs: Fix test assertion.
---
 gcc/rust/typecheck/rust-autoderef.cc          | 12 ++-
 gcc/rust/typecheck/rust-hir-dot-operator.cc   | 80 ++++++++++++++++---
 gcc/rust/typecheck/rust-hir-dot-operator.h    | 16 +++-
 .../rust-hir-inherent-impl-overlap.h          |  5 +-
 .../typecheck/rust-hir-type-check-expr.cc     | 35 +++++++-
 gcc/rust/typecheck/rust-tyty-cmp.h            | 14 +++-
 gcc/rust/typecheck/rust-tyty.cc               | 13 +++
 gcc/rust/typecheck/rust-tyty.h                |  5 ++
 gcc/testsuite/rust/compile/generics7.rs       |  6 +-
 .../execute/torture/operator_overload_9.rs    |  2 +-
 10 files changed, 157 insertions(+), 31 deletions(-)

diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc
index ca43f847e98..fe05aeec388 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -139,15 +139,23 @@ resolve_operator_overload_fn (
     return false;
 
   auto segment = HIR::PathIdentSegment (associated_item_name);
-  auto candidate
+  auto candidates
     = MethodResolver::Probe (ty, HIR::PathIdentSegment (associated_item_name),
 			     true);
 
-  bool have_implementation_for_lang_item = !candidate.is_error ();
+  bool have_implementation_for_lang_item = !candidates.empty ();
   if (!have_implementation_for_lang_item)
     return false;
 
+  // multiple candidates?
+  if (candidates.size () > 1)
+    {
+      // error out? probably not for this case
+      return false;
+    }
+
   // Get the adjusted self
+  auto candidate = *candidates.begin ();
   Adjuster adj (ty);
   TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
 
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index ed2df11da45..84fa8d4f08b 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -25,18 +25,17 @@ namespace Resolver {
 
 MethodResolver::MethodResolver (bool autoderef_flag,
 				const HIR::PathIdentSegment &segment_name)
-  : AutoderefCycle (autoderef_flag), segment_name (segment_name),
-    try_result (MethodCandidate::get_error ())
+  : AutoderefCycle (autoderef_flag), segment_name (segment_name), result ()
 {}
 
-MethodCandidate
+std::set<MethodCandidate>
 MethodResolver::Probe (const TyTy::BaseType *receiver,
 		       const HIR::PathIdentSegment &segment_name,
 		       bool autoderef_flag)
 {
   MethodResolver resolver (autoderef_flag, segment_name);
-  bool ok = resolver.cycle (receiver);
-  return ok ? resolver.try_result : MethodCandidate::get_error ();
+  resolver.cycle (receiver);
+  return resolver.result;
 }
 
 void
@@ -177,8 +176,18 @@ MethodResolver::select (const TyTy::BaseType &receiver)
 	      (unsigned long) trait_fns.size (),
 	      (unsigned long) predicate_items.size ());
 
-  for (auto impl_item : inherent_impl_fns)
+  // see the follow for the proper fix to get rid of this we need to assemble
+  // candidates based on a match expression gathering the relevant impl blocks
+  // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L580-L694
+  TyTy::set_cmp_autoderef_mode ();
+
+  bool found_possible_candidate = false;
+  for (auto &impl_item : inherent_impl_fns)
     {
+      bool is_trait_impl_block = impl_item.impl_block->has_trait_ref ();
+      if (is_trait_impl_block)
+	continue;
+
       TyTy::FnType *fn = impl_item.ty;
       rust_assert (fn->is_method ());
 
@@ -190,13 +199,50 @@ MethodResolver::select (const TyTy::BaseType &receiver)
 	{
 	  PathProbeCandidate::ImplItemCandidate c{impl_item.item,
 						  impl_item.impl_block};
-	  try_result = MethodCandidate{
+	  auto try_result = MethodCandidate{
 	    PathProbeCandidate (PathProbeCandidate::CandidateType::IMPL_FUNC,
 				fn, impl_item.item->get_locus (), c),
 	    adjustments};
-	  return true;
+	  result.insert (std::move (try_result));
+	  found_possible_candidate = true;
 	}
     }
+  if (found_possible_candidate)
+    {
+      TyTy::reset_cmp_autoderef_mode ();
+      return true;
+    }
+
+  for (auto &impl_item : inherent_impl_fns)
+    {
+      bool is_trait_impl_block = impl_item.impl_block->has_trait_ref ();
+      if (!is_trait_impl_block)
+	continue;
+
+      TyTy::FnType *fn = impl_item.ty;
+      rust_assert (fn->is_method ());
+
+      TyTy::BaseType *fn_self = fn->get_self_type ();
+      rust_debug (
+	"dot-operator trait_impl_item fn_self={%s} can_eq receiver={%s}",
+	fn_self->debug_str ().c_str (), receiver.debug_str ().c_str ());
+      if (fn_self->can_eq (&receiver, false))
+	{
+	  PathProbeCandidate::ImplItemCandidate c{impl_item.item,
+						  impl_item.impl_block};
+	  auto try_result = MethodCandidate{
+	    PathProbeCandidate (PathProbeCandidate::CandidateType::IMPL_FUNC,
+				fn, impl_item.item->get_locus (), c),
+	    adjustments};
+	  result.insert (std::move (try_result));
+	  found_possible_candidate = true;
+	}
+    }
+  if (found_possible_candidate)
+    {
+      TyTy::reset_cmp_autoderef_mode ();
+      return true;
+    }
 
   for (auto trait_item : trait_fns)
     {
@@ -212,13 +258,19 @@ MethodResolver::select (const TyTy::BaseType &receiver)
 	  PathProbeCandidate::TraitItemCandidate c{trait_item.reference,
 						   trait_item.item_ref,
 						   nullptr};
-	  try_result = MethodCandidate{
+	  auto try_result = MethodCandidate{
 	    PathProbeCandidate (PathProbeCandidate::CandidateType::TRAIT_FUNC,
 				fn, trait_item.item->get_locus (), c),
 	    adjustments};
-	  return true;
+	  result.insert (std::move (try_result));
+	  found_possible_candidate = true;
 	}
     }
+  if (found_possible_candidate)
+    {
+      TyTy::reset_cmp_autoderef_mode ();
+      return true;
+    }
 
   for (const auto &predicate : predicate_items)
     {
@@ -238,15 +290,17 @@ MethodResolver::select (const TyTy::BaseType &receiver)
 
 	  PathProbeCandidate::TraitItemCandidate c{trait_ref, trait_item,
 						   nullptr};
-	  try_result = MethodCandidate{
+	  auto try_result = MethodCandidate{
 	    PathProbeCandidate (PathProbeCandidate::CandidateType::TRAIT_FUNC,
 				fn->clone (), trait_item->get_locus (), c),
 	    adjustments};
-	  return true;
+	  result.insert (std::move (try_result));
+	  found_possible_candidate = true;
 	}
     }
 
-  return false;
+  TyTy::reset_cmp_autoderef_mode ();
+  return found_possible_candidate;
 }
 
 std::vector<MethodResolver::predicate_candidate>
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.h b/gcc/rust/typecheck/rust-hir-dot-operator.h
index 8341173a061..e14baf3f87d 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.h
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.h
@@ -35,6 +35,13 @@ struct MethodCandidate
   }
 
   bool is_error () const { return candidate.is_error (); }
+
+  DefId get_defid () const { return candidate.get_defid (); }
+
+  bool operator< (const MethodCandidate &c) const
+  {
+    return get_defid () < c.get_defid ();
+  }
 };
 
 class MethodResolver : private TypeCheckBase, protected AutoderefCycle
@@ -46,9 +53,10 @@ public:
     TyTy::FnType *fntype;
   };
 
-  static MethodCandidate Probe (const TyTy::BaseType *receiver,
-				const HIR::PathIdentSegment &segment_name,
-				bool autoderef_flag = false);
+  static std::set<MethodCandidate>
+  Probe (const TyTy::BaseType *receiver,
+	 const HIR::PathIdentSegment &segment_name,
+	 bool autoderef_flag = false);
 
   static std::vector<predicate_candidate> get_predicate_items (
     const HIR::PathIdentSegment &segment_name, const TyTy::BaseType &receiver,
@@ -68,7 +76,7 @@ private:
   std::vector<MethodResolver::predicate_candidate> predicate_items;
 
   // mutable fields
-  MethodCandidate try_result;
+  std::set<MethodCandidate> result;
 };
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
index 3733f555cfb..6e2fe1b2286 100644
--- a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
+++ b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
@@ -93,8 +93,9 @@ public:
 
     HirId impl_type_id = impl->get_type ()->get_mappings ().get_hirid ();
     TyTy::BaseType *impl_type = nullptr;
-    bool ok = context->lookup_type (impl_type_id, &impl_type);
-    rust_assert (ok);
+    bool ok = query_type (impl_type_id, &impl_type);
+    if (!ok)
+      return;
 
     std::string impl_item_name;
     ok = ImplItemToName::resolve (impl_item, impl_item_name);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 2f22c82f063..4e377d52a0f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1015,10 +1015,10 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
 
   context->insert_receiver (expr.get_mappings ().get_hirid (), receiver_tyty);
 
-  auto candidate
+  auto candidates
     = MethodResolver::Probe (receiver_tyty,
 			     expr.get_method_name ().get_segment ());
-  if (candidate.is_error ())
+  if (candidates.empty ())
     {
       rust_error_at (
 	expr.get_method_name ().get_locus (),
@@ -1027,6 +1027,19 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
       return;
     }
 
+  if (candidates.size () > 1)
+    {
+      RichLocation r (expr.get_method_name ().get_locus ());
+      for (auto &c : candidates)
+	r.add_range (c.candidate.locus);
+
+      rust_error_at (
+	r, "multiple candidates found for method %<%s%>",
+	expr.get_method_name ().get_segment ().as_string ().c_str ());
+      return;
+    }
+
+  auto candidate = *candidates.begin ();
   rust_debug_loc (expr.get_method_name ().get_locus (),
 		  "resolved method to: {%u} {%s}",
 		  candidate.candidate.ty->get_ref (),
@@ -1422,14 +1435,28 @@ TypeCheckExpr::resolve_operator_overload (
     return false;
 
   auto segment = HIR::PathIdentSegment (associated_item_name);
-  auto candidate
+  auto candidates
     = MethodResolver::Probe (lhs, HIR::PathIdentSegment (associated_item_name));
 
-  bool have_implementation_for_lang_item = !candidate.is_error ();
+  bool have_implementation_for_lang_item = candidates.size () > 0;
   if (!have_implementation_for_lang_item)
     return false;
 
+  if (candidates.size () > 1)
+    {
+      // mutliple candidates
+      RichLocation r (expr.get_locus ());
+      for (auto &c : candidates)
+	r.add_range (c.candidate.locus);
+
+      rust_error_at (
+	r, "multiple candidates found for possible operator overload");
+
+      return false;
+    }
+
   // Get the adjusted self
+  auto candidate = *candidates.begin ();
   Adjuster adj (lhs);
   TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
 
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index d47cbb4369a..5dfd2d7184a 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -28,6 +28,10 @@
 namespace Rust {
 namespace TyTy {
 
+// we need to fix this properly by implementing the match for assembling
+// candidates
+extern bool autoderef_cmp_flag;
+
 class BaseCmp : public TyConstVisitor
 {
 public:
@@ -1244,6 +1248,9 @@ public:
     auto other_base_type = type.get_base ();
 
     bool mutability_ok = base->is_mutable () ? type.is_mutable () : true;
+    if (autoderef_cmp_flag)
+      mutability_ok = base->mutability () == type.mutability ();
+
     if (!mutability_ok)
       {
 	BaseCmp::visit (type);
@@ -1289,9 +1296,10 @@ public:
     auto base_type = base->get_base ();
     auto other_base_type = type.get_base ();
 
-    // rust is permissive about mutablity here you can always go from mutable to
-    // immutable but not the otherway round
     bool mutability_ok = base->is_mutable () ? type.is_mutable () : true;
+    if (autoderef_cmp_flag)
+      mutability_ok = base->mutability () == type.mutability ();
+
     if (!mutability_ok)
       {
 	BaseCmp::visit (type);
@@ -1370,7 +1378,7 @@ public:
 
   void visit (const ArrayType &) override { ok = true; }
 
-  void visit (const SliceType &) override { ok = true; }
+  void visit (const SliceType &) override { ok = !autoderef_cmp_flag; }
 
   void visit (const BoolType &) override { ok = true; }
 
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index e2f79971337..462c5bf91fd 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -32,6 +32,19 @@
 namespace Rust {
 namespace TyTy {
 
+bool autoderef_cmp_flag = false;
+
+void
+set_cmp_autoderef_mode ()
+{
+  autoderef_cmp_flag = true;
+}
+void
+reset_cmp_autoderef_mode ()
+{
+  autoderef_cmp_flag = false;
+}
+
 std::string
 TypeKindFormat::to_string (TypeKind kind)
 {
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index a033fcad6c9..b17f01f67ea 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -135,6 +135,11 @@ protected:
   std::vector<TypeBoundPredicate> specified_bounds;
 };
 
+extern void
+set_cmp_autoderef_mode ();
+extern void
+reset_cmp_autoderef_mode ();
+
 class TyVisitor;
 class TyConstVisitor;
 class BaseType : public TypeBoundsMappings
diff --git a/gcc/testsuite/rust/compile/generics7.rs b/gcc/testsuite/rust/compile/generics7.rs
index 2a41632e693..2789c30ee38 100644
--- a/gcc/testsuite/rust/compile/generics7.rs
+++ b/gcc/testsuite/rust/compile/generics7.rs
@@ -3,13 +3,13 @@ struct Foo<A> {
 }
 
 impl Foo<isize> {
-    fn bar(self) -> isize { // { dg-error "duplicate definitions with name bar" }
+    fn bar(self) -> isize {
         self.a
     }
 }
 
 impl Foo<char> {
-    fn bar(self) -> char { // { dg-error "duplicate definitions with name bar" }
+    fn bar(self) -> char {
         self.a
     }
 }
@@ -23,4 +23,6 @@ impl<T> Foo<T> {
 fn main() {
     let a = Foo { a: 123 };
     a.bar();
+    // { dg-error "multiple candidates found for method .bar." "" { target *-*-* } .-1 }
+    // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
 }
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
index fbb96a60d36..fd972e28ab3 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
@@ -1,4 +1,4 @@
-/* { dg-output "imm_deref\n123\n" } */
+/* { dg-output "mut_deref\n123\n" } */
 extern "C" {
     fn printf(s: *const i8, ...);
 }
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 025/103] gccrs: ast: dump: fix extra newline in block without tail
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (23 preceding siblings ...)
  2023-02-21 12:01 ` [committed 024/103] gccrs: Method resolution must support multiple candidates arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 026/103] gccrs: ast: dump: minor fixups to IfExpr formatting arthur.cohen
                   ` (77 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Fix block formatting.
---
 gcc/rust/ast/rust-ast-dump.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 7cbdfa21fcb..3b00c9fedb6 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -498,11 +498,11 @@ Dump::visit (BlockExpr &expr)
     {
       stream << indentation;
       expr.get_tail_expr ()->accept_vis (*this);
-      stream << " /* tail expr */";
+      stream << " /* tail expr */\n";
     }
 
   indentation.decrement ();
-  stream << "\n" << indentation << "}\n";
+  stream << indentation << "}\n";
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 026/103] gccrs: ast: dump: minor fixups to IfExpr formatting
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (24 preceding siblings ...)
  2023-02-21 12:01 ` [committed 025/103] gccrs: ast: dump: fix extra newline in block without tail arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 027/103] gccrs: ast: dump: ComparisonExpr and LazyBooleanExpr arthur.cohen
                   ` (76 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Fix IfExpr formatting.
---
 gcc/rust/ast/rust-ast-dump.cc | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 3b00c9fedb6..1ba84b8efa1 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -570,6 +570,7 @@ Dump::visit (IfExpr &expr)
 {
   stream << "if ";
   expr.vis_if_condition (*this);
+  stream << " ";
   expr.vis_if_block (*this);
 }
 
@@ -578,6 +579,7 @@ Dump::visit (IfExprConseqElse &expr)
 {
   stream << "if ";
   expr.vis_if_condition (*this);
+  stream << " ";
   expr.vis_if_block (*this);
   stream << indentation << "else ";
   expr.vis_else_block (*this);
@@ -588,8 +590,10 @@ Dump::visit (IfExprConseqIf &expr)
 {
   stream << "if ";
   expr.vis_if_condition (*this);
+  stream << " ";
   expr.vis_if_block (*this);
-  stream << indentation << "else if ";
+  stream << indentation << "else ";
+  // The "if" part of the "else if" is printed by the next visitor
   expr.vis_conseq_if_expr (*this);
 }
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 027/103] gccrs: ast: dump: ComparisonExpr and LazyBooleanExpr
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (25 preceding siblings ...)
  2023-02-21 12:01 ` [committed 026/103] gccrs: ast: dump: minor fixups to IfExpr formatting arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 028/103] gccrs: ast: dump: ArrayExpr arthur.cohen
                   ` (75 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add dumps for ComparisonExpr and
	LazyBooleanExpr.
---
 gcc/rust/ast/rust-ast-dump.cc | 50 +++++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 1ba84b8efa1..ddc43b33512 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -327,11 +327,57 @@ Dump::visit (ArithmeticOrLogicalExpr &expr)
 
 void
 Dump::visit (ComparisonExpr &expr)
-{}
+{
+  auto op = "";
+  switch (expr.get_expr_type ())
+    {
+    case ComparisonOperator::EQUAL:
+      op = "==";
+      break;
+    case ComparisonOperator::NOT_EQUAL:
+      op = "!=";
+      break;
+
+    case ComparisonOperator::GREATER_THAN:
+      op = ">";
+      break;
+
+    case ComparisonOperator::LESS_THAN:
+      op = "<";
+      break;
+
+    case ComparisonOperator::GREATER_OR_EQUAL:
+      op = ">=";
+      break;
+
+    case ComparisonOperator::LESS_OR_EQUAL:
+      op = "<=";
+      break;
+    }
+
+  expr.get_left_expr ()->accept_vis (*this);
+  stream << " " << op << " ";
+  expr.get_right_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (LazyBooleanExpr &expr)
-{}
+{
+  auto op = "";
+  switch (expr.get_expr_type ())
+    {
+    case LazyBooleanOperator::LOGICAL_AND:
+      op = "&&";
+      break;
+    case LazyBooleanOperator::LOGICAL_OR:
+      op = "||";
+      break;
+    }
+
+  expr.get_left_expr ()->accept_vis (*this);
+  stream << " " << op << " ";
+  expr.get_right_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (TypeCastExpr &expr)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 028/103] gccrs: ast: dump: ArrayExpr
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (26 preceding siblings ...)
  2023-02-21 12:01 ` [committed 027/103] gccrs: ast: dump: ComparisonExpr and LazyBooleanExpr arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 029/103] gccrs: ast: dump: various simple Exprs arthur.cohen
                   ` (74 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add dump code for ArrayExpr.
---
 gcc/rust/ast/rust-ast-dump.cc | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index ddc43b33512..91e540a1ee8 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -449,19 +449,43 @@ Dump::visit (GroupedExpr &expr)
 
 void
 Dump::visit (ArrayElemsValues &elems)
-{}
+{
+  auto &vals = elems.get_values ();
+  if (vals.size () >= 1)
+    {
+      vals[0]->accept_vis (*this);
+      for (size_t i = 1; i < vals.size (); i++)
+	{
+	  stream << ", ";
+	  vals[i]->accept_vis (*this);
+	}
+    }
+}
 
 void
 Dump::visit (ArrayElemsCopied &elems)
-{}
+{
+  elems.get_elem_to_copy ()->accept_vis (*this);
+  stream << "; ";
+  elems.get_num_copies ()->accept_vis (*this);
+}
 
 void
 Dump::visit (ArrayExpr &expr)
-{}
+{
+  stream << '[';
+  expr.get_array_elems ()->accept_vis (*this);
+  stream << ']';
+}
 
 void
 Dump::visit (ArrayIndexExpr &expr)
-{}
+{
+  expr.get_array_expr ()->accept_vis (*this);
+  stream << '[';
+  expr.get_index_expr ()->accept_vis (*this);
+  stream << ']';
+}
 
 void
 Dump::visit (TupleExpr &expr)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 029/103] gccrs: ast: dump: various simple Exprs
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (27 preceding siblings ...)
  2023-02-21 12:01 ` [committed 028/103] gccrs: ast: dump: ArrayExpr arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 030/103] gccrs: ast: dump: RangeExprs arthur.cohen
                   ` (73 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

Adds dump for:
- BorrowExpr
- DereferenceExpr
- ErrorPropagationExpr
- NegationExpr
- TypeCastExpr
- GroupedExpr

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add dump for, BorrowExpr, DereferenceExpr,
	ErrorPropagationExpr, NegationExpr, TypeCastExpr and GroupedExpr.
---
 gcc/rust/ast/rust-ast-dump.cc | 45 ++++++++++++++++++++++++++++++-----
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 91e540a1ee8..b9e08b59554 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -259,19 +259,44 @@ Dump::visit (MetaItemPathLit &meta_item)
 
 void
 Dump::visit (BorrowExpr &expr)
-{}
+{
+  stream << '&';
+  if (expr.get_is_double_borrow ())
+    stream << '&';
+  if (expr.get_is_mut ())
+    stream << "mut ";
+
+  expr.get_borrowed_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (DereferenceExpr &expr)
-{}
+{
+  stream << '*';
+  expr.get_dereferenced_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (ErrorPropagationExpr &expr)
-{}
+{
+  expr.get_propagating_expr ()->accept_vis (*this);
+  stream << '?';
+}
 
 void
 Dump::visit (NegationExpr &expr)
-{}
+{
+  switch (expr.get_expr_type ())
+    {
+    case NegationOperator::NEGATE:
+      stream << '-';
+      break;
+    case NegationOperator::NOT:
+      stream << '!';
+      break;
+    }
+  expr.get_negated_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (ArithmeticOrLogicalExpr &expr)
@@ -381,7 +406,11 @@ Dump::visit (LazyBooleanExpr &expr)
 
 void
 Dump::visit (TypeCastExpr &expr)
-{}
+{
+  expr.get_casted_expr ()->accept_vis (*this);
+  stream << " as ";
+  expr.get_type_to_cast_to ()->accept_vis (*this);
+}
 
 void
 Dump::visit (AssignmentExpr &expr)
@@ -445,7 +474,11 @@ Dump::visit (CompoundAssignmentExpr &expr)
 
 void
 Dump::visit (GroupedExpr &expr)
-{}
+{
+  stream << '(';
+  expr.get_expr_in_parens ()->accept_vis (*this);
+  stream << ')';
+}
 
 void
 Dump::visit (ArrayElemsValues &elems)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 030/103] gccrs: ast: dump: RangeExprs
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (28 preceding siblings ...)
  2023-02-21 12:01 ` [committed 029/103] gccrs: ast: dump: various simple Exprs arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 031/103] gccrs: Refactor TraitResolver to not require a visitor arthur.cohen
                   ` (72 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, David Faust

From: David Faust <david.faust@oracle.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add dump for RangeExprs.
---
 gcc/rust/ast/rust-ast-dump.cc | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index b9e08b59554..8caad987538 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -622,27 +622,46 @@ Dump::visit (BreakExpr &expr)
 
 void
 Dump::visit (RangeFromToExpr &expr)
-{}
+{
+  expr.get_from_expr ()->accept_vis (*this);
+  stream << "..";
+  expr.get_to_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (RangeFromExpr &expr)
-{}
+{
+  expr.get_from_expr ()->accept_vis (*this);
+  stream << "..";
+}
 
 void
 Dump::visit (RangeToExpr &expr)
-{}
+{
+  stream << "..";
+  expr.get_to_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (RangeFullExpr &expr)
-{}
+{
+  stream << "..";
+}
 
 void
 Dump::visit (RangeFromToInclExpr &expr)
-{}
+{
+  expr.get_from_expr ()->accept_vis (*this);
+  stream << "..=";
+  expr.get_to_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (RangeToInclExpr &expr)
-{}
+{
+  stream << "..=";
+  expr.get_to_expr ()->accept_vis (*this);
+}
 
 void
 Dump::visit (ReturnExpr &expr)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 031/103] gccrs: Refactor TraitResolver to not require a visitor
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (29 preceding siblings ...)
  2023-02-21 12:01 ` [committed 030/103] gccrs: ast: dump: RangeExprs arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 032/103] gccrs: ast: dump TypeAlias arthur.cohen
                   ` (71 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-trait-resolve.cc (TraitResolver::TraitResolver): Do not nullptr init
	`resolved_trait_reference` anymore.
	(TraitResolver::resolve_path): Simplify function and rename to...
	(TraitResolver::resolve_path_to_trait): ...this.
	(TraitResolver::lookup_path): Use new interface.
	* typecheck/rust-hir-trait-resolve.h (class TraitResolver): Do not inherit `HIRFullVisitor`
	class anymore.
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc | 53 +++++++++-----------
 gcc/rust/typecheck/rust-hir-trait-resolve.h  | 10 ++--
 2 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 22398b1fa8a..1b0bcaac79d 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -91,33 +91,42 @@ TraitResolver::Lookup (HIR::TypePath &path)
   return resolver.lookup_path (path);
 }
 
-TraitResolver::TraitResolver ()
-  : TypeCheckBase (), resolved_trait_reference (nullptr)
-{}
+TraitResolver::TraitResolver () : TypeCheckBase () {}
 
-TraitReference *
-TraitResolver::resolve_path (HIR::TypePath &path)
+bool
+TraitResolver::resolve_path_to_trait (const HIR::TypePath &path,
+				      HIR::Trait **resolved) const
 {
   NodeId ref;
   if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
 				       &ref))
     {
       rust_error_at (path.get_locus (), "Failed to resolve path to node-id");
-      return &TraitReference::error_node ();
+      return false;
     }
 
   HirId hir_node = UNKNOWN_HIRID;
   if (!mappings->lookup_node_to_hir (ref, &hir_node))
     {
       rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
-      return &TraitReference::error_node ();
+      return false;
     }
 
   HIR::Item *resolved_item = mappings->lookup_hir_item (hir_node);
-
   rust_assert (resolved_item != nullptr);
-  resolved_item->accept_vis (*this);
-  rust_assert (resolved_trait_reference != nullptr);
+  rust_assert (resolved_item->get_item_kind () == HIR::Item::ItemKind::Trait);
+  *resolved = static_cast<HIR::Trait *> (resolved_item);
+
+  return true;
+}
+
+TraitReference *
+TraitResolver::resolve_path (HIR::TypePath &path)
+{
+  HIR::Trait *resolved_trait_reference;
+  bool ok = resolve_path_to_trait (path, &resolved_trait_reference);
+  if (!ok)
+    return &TraitReference::error_node ();
 
   return resolve_trait (resolved_trait_reference);
 }
@@ -237,26 +246,10 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 TraitReference *
 TraitResolver::lookup_path (HIR::TypePath &path)
 {
-  NodeId ref;
-  if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
-				       &ref))
-    {
-      rust_error_at (path.get_locus (), "Failed to resolve path to node-id");
-      return &TraitReference::error_node ();
-    }
-
-  HirId hir_node = UNKNOWN_HIRID;
-  if (!mappings->lookup_node_to_hir (ref, &hir_node))
-    {
-      rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
-      return &TraitReference::error_node ();
-    }
-
-  HIR::Item *resolved_item = mappings->lookup_hir_item (hir_node);
-
-  rust_assert (resolved_item != nullptr);
-  resolved_item->accept_vis (*this);
-  rust_assert (resolved_trait_reference != nullptr);
+  HIR::Trait *resolved_trait_reference;
+  bool ok = resolve_path_to_trait (path, &resolved_trait_reference);
+  if (!ok)
+    return &TraitReference::error_node ();
 
   TraitReference *tref = &TraitReference::error_node ();
   if (context->lookup_trait_reference (
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h
index 6d4b932e468..ca23d48c3dd 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.h
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h
@@ -55,10 +55,8 @@ private:
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
 };
 
-class TraitResolver : public TypeCheckBase, private HIR::HIRFullVisitorBase
+class TraitResolver : public TypeCheckBase
 {
-  using HIR::HIRFullVisitorBase::visit;
-
 public:
   static TraitReference *Resolve (HIR::TypePath &path);
 
@@ -75,10 +73,8 @@ private:
 
   TraitReference *lookup_path (HIR::TypePath &path);
 
-  HIR::Trait *resolved_trait_reference;
-
-public:
-  void visit (HIR::Trait &trait) override { resolved_trait_reference = &trait; }
+  bool resolve_path_to_trait (const HIR::TypePath &path,
+			      HIR::Trait **resolved) const;
 };
 
 } // namespace Resolver
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 032/103] gccrs: ast: dump TypeAlias
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (30 preceding siblings ...)
  2023-02-21 12:01 ` [committed 031/103] gccrs: Refactor TraitResolver to not require a visitor arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 033/103] gccrs: Support outer attribute handling on trait items just like normal items arthur.cohen
                   ` (70 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add code for dumping type aliases.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 8caad987538..fdcd97561bb 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -836,7 +836,6 @@ Dump::visit (Function &function)
 {
   emit_visibility (function.get_visibility ());
   stream << "fn " << function.get_function_name ();
-
   if (function.has_generics ())
     emit_generic_params (function.get_generic_params ());
 
@@ -872,7 +871,24 @@ Dump::visit (Function &function)
 
 void
 Dump::visit (TypeAlias &type_alias)
-{}
+{
+  // Syntax:
+  // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
+
+  // Note: Associated types are handled by `AST::TraitItemType`.
+
+  if (type_alias.has_visibility ())
+    emit_visibility (type_alias.get_visibility ());
+  stream << "type " << type_alias.get_new_type_name ();
+  if (type_alias.has_generics ())
+    emit_generic_params (type_alias.get_generic_params ());
+  if (type_alias.has_where_clause ())
+    {
+    } // FIXME: WhereClause
+  stream << " = ";
+  type_alias.get_type_aliased ()->accept_vis (*this);
+  stream << ";\n";
+}
 
 void
 Dump::visit (StructStruct &struct_item)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 033/103] gccrs: Support outer attribute handling on trait items just like normal items
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (31 preceding siblings ...)
  2023-02-21 12:01 ` [committed 032/103] gccrs: ast: dump TypeAlias arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 034/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
                   ` (69 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* hir/rust-ast-lower-base.h (class ItemWrapper): New class.
	* hir/rust-ast-lower-base.cc (ASTLoweringBase::handle_outer_attributes): Use
	`ItemWrapper` class.
	(ASTLoweringBase::handle_doc_item_attribute): Likewise.
	(ASTLoweringBase::handle_lang_item_attribute): Likewise.
	* hir/rust-ast-lower-implitem.h: Check outer attributes on items.
	* hir/tree/rust-hir-item.h: Add `get_trait_locus` methods.
	* hir/tree/rust-hir.h: Likewise.
	* util/rust-hir-map.h: Add defId mappings and associated functions.
	* util/rust-hir-map.cc (Mappings::insert_defid_mapping): Implement insertion to said
	mappings.
	(Mappings::lookup_trait_item_defid): And looking up said mappings.
---
 gcc/rust/hir/rust-ast-lower-base.cc    |  6 +++---
 gcc/rust/hir/rust-ast-lower-base.h     | 30 +++++++++++++++++++++++---
 gcc/rust/hir/rust-ast-lower-implitem.h | 14 ++++++------
 gcc/rust/hir/tree/rust-hir-item.h      |  6 ++++++
 gcc/rust/hir/tree/rust-hir.h           |  4 +++-
 gcc/rust/util/rust-hir-map.cc          | 24 +++++++++++++++++++++
 gcc/rust/util/rust-hir-map.h           |  3 +++
 7 files changed, 72 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index a4bcfd6c4b4..098014ff92b 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -824,7 +824,7 @@ ASTLoweringBase::lower_qualifiers (const AST::FunctionQualifiers &qualifiers)
 }
 
 void
-ASTLoweringBase::handle_outer_attributes (const HIR::Item &item)
+ASTLoweringBase::handle_outer_attributes (const ItemWrapper &item)
 {
   for (const auto &attr : item.get_outer_attrs ())
     {
@@ -855,7 +855,7 @@ ASTLoweringBase::handle_outer_attributes (const HIR::Item &item)
 }
 
 void
-ASTLoweringBase::handle_doc_item_attribute (const HIR::Item &item,
+ASTLoweringBase::handle_doc_item_attribute (const ItemWrapper &item,
 					    const AST::Attribute &attr)
 {
   auto simple_doc_comment = attr.has_attr_input ()
@@ -878,7 +878,7 @@ ASTLoweringBase::handle_doc_item_attribute (const HIR::Item &item,
 }
 
 void
-ASTLoweringBase::handle_lang_item_attribute (const HIR::Item &item,
+ASTLoweringBase::handle_lang_item_attribute (const ItemWrapper &item,
 					     const AST::Attribute &attr)
 {
   auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index f08e3185451..adcbc5d2f69 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -29,6 +29,30 @@
 namespace Rust {
 namespace HIR {
 
+// proxy class so we can do attribute checking on items and trait items
+class ItemWrapper
+{
+public:
+  ItemWrapper (const HIR::Item &item)
+    : mappings (item.get_mappings ()), locus (item.get_locus ()),
+      outer_attrs (item.get_outer_attrs ())
+  {}
+
+  ItemWrapper (const HIR::TraitItem &item)
+    : mappings (item.get_mappings ()), locus (item.get_trait_locus ()),
+      outer_attrs (item.get_outer_attrs ())
+  {}
+
+  const Analysis::NodeMapping &get_mappings () const { return mappings; }
+  Location get_locus () const { return locus; }
+  const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
+
+private:
+  const Analysis::NodeMapping &mappings;
+  Location locus;
+  const AST::AttrVec &outer_attrs;
+};
+
 // base class to allow derivatives to overload as needed
 class ASTLoweringBase : public AST::ASTVisitor
 {
@@ -264,12 +288,12 @@ protected:
   HIR::FunctionQualifiers
   lower_qualifiers (const AST::FunctionQualifiers &qualifiers);
 
-  void handle_outer_attributes (const HIR::Item &item);
+  void handle_outer_attributes (const ItemWrapper &item);
 
-  void handle_lang_item_attribute (const HIR::Item &item,
+  void handle_lang_item_attribute (const ItemWrapper &item,
 				   const AST::Attribute &attr);
 
-  void handle_doc_item_attribute (const HIR::Item &item,
+  void handle_doc_item_attribute (const ItemWrapper &item,
 				  const AST::Attribute &attr);
 
   bool is_known_attribute (const std::string &attribute_path) const;
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index 69436543825..709bb573046 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -305,16 +305,14 @@ public:
 
     if (resolver.translated != nullptr)
       {
-	// FIXME
+	auto id = resolver.translated->get_mappings ().get_hirid ();
+	auto defid = resolver.translated->get_mappings ().get_defid ();
+	auto locus = resolver.translated->get_trait_locus ();
 
-	// auto id = resolver.translated->get_mappings ().get_hirid ();
-	// auto defid = resolver.translated->get_mappings ().get_defid ();
-	// auto locus = resolver.translated->get_locus ();
-
-	// resolver.handle_outer_attributes (*resolver.translated);
+	resolver.handle_outer_attributes (*resolver.translated);
 	resolver.mappings->insert_hir_trait_item (resolver.translated);
-	// resolver.mappings->insert_location (id, locus);
-	// resolver.mappings->insert_defid_mapping (defid, resolver.item_cast);
+	resolver.mappings->insert_location (id, locus);
+	resolver.mappings->insert_defid_mapping (defid, resolver.translated);
       }
 
     return resolver.translated;
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 8d371e00b98..7f665159572 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2394,6 +2394,8 @@ public:
     return outer_attrs;
   }
 
+  Location get_trait_locus () const override { return get_locus (); }
+
 protected:
   // Clone function implementation as (not pure) virtual method
   TraitItemFunc *clone_trait_item_impl () const override
@@ -2480,6 +2482,8 @@ public:
     return outer_attrs;
   }
 
+  Location get_trait_locus () const override { return get_locus (); }
+
 protected:
   // Clone function implementation as (not pure) virtual method
   TraitItemConst *clone_trait_item_impl () const override
@@ -2567,6 +2571,8 @@ public:
     return outer_attrs;
   }
 
+  Location get_trait_locus () const override { return get_locus (); }
+
 protected:
   // Clone function implementation as (not pure) virtual method
   TraitItemType *clone_trait_item_impl () const override
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index 2614ef85b29..aa305f1590c 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -796,7 +796,9 @@ public:
 
   virtual const std::string trait_identifier () const = 0;
 
-  const Analysis::NodeMapping get_mappings () const { return mappings; }
+  const Analysis::NodeMapping &get_mappings () const { return mappings; }
+
+  virtual Location get_trait_locus () const = 0;
 
   virtual TraitItemKind get_item_kind () const = 0;
 
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 7ea782ed4c4..4aeb7f5ae18 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -316,6 +316,7 @@ Mappings::insert_defid_mapping (DefId id, HIR::Item *item)
 
   rust_assert (lookup_defid (id) == nullptr);
   rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr);
+  rust_assert (lookup_trait_item_defid (id) == nullptr);
 
   defIdMappings[id] = item;
   insert_local_defid_mapping (crate_num, local_def_id, item);
@@ -331,6 +332,29 @@ Mappings::lookup_defid (DefId id)
   return it->second;
 }
 
+void
+Mappings::insert_defid_mapping (DefId id, HIR::TraitItem *item)
+{
+  CrateNum crate_num = id.crateNum;
+  LocalDefId local_def_id = id.localDefId;
+
+  rust_assert (lookup_defid (id) == nullptr);
+  rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr);
+  rust_assert (lookup_trait_item_defid (id) == nullptr);
+
+  defIdTraitItemMappings[id] = item;
+}
+
+HIR::TraitItem *
+Mappings::lookup_trait_item_defid (DefId id)
+{
+  auto it = defIdTraitItemMappings.find (id);
+  if (it == defIdTraitItemMappings.end ())
+    return nullptr;
+
+  return it->second;
+}
+
 void
 Mappings::insert_hir_item (HIR::Item *item)
 {
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index addd9efc3b0..13cae717031 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -104,6 +104,8 @@ public:
 
   void insert_defid_mapping (DefId id, HIR::Item *item);
   HIR::Item *lookup_defid (DefId id);
+  void insert_defid_mapping (DefId id, HIR::TraitItem *item);
+  HIR::TraitItem *lookup_trait_item_defid (DefId id);
 
   void insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
 				   HIR::Item *item);
@@ -307,6 +309,7 @@ private:
   std::map<CrateNum, AST::Crate *> ast_crate_mappings;
   std::map<CrateNum, HIR::Crate *> hir_crate_mappings;
   std::map<DefId, HIR::Item *> defIdMappings;
+  std::map<DefId, HIR::TraitItem *> defIdTraitItemMappings;
   std::map<CrateNum, std::map<LocalDefId, HIR::Item *>> localDefIdMappings;
 
   std::map<HirId, HIR::Module *> hirModuleMappings;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 034/103] gccrs: dump: Emit visibility when dumping items
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (32 preceding siblings ...)
  2023-02-21 12:01 ` [committed 033/103] gccrs: Support outer attribute handling on trait items just like normal items arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-23  1:01   ` Gerald Pfeifer
  2023-02-21 12:01 ` [committed 035/103] gccrs: dump: Dump items within modules arthur.cohen
                   ` (68 subsequent siblings)
  102 siblings, 1 reply; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc: Emit visibility when dumping items.
---
 gcc/rust/ast/rust-ast-dump.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index fdcd97561bb..b7557bdee0c 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -835,6 +835,7 @@ void
 Dump::visit (Function &function)
 {
   emit_visibility (function.get_visibility ());
+
   stream << "fn " << function.get_function_name ();
   if (function.has_generics ())
     emit_generic_params (function.get_generic_params ());
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 035/103] gccrs: dump: Dump items within modules
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (33 preceding siblings ...)
  2023-02-21 12:01 ` [committed 034/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 036/103] gccrs: dump: Fix module dumping arthur.cohen
                   ` (67 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Dump items in modules properly.
---
 gcc/rust/ast/rust-ast-dump.cc | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index b7557bdee0c..653c1d9ff03 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -809,7 +809,23 @@ Dump::visit (Method &method)
 
 void
 Dump::visit (Module &module)
-{}
+{
+  indentation.increment ();
+
+  stream << indentation;
+  emit_visibility (module.get_visibility ());
+  stream << "mod" << module.get_name () << " {\n";
+
+  for (auto &item : module.get_items ())
+    {
+      stream << indentation;
+      item->accept_vis (*this);
+      stream << '\n';
+    }
+
+  indentation.decrement ();
+  stream << indentation << "}\n";
+}
 
 void
 Dump::visit (ExternCrate &crate)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 036/103] gccrs: dump: Fix module dumping
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (34 preceding siblings ...)
  2023-02-21 12:01 ` [committed 035/103] gccrs: dump: Dump items within modules arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 037/103] gccrs: ast: Module: unloaded module and inner attributes arthur.cohen
                   ` (66 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Fix formatting when dumping modules.
---
 gcc/rust/ast/rust-ast-dump.cc | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 653c1d9ff03..1e7a235932d 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -810,11 +810,10 @@ Dump::visit (Method &method)
 void
 Dump::visit (Module &module)
 {
-  indentation.increment ();
-
-  stream << indentation;
   emit_visibility (module.get_visibility ());
-  stream << "mod" << module.get_name () << " {\n";
+  stream << "mod " << module.get_name () << " {\n";
+
+  indentation.increment ();
 
   for (auto &item : module.get_items ())
     {
@@ -824,6 +823,7 @@ Dump::visit (Module &module)
     }
 
   indentation.decrement ();
+
   stream << indentation << "}\n";
 }
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 037/103] gccrs: ast: Module: unloaded module and inner attributes
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (35 preceding siblings ...)
  2023-02-21 12:01 ` [committed 036/103] gccrs: dump: Fix module dumping arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 038/103] gccrs: dump: Dump macro rules definition arthur.cohen
                   ` (65 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Properly handle unloaded modules.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 41 +++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 1e7a235932d..a12c3922c47 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -810,21 +810,44 @@ Dump::visit (Method &method)
 void
 Dump::visit (Module &module)
 {
-  emit_visibility (module.get_visibility ());
-  stream << "mod " << module.get_name () << " {\n";
+  //  Syntax:
+  //	mod IDENTIFIER ;
+  //     | mod IDENTIFIER {
+  //	  InnerAttribute*
+  //	  Item*
+  //	}
 
-  indentation.increment ();
+  emit_visibility (module.get_visibility ());
+  stream << "mod " << module.get_name ();
 
-  for (auto &item : module.get_items ())
+  if (module.get_kind () == Module::UNLOADED)
     {
-      stream << indentation;
-      item->accept_vis (*this);
-      stream << '\n';
+      stream << ";\n";
     }
+  else /* Module::LOADED */
+    {
+      stream << " {\n";
 
-  indentation.decrement ();
+      indentation.increment ();
 
-  stream << indentation << "}\n";
+      for (auto &item : module.get_inner_attrs ())
+	{
+	  stream << indentation;
+	  emit_attrib (item);
+	  stream << '\n';
+	}
+
+      for (auto &item : module.get_items ())
+	{
+	  stream << indentation;
+	  item->accept_vis (*this);
+	  stream << '\n';
+	}
+
+      indentation.decrement ();
+
+      stream << indentation << "}\n";
+    }
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 038/103] gccrs: dump: Dump macro rules definition
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (36 preceding siblings ...)
  2023-02-21 12:01 ` [committed 037/103] gccrs: ast: Module: unloaded module and inner attributes arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 039/103] gccrs: Add check for recursive trait cycles arthur.cohen
                   ` (64 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitors for macro definition dumping.
	(get_delimiters): New function.
	* ast/rust-ast-dump.h: Declare `get_delimiters` and add documentation.
	* ast/rust-macro.h: Add `get_token_tree` method.
---
 gcc/rust/ast/rust-ast-dump.cc | 126 +++++++++++++++++++++++++++++++---
 gcc/rust/ast/rust-ast-dump.h  |  16 +++--
 gcc/rust/ast/rust-macro.h     |   1 +
 3 files changed, 131 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index a12c3922c47..4817962f767 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -175,11 +175,27 @@ Dump::format_struct_field (StructField &field)
 
 void
 Dump::visit (Token &tok)
-{}
+{
+  stream << tok.as_string ();
+}
 
 void
 Dump::visit (DelimTokenTree &delim_tok_tree)
-{}
+{
+  auto tokens = delim_tok_tree.to_token_stream ();
+
+  indentation.increment ();
+  stream << '\n' << indentation;
+
+  for (const auto &tok : tokens)
+    {
+      stream << ' ';
+      tok->accept_vis (*this);
+    }
+
+  indentation.decrement ();
+  stream << '\n' << indentation;
+}
 
 void
 Dump::visit (AttrInputMetaItemContainer &input)
@@ -1308,22 +1324,116 @@ Dump::visit (ExternBlock &block)
   stream << "\n" << indentation << "}\n";
 }
 
-// rust-macro.h
+static std::pair<char, char>
+get_delimiters (DelimType delim)
+{
+  auto start_delim = '\0';
+  auto end_delim = '\0';
+
+  switch (delim)
+    {
+    case PARENS:
+      start_delim = '(';
+      end_delim = ')';
+      break;
+    case SQUARE:
+      start_delim = '[';
+      end_delim = ']';
+      break;
+    case CURLY:
+      start_delim = '{';
+      end_delim = '}';
+      break;
+    }
+
+  return {start_delim, end_delim};
+}
+
 void
 Dump::visit (MacroMatchFragment &match)
-{}
+{
+  stream << '$' << match.get_ident () << ':'
+	 << match.get_frag_spec ().as_string ();
+}
 
 void
-Dump::visit (MacroMatchRepetition &match)
-{}
+Dump::visit (MacroMatchRepetition &repetition)
+{
+  stream << "$(";
+
+  for (auto &match : repetition.get_matches ())
+    {
+      match->accept_vis (*this);
+      stream << ' ';
+    }
+
+  auto op_char = '\0';
+  switch (repetition.get_op ())
+    {
+    case MacroMatchRepetition::ANY:
+      op_char = '*';
+      break;
+    case MacroMatchRepetition::ONE_OR_MORE:
+      op_char = '+';
+      break;
+    case MacroMatchRepetition::ZERO_OR_ONE:
+      op_char = '?';
+      break;
+    case MacroMatchRepetition::NONE:
+      break;
+    }
+
+  stream << ')';
+
+  if (repetition.has_sep ())
+    stream << repetition.get_sep ()->as_string ();
+
+  stream << op_char;
+}
 
 void
 Dump::visit (MacroMatcher &matcher)
-{}
+{
+  auto delimiters = get_delimiters (matcher.get_delim_type ());
+
+  stream << delimiters.first;
+
+  for (auto &match : matcher.get_matches ())
+    {
+      match->accept_vis (*this);
+      stream << ' ';
+    }
+
+  stream << delimiters.second;
+}
 
 void
 Dump::visit (MacroRulesDefinition &rules_def)
-{}
+{
+  for (auto &outer_attr : rules_def.get_outer_attrs ())
+    emit_attrib (outer_attr);
+
+  stream << "macro_rules! " << rules_def.get_rule_name () << " {\n";
+
+  indentation.increment ();
+
+  for (auto &rule : rules_def.get_rules ())
+    {
+      stream << indentation;
+
+      rule.get_matcher ().accept_vis (*this);
+
+      stream << " => ";
+
+      rule.get_transcriber ().get_token_tree ().accept_vis (*this);
+
+      stream << ";\n";
+    }
+
+  indentation.decrement ();
+
+  stream << "}\n";
+}
 
 void
 Dump::visit (MacroInvocation &macro_invoc)
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 2da2736c95b..9fe8ee95493 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -72,7 +72,9 @@ private:
   std::ostream &stream;
   Indent indentation;
 
-  // Format together common items of functions: Parameters, return type, block
+  /**
+   * Format together common items of functions: Parameters, return type, block
+   */
   void format_function_common (std::unique_ptr<Type> &return_type,
 			       std::unique_ptr<BlockExpr> &block);
 
@@ -97,13 +99,19 @@ private:
   std::ostream &emit_indented_string (const std::string &value,
 				      const std::string &comment = "");
 
-  // Emit formatted string for generic parameters.
+  /**
+   * Emit formatted string for generic parameters
+   */
   void emit_generic_params (std::vector<std::unique_ptr<GenericParam>> &params);
 
-  // Format a single field of a tuple.
+  /**
+   * Format a single field of a tuple
+   */
   void format_tuple_field (TupleField &field);
 
-  // Format a single field of a struct.
+  /**
+   * Format a single field of a struct
+   */
   void format_struct_field (StructField &field);
 
   // rust-ast.h
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 4f980b0b506..798bc974fbb 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -407,6 +407,7 @@ public:
   Location get_locus () const { return locus; }
 
   DelimTokenTree &get_token_tree () { return token_tree; }
+  const DelimTokenTree &get_token_tree () const { return token_tree; }
 };
 
 // A macro rule? Matcher and transcriber pair?
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 039/103] gccrs: Add check for recursive trait cycles
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (37 preceding siblings ...)
  2023-02-21 12:01 ` [committed 038/103] gccrs: dump: Dump macro rules definition arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 040/103] gccrs: ast: Refactor ASTFragment -> Fragment class arthur.cohen
                   ` (63 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): Check if a
	trait query is currently in progress.
	* typecheck/rust-hir-type-check.h (class TraitQueryGuard): Add helpers around
	checking for trait queries and inserting them.

gcc/testsuite/ChangeLog:

	* rust/compile/issue-1589.rs: New test.
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc | 12 +++++++-
 gcc/rust/typecheck/rust-hir-type-check.h     | 29 ++++++++++++++++++++
 gcc/testsuite/rust/compile/issue-1589.rs     |  5 ++++
 3 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-1589.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 1b0bcaac79d..2ec9b2ef83e 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -141,6 +141,14 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
       return tref;
     }
 
+  DefId trait_id = trait_reference->get_mappings ().get_defid ();
+  if (context->trait_query_in_progress (trait_id))
+    {
+      rust_error_at (trait_reference->get_locus (), "trait cycle detected");
+      return &TraitReference::error_node ();
+    }
+
+  TraitQueryGuard guard (trait_id);
   TyTy::BaseType *self = nullptr;
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   for (auto &generic_param : trait_reference->get_generic_params ())
@@ -201,8 +209,10 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 	      HIR::TraitBound *b
 		= static_cast<HIR::TraitBound *> (bound.get ());
 
-	      // FIXME this might be recursive we need a check for that
 	      auto predicate = get_predicate_from_bound (b->get_path ());
+	      if (predicate.is_error ())
+		return &TraitReference::error_node ();
+
 	      specified_bounds.push_back (predicate);
 	      super_traits.push_back (predicate.get ());
 	    }
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index a1dd8052246..2b47c6738b5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -381,6 +381,19 @@ public:
     return querys_in_progress.find (id) != querys_in_progress.end ();
   }
 
+  void insert_trait_query (DefId id) { trait_queries_in_progress.insert (id); }
+
+  void trait_query_completed (DefId id)
+  {
+    trait_queries_in_progress.erase (id);
+  }
+
+  bool trait_query_in_progress (DefId id) const
+  {
+    return trait_queries_in_progress.find (id)
+	   != trait_queries_in_progress.end ();
+  }
+
 private:
   TypeCheckContext ();
 
@@ -418,6 +431,7 @@ private:
 
   // query context lookups
   std::set<HirId> querys_in_progress;
+  std::set<DefId> trait_queries_in_progress;
 };
 
 class TypeResolution
@@ -426,6 +440,21 @@ public:
   static void Resolve (HIR::Crate &crate);
 };
 
+class TraitQueryGuard
+{
+public:
+  TraitQueryGuard (DefId id) : id (id), ctx (*TypeCheckContext::get ())
+  {
+    ctx.insert_trait_query (id);
+  }
+
+  ~TraitQueryGuard () { ctx.trait_query_completed (id); }
+
+private:
+  DefId id;
+  TypeCheckContext &ctx;
+};
+
 } // namespace Resolver
 } // namespace Rust
 
diff --git a/gcc/testsuite/rust/compile/issue-1589.rs b/gcc/testsuite/rust/compile/issue-1589.rs
new file mode 100644
index 00000000000..79a5866e4af
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1589.rs
@@ -0,0 +1,5 @@
+pub trait A: B {}
+// { dg-error "trait cycle detected" "" { target *-*-* } .-1 }
+
+pub trait B: A {}
+// { dg-error "trait cycle detected" "" { target *-*-* } .-1 }
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 040/103] gccrs: ast: Refactor ASTFragment -> Fragment class
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (38 preceding siblings ...)
  2023-02-21 12:01 ` [committed 039/103] gccrs: Add check for recursive trait cycles arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 041/103] gccrs: rust: Replace uses of ASTFragment -> Fragment arthur.cohen
                   ` (62 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* Make-lang.in: Add `rust-ast-fragment.o` object file.
	* ast/rust-ast-fragment.cc: New file.
	* ast/rust-ast-fragment.h: New file.
---
 gcc/rust/Make-lang.in             |   1 +
 gcc/rust/ast/rust-ast-fragment.cc | 168 ++++++++++++++++++++++++++++++
 gcc/rust/ast/rust-ast-fragment.h  | 104 ++++++++++++++++++
 3 files changed, 273 insertions(+)
 create mode 100644 gcc/rust/ast/rust-ast-fragment.cc
 create mode 100644 gcc/rust/ast/rust-ast-fragment.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index a906516bd33..c5960530d0a 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -74,6 +74,7 @@ GRS_OBJS = \
     rust/rust-cfg-parser.o \
     rust/rust-parse.o \
     rust/rust-ast-full-test.o \
+    rust/rust-ast-fragment.o \
     rust/rust-ast-dump.o \
     rust/rust-hir-dump.o \
     rust/rust-session-manager.o \
diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc
new file mode 100644
index 00000000000..1a2dd99835a
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-fragment.cc
@@ -0,0 +1,168 @@
+// Copyright (C) 2020-2022 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-fragment.h"
+
+namespace Rust {
+namespace AST {
+
+Fragment::Fragment (std::vector<SingleASTNode> nodes, bool fragment_is_error)
+  : kind (fragment_is_error ? FragmentKind::Error : FragmentKind::Complete),
+    nodes (std::move (nodes))
+{
+  if (fragment_is_error)
+    rust_assert (nodes.empty ());
+}
+
+Fragment::Fragment (Fragment const &other) : kind (other.get_kind ())
+{
+  nodes.clear ();
+  nodes.reserve (other.nodes.size ());
+  for (auto &n : other.nodes)
+    {
+      nodes.push_back (n);
+    }
+}
+
+Fragment &
+Fragment::operator= (Fragment const &other)
+{
+  nodes.clear ();
+  nodes.reserve (other.nodes.size ());
+  kind = other.get_kind ();
+  for (auto &n : other.nodes)
+    {
+      nodes.push_back (n);
+    }
+
+  return *this;
+}
+
+Fragment
+Fragment::create_error ()
+{
+  return Fragment ({}, true);
+}
+
+std::vector<SingleASTNode> &
+Fragment::get_nodes ()
+{
+  return nodes;
+}
+
+FragmentKind
+Fragment::get_kind () const
+{
+  return kind;
+}
+
+bool
+Fragment::is_error () const
+{
+  return get_kind () == FragmentKind::Error;
+}
+
+bool
+Fragment::should_expand () const
+{
+  return !is_error ();
+}
+
+bool
+Fragment::is_expression_fragment () const
+{
+  return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION);
+}
+
+bool
+Fragment::is_type_fragment () const
+{
+  return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE);
+}
+
+std::unique_ptr<Expr>
+Fragment::take_expression_fragment ()
+{
+  assert_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+  return nodes[0].take_expr ();
+}
+
+std::unique_ptr<Type>
+Fragment::take_type_fragment ()
+{
+  assert_single_fragment (SingleASTNode::NodeType::TYPE);
+  return nodes[0].take_type ();
+}
+
+void
+Fragment::accept_vis (ASTVisitor &vis)
+{
+  for (auto &node : nodes)
+    node.accept_vis (vis);
+}
+
+bool
+Fragment::is_single_fragment () const
+{
+  return nodes.size () == 1;
+}
+
+bool
+Fragment::is_single_fragment_of_kind (SingleASTNode::NodeType 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::IMPL, "impl"},
+    {SingleASTNode::NodeType::ITEM, "item"},
+    {SingleASTNode::NodeType::TYPE, "type"},
+    {SingleASTNode::NodeType::EXPRESSION, "expr"},
+    {SingleASTNode::NodeType::STMT, "stmt"},
+    {SingleASTNode::NodeType::EXTERN, "extern"},
+    {SingleASTNode::NodeType::TRAIT, "trait"},
+    {SingleASTNode::NodeType::TRAIT_IMPL, "trait impl"},
+  };
+
+  auto actual = nodes[0].get_kind ();
+  auto fail = false;
+
+  if (!is_single_fragment ())
+    {
+      rust_error_at (Location (), "fragment is not single");
+      fail = true;
+    }
+
+  if (actual != expected)
+    {
+      rust_error_at (
+	Location (),
+	"invalid fragment operation: expected %qs node, got %qs node",
+	str_map.find (expected)->second,
+	str_map.find (nodes[0].get_kind ())->second);
+      fail = true;
+    }
+
+  rust_assert (!fail);
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h
new file mode 100644
index 00000000000..ee6ab0d8433
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-fragment.h
@@ -0,0 +1,104 @@
+// Copyright (C) 2020-2022 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_FRAGMENT_H
+#define RUST_AST_FRAGMENT_H
+
+#include "rust-ast.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+enum class FragmentKind
+{
+  /**
+   * If an AST Fragment still contains unexpanded tokens - this should only be
+   * used in the case of builtin macros which need to be expanded eagerly.
+   */
+  Unexpanded,
+  /**
+   * A completely expanded AST Fragment. This signifies that all
+   * `SingleASTNode`s in the `nodes` vector are valid.
+   *
+   * Note that this doesn't imply that the expansion is "done". One of the
+   * expanded nodes could very well be another macro invocation
+   */
+  Complete,
+  /**
+   * An error fragment.
+   */
+  Error,
+};
+
+/**
+ * An AST Fragment. Previously named `ASTFragment`.
+ *
+ * Basically, a "fragment" that can be incorporated into the AST, created as
+ * a result of macro expansion. Really annoying to work with due to the fact
+ * that macros can really expand to anything. As such, horrible representation
+ * at the moment.
+ */
+class Fragment
+{
+public:
+  Fragment (std::vector<SingleASTNode> nodes, bool fragment_is_error = false);
+  Fragment (Fragment const &other);
+  static Fragment create_error ();
+
+  Fragment &operator= (Fragment const &other);
+
+  FragmentKind get_kind () const;
+  std::vector<SingleASTNode> &get_nodes ();
+
+  bool is_error () const;
+  bool should_expand () const;
+
+  bool is_expression_fragment () const;
+  bool is_type_fragment () const;
+
+  std::unique_ptr<Expr> take_expression_fragment ();
+  std::unique_ptr<Type> take_type_fragment ();
+
+  void accept_vis (ASTVisitor &vis);
+
+private:
+  FragmentKind kind;
+
+  /**
+   * Basic idea: essentially, a vector of tagged unions of different AST node
+   * types. Now, this could actually be stored without a tagged union if the
+   * different AST node types had a unified parent, but that would create
+   * issues with the diamond problem or significant performance penalties. So
+   * a tagged union had to be used instead. A vector is used to represent the
+   * ability for a macro to expand to two statements, for instance.
+   */
+  std::vector<SingleASTNode> nodes;
+
+  /**
+   * We need to make a special case for Expression and Type fragments as only
+   * 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;
+};
+} // namespace AST
+} // namespace Rust
+
+#endif // !RUST_AST_FRAGMENT_H
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 041/103] gccrs: rust: Replace uses of ASTFragment -> Fragment
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (39 preceding siblings ...)
  2023-02-21 12:01 ` [committed 040/103] gccrs: ast: Refactor ASTFragment -> Fragment class arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 042/103] gccrs: ast: Improve Fragment API arthur.cohen
                   ` (61 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-ast.h (class ASTFragment): Remove old ASTFragment class.
	* ast/rust-macro.h (class MacroRulesDefinition): Use new Fragment API.
	* expand/rust-attribute-visitor.h: Likewise.
	* expand/rust-macro-builtins.cc (macro_end_token): Likewise.
	(MacroBuiltin::assert): Likewise.
	(MacroBuiltin::file): Likewise.
	(MacroBuiltin::column): Likewise.
	(MacroBuiltin::include_bytes): Likewise.
	(MacroBuiltin::include_str): Likewise.
	(MacroBuiltin::compile_error): Likewise.
	(MacroBuiltin::concat): Likewise.
	(MacroBuiltin::env): Likewise.
	(MacroBuiltin::cfg): Likewise.
	(MacroBuiltin::include): Likewise.
	(MacroBuiltin::line): Likewise.
	* expand/rust-macro-builtins.h: Likewise.
	* expand/rust-macro-expand.cc (MacroExpander::expand_decl_macro): Likewise.
	(MacroExpander::expand_invoc): Likewise.
	(MacroExpander::match_repetition): Likewise.
	(parse_many): Likewise.
	(transcribe_many_items): Likewise.
	(transcribe_many_ext): Likewise.
	(transcribe_many_trait_items): Likewise.
	(transcribe_many_impl_items): Likewise.
	(transcribe_many_trait_impl_items): Likewise.
	(transcribe_expression): Likewise.
	(transcribe_type): Likewise.
	(transcribe_on_delimiter): Likewise.
	(tokens_to_str): Likewise.
	* expand/rust-macro-expand.h (struct MacroExpander): Likewise.
	* util/rust-hir-map.cc (Mappings::insert_macro_def): Likewise.
---
 gcc/rust/ast/rust-ast.h                  | 132 -----------------------
 gcc/rust/ast/rust-macro.h                |  18 ++--
 gcc/rust/expand/rust-attribute-visitor.h |   4 +-
 gcc/rust/expand/rust-macro-builtins.cc   |  72 ++++++-------
 gcc/rust/expand/rust-macro-builtins.h    |  40 ++++---
 gcc/rust/expand/rust-macro-expand.cc     |  42 ++++----
 gcc/rust/expand/rust-macro-expand.h      |  23 ++--
 gcc/rust/util/rust-hir-map.cc            |   4 +-
 8 files changed, 100 insertions(+), 235 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index ccabccd6aff..3d602b1a379 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1858,138 +1858,6 @@ public:
   }
 };
 
-/* Basically, a "fragment" that can be incorporated into the AST, created as
- * a result of macro expansion. Really annoying to work with due to the fact
- * that macros can really expand to anything. As such, horrible representation
- * at the moment. */
-class ASTFragment
-{
-private:
-  /* basic idea: essentially, a vector of tagged unions of different AST node
-   * types. Now, this could actually be stored without a tagged union if the
-   * different AST node types had a unified parent, but that would create
-   * issues with the diamond problem or significant performance penalties. So
-   * a tagged union had to be used instead. A vector is used to represent the
-   * ability for a macro to expand to two statements, for instance. */
-
-  std::vector<SingleASTNode> nodes;
-  bool fragment_is_error;
-
-  /**
-   * We need to make a special case for Expression and Type fragments as only
-   * one Node will be extracted from the `nodes` vector
-   */
-
-  bool is_single_fragment () const { return nodes.size () == 1; }
-
-  bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const
-  {
-    return is_single_fragment () && nodes[0].get_kind () == expected;
-  }
-
-  void assert_single_fragment (SingleASTNode::NodeType expected) const
-  {
-    static const std::map<SingleASTNode::NodeType, const char *> str_map = {
-      {SingleASTNode::NodeType::IMPL, "impl"},
-      {SingleASTNode::NodeType::ITEM, "item"},
-      {SingleASTNode::NodeType::TYPE, "type"},
-      {SingleASTNode::NodeType::EXPRESSION, "expr"},
-      {SingleASTNode::NodeType::STMT, "stmt"},
-      {SingleASTNode::NodeType::EXTERN, "extern"},
-      {SingleASTNode::NodeType::TRAIT, "trait"},
-      {SingleASTNode::NodeType::TRAIT_IMPL, "trait impl"},
-    };
-
-    auto actual = nodes[0].get_kind ();
-    auto fail = false;
-
-    if (!is_single_fragment ())
-      {
-	rust_error_at (Location (), "fragment is not single");
-	fail = true;
-      }
-
-    if (actual != expected)
-      {
-	rust_error_at (
-	  Location (),
-	  "invalid fragment operation: expected %qs node, got %qs node",
-	  str_map.find (expected)->second,
-	  str_map.find (nodes[0].get_kind ())->second);
-	fail = true;
-      }
-
-    rust_assert (!fail);
-  }
-
-public:
-  ASTFragment (std::vector<SingleASTNode> nodes, bool fragment_is_error = false)
-    : nodes (std::move (nodes)), fragment_is_error (fragment_is_error)
-  {
-    if (fragment_is_error)
-      rust_assert (nodes.empty ());
-  }
-
-  ASTFragment (ASTFragment const &other)
-    : fragment_is_error (other.fragment_is_error)
-  {
-    nodes.clear ();
-    nodes.reserve (other.nodes.size ());
-    for (auto &n : other.nodes)
-      {
-	nodes.push_back (n);
-      }
-  }
-
-  ASTFragment &operator= (ASTFragment const &other)
-  {
-    fragment_is_error = other.fragment_is_error;
-    nodes.clear ();
-    nodes.reserve (other.nodes.size ());
-    for (auto &n : other.nodes)
-      {
-	nodes.push_back (n);
-      }
-
-    return *this;
-  }
-
-  static ASTFragment create_error () { return ASTFragment ({}, true); }
-
-  std::vector<SingleASTNode> &get_nodes () { return nodes; }
-  bool is_error () const { return fragment_is_error; }
-
-  bool should_expand () const { return !is_error (); }
-
-  bool is_expression_fragment () const
-  {
-    return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION);
-  }
-
-  bool is_type_fragment () const
-  {
-    return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE);
-  }
-
-  std::unique_ptr<Expr> take_expression_fragment ()
-  {
-    assert_single_fragment (SingleASTNode::NodeType::EXPRESSION);
-    return nodes[0].take_expr ();
-  }
-
-  std::unique_ptr<Type> take_type_fragment ()
-  {
-    assert_single_fragment (SingleASTNode::NodeType::TYPE);
-    return nodes[0].take_type ();
-  }
-
-  void accept_vis (ASTVisitor &vis)
-  {
-    for (auto &node : nodes)
-      node.accept_vis (vis);
-  }
-};
-
 // A crate AST object - holds all the data for a single compilation unit
 struct Crate
 {
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 798bc974fbb..fc4b5b82fb5 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -21,6 +21,7 @@
 
 #include "rust-system.h"
 #include "rust-ast.h"
+#include "rust-ast-fragment.h"
 #include "rust-location.h"
 
 namespace Rust {
@@ -456,8 +457,7 @@ class MacroRulesDefinition : public MacroItem
   std::vector<MacroRule> rules; // inlined form
   Location locus;
 
-  std::function<ASTFragment (Location, MacroInvocData &)>
-    associated_transcriber;
+  std::function<Fragment (Location, MacroInvocData &)> associated_transcriber;
   // Since we can't compare std::functions, we need to use an extra boolean
   bool is_builtin_rule;
 
@@ -468,10 +468,10 @@ class MacroRulesDefinition : public MacroItem
    * should make use of the actual rules. If the macro is builtin, then another
    * associated transcriber should be used
    */
-  static ASTFragment dummy_builtin (Location, MacroInvocData &)
+  static Fragment dummy_builtin (Location, MacroInvocData &)
   {
     gcc_unreachable ();
-    return ASTFragment::create_error ();
+    return Fragment::create_error ();
   }
 
   /* NOTE: in rustc, macro definitions are considered (and parsed as) a type
@@ -491,9 +491,9 @@ public:
       associated_transcriber (dummy_builtin), is_builtin_rule (false)
   {}
 
-  MacroRulesDefinition (Identifier builtin_name, DelimType delim_type,
-			std::function<ASTFragment (Location, MacroInvocData &)>
-			  associated_transcriber)
+  MacroRulesDefinition (
+    Identifier builtin_name, DelimType delim_type,
+    std::function<Fragment (Location, MacroInvocData &)> associated_transcriber)
     : outer_attrs (std::vector<Attribute> ()), rule_name (builtin_name),
       delim_type (delim_type), rules (std::vector<MacroRule> ()),
       locus (Location ()), associated_transcriber (associated_transcriber),
@@ -521,14 +521,14 @@ public:
   const std::vector<MacroRule> &get_rules () const { return rules; }
 
   bool is_builtin () const { return is_builtin_rule; }
-  const std::function<ASTFragment (Location, MacroInvocData &)> &
+  const std::function<Fragment (Location, MacroInvocData &)> &
   get_builtin_transcriber () const
   {
     rust_assert (is_builtin ());
     return associated_transcriber;
   }
   void set_builtin_transcriber (
-    std::function<ASTFragment (Location, MacroInvocData &)> transcriber)
+    std::function<Fragment (Location, MacroInvocData &)> transcriber)
   {
     associated_transcriber = transcriber;
     is_builtin_rule = true;
diff --git a/gcc/rust/expand/rust-attribute-visitor.h b/gcc/rust/expand/rust-attribute-visitor.h
index 80f9d4b4ded..6b562bd49b1 100644
--- a/gcc/rust/expand/rust-attribute-visitor.h
+++ b/gcc/rust/expand/rust-attribute-visitor.h
@@ -56,11 +56,11 @@ public:
    * @return Either the expanded fragment or an empty errored-out fragment
    * indicating an expansion failure.
    */
-  AST::ASTFragment expand_macro_fragment_recursive ()
+  AST::Fragment expand_macro_fragment_recursive ()
   {
     auto fragment = expander.take_expanded_fragment (*this);
     unsigned int original_depth = expander.expansion_depth;
-    auto final_fragment = AST::ASTFragment ({}, true);
+    auto final_fragment = AST::Fragment ({}, true);
 
     while (fragment.should_expand ())
       {
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index a230ad9f2d8..2a8a3f752f4 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -66,7 +66,7 @@ macro_end_token (AST::DelimTokenTree &invoc_token_tree,
 
 /* Expand and extract an expression from the macro */
 
-static inline AST::ASTFragment
+static inline AST::Fragment
 try_expand_macro_expression (AST::Expr *expr, MacroExpander *expander)
 {
   rust_assert (expander);
@@ -264,25 +264,25 @@ load_file_bytes (const char *filename)
 }
 } // namespace
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::assert (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   rust_debug ("assert!() called");
 
-  return AST::ASTFragment::create_error ();
+  return AST::Fragment::create_error ();
 }
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::file (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto current_file
     = Session::get_instance ().linemap->location_file (invoc_locus);
   auto file_str = AST::SingleASTNode (make_string (invoc_locus, current_file));
 
-  return AST::ASTFragment ({file_str});
+  return AST::Fragment ({file_str});
 }
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::column (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto current_column
@@ -292,14 +292,14 @@ MacroBuiltin::column (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::LiteralExpr (std::to_string (current_column), AST::Literal::INT,
 			  PrimitiveCoreType::CORETYPE_U32, {}, invoc_locus)));
 
-  return AST::ASTFragment ({column_no});
+  return AST::Fragment ({column_no});
 }
 
 /* Expand builtin macro include_bytes!("filename"), which includes the contents
    of the given file as reference to a byte array. Yields an expression of type
    &'static [u8; N].  */
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   /* Get target filename from the macro invocation, which is treated as a path
@@ -308,7 +308,7 @@ MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc)
     = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus,
 				   invoc.get_expander ());
   if (lit_expr == nullptr)
-    return AST::ASTFragment::create_error ();
+    return AST::Fragment::create_error ();
 
   std::string target_filename
     = source_relative_path (lit_expr->as_string (), invoc_locus);
@@ -335,14 +335,14 @@ MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::BorrowExpr (std::move (array), false, false, {}, invoc_locus));
 
   auto node = AST::SingleASTNode (std::move (borrow));
-  return AST::ASTFragment ({node});
+  return AST::Fragment ({node});
 }
 
 /* Expand builtin macro include_str!("filename"), which includes the contents
    of the given file as a string. The file must be UTF-8 encoded. Yields an
    expression of type &'static str.  */
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   /* Get target filename from the macro invocation, which is treated as a path
@@ -351,7 +351,7 @@ MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc)
     = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus,
 				   invoc.get_expander ());
   if (lit_expr == nullptr)
-    return AST::ASTFragment::create_error ();
+    return AST::Fragment::create_error ();
 
   std::string target_filename
     = source_relative_path (lit_expr->as_string (), invoc_locus);
@@ -362,30 +362,30 @@ MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc)
   std::string str ((const char *) &bytes[0], bytes.size ());
 
   auto node = AST::SingleASTNode (make_string (invoc_locus, str));
-  return AST::ASTFragment ({node});
+  return AST::Fragment ({node});
 }
 
 /* Expand builtin macro compile_error!("error"), which forces a compile error
    during the compile time. */
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::compile_error (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto lit_expr
     = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus,
 				   invoc.get_expander ());
   if (lit_expr == nullptr)
-    return AST::ASTFragment::create_error ();
+    return AST::Fragment::create_error ();
 
   std::string error_string = lit_expr->as_string ();
   rust_error_at (invoc_locus, "%s", error_string.c_str ());
 
-  return AST::ASTFragment::create_error ();
+  return AST::Fragment::create_error ();
 }
 
 /* Expand builtin macro concat!(), which joins all the literal parameters
    into a string with no delimiter. */
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto invoc_token_tree = invoc.get_delim_tok_tree ();
@@ -427,16 +427,16 @@ MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc)
   parser.skip_token (last_token_id);
 
   if (has_error)
-    return AST::ASTFragment::create_error ();
+    return AST::Fragment::create_error ();
 
   auto node = AST::SingleASTNode (make_string (invoc_locus, str));
-  return AST::ASTFragment ({node});
+  return AST::Fragment ({node});
 }
 
 /* Expand builtin macro env!(), which inspects an environment variable at
    compile time. */
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto invoc_token_tree = invoc.get_delim_tok_tree ();
@@ -451,11 +451,11 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
   auto expanded_expr = try_expand_many_expr (parser, invoc_locus, last_token_id,
 					     invoc.get_expander (), has_error);
   if (has_error)
-    return AST::ASTFragment::create_error ();
+    return AST::Fragment::create_error ();
   if (expanded_expr.size () < 1 || expanded_expr.size () > 2)
     {
       rust_error_at (invoc_locus, "env! takes 1 or 2 arguments");
-      return AST::ASTFragment::create_error ();
+      return AST::Fragment::create_error ();
     }
   if (expanded_expr.size () > 0)
     {
@@ -463,7 +463,7 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
 	    = try_extract_string_literal_from_fragment (invoc_locus,
 							expanded_expr[0])))
 	{
-	  return AST::ASTFragment::create_error ();
+	  return AST::Fragment::create_error ();
 	}
     }
   if (expanded_expr.size () > 1)
@@ -472,7 +472,7 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
 	    = try_extract_string_literal_from_fragment (invoc_locus,
 							expanded_expr[1])))
 	{
-	  return AST::ASTFragment::create_error ();
+	  return AST::Fragment::create_error ();
 	}
     }
 
@@ -487,14 +487,14 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
 		       lit_expr->as_string ().c_str ());
       else
 	rust_error_at (invoc_locus, "%s", error_expr->as_string ().c_str ());
-      return AST::ASTFragment::create_error ();
+      return AST::Fragment::create_error ();
     }
 
   auto node = AST::SingleASTNode (make_string (invoc_locus, env_value));
-  return AST::ASTFragment ({node});
+  return AST::Fragment ({node});
 }
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   // only parse if not already parsed
@@ -519,7 +519,7 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc)
   /* TODO: assuming that cfg! macros can only have one meta item inner, like cfg
    * attributes */
   if (invoc.get_meta_items ().size () != 1)
-    return AST::ASTFragment::create_error ();
+    return AST::Fragment::create_error ();
 
   bool result = invoc.get_meta_items ()[0]->check_cfg_predicate (
     Session::get_instance ());
@@ -527,13 +527,13 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::LiteralExpr (result ? "true" : "false", AST::Literal::BOOL,
 			  PrimitiveCoreType::CORETYPE_BOOL, {}, invoc_locus)));
 
-  return AST::ASTFragment ({literal_exp});
+  return AST::Fragment ({literal_exp});
 }
 
 /* Expand builtin macro include!(), which includes a source file at the current
  scope compile time. */
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   /* Get target filename from the macro invocation, which is treated as a path
@@ -542,7 +542,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
     = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus,
 				   invoc.get_expander ());
   if (lit_expr == nullptr)
-    return AST::ASTFragment::create_error ();
+    return AST::Fragment::create_error ();
 
   std::string filename
     = source_relative_path (lit_expr->as_string (), invoc_locus);
@@ -556,7 +556,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
     {
       rust_error_at (lit_expr->get_locus (),
 		     "cannot open included file %qs: %m", target_filename);
-      return AST::ASTFragment::create_error ();
+      return AST::Fragment::create_error ();
     }
 
   rust_debug ("Attempting to parse included file %s", target_filename);
@@ -574,7 +574,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
     {
       // inform the user that the errors above are from a included file
       rust_inform (invoc_locus, "included from here");
-      return AST::ASTFragment::create_error ();
+      return AST::Fragment::create_error ();
     }
 
   std::vector<AST::SingleASTNode> nodes{};
@@ -584,10 +584,10 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
       nodes.push_back (node);
     }
 
-  return AST::ASTFragment (nodes);
+  return AST::Fragment (nodes);
 }
 
-AST::ASTFragment
+AST::Fragment
 MacroBuiltin::line (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto current_line
@@ -597,7 +597,7 @@ MacroBuiltin::line (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::LiteralExpr (std::to_string (current_line), AST::Literal::INT,
 			  PrimitiveCoreType::CORETYPE_U32, {}, invoc_locus)));
 
-  return AST::ASTFragment ({line_no});
+  return AST::Fragment ({line_no});
 }
 
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h
index f1ea545ed21..c65bd940189 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -20,6 +20,7 @@
 #define RUST_MACRO_BUILTINS_H
 
 #include "rust-ast.h"
+#include "rust-ast-fragment.h"
 #include "rust-location.h"
 
 /**
@@ -61,6 +62,7 @@
 
 /* If assert is defined as a macro this file will not parse, so undefine this
    before continuing.  */
+// TODO: Rename all functions here `*_handler`
 #ifdef assert
 #undef assert
 #endif
@@ -69,38 +71,34 @@ namespace Rust {
 class MacroBuiltin
 {
 public:
-  static AST::ASTFragment assert (Location invoc_locus,
-				  AST::MacroInvocData &invoc);
-
-  static AST::ASTFragment file (Location invoc_locus,
-				AST::MacroInvocData &invoc);
+  static AST::Fragment assert (Location invoc_locus,
+			       AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment column (Location invoc_locus,
-				  AST::MacroInvocData &invoc);
+  static AST::Fragment file (Location invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment include_bytes (Location invoc_locus,
-					 AST::MacroInvocData &invoc);
+  static AST::Fragment column (Location invoc_locus,
+			       AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment include_str (Location invoc_locus,
-				       AST::MacroInvocData &invoc);
+  static AST::Fragment include_bytes (Location invoc_locus,
+				      AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment compile_error (Location invoc_locus,
-					 AST::MacroInvocData &invoc);
+  static AST::Fragment include_str (Location invoc_locus,
+				    AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment concat (Location invoc_locus,
-				  AST::MacroInvocData &invoc);
+  static AST::Fragment compile_error (Location invoc_locus,
+				      AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment env (Location invoc_locus,
+  static AST::Fragment concat (Location invoc_locus,
 			       AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment cfg (Location invoc_locus,
-			       AST::MacroInvocData &invoc);
+  static AST::Fragment env (Location invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment include (Location invoc_locus,
-				   AST::MacroInvocData &invoc);
+  static AST::Fragment cfg (Location invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::ASTFragment line (Location invoc_locus,
+  static AST::Fragment include (Location invoc_locus,
 				AST::MacroInvocData &invoc);
+
+  static AST::Fragment line (Location invoc_locus, AST::MacroInvocData &invoc);
 };
 } // namespace Rust
 
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index d94cd118700..0684a28787f 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -26,7 +26,7 @@
 #include "rust-early-name-resolver.h"
 
 namespace Rust {
-AST::ASTFragment
+AST::Fragment
 MacroExpander::expand_decl_macro (Location invoc_locus,
 				  AST::MacroInvocData &invoc,
 				  AST::MacroRulesDefinition &rules_def,
@@ -103,7 +103,7 @@ MacroExpander::expand_decl_macro (Location invoc_locus,
       RichLocation r (invoc_locus);
       r.add_range (rules_def.get_locus ());
       rust_error_at (r, "Failed to match any rule within macro");
-      return AST::ASTFragment::create_error ();
+      return AST::Fragment::create_error ();
     }
 
   return transcribe_rule (*matched_rule, invoc_token_tree, matched_fragments,
@@ -139,7 +139,7 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon)
   //      - else is unreachable
   //  - derive container macro - unreachable
 
-  auto fragment = AST::ASTFragment::create_error ();
+  auto fragment = AST::Fragment::create_error ();
   invoc_data.set_expander (this);
 
   // lookup the rules
@@ -707,7 +707,7 @@ MacroExpander::match_repetition (Parser<MacroInvocLexer> &parser,
 /**
  * Helper function to refactor calling a parsing function 0 or more times
  */
-static AST::ASTFragment
+static AST::Fragment
 parse_many (Parser<MacroInvocLexer> &parser, TokenId &delimiter,
 	    std::function<AST::SingleASTNode ()> parse_fn)
 {
@@ -723,13 +723,13 @@ parse_many (Parser<MacroInvocLexer> &parser, TokenId &delimiter,
 	  for (auto err : parser.get_errors ())
 	    err.emit_error ();
 
-	  return AST::ASTFragment::create_error ();
+	  return AST::Fragment::create_error ();
 	}
 
       nodes.emplace_back (std::move (node));
     }
 
-  return AST::ASTFragment (std::move (nodes));
+  return AST::Fragment (std::move (nodes));
 }
 
 /**
@@ -738,7 +738,7 @@ parse_many (Parser<MacroInvocLexer> &parser, TokenId &delimiter,
  * @param parser Parser to extract items from
  * @param delimiter Id of the token on which parsing should stop
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_many_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
 {
   return parse_many (parser, delimiter, [&parser] () {
@@ -753,7 +753,7 @@ transcribe_many_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
  * @param parser Parser to extract items from
  * @param delimiter Id of the token on which parsing should stop
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_many_ext (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
 {
   return parse_many (parser, delimiter, [&parser] () {
@@ -768,7 +768,7 @@ transcribe_many_ext (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
  * @param parser Parser to extract items from
  * @param delimiter Id of the token on which parsing should stop
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_many_trait_items (Parser<MacroInvocLexer> &parser,
 			     TokenId &delimiter)
 {
@@ -784,7 +784,7 @@ transcribe_many_trait_items (Parser<MacroInvocLexer> &parser,
  * @param parser Parser to extract items from
  * @param delimiter Id of the token on which parsing should stop
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_many_impl_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
 {
   return parse_many (parser, delimiter, [&parser] () {
@@ -799,7 +799,7 @@ transcribe_many_impl_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
  * @param parser Parser to extract items from
  * @param delimiter Id of the token on which parsing should stop
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_many_trait_impl_items (Parser<MacroInvocLexer> &parser,
 				  TokenId &delimiter)
 {
@@ -815,7 +815,7 @@ transcribe_many_trait_impl_items (Parser<MacroInvocLexer> &parser,
  * @param parser Parser to extract statements from
  * @param delimiter Id of the token on which parsing should stop
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_many_stmts (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
 {
   auto restrictions = ParseRestrictions ();
@@ -835,12 +835,12 @@ transcribe_many_stmts (Parser<MacroInvocLexer> &parser, TokenId &delimiter)
  *
  * @param parser Parser to extract statements from
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_expression (Parser<MacroInvocLexer> &parser)
 {
   auto expr = parser.parse_expr ();
 
-  return AST::ASTFragment ({std::move (expr)});
+  return AST::Fragment ({std::move (expr)});
 }
 
 /**
@@ -848,17 +848,17 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
  *
  * @param parser Parser to extract statements from
  */
-static AST::ASTFragment
+static AST::Fragment
 transcribe_type (Parser<MacroInvocLexer> &parser)
 {
   auto type = parser.parse_type (true);
   for (auto err : parser.get_errors ())
     err.emit_error ();
 
-  return AST::ASTFragment ({std::move (type)});
+  return AST::Fragment ({std::move (type)});
 }
 
-static AST::ASTFragment
+static AST::Fragment
 transcribe_on_delimiter (Parser<MacroInvocLexer> &parser, bool semicolon,
 			 AST::DelimType delimiter, TokenId last_token_id)
 {
@@ -868,7 +868,7 @@ transcribe_on_delimiter (Parser<MacroInvocLexer> &parser, bool semicolon,
     return transcribe_expression (parser);
 } // namespace Rust
 
-static AST::ASTFragment
+static AST::Fragment
 transcribe_context (MacroExpander::ContextType ctx,
 		    Parser<MacroInvocLexer> &parser, bool semicolon,
 		    AST::DelimType delimiter, TokenId last_token_id)
@@ -929,7 +929,7 @@ tokens_to_str (std::vector<std::unique_ptr<AST::Token>> &tokens)
   return str;
 }
 
-AST::ASTFragment
+AST::Fragment
 MacroExpander::transcribe_rule (
   AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree,
   std::map<std::string, MatchedFragmentContainer> &matched_fragments,
@@ -951,7 +951,7 @@ MacroExpander::transcribe_rule (
   rust_debug ("substituted tokens: %s",
 	      tokens_to_str (substituted_tokens).c_str ());
 
-  // parse it to an ASTFragment
+  // parse it to an Fragment
   MacroInvocLexer lex (std::move (substituted_tokens));
   Parser<MacroInvocLexer> parser (lex);
 
@@ -994,7 +994,7 @@ MacroExpander::transcribe_rule (
     {
       for (auto &err : parser.get_errors ())
 	rust_error_at (err.locus, "%s", err.message.c_str ());
-      return AST::ASTFragment::create_error ();
+      return AST::Fragment::create_error ();
     }
 
   // are all the tokens used?
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 187d79f9a28..b0c0c23a0c3 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -230,7 +230,7 @@ struct MacroExpander
   MacroExpander (AST::Crate &crate, ExpansionCfg cfg, Session &session)
     : cfg (cfg), crate (crate), session (session),
       sub_stack (SubstitutionScope ()),
-      expanded_fragment (AST::ASTFragment::create_error ()),
+      expanded_fragment (AST::Fragment::create_error ()),
       resolver (Resolver::Resolver::get ()),
       mappings (Analysis::Mappings::get ())
   {}
@@ -246,10 +246,9 @@ struct MacroExpander
   void expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon);
 
   // Expands a single declarative macro.
-  AST::ASTFragment expand_decl_macro (Location locus,
-				      AST::MacroInvocData &invoc,
-				      AST::MacroRulesDefinition &rules_def,
-				      bool semicolon);
+  AST::Fragment expand_decl_macro (Location locus, AST::MacroInvocData &invoc,
+				   AST::MacroRulesDefinition &rules_def,
+				   bool semicolon);
 
   void expand_cfg_attrs (AST::AttrVec &attrs);
   bool fails_cfg (const AST::AttrVec &attr) const;
@@ -260,7 +259,7 @@ struct MacroExpander
   bool try_match_rule (AST::MacroRule &match_rule,
 		       AST::DelimTokenTree &invoc_token_tree);
 
-  AST::ASTFragment transcribe_rule (
+  AST::Fragment transcribe_rule (
     AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree,
     std::map<std::string, MatchedFragmentContainer> &matched_fragments,
     bool semicolon, ContextType ctx);
@@ -314,16 +313,16 @@ struct MacroExpander
 
   ContextType peek_context () { return context.back (); }
 
-  void set_expanded_fragment (AST::ASTFragment &&fragment)
+  void set_expanded_fragment (AST::Fragment &&fragment)
   {
     expanded_fragment = std::move (fragment);
   }
 
-  AST::ASTFragment take_expanded_fragment (AST::ASTVisitor &vis)
+  AST::Fragment take_expanded_fragment (AST::ASTVisitor &vis)
   {
-    AST::ASTFragment old_fragment = std::move (expanded_fragment);
+    AST::Fragment old_fragment = std::move (expanded_fragment);
     auto accumulator = std::vector<AST::SingleASTNode> ();
-    expanded_fragment = AST::ASTFragment::create_error ();
+    expanded_fragment = AST::Fragment::create_error ();
     auto early_name_resolver = Resolver::EarlyNameResolver ();
 
     for (auto &node : old_fragment.get_nodes ())
@@ -345,7 +344,7 @@ struct MacroExpander
 	    auto new_nodes = expanded_fragment.get_nodes ();
 	    std::move (new_nodes.begin (), new_nodes.end (),
 		       std::back_inserter (accumulator));
-	    expanded_fragment = AST::ASTFragment (accumulator);
+	    expanded_fragment = AST::Fragment (accumulator);
 	  }
 	expansion_depth--;
       }
@@ -358,7 +357,7 @@ private:
   Session &session;
   SubstitutionScope sub_stack;
   std::vector<ContextType> context;
-  AST::ASTFragment expanded_fragment;
+  AST::Fragment expanded_fragment;
 
 public:
   Resolver::Resolver *resolver;
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 4aeb7f5ae18..bee0682e9b4 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -840,8 +840,8 @@ Mappings::iterate_trait_items (
 void
 Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
 {
-  static std::map<std::string, std::function<AST::ASTFragment (
-				 Location, AST::MacroInvocData &)>>
+  static std::map<
+    std::string, std::function<AST::Fragment (Location, AST::MacroInvocData &)>>
     builtin_macros = {
       {"assert", MacroBuiltin::assert},
       {"file", MacroBuiltin::file},
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 042/103] gccrs: ast: Improve Fragment API
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (40 preceding siblings ...)
  2023-02-21 12:01 ` [committed 041/103] gccrs: rust: Replace uses of ASTFragment -> Fragment arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 043/103] gccrs: Add missing fn_once_output langitem arthur.cohen
                   ` (60 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-fragment.cc (Fragment::Fragment): Add better APIs.
	(Fragment::complete): New function.
	(Fragment::unexpanded): New function.
	* ast/rust-ast-fragment.h: Declare new APIs and add documentation.
	* expand/rust-attribute-visitor.h: Use new Fragment API.
	* expand/rust-macro-builtins.cc (MacroBuiltin::file): Likewise.
	(MacroBuiltin::column): Likewise.
	(MacroBuiltin::include_bytes): Likewise.
	(MacroBuiltin::include_str): Likewise.
	(MacroBuiltin::concat): Likewise.
	(MacroBuiltin::env): Likewise.
	(MacroBuiltin::cfg): Likewise.
	(MacroBuiltin::include): Likewise.
	(MacroBuiltin::line): Likewise.
	* expand/rust-macro-expand.cc (parse_many): Likewise.
	(transcribe_expression): Likewise.
	(transcribe_type): Likewise.
	* expand/rust-macro-expand.h (struct MacroExpander): Likewise.
---
 gcc/rust/ast/rust-ast-fragment.cc        | 31 +++++++++++++-----------
 gcc/rust/ast/rust-ast-fragment.h         | 18 ++++++++++++--
 gcc/rust/expand/rust-attribute-visitor.h |  2 +-
 gcc/rust/expand/rust-macro-builtins.cc   | 18 +++++++-------
 gcc/rust/expand/rust-macro-expand.cc     |  6 ++---
 gcc/rust/expand/rust-macro-expand.h      |  2 +-
 6 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc
index 1a2dd99835a..c4916093fc6 100644
--- a/gcc/rust/ast/rust-ast-fragment.cc
+++ b/gcc/rust/ast/rust-ast-fragment.cc
@@ -21,22 +21,13 @@
 namespace Rust {
 namespace AST {
 
-Fragment::Fragment (std::vector<SingleASTNode> nodes, bool fragment_is_error)
-  : kind (fragment_is_error ? FragmentKind::Error : FragmentKind::Complete),
-    nodes (std::move (nodes))
-{
-  if (fragment_is_error)
-    rust_assert (nodes.empty ());
-}
+Fragment::Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes)
+  : kind (kind), nodes (std::move (nodes))
+{}
 
 Fragment::Fragment (Fragment const &other) : kind (other.get_kind ())
 {
-  nodes.clear ();
-  nodes.reserve (other.nodes.size ());
-  for (auto &n : other.nodes)
-    {
-      nodes.push_back (n);
-    }
+  *this = other;
 }
 
 Fragment &
@@ -56,7 +47,19 @@ Fragment::operator= (Fragment const &other)
 Fragment
 Fragment::create_error ()
 {
-  return Fragment ({}, true);
+  return Fragment (FragmentKind::Error, {});
+}
+
+Fragment
+Fragment::complete (std::vector<AST::SingleASTNode> nodes)
+{
+  return Fragment (FragmentKind::Complete, std::move (nodes));
+}
+
+Fragment
+Fragment::unexpanded ()
+{
+  return Fragment (FragmentKind::Unexpanded, {});
 }
 
 std::vector<SingleASTNode> &
diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h
index ee6ab0d8433..3ef4ba16dce 100644
--- a/gcc/rust/ast/rust-ast-fragment.h
+++ b/gcc/rust/ast/rust-ast-fragment.h
@@ -57,11 +57,23 @@ enum class FragmentKind
 class Fragment
 {
 public:
-  Fragment (std::vector<SingleASTNode> nodes, bool fragment_is_error = false);
   Fragment (Fragment const &other);
+  Fragment &operator= (Fragment const &other);
+
+  /**
+   * Create an error fragment
+   */
   static Fragment create_error ();
 
-  Fragment &operator= (Fragment const &other);
+  /**
+   * Create a complete AST fragment
+   */
+  static Fragment complete (std::vector<AST::SingleASTNode> nodes);
+
+  /**
+   * Create a fragment which contains unexpanded nodes
+   */
+  static Fragment unexpanded ();
 
   FragmentKind get_kind () const;
   std::vector<SingleASTNode> &get_nodes ();
@@ -78,6 +90,8 @@ public:
   void accept_vis (ASTVisitor &vis);
 
 private:
+  Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes);
+
   FragmentKind kind;
 
   /**
diff --git a/gcc/rust/expand/rust-attribute-visitor.h b/gcc/rust/expand/rust-attribute-visitor.h
index 6b562bd49b1..cbddc163da7 100644
--- a/gcc/rust/expand/rust-attribute-visitor.h
+++ b/gcc/rust/expand/rust-attribute-visitor.h
@@ -60,7 +60,7 @@ public:
   {
     auto fragment = expander.take_expanded_fragment (*this);
     unsigned int original_depth = expander.expansion_depth;
-    auto final_fragment = AST::Fragment ({}, true);
+    auto final_fragment = AST::Fragment::create_error ();
 
     while (fragment.should_expand ())
       {
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 2a8a3f752f4..a2129e84a46 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -279,7 +279,7 @@ MacroBuiltin::file (Location invoc_locus, AST::MacroInvocData &invoc)
     = Session::get_instance ().linemap->location_file (invoc_locus);
   auto file_str = AST::SingleASTNode (make_string (invoc_locus, current_file));
 
-  return AST::Fragment ({file_str});
+  return AST::Fragment::complete ({file_str});
 }
 
 AST::Fragment
@@ -292,7 +292,7 @@ MacroBuiltin::column (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::LiteralExpr (std::to_string (current_column), AST::Literal::INT,
 			  PrimitiveCoreType::CORETYPE_U32, {}, invoc_locus)));
 
-  return AST::Fragment ({column_no});
+  return AST::Fragment::complete ({column_no});
 }
 
 /* Expand builtin macro include_bytes!("filename"), which includes the contents
@@ -335,7 +335,7 @@ MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::BorrowExpr (std::move (array), false, false, {}, invoc_locus));
 
   auto node = AST::SingleASTNode (std::move (borrow));
-  return AST::Fragment ({node});
+  return AST::Fragment::complete ({node});
 }
 
 /* Expand builtin macro include_str!("filename"), which includes the contents
@@ -362,7 +362,7 @@ MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc)
   std::string str ((const char *) &bytes[0], bytes.size ());
 
   auto node = AST::SingleASTNode (make_string (invoc_locus, str));
-  return AST::Fragment ({node});
+  return AST::Fragment::complete ({node});
 }
 
 /* Expand builtin macro compile_error!("error"), which forces a compile error
@@ -430,7 +430,7 @@ MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc)
     return AST::Fragment::create_error ();
 
   auto node = AST::SingleASTNode (make_string (invoc_locus, str));
-  return AST::Fragment ({node});
+  return AST::Fragment::complete ({node});
 }
 
 /* Expand builtin macro env!(), which inspects an environment variable at
@@ -491,7 +491,7 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
     }
 
   auto node = AST::SingleASTNode (make_string (invoc_locus, env_value));
-  return AST::Fragment ({node});
+  return AST::Fragment::complete ({node});
 }
 
 AST::Fragment
@@ -527,7 +527,7 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::LiteralExpr (result ? "true" : "false", AST::Literal::BOOL,
 			  PrimitiveCoreType::CORETYPE_BOOL, {}, invoc_locus)));
 
-  return AST::Fragment ({literal_exp});
+  return AST::Fragment::complete ({literal_exp});
 }
 
 /* Expand builtin macro include!(), which includes a source file at the current
@@ -584,7 +584,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
       nodes.push_back (node);
     }
 
-  return AST::Fragment (nodes);
+  return AST::Fragment::complete (nodes);
 }
 
 AST::Fragment
@@ -597,7 +597,7 @@ MacroBuiltin::line (Location invoc_locus, AST::MacroInvocData &invoc)
     new AST::LiteralExpr (std::to_string (current_line), AST::Literal::INT,
 			  PrimitiveCoreType::CORETYPE_U32, {}, invoc_locus)));
 
-  return AST::Fragment ({line_no});
+  return AST::Fragment::complete ({line_no});
 }
 
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 0684a28787f..9c3523e0515 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -729,7 +729,7 @@ parse_many (Parser<MacroInvocLexer> &parser, TokenId &delimiter,
       nodes.emplace_back (std::move (node));
     }
 
-  return AST::Fragment (std::move (nodes));
+  return AST::Fragment::complete (std::move (nodes));
 }
 
 /**
@@ -840,7 +840,7 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
 {
   auto expr = parser.parse_expr ();
 
-  return AST::Fragment ({std::move (expr)});
+  return AST::Fragment::complete ({std::move (expr)});
 }
 
 /**
@@ -855,7 +855,7 @@ transcribe_type (Parser<MacroInvocLexer> &parser)
   for (auto err : parser.get_errors ())
     err.emit_error ();
 
-  return AST::Fragment ({std::move (type)});
+  return AST::Fragment::complete ({std::move (type)});
 }
 
 static AST::Fragment
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index b0c0c23a0c3..bf761c1b199 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -344,7 +344,7 @@ struct MacroExpander
 	    auto new_nodes = expanded_fragment.get_nodes ();
 	    std::move (new_nodes.begin (), new_nodes.end (),
 		       std::back_inserter (accumulator));
-	    expanded_fragment = AST::Fragment (accumulator);
+	    expanded_fragment = AST::Fragment::complete (accumulator);
 	  }
 	expansion_depth--;
       }
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 043/103] gccrs: Add missing fn_once_output langitem
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (41 preceding siblings ...)
  2023-02-21 12:01 ` [committed 042/103] gccrs: ast: Improve Fragment API arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 044/103] gccrs: Refactor expression hir lowering into cc file arthur.cohen
                   ` (59 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* util/rust-lang-item.h: Add handling for `fn_once_output`.
---
 gcc/rust/util/rust-lang-item.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index c7e0e5c811d..02eeaee60df 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -75,6 +75,7 @@ public:
 
     // functions
     FN_ONCE,
+    FN_ONCE_OUTPUT,
 
     UNKNOWN,
   };
@@ -225,6 +226,10 @@ public:
       {
 	return ItemType::FN_ONCE;
       }
+    else if (item.compare ("fn_once_output") == 0)
+      {
+	return ItemType::FN_ONCE_OUTPUT;
+      }
 
     return ItemType::UNKNOWN;
   }
@@ -305,6 +310,8 @@ public:
 	return "const_slice_ptr";
       case FN_ONCE:
 	return "fn_once";
+      case FN_ONCE_OUTPUT:
+	return "fn_once_output";
 
       case UNKNOWN:
 	return "<UNKNOWN>";
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 044/103] gccrs: Refactor expression hir lowering into cc file
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (42 preceding siblings ...)
  2023-02-21 12:01 ` [committed 043/103] gccrs: Add missing fn_once_output langitem arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 045/103] gccrs: Formatting cleanup in HIR lowering pattern arthur.cohen
                   ` (58 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* Make-lang.in: Add new object file for expression lowering.
	* ast/rust-expr.h: Move implementation of expr lowering to source file.
	* backend/rust-compile-block.h: Likewise.
	* backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
	* backend/rust-compile-expr.h: Likewise.
	* checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit): Likewise.
	* checks/errors/privacy/rust-privacy-reporter.h: Likewise.
	* checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
	* checks/errors/rust-const-checker.h: Likewise.
	* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise.
	* checks/errors/rust-unsafe-checker.h: Likewise.
	* hir/rust-ast-lower-base.h: Likewise.
	* hir/rust-ast-lower-expr.h (RUST_AST_LOWER_EXPR): Likewise.
	* hir/rust-ast-lower.cc (ASTLoweringBase::lower_closure_param): Likewise.
	* hir/rust-hir-dump.cc (Dump::visit): Likewise.
	* hir/rust-hir-dump.h: Likewise.
	* hir/tree/rust-hir-expr.h (class ClosureExpr): Likewise.
	(class ClosureExprInner): Likewise.
	(class ClosureExprInnerTyped): Likewise.
	* hir/tree/rust-hir-full-decls.h (class ClosureExprInner): Likewise.
	(class ClosureExprInnerTyped): Likewise.
	* hir/tree/rust-hir-full-test.cc (ClosureExprInnerTyped::as_string): Likewise.
	(ClosureExprInner::as_string): Likewise.
	(ClosureExprInner::accept_vis): Likewise.
	(ClosureExpr::accept_vis): Likewise.
	(ClosureExprInnerTyped::accept_vis): Likewise.
	* hir/tree/rust-hir-visitor.h: Likewise.
	* hir/tree/rust-hir.h (class Expr): Likewise.
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise.
	* typecheck/rust-hir-type-check-expr.h: Likewise.
	* hir/rust-ast-lower-expr.cc: New file.
---
 gcc/rust/Make-lang.in                         |   1 +
 gcc/rust/ast/rust-expr.h                      |   9 +-
 gcc/rust/backend/rust-compile-block.h         |   6 +-
 gcc/rust/backend/rust-compile-expr.cc         |   6 +
 gcc/rust/backend/rust-compile-expr.h          |   3 +-
 .../errors/privacy/rust-privacy-reporter.cc   |   8 +-
 .../errors/privacy/rust-privacy-reporter.h    |   3 +-
 gcc/rust/checks/errors/rust-const-checker.cc  |   6 +-
 gcc/rust/checks/errors/rust-const-checker.h   |   3 +-
 gcc/rust/checks/errors/rust-unsafe-checker.cc |   6 +-
 gcc/rust/checks/errors/rust-unsafe-checker.h  |   3 +-
 gcc/rust/hir/rust-ast-lower-base.h            |   2 +
 gcc/rust/hir/rust-ast-lower-expr.cc           | 810 ++++++++++++++++++
 gcc/rust/hir/rust-ast-lower-expr.h            | 746 +---------------
 gcc/rust/hir/rust-ast-lower.cc                |  23 +
 gcc/rust/hir/rust-hir-dump.cc                 |   6 +-
 gcc/rust/hir/rust-hir-dump.h                  |   3 +-
 gcc/rust/hir/tree/rust-hir-expr.h             | 213 ++---
 gcc/rust/hir/tree/rust-hir-full-decls.h       |   2 -
 gcc/rust/hir/tree/rust-hir-full-test.cc       |  37 +-
 gcc/rust/hir/tree/rust-hir-visitor.h          |   9 +-
 gcc/rust/hir/tree/rust-hir.h                  |   1 +
 .../typecheck/rust-hir-type-check-expr.cc     |   6 +
 gcc/rust/typecheck/rust-hir-type-check-expr.h |   3 +-
 24 files changed, 1009 insertions(+), 906 deletions(-)
 create mode 100644 gcc/rust/hir/rust-ast-lower-expr.cc

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index c5960530d0a..2f4f409f54f 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -94,6 +94,7 @@ GRS_OBJS = \
     rust/rust-ast-lower-base.o \
     rust/rust-ast-lower-pattern.o \
     rust/rust-ast-lower-item.o \
+    rust/rust-ast-lower-expr.o \
     rust/rust-early-name-resolver.o \
     rust/rust-name-resolver.o \
     rust/rust-ast-resolve.o \
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index c764f9c4c66..c58fae5e564 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -2134,8 +2134,6 @@ struct ClosureParam
 private:
   std::vector<Attribute> outer_attrs;
   std::unique_ptr<Pattern> pattern;
-
-  // bool has_type_given;
   std::unique_ptr<Type> type;
   Location locus;
 
@@ -2202,19 +2200,19 @@ public:
   const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
   std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
 
-  // TODO: is this better? Or is a "vis_block" better?
   std::unique_ptr<Pattern> &get_pattern ()
   {
     rust_assert (pattern != nullptr);
     return pattern;
   }
 
-  // TODO: is this better? Or is a "vis_block" better?
   std::unique_ptr<Type> &get_type ()
   {
     rust_assert (has_type_given ());
     return type;
   }
+
+  Location get_locus () const { return locus; }
 };
 
 // Base closure definition expression AST node - abstract
@@ -2248,6 +2246,8 @@ public:
   {
     outer_attrs = std::move (new_attrs);
   }
+
+  bool get_has_move () const { return has_move; }
 };
 
 // Represents a non-type-specified closure expression AST node
@@ -2307,7 +2307,6 @@ public:
     return closure_inner == nullptr;
   }
 
-  // TODO: is this better? Or is a "vis_block" better?
   std::unique_ptr<Expr> &get_definition_expr ()
   {
     rust_assert (closure_inner != nullptr);
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index bcb7e77fc6d..0ccf81f376b 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -57,8 +57,7 @@ public:
   // Empty visit for unused Expression HIR nodes.
   void visit (HIR::PathInExpression &) override {}
   void visit (HIR::QualifiedPathInExpression &) override {}
-  void visit (HIR::ClosureExprInner &) override {}
-  void visit (HIR::ClosureExprInnerTyped &) override {}
+  void visit (HIR::ClosureExpr &) override {}
   void visit (HIR::StructExprFieldIdentifier &) override {}
   void visit (HIR::StructExprFieldIdentifierValue &) override {}
   void visit (HIR::StructExprFieldIndexValue &) override {}
@@ -146,8 +145,7 @@ public:
   // Empty visit for unused Expression HIR nodes.
   void visit (HIR::PathInExpression &) override {}
   void visit (HIR::QualifiedPathInExpression &) override {}
-  void visit (HIR::ClosureExprInner &) override {}
-  void visit (HIR::ClosureExprInnerTyped &) override {}
+  void visit (HIR::ClosureExpr &) override {}
   void visit (HIR::StructExprFieldIdentifier &) override {}
   void visit (HIR::StructExprFieldIdentifierValue &) override {}
   void visit (HIR::StructExprFieldIndexValue &) override {}
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index ddf914f6736..724a93a68bd 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2803,5 +2803,11 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
 						   expr.get_locus ());
 }
 
+void
+CompileExpr::visit (HIR::ClosureExpr &expr)
+{
+  gcc_unreachable ();
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 845511f9f43..7fc3f5e7f4d 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -67,10 +67,9 @@ public:
   void visit (HIR::RangeToExpr &expr) override;
   void visit (HIR::RangeFullExpr &expr) override;
   void visit (HIR::RangeFromToInclExpr &expr) override;
+  void visit (HIR::ClosureExpr &expr) override;
 
   // TODO
-  void visit (HIR::ClosureExprInner &) override {}
-  void visit (HIR::ClosureExprInnerTyped &) override {}
   void visit (HIR::ErrorPropagationExpr &) override {}
   void visit (HIR::RangeToInclExpr &) override {}
   void visit (HIR::ForLoopExpr &) override {}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index e5afe817801..a126e7b4462 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -426,7 +426,7 @@ PrivacyReporter::visit (HIR::FieldAccessExpr &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::ClosureExprInner &expr)
+PrivacyReporter::visit (HIR::ClosureExpr &expr)
 {
   // Not handled yet
 }
@@ -442,12 +442,6 @@ PrivacyReporter::visit (HIR::BlockExpr &expr)
     last_expr->accept_vis (*this);
 }
 
-void
-PrivacyReporter::visit (HIR::ClosureExprInnerTyped &expr)
-{
-  // Not handled yet
-}
-
 void
 PrivacyReporter::visit (HIR::ContinueExpr &expr)
 {}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index 98f7a9419b2..c9307787e9e 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -83,8 +83,7 @@ types
 
   virtual void visit (HIR::QualifiedPathInExpression &expr);
   virtual void visit (HIR::PathInExpression &expr);
-  virtual void visit (HIR::ClosureExprInnerTyped &);
-  virtual void visit (HIR::ClosureExprInner &expr);
+  virtual void visit (HIR::ClosureExpr &expr);
   virtual void visit (HIR::StructExprStructFields &);
   virtual void visit (HIR::StructExprStruct &);
   virtual void visit (HIR::LiteralExpr &expr);
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 2fa9614abf1..01dc2620767 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -382,7 +382,7 @@ ConstChecker::visit (FieldAccessExpr &expr)
 }
 
 void
-ConstChecker::visit (ClosureExprInner &expr)
+ConstChecker::visit (ClosureExpr &expr)
 {}
 
 void
@@ -395,10 +395,6 @@ ConstChecker::visit (BlockExpr &expr)
     expr.get_final_expr ()->accept_vis (*this);
 }
 
-void
-ConstChecker::visit (ClosureExprInnerTyped &expr)
-{}
-
 void
 ConstChecker::visit (ContinueExpr &expr)
 {}
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
index 13cf44b1273..238173874aa 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -111,9 +111,8 @@ private:
   virtual void visit (CallExpr &expr) override;
   virtual void visit (MethodCallExpr &expr) override;
   virtual void visit (FieldAccessExpr &expr) override;
-  virtual void visit (ClosureExprInner &expr) override;
+  virtual void visit (ClosureExpr &expr) override;
   virtual void visit (BlockExpr &expr) override;
-  virtual void visit (ClosureExprInnerTyped &expr) override;
   virtual void visit (ContinueExpr &expr) override;
   virtual void visit (BreakExpr &expr) override;
   virtual void visit (RangeFromToExpr &expr) override;
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index bb85fa77dc7..02868794cbc 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -453,7 +453,7 @@ UnsafeChecker::visit (FieldAccessExpr &expr)
 }
 
 void
-UnsafeChecker::visit (ClosureExprInner &expr)
+UnsafeChecker::visit (ClosureExpr &expr)
 {}
 
 void
@@ -466,10 +466,6 @@ UnsafeChecker::visit (BlockExpr &expr)
     expr.get_final_expr ()->accept_vis (*this);
 }
 
-void
-UnsafeChecker::visit (ClosureExprInnerTyped &expr)
-{}
-
 void
 UnsafeChecker::visit (ContinueExpr &expr)
 {}
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 39c3b229ccc..9df44db06a9 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -88,9 +88,8 @@ private:
   virtual void visit (CallExpr &expr) override;
   virtual void visit (MethodCallExpr &expr) override;
   virtual void visit (FieldAccessExpr &expr) override;
-  virtual void visit (ClosureExprInner &expr) override;
+  virtual void visit (ClosureExpr &expr) override;
   virtual void visit (BlockExpr &expr) override;
-  virtual void visit (ClosureExprInnerTyped &expr) override;
   virtual void visit (ContinueExpr &expr) override;
   virtual void visit (BreakExpr &expr) override;
   virtual void visit (RangeFromToExpr &expr) override;
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index adcbc5d2f69..1af44aa239f 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -313,6 +313,8 @@ protected:
   HIR::Literal lower_literal (const AST::Literal &literal);
 
   HIR::ExternBlock *lower_extern_block (AST::ExternBlock &extern_block);
+
+  HIR::ClosureParam lower_closure_param (AST::ClosureParam &param);
 };
 
 } // namespace HIR
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc
new file mode 100644
index 00000000000..df4ba9d2911
--- /dev/null
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -0,0 +1,810 @@
+// Copyright (C) 2020-2022 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-lower-expr.h"
+#include "rust-ast-lower-base.h"
+#include "rust-ast-lower-block.h"
+#include "rust-ast-lower-struct-field-expr.h"
+#include "rust-ast-lower-pattern.h"
+#include "rust-ast-lower-type.h"
+
+namespace Rust {
+namespace HIR {
+
+ASTLoweringExpr::ASTLoweringExpr ()
+  : ASTLoweringBase (), translated (nullptr), translated_array_elems (nullptr),
+    terminated (false)
+{}
+
+HIR::Expr *
+ASTLoweringExpr::translate (AST::Expr *expr, bool *terminated)
+{
+  ASTLoweringExpr resolver;
+  expr->accept_vis (resolver);
+  if (resolver.translated == nullptr)
+    {
+      rust_fatal_error (expr->get_locus (), "Failed to lower expr: [%s]",
+			expr->as_string ().c_str ());
+      return nullptr;
+    }
+
+  resolver.mappings->insert_hir_expr (resolver.translated);
+  resolver.mappings->insert_location (
+    resolver.translated->get_mappings ().get_hirid (), expr->get_locus ());
+
+  if (terminated != nullptr)
+    *terminated = resolver.terminated;
+
+  return resolver.translated;
+}
+
+void
+ASTLoweringExpr::visit (AST::TupleIndexExpr &expr)
+{
+  HIR::Expr *tuple_expr
+    = ASTLoweringExpr::translate (expr.get_tuple_expr ().get (), &terminated);
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::TupleIndexExpr (mapping, std::unique_ptr<HIR::Expr> (tuple_expr),
+			       expr.get_tuple_index (), expr.get_outer_attrs (),
+			       expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::TupleExpr &expr)
+{
+  std::vector<std::unique_ptr<HIR::Expr> > tuple_elements;
+  for (auto &e : expr.get_tuple_elems ())
+    {
+      HIR::Expr *t = ASTLoweringExpr::translate (e.get ());
+      tuple_elements.push_back (std::unique_ptr<HIR::Expr> (t));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::TupleExpr (std::move (mapping), std::move (tuple_elements),
+			  expr.get_inner_attrs (), expr.get_outer_attrs (),
+			  expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::IfExpr &expr)
+{
+  translated = ASTLoweringIfBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::IfExprConseqElse &expr)
+{
+  translated = ASTLoweringIfBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::IfExprConseqIf &expr)
+{
+  translated = ASTLoweringIfBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::BlockExpr &expr)
+{
+  translated = ASTLoweringBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::UnsafeBlockExpr &expr)
+{
+  translated = ASTLoweringBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::PathInExpression &expr)
+{
+  translated = ASTLowerPathInExpression::translate (&expr);
+}
+
+void
+ASTLoweringExpr::visit (AST::QualifiedPathInExpression &expr)
+{
+  translated = ASTLowerQualPathInExpression::translate (&expr);
+}
+
+void
+ASTLoweringExpr::visit (AST::ReturnExpr &expr)
+{
+  terminated = true;
+  HIR::Expr *return_expr
+    = expr.has_returned_expr ()
+	? ASTLoweringExpr::translate (expr.get_returned_expr ().get ())
+	: nullptr;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::ReturnExpr (mapping, expr.get_locus (),
+				    std::unique_ptr<HIR::Expr> (return_expr));
+}
+
+void
+ASTLoweringExpr::visit (AST::CallExpr &expr)
+{
+  HIR::Expr *func
+    = ASTLoweringExpr::translate (expr.get_function_expr ().get ());
+
+  auto const &in_params = expr.get_params ();
+  std::vector<std::unique_ptr<HIR::Expr> > params;
+  for (auto &param : in_params)
+    {
+      auto trans = ASTLoweringExpr::translate (param.get ());
+      params.push_back (std::unique_ptr<HIR::Expr> (trans));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (
+    crate_num, UNKNOWN_NODEID /* this can map back to the AST*/,
+    mappings->get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::CallExpr (mapping, std::unique_ptr<HIR::Expr> (func),
+				  std::move (params), expr.get_outer_attrs (),
+				  expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::MethodCallExpr &expr)
+{
+  HIR::PathExprSegment method_path
+    = lower_path_expr_seg (expr.get_method_name ());
+
+  HIR::Expr *receiver
+    = ASTLoweringExpr::translate (expr.get_receiver_expr ().get ());
+
+  auto const &in_params = expr.get_params ();
+  std::vector<std::unique_ptr<HIR::Expr> > params;
+  for (auto &param : in_params)
+    {
+      auto trans = ASTLoweringExpr::translate (param.get ());
+      params.push_back (std::unique_ptr<HIR::Expr> (trans));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::MethodCallExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
+			       method_path, std::move (params),
+			       expr.get_outer_attrs (), expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::AssignmentExpr &expr)
+{
+  HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
+  HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::AssignmentExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
+			       std::unique_ptr<HIR::Expr> (rhs),
+			       expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::IdentifierExpr &expr)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping1 (crate_num, expr.get_node_id (),
+				  mappings->get_next_hir_id (crate_num),
+				  UNKNOWN_LOCAL_DEFID);
+  Analysis::NodeMapping mapping2 (mapping1);
+
+  HIR::PathIdentSegment ident_seg (expr.get_ident ());
+  HIR::PathExprSegment seg (mapping1, ident_seg, expr.get_locus (),
+			    HIR::GenericArgs::create_empty ());
+  translated = new HIR::PathInExpression (mapping2, {seg}, expr.get_locus (),
+					  false, expr.get_outer_attrs ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ArrayExpr &expr)
+{
+  expr.get_array_elems ()->accept_vis (*this);
+  rust_assert (translated_array_elems != nullptr);
+  HIR::ArrayElems *elems = translated_array_elems;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::ArrayExpr (mapping, std::unique_ptr<HIR::ArrayElems> (elems),
+			  expr.get_inner_attrs (), expr.get_outer_attrs (),
+			  expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ArrayIndexExpr &expr)
+{
+  HIR::Expr *array_expr
+    = ASTLoweringExpr::translate (expr.get_array_expr ().get ());
+  HIR::Expr *array_index_expr
+    = ASTLoweringExpr::translate (expr.get_index_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::ArrayIndexExpr (mapping, std::unique_ptr<HIR::Expr> (array_expr),
+			       std::unique_ptr<HIR::Expr> (array_index_expr),
+			       expr.get_outer_attrs (), expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ArrayElemsValues &elems)
+{
+  std::vector<std::unique_ptr<HIR::Expr> > elements;
+  for (auto &elem : elems.get_values ())
+    {
+      HIR::Expr *translated_elem = ASTLoweringExpr::translate (elem.get ());
+      elements.push_back (std::unique_ptr<HIR::Expr> (translated_elem));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (mappings->get_current_crate (),
+				 elems.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated_array_elems
+    = new HIR::ArrayElemsValues (mapping, std::move (elements));
+}
+
+void
+ASTLoweringExpr::visit (AST::ArrayElemsCopied &elems)
+{
+  HIR::Expr *element
+    = ASTLoweringExpr::translate (elems.get_elem_to_copy ().get ());
+  HIR::Expr *num_copies
+    = ASTLoweringExpr::translate (elems.get_num_copies ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (mappings->get_current_crate (),
+				 elems.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated_array_elems
+    = new HIR::ArrayElemsCopied (mapping, std::unique_ptr<HIR::Expr> (element),
+				 std::unique_ptr<HIR::Expr> (num_copies));
+}
+
+void
+ASTLoweringExpr::visit (AST::LiteralExpr &expr)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::Literal l = lower_literal (expr.get_literal ());
+  translated = new HIR::LiteralExpr (mapping, std::move (l), expr.get_locus (),
+				     expr.get_outer_attrs ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ArithmeticOrLogicalExpr &expr)
+{
+  HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
+  rust_assert (lhs != nullptr);
+  HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
+  rust_assert (rhs != nullptr);
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::ArithmeticOrLogicalExpr (
+    mapping, std::unique_ptr<HIR::Expr> (lhs), std::unique_ptr<HIR::Expr> (rhs),
+    expr.get_expr_type (), expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ComparisonExpr &expr)
+{
+  HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
+  rust_assert (lhs != nullptr);
+  HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
+  rust_assert (rhs != nullptr);
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::ComparisonExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
+			       std::unique_ptr<HIR::Expr> (rhs),
+			       expr.get_expr_type (), expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::LazyBooleanExpr &expr)
+{
+  HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
+  rust_assert (lhs != nullptr);
+  HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
+  rust_assert (rhs != nullptr);
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::LazyBooleanExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
+				std::unique_ptr<HIR::Expr> (rhs),
+				expr.get_expr_type (), expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::NegationExpr &expr)
+{
+  HIR::Expr *negated_value
+    = ASTLoweringExpr::translate (expr.get_negated_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+  translated
+    = new HIR::NegationExpr (mapping,
+			     std::unique_ptr<HIR::Expr> (negated_value),
+			     expr.get_expr_type (), expr.get_outer_attrs (),
+			     expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::TypeCastExpr &expr)
+{
+  HIR::Expr *expr_to_cast_to
+    = ASTLoweringExpr::translate (expr.get_casted_expr ().get ());
+  HIR::Type *type_to_cast_to
+    = lower_type_no_bounds (expr.get_type_to_cast_to ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::TypeCastExpr (mapping,
+			     std::unique_ptr<HIR::Expr> (expr_to_cast_to),
+			     std::unique_ptr<HIR::Type> (type_to_cast_to),
+			     expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::CompoundAssignmentExpr &expr)
+{
+  ArithmeticOrLogicalOperator op;
+  switch (expr.get_expr_type ())
+    {
+    case CompoundAssignmentOperator::ADD:
+      op = ArithmeticOrLogicalOperator::ADD;
+      break;
+    case CompoundAssignmentOperator::SUBTRACT:
+      op = ArithmeticOrLogicalOperator::SUBTRACT;
+      break;
+    case CompoundAssignmentOperator::MULTIPLY:
+      op = ArithmeticOrLogicalOperator::MULTIPLY;
+      break;
+    case CompoundAssignmentOperator::DIVIDE:
+      op = ArithmeticOrLogicalOperator::DIVIDE;
+      break;
+    case CompoundAssignmentOperator::MODULUS:
+      op = ArithmeticOrLogicalOperator::MODULUS;
+      break;
+    case CompoundAssignmentOperator::BITWISE_AND:
+      op = ArithmeticOrLogicalOperator::BITWISE_AND;
+      break;
+    case CompoundAssignmentOperator::BITWISE_OR:
+      op = ArithmeticOrLogicalOperator::BITWISE_OR;
+      break;
+    case CompoundAssignmentOperator::BITWISE_XOR:
+      op = ArithmeticOrLogicalOperator::BITWISE_XOR;
+      break;
+    case CompoundAssignmentOperator::LEFT_SHIFT:
+      op = ArithmeticOrLogicalOperator::LEFT_SHIFT;
+      break;
+    case CompoundAssignmentOperator::RIGHT_SHIFT:
+      op = ArithmeticOrLogicalOperator::RIGHT_SHIFT;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  HIR::Expr *asignee_expr
+    = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
+  HIR::Expr *value = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::CompoundAssignmentExpr (
+    mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
+    std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::StructExprStruct &struct_expr)
+{
+  HIR::PathInExpression *path
+    = ASTLowerPathInExpression::translate (&struct_expr.get_struct_name ());
+  HIR::PathInExpression copied_path (*path);
+  delete path;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::StructExprStruct (mapping, copied_path,
+					  struct_expr.get_inner_attrs (),
+					  struct_expr.get_outer_attrs (),
+					  struct_expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::StructExprStructFields &struct_expr)
+{
+  // bit of a hack for now
+  HIR::PathInExpression *path
+    = ASTLowerPathInExpression::translate (&struct_expr.get_struct_name ());
+  HIR::PathInExpression copied_path (*path);
+  delete path;
+
+  HIR::StructBase *base = nullptr;
+  if (struct_expr.has_struct_base ())
+    {
+      HIR::Expr *translated_base = ASTLoweringExpr::translate (
+	struct_expr.get_struct_base ().get_base_struct ().get ());
+      base = new HIR::StructBase (std::unique_ptr<HIR::Expr> (translated_base));
+    }
+
+  auto const &in_fields = struct_expr.get_fields ();
+  std::vector<std::unique_ptr<HIR::StructExprField> > fields;
+  for (auto &field : in_fields)
+    {
+      HIR::StructExprField *translated
+	= ASTLowerStructExprField::translate (field.get ());
+      fields.push_back (std::unique_ptr<HIR::StructExprField> (translated));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::StructExprStructFields (mapping, copied_path, std::move (fields),
+				       struct_expr.get_locus (), base,
+				       struct_expr.get_inner_attrs (),
+				       struct_expr.get_outer_attrs ());
+}
+
+void
+ASTLoweringExpr::visit (AST::GroupedExpr &expr)
+{
+  HIR::Expr *paren_expr
+    = ASTLoweringExpr::translate (expr.get_expr_in_parens ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::GroupedExpr (mapping, std::unique_ptr<HIR::Expr> (paren_expr),
+			    expr.get_inner_attrs (), expr.get_outer_attrs (),
+			    expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::FieldAccessExpr &expr)
+{
+  HIR::Expr *receiver
+    = ASTLoweringExpr::translate (expr.get_receiver_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+  translated
+    = new HIR::FieldAccessExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
+				expr.get_field_name (), expr.get_outer_attrs (),
+				expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::LoopExpr &expr)
+{
+  translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::WhileLoopExpr &expr)
+{
+  translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::ForLoopExpr &expr)
+{
+  translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::BreakExpr &expr)
+{
+  HIR::Lifetime break_label = lower_lifetime (expr.get_label ());
+  HIR::Expr *break_expr
+    = expr.has_break_expr ()
+	? ASTLoweringExpr::translate (expr.get_break_expr ().get ())
+	: nullptr;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::BreakExpr (mapping, expr.get_locus (), std ::move (break_label),
+			  std::unique_ptr<HIR::Expr> (break_expr),
+			  expr.get_outer_attrs ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ContinueExpr &expr)
+{
+  HIR::Lifetime break_label = lower_lifetime (expr.get_label ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::ContinueExpr (mapping, expr.get_locus (),
+			     std ::move (break_label), expr.get_outer_attrs ());
+}
+
+void
+ASTLoweringExpr::visit (AST::BorrowExpr &expr)
+{
+  HIR::Expr *borrow_lvalue
+    = ASTLoweringExpr::translate (expr.get_borrowed_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::BorrowExpr *borrow_expr
+    = new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue),
+			   expr.get_is_mut () ? Mutability::Mut
+					      : Mutability::Imm,
+			   expr.get_outer_attrs (), expr.get_locus ());
+
+  if (expr.get_is_double_borrow ())
+    {
+      NodeId artifical_bouble_borrow_id = mappings->get_next_node_id ();
+      Analysis::NodeMapping mapping (crate_num, artifical_bouble_borrow_id,
+				     mappings->get_next_hir_id (crate_num),
+				     UNKNOWN_LOCAL_DEFID);
+
+      borrow_expr
+	= new HIR::BorrowExpr (mapping,
+			       std::unique_ptr<HIR::Expr> (borrow_expr),
+			       expr.get_is_mut () ? Mutability::Mut
+						  : Mutability::Imm,
+			       expr.get_outer_attrs (), expr.get_locus ());
+    }
+
+  translated = borrow_expr;
+}
+
+void
+ASTLoweringExpr::visit (AST::DereferenceExpr &expr)
+{
+  HIR::Expr *dref_lvalue
+    = ASTLoweringExpr::translate (expr.get_dereferenced_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::DereferenceExpr (mapping,
+				std::unique_ptr<HIR::Expr> (dref_lvalue),
+				expr.get_outer_attrs (), expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::MatchExpr &expr)
+{
+  translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
+}
+
+void
+ASTLoweringExpr::visit (AST::RangeFromToExpr &expr)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::Expr *range_from
+    = ASTLoweringExpr::translate (expr.get_from_expr ().get ());
+  HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ().get ());
+
+  translated
+    = new HIR::RangeFromToExpr (mapping,
+				std::unique_ptr<HIR::Expr> (range_from),
+				std::unique_ptr<HIR::Expr> (range_to),
+				expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::RangeFromExpr &expr)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::Expr *range_from
+    = ASTLoweringExpr::translate (expr.get_from_expr ().get ());
+
+  translated
+    = new HIR::RangeFromExpr (mapping, std::unique_ptr<HIR::Expr> (range_from),
+			      expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::RangeToExpr &expr)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ().get ());
+
+  translated
+    = new HIR::RangeToExpr (mapping, std::unique_ptr<HIR::Expr> (range_to),
+			    expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::RangeFullExpr &expr)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::RangeFullExpr (mapping, expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::RangeFromToInclExpr &expr)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::Expr *range_from
+    = ASTLoweringExpr::translate (expr.get_from_expr ().get ());
+  HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ().get ());
+
+  translated
+    = new HIR::RangeFromToInclExpr (mapping,
+				    std::unique_ptr<HIR::Expr> (range_from),
+				    std::unique_ptr<HIR::Expr> (range_to),
+				    expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ClosureExprInner &expr)
+{
+  HIR::Expr *closure_expr
+    = ASTLoweringExpr::translate (expr.get_definition_expr ().get ());
+
+  std::vector<HIR::ClosureParam> closure_params;
+  for (auto &param : expr.get_params ())
+    {
+      HIR::ClosureParam p = lower_closure_param (param);
+      closure_params.push_back (std::move (p));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  translated
+    = new HIR::ClosureExpr (mapping, std::move (closure_params),
+			    nullptr /* closure_return_type */,
+			    std::unique_ptr<HIR::Expr> (closure_expr),
+			    expr.get_has_move (), expr.get_outer_attrs (),
+			    expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
+{
+  HIR::Type *closure_return_type = nullptr;
+  HIR::Expr *closure_expr
+    = ASTLoweringExpr::translate (expr.get_definition_block ().get ());
+
+  std::vector<HIR::ClosureParam> closure_params;
+  for (auto &param : expr.get_params ())
+    {
+      HIR::ClosureParam p = lower_closure_param (param);
+      closure_params.push_back (std::move (p));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  translated
+    = new HIR::ClosureExpr (mapping, std::move (closure_params),
+			    std::unique_ptr<HIR::Type> (closure_return_type),
+			    std::unique_ptr<HIR::Expr> (closure_expr),
+			    expr.get_has_move (), expr.get_outer_attrs (),
+			    expr.get_locus ());
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index b0ab409646d..bea254de79d 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -19,11 +19,7 @@
 #ifndef RUST_AST_LOWER_EXPR
 #define RUST_AST_LOWER_EXPR
 
-#include "rust-diagnostics.h"
 #include "rust-ast-lower-base.h"
-#include "rust-ast-lower-block.h"
-#include "rust-ast-lower-struct-field-expr.h"
-#include "rust-ast-lower-pattern.h"
 
 namespace Rust {
 namespace HIR {
@@ -76,703 +72,55 @@ class ASTLoweringExpr : public ASTLoweringBase
   using Rust::HIR::ASTLoweringBase::visit;
 
 public:
-  static HIR::Expr *translate (AST::Expr *expr, bool *terminated = nullptr)
-  {
-    ASTLoweringExpr resolver;
-    expr->accept_vis (resolver);
-    if (resolver.translated == nullptr)
-      {
-	rust_fatal_error (expr->get_locus (), "Failed to lower expr: [%s]",
-			  expr->as_string ().c_str ());
-	return nullptr;
-      }
-
-    resolver.mappings->insert_hir_expr (resolver.translated);
-    resolver.mappings->insert_location (
-      resolver.translated->get_mappings ().get_hirid (), expr->get_locus ());
-
-    if (terminated != nullptr)
-      *terminated = resolver.terminated;
-
-    return resolver.translated;
-  }
-
-  void visit (AST::TupleIndexExpr &expr) override
-  {
-    HIR::Expr *tuple_expr
-      = ASTLoweringExpr::translate (expr.get_tuple_expr ().get (), &terminated);
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::TupleIndexExpr (mapping,
-				 std::unique_ptr<HIR::Expr> (tuple_expr),
-				 expr.get_tuple_index (),
-				 expr.get_outer_attrs (), expr.get_locus ());
-  }
-
-  void visit (AST::TupleExpr &expr) override
-  {
-    std::vector<std::unique_ptr<HIR::Expr> > tuple_elements;
-    for (auto &e : expr.get_tuple_elems ())
-      {
-	HIR::Expr *t = ASTLoweringExpr::translate (e.get ());
-	tuple_elements.push_back (std::unique_ptr<HIR::Expr> (t));
-      }
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::TupleExpr (std::move (mapping), std::move (tuple_elements),
-			    expr.get_inner_attrs (), expr.get_outer_attrs (),
-			    expr.get_locus ());
-  }
-
-  void visit (AST::IfExpr &expr) override
-  {
-    translated = ASTLoweringIfBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::IfExprConseqElse &expr) override
-  {
-    translated = ASTLoweringIfBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::IfExprConseqIf &expr) override
-  {
-    translated = ASTLoweringIfBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::BlockExpr &expr) override
-  {
-    translated = ASTLoweringBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::UnsafeBlockExpr &expr) override
-  {
-    translated = ASTLoweringBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::PathInExpression &expr) override
-  {
-    translated = ASTLowerPathInExpression::translate (&expr);
-  }
-
-  void visit (AST::QualifiedPathInExpression &expr) override
-  {
-    translated = ASTLowerQualPathInExpression::translate (&expr);
-  }
-
-  void visit (AST::ReturnExpr &expr) override
-  {
-    terminated = true;
-    HIR::Expr *return_expr
-      = expr.has_returned_expr ()
-	  ? ASTLoweringExpr::translate (expr.get_returned_expr ().get ())
-	  : nullptr;
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::ReturnExpr (mapping, expr.get_locus (),
-				      std::unique_ptr<HIR::Expr> (return_expr));
-  }
-
-  void visit (AST::CallExpr &expr) override
-  {
-    HIR::Expr *func
-      = ASTLoweringExpr::translate (expr.get_function_expr ().get ());
-
-    auto const &in_params = expr.get_params ();
-    std::vector<std::unique_ptr<HIR::Expr> > params;
-    for (auto &param : in_params)
-      {
-	auto trans = ASTLoweringExpr::translate (param.get ());
-	params.push_back (std::unique_ptr<HIR::Expr> (trans));
-      }
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (
-      crate_num, UNKNOWN_NODEID /* this can map back to the AST*/,
-      mappings->get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::CallExpr (mapping, std::unique_ptr<HIR::Expr> (func),
-				    std::move (params), expr.get_outer_attrs (),
-				    expr.get_locus ());
-  }
-
-  void visit (AST::MethodCallExpr &expr) override
-  {
-    HIR::PathExprSegment method_path
-      = lower_path_expr_seg (expr.get_method_name ());
-
-    HIR::Expr *receiver
-      = ASTLoweringExpr::translate (expr.get_receiver_expr ().get ());
-
-    auto const &in_params = expr.get_params ();
-    std::vector<std::unique_ptr<HIR::Expr> > params;
-    for (auto &param : in_params)
-      {
-	auto trans = ASTLoweringExpr::translate (param.get ());
-	params.push_back (std::unique_ptr<HIR::Expr> (trans));
-      }
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::MethodCallExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
-				 method_path, std::move (params),
-				 expr.get_outer_attrs (), expr.get_locus ());
-  }
-
-  void visit (AST::AssignmentExpr &expr) override
-  {
-    HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
-    HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::AssignmentExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
-				 std::unique_ptr<HIR::Expr> (rhs),
-				 expr.get_locus ());
-  }
-
-  void visit (AST::IdentifierExpr &expr) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping1 (crate_num, expr.get_node_id (),
-				    mappings->get_next_hir_id (crate_num),
-				    UNKNOWN_LOCAL_DEFID);
-    Analysis::NodeMapping mapping2 (mapping1);
-
-    HIR::PathIdentSegment ident_seg (expr.get_ident ());
-    HIR::PathExprSegment seg (mapping1, ident_seg, expr.get_locus (),
-			      HIR::GenericArgs::create_empty ());
-    translated = new HIR::PathInExpression (mapping2, {seg}, expr.get_locus (),
-					    false, expr.get_outer_attrs ());
-  }
-
-  void visit (AST::ArrayExpr &expr) override
-  {
-    expr.get_array_elems ()->accept_vis (*this);
-    rust_assert (translated_array_elems != nullptr);
-    HIR::ArrayElems *elems = translated_array_elems;
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::ArrayExpr (mapping, std::unique_ptr<HIR::ArrayElems> (elems),
-			    expr.get_inner_attrs (), expr.get_outer_attrs (),
-			    expr.get_locus ());
-  }
-
-  void visit (AST::ArrayIndexExpr &expr) override
-  {
-    HIR::Expr *array_expr
-      = ASTLoweringExpr::translate (expr.get_array_expr ().get ());
-    HIR::Expr *array_index_expr
-      = ASTLoweringExpr::translate (expr.get_index_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::ArrayIndexExpr (mapping,
-				 std::unique_ptr<HIR::Expr> (array_expr),
-				 std::unique_ptr<HIR::Expr> (array_index_expr),
-				 expr.get_outer_attrs (), expr.get_locus ());
-  }
-
-  void visit (AST::ArrayElemsValues &elems) override
-  {
-    std::vector<std::unique_ptr<HIR::Expr> > elements;
-    for (auto &elem : elems.get_values ())
-      {
-	HIR::Expr *translated_elem = ASTLoweringExpr::translate (elem.get ());
-	elements.push_back (std::unique_ptr<HIR::Expr> (translated_elem));
-      }
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (mappings->get_current_crate (),
-				   elems.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated_array_elems
-      = new HIR::ArrayElemsValues (mapping, std::move (elements));
-  }
-
-  void visit (AST::ArrayElemsCopied &elems) override
-  {
-    HIR::Expr *element
-      = ASTLoweringExpr::translate (elems.get_elem_to_copy ().get ());
-    HIR::Expr *num_copies
-      = ASTLoweringExpr::translate (elems.get_num_copies ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (mappings->get_current_crate (),
-				   elems.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated_array_elems
-      = new HIR::ArrayElemsCopied (mapping,
-				   std::unique_ptr<HIR::Expr> (element),
-				   std::unique_ptr<HIR::Expr> (num_copies));
-  }
-
-  void visit (AST::LiteralExpr &expr) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    HIR::Literal l = lower_literal (expr.get_literal ());
-    translated
-      = new HIR::LiteralExpr (mapping, std::move (l), expr.get_locus (),
-			      expr.get_outer_attrs ());
-  }
-
-  void visit (AST::ArithmeticOrLogicalExpr &expr) override
-  {
-    HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
-    rust_assert (lhs != nullptr);
-    HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
-    rust_assert (rhs != nullptr);
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::ArithmeticOrLogicalExpr (mapping,
-					  std::unique_ptr<HIR::Expr> (lhs),
-					  std::unique_ptr<HIR::Expr> (rhs),
-					  expr.get_expr_type (),
-					  expr.get_locus ());
-  }
-
-  void visit (AST::ComparisonExpr &expr) override
-  {
-    HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
-    rust_assert (lhs != nullptr);
-    HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
-    rust_assert (rhs != nullptr);
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::ComparisonExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
-				 std::unique_ptr<HIR::Expr> (rhs),
-				 expr.get_expr_type (), expr.get_locus ());
-  }
-
-  void visit (AST::LazyBooleanExpr &expr) override
-  {
-    HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
-    rust_assert (lhs != nullptr);
-    HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
-    rust_assert (rhs != nullptr);
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::LazyBooleanExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
-				  std::unique_ptr<HIR::Expr> (rhs),
-				  expr.get_expr_type (), expr.get_locus ());
-  }
-
-  void visit (AST::NegationExpr &expr) override
-  {
-    HIR::Expr *negated_value
-      = ASTLoweringExpr::translate (expr.get_negated_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-    translated
-      = new HIR::NegationExpr (mapping,
-			       std::unique_ptr<HIR::Expr> (negated_value),
-			       expr.get_expr_type (), expr.get_outer_attrs (),
-			       expr.get_locus ());
-  }
-
-  void visit (AST::TypeCastExpr &expr) override
-  {
-    HIR::Expr *expr_to_cast_to
-      = ASTLoweringExpr::translate (expr.get_casted_expr ().get ());
-    HIR::Type *type_to_cast_to
-      = lower_type_no_bounds (expr.get_type_to_cast_to ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::TypeCastExpr (mapping,
-			       std::unique_ptr<HIR::Expr> (expr_to_cast_to),
-			       std::unique_ptr<HIR::Type> (type_to_cast_to),
-			       expr.get_locus ());
-  }
-
-  void visit (AST::CompoundAssignmentExpr &expr) override
-  {
-    ArithmeticOrLogicalOperator op;
-    switch (expr.get_expr_type ())
-      {
-      case CompoundAssignmentOperator::ADD:
-	op = ArithmeticOrLogicalOperator::ADD;
-	break;
-      case CompoundAssignmentOperator::SUBTRACT:
-	op = ArithmeticOrLogicalOperator::SUBTRACT;
-	break;
-      case CompoundAssignmentOperator::MULTIPLY:
-	op = ArithmeticOrLogicalOperator::MULTIPLY;
-	break;
-      case CompoundAssignmentOperator::DIVIDE:
-	op = ArithmeticOrLogicalOperator::DIVIDE;
-	break;
-      case CompoundAssignmentOperator::MODULUS:
-	op = ArithmeticOrLogicalOperator::MODULUS;
-	break;
-      case CompoundAssignmentOperator::BITWISE_AND:
-	op = ArithmeticOrLogicalOperator::BITWISE_AND;
-	break;
-      case CompoundAssignmentOperator::BITWISE_OR:
-	op = ArithmeticOrLogicalOperator::BITWISE_OR;
-	break;
-      case CompoundAssignmentOperator::BITWISE_XOR:
-	op = ArithmeticOrLogicalOperator::BITWISE_XOR;
-	break;
-      case CompoundAssignmentOperator::LEFT_SHIFT:
-	op = ArithmeticOrLogicalOperator::LEFT_SHIFT;
-	break;
-      case CompoundAssignmentOperator::RIGHT_SHIFT:
-	op = ArithmeticOrLogicalOperator::RIGHT_SHIFT;
-	break;
-      default:
-	gcc_unreachable ();
-      }
-
-    HIR::Expr *asignee_expr
-      = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
-    HIR::Expr *value
-      = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::CompoundAssignmentExpr (
-      mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
-      std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
-  }
-
-  void visit (AST::StructExprStruct &struct_expr) override
-  {
-    HIR::PathInExpression *path
-      = ASTLowerPathInExpression::translate (&struct_expr.get_struct_name ());
-    HIR::PathInExpression copied_path (*path);
-    delete path;
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::StructExprStruct (mapping, copied_path,
-					    struct_expr.get_inner_attrs (),
-					    struct_expr.get_outer_attrs (),
-					    struct_expr.get_locus ());
-  }
-
-  void visit (AST::StructExprStructFields &struct_expr) override
-  {
-    // bit of a hack for now
-    HIR::PathInExpression *path
-      = ASTLowerPathInExpression::translate (&struct_expr.get_struct_name ());
-    HIR::PathInExpression copied_path (*path);
-    delete path;
-
-    HIR::StructBase *base = nullptr;
-    if (struct_expr.has_struct_base ())
-      {
-	HIR::Expr *translated_base = ASTLoweringExpr::translate (
-	  struct_expr.get_struct_base ().get_base_struct ().get ());
-	base
-	  = new HIR::StructBase (std::unique_ptr<HIR::Expr> (translated_base));
-      }
-
-    auto const &in_fields = struct_expr.get_fields ();
-    std::vector<std::unique_ptr<HIR::StructExprField> > fields;
-    for (auto &field : in_fields)
-      {
-	HIR::StructExprField *translated
-	  = ASTLowerStructExprField::translate (field.get ());
-	fields.push_back (std::unique_ptr<HIR::StructExprField> (translated));
-      }
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::StructExprStructFields (
-      mapping, copied_path, std::move (fields), struct_expr.get_locus (), base,
-      struct_expr.get_inner_attrs (), struct_expr.get_outer_attrs ());
-  }
-
-  void visit (AST::GroupedExpr &expr) override
-  {
-    HIR::Expr *paren_expr
-      = ASTLoweringExpr::translate (expr.get_expr_in_parens ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::GroupedExpr (mapping, std::unique_ptr<HIR::Expr> (paren_expr),
-			      expr.get_inner_attrs (), expr.get_outer_attrs (),
-			      expr.get_locus ());
-  }
-
-  void visit (AST::FieldAccessExpr &expr) override
-  {
-    HIR::Expr *receiver
-      = ASTLoweringExpr::translate (expr.get_receiver_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-    translated
-      = new HIR::FieldAccessExpr (mapping,
-				  std::unique_ptr<HIR::Expr> (receiver),
-				  expr.get_field_name (),
-				  expr.get_outer_attrs (), expr.get_locus ());
-  }
-
-  void visit (AST::LoopExpr &expr) override
-  {
-    translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::WhileLoopExpr &expr) override
-  {
-    translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::ForLoopExpr &expr) override
-  {
-    translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::BreakExpr &expr) override
-  {
-    HIR::Lifetime break_label = lower_lifetime (expr.get_label ());
-    HIR::Expr *break_expr
-      = expr.has_break_expr ()
-	  ? ASTLoweringExpr::translate (expr.get_break_expr ().get ())
-	  : nullptr;
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::BreakExpr (mapping, expr.get_locus (),
-				     std ::move (break_label),
-				     std::unique_ptr<HIR::Expr> (break_expr),
-				     expr.get_outer_attrs ());
-  }
-
-  void visit (AST::ContinueExpr &expr) override
-  {
-    HIR::Lifetime break_label = lower_lifetime (expr.get_label ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::ContinueExpr (mapping, expr.get_locus (),
-					std ::move (break_label),
-					expr.get_outer_attrs ());
-  }
-
-  void visit (AST::BorrowExpr &expr) override
-  {
-    HIR::Expr *borrow_lvalue
-      = ASTLoweringExpr::translate (expr.get_borrowed_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    HIR::BorrowExpr *borrow_expr
-      = new HIR::BorrowExpr (mapping,
-			     std::unique_ptr<HIR::Expr> (borrow_lvalue),
-			     expr.get_is_mut () ? Mutability::Mut
-						: Mutability::Imm,
-			     expr.get_outer_attrs (), expr.get_locus ());
-
-    if (expr.get_is_double_borrow ())
-      {
-	NodeId artifical_bouble_borrow_id = mappings->get_next_node_id ();
-	Analysis::NodeMapping mapping (crate_num, artifical_bouble_borrow_id,
-				       mappings->get_next_hir_id (crate_num),
-				       UNKNOWN_LOCAL_DEFID);
-
-	borrow_expr
-	  = new HIR::BorrowExpr (mapping,
-				 std::unique_ptr<HIR::Expr> (borrow_expr),
-				 expr.get_is_mut () ? Mutability::Mut
-						    : Mutability::Imm,
-				 expr.get_outer_attrs (), expr.get_locus ());
-      }
-
-    translated = borrow_expr;
-  }
-
-  void visit (AST::DereferenceExpr &expr) override
-  {
-    HIR::Expr *dref_lvalue
-      = ASTLoweringExpr::translate (expr.get_dereferenced_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated
-      = new HIR::DereferenceExpr (mapping,
-				  std::unique_ptr<HIR::Expr> (dref_lvalue),
-				  expr.get_outer_attrs (), expr.get_locus ());
-  }
-
-  void visit (AST::MatchExpr &expr) override
-  {
-    translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
-  }
-
-  void visit (AST::RangeFromToExpr &expr) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    HIR::Expr *range_from
-      = ASTLoweringExpr::translate (expr.get_from_expr ().get ());
-    HIR::Expr *range_to
-      = ASTLoweringExpr::translate (expr.get_to_expr ().get ());
-
-    translated
-      = new HIR::RangeFromToExpr (mapping,
-				  std::unique_ptr<HIR::Expr> (range_from),
-				  std::unique_ptr<HIR::Expr> (range_to),
-				  expr.get_locus ());
-  }
-
-  void visit (AST::RangeFromExpr &expr) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    HIR::Expr *range_from
-      = ASTLoweringExpr::translate (expr.get_from_expr ().get ());
-
-    translated
-      = new HIR::RangeFromExpr (mapping,
-				std::unique_ptr<HIR::Expr> (range_from),
-				expr.get_locus ());
-  }
-
-  void visit (AST::RangeToExpr &expr) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    HIR::Expr *range_to
-      = ASTLoweringExpr::translate (expr.get_to_expr ().get ());
-
-    translated
-      = new HIR::RangeToExpr (mapping, std::unique_ptr<HIR::Expr> (range_to),
-			      expr.get_locus ());
-  }
-
-  void visit (AST::RangeFullExpr &expr) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    translated = new HIR::RangeFullExpr (mapping, expr.get_locus ());
-  }
-
-  void visit (AST::RangeFromToInclExpr &expr) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    HIR::Expr *range_from
-      = ASTLoweringExpr::translate (expr.get_from_expr ().get ());
-    HIR::Expr *range_to
-      = ASTLoweringExpr::translate (expr.get_to_expr ().get ());
-
-    translated
-      = new HIR::RangeFromToInclExpr (mapping,
-				      std::unique_ptr<HIR::Expr> (range_from),
-				      std::unique_ptr<HIR::Expr> (range_to),
-				      expr.get_locus ());
-  }
+  static HIR::Expr *translate (AST::Expr *expr, bool *terminated = nullptr);
+
+  void visit (AST::TupleIndexExpr &expr) override;
+  void visit (AST::TupleExpr &expr) override;
+  void visit (AST::IfExpr &expr) override;
+  void visit (AST::IfExprConseqElse &expr) override;
+  void visit (AST::IfExprConseqIf &expr) override;
+  void visit (AST::BlockExpr &expr) override;
+  void visit (AST::UnsafeBlockExpr &expr) override;
+  void visit (AST::PathInExpression &expr) override;
+  void visit (AST::QualifiedPathInExpression &expr) override;
+  void visit (AST::ReturnExpr &expr) override;
+  void visit (AST::CallExpr &expr) override;
+  void visit (AST::MethodCallExpr &expr) override;
+  void visit (AST::AssignmentExpr &expr) override;
+  void visit (AST::IdentifierExpr &expr) override;
+  void visit (AST::ArrayExpr &expr) override;
+  void visit (AST::ArrayIndexExpr &expr) override;
+  void visit (AST::ArrayElemsValues &elems) override;
+  void visit (AST::ArrayElemsCopied &elems) override;
+  void visit (AST::LiteralExpr &expr) override;
+  void visit (AST::ArithmeticOrLogicalExpr &expr) override;
+  void visit (AST::ComparisonExpr &expr) override;
+  void visit (AST::LazyBooleanExpr &expr) override;
+  void visit (AST::NegationExpr &expr) override;
+  void visit (AST::TypeCastExpr &expr) override;
+  void visit (AST::CompoundAssignmentExpr &expr) override;
+  void visit (AST::StructExprStruct &struct_expr) override;
+  void visit (AST::StructExprStructFields &struct_expr) override;
+  void visit (AST::GroupedExpr &expr) override;
+  void visit (AST::FieldAccessExpr &expr) override;
+  void visit (AST::LoopExpr &expr) override;
+  void visit (AST::WhileLoopExpr &expr) override;
+  void visit (AST::ForLoopExpr &expr) override;
+  void visit (AST::BreakExpr &expr) override;
+  void visit (AST::ContinueExpr &expr) override;
+  void visit (AST::BorrowExpr &expr) override;
+  void visit (AST::DereferenceExpr &expr) override;
+  void visit (AST::MatchExpr &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::ClosureExprInner &expr) override;
+  void visit (AST::ClosureExprInnerTyped &expr) override;
 
 private:
-  ASTLoweringExpr ()
-    : ASTLoweringBase (), translated (nullptr),
-      translated_array_elems (nullptr), terminated (false)
-  {}
+  ASTLoweringExpr ();
 
   HIR::Expr *translated;
   HIR::ArrayElems *translated_array_elems;
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index 4f1bfd1f0c1..fdf8abe3ed3 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -22,9 +22,12 @@
 #include "rust-ast-lower-expr.h"
 #include "rust-ast-lower-block.h"
 #include "rust-ast-lower-type.h"
+#include "rust-ast-lower-pattern.h"
+#include "rust-ast-lower-struct-field-expr.h"
 
 namespace Rust {
 namespace HIR {
+using HIR::ClosureParam;
 
 Visibility
 translate_visibility (const AST::Visibility &vis)
@@ -473,5 +476,25 @@ ASTLowerQualPathInExpression::visit (AST::QualifiedPathInExpression &expr)
 						   expr.get_locus (),
 						   expr.get_outer_attrs ());
 }
+
+ClosureParam
+ASTLoweringBase::lower_closure_param (AST::ClosureParam &param)
+{
+  HIR::Pattern *param_pattern
+    = ASTLoweringPattern::translate (param.get_pattern ().get ());
+
+  HIR::Type *param_type
+    = param.has_type_given ()
+	? ASTLoweringType::translate (param.get_type ().get ())
+	: nullptr;
+
+  return HIR::ClosureParam (std::unique_ptr<HIR::Pattern> (param_pattern),
+			    param.get_locus (),
+			    param.has_type_given ()
+			      ? std::unique_ptr<HIR::Type> (param_type)
+			      : nullptr,
+			    param.get_outer_attrs ());
+}
+
 } // namespace HIR
 } // namespace Rust
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 6bbd7ef3a7f..261a36daa05 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -197,7 +197,7 @@ void
 Dump::visit (FieldAccessExpr &)
 {}
 void
-Dump::visit (ClosureExprInner &)
+Dump::visit (ClosureExpr &)
 {}
 void
 Dump::visit (BlockExpr &block_expr)
@@ -212,9 +212,7 @@ Dump::visit (BlockExpr &block_expr)
   stream << "]";
   indent--;
 }
-void
-Dump::visit (ClosureExprInnerTyped &)
-{}
+
 void
 Dump::visit (ContinueExpr &)
 {}
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index ead8d774b03..8715a95ada8 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -78,9 +78,8 @@ private:
   virtual void visit (CallExpr &) override;
   virtual void visit (MethodCallExpr &) override;
   virtual void visit (FieldAccessExpr &) override;
-  virtual void visit (ClosureExprInner &) override;
+  virtual void visit (ClosureExpr &) override;
   virtual void visit (BlockExpr &) override;
-  virtual void visit (ClosureExprInnerTyped &) override;
   virtual void visit (ContinueExpr &) override;
   virtual void visit (BreakExpr &) override;
   virtual void visit (RangeFromToExpr &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 564d5215724..4c5caf17ac3 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -1985,21 +1985,22 @@ protected:
 struct ClosureParam
 {
 private:
+  std::vector<AST::Attribute> outer_attrs;
   std::unique_ptr<Pattern> pattern;
-
-  // bool has_type_given;
   std::unique_ptr<Type> type;
-
-  // TODO: should this store location data?
+  Location locus;
 
 public:
   // Returns whether the type of the parameter has been given.
   bool has_type_given () const { return type != nullptr; }
 
   // Constructor for closure parameter
-  ClosureParam (std::unique_ptr<Pattern> param_pattern,
-		std::unique_ptr<Type> param_type = nullptr)
-    : pattern (std::move (param_pattern)), type (std::move (param_type))
+  ClosureParam (std::unique_ptr<Pattern> param_pattern, Location locus,
+		std::unique_ptr<Type> param_type = nullptr,
+		std::vector<AST::Attribute> outer_attrs = {})
+    : outer_attrs (std::move (outer_attrs)),
+      pattern (std::move (param_pattern)), type (std::move (param_type)),
+      locus (locus)
   {}
 
   // Copy constructor required due to cloning as a result of unique_ptrs
@@ -2007,6 +2008,8 @@ public:
     : pattern (other.pattern->clone_pattern ())
   {
     // guard to protect from null pointer dereference
+    if (other.pattern != nullptr)
+      pattern = other.pattern->clone_pattern ();
     if (other.type != nullptr)
       type = other.type->clone_type ();
   }
@@ -2016,8 +2019,17 @@ public:
   // Assignment operator must be overloaded to clone as well
   ClosureParam &operator= (ClosureParam const &other)
   {
-    pattern = other.pattern->clone_pattern ();
-    type = other.type->clone_type ();
+    outer_attrs = other.outer_attrs;
+
+    // guard to protect from null pointer dereference
+    if (other.pattern != nullptr)
+      pattern = other.pattern->clone_pattern ();
+    else
+      pattern = nullptr;
+    if (other.type != nullptr)
+      type = other.type->clone_type ();
+    else
+      type = nullptr;
 
     return *this;
   }
@@ -2026,31 +2038,79 @@ public:
   ClosureParam (ClosureParam &&other) = default;
   ClosureParam &operator= (ClosureParam &&other) = default;
 
-  // Returns whether closure parameter is in an error state.
-  bool is_error () const { return pattern == nullptr; }
+  std::string as_string () const;
 
-  // Creates an error state closure parameter.
-  static ClosureParam create_error () { return ClosureParam (nullptr); }
+  const std::vector<AST::Attribute> &get_outer_attrs () const
+  {
+    return outer_attrs;
+  }
+  std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
 
-  std::string as_string () const;
+  std::unique_ptr<Pattern> &get_pattern ()
+  {
+    rust_assert (pattern != nullptr);
+    return pattern;
+  }
+
+  std::unique_ptr<Type> &get_type ()
+  {
+    rust_assert (has_type_given ());
+    return type;
+  }
+
+  Location get_locus () const { return locus; }
 };
 
 // Base closure definition expression HIR node - abstract
 class ClosureExpr : public ExprWithoutBlock
 {
+private:
   bool has_move;
   std::vector<ClosureParam> params;
   Location locus;
+  std::unique_ptr<Type> return_type;
+  std::unique_ptr<Expr> expr;
 
-protected:
+public:
   ClosureExpr (Analysis::NodeMapping mappings,
-	       std::vector<ClosureParam> closure_params, bool has_move,
+	       std::vector<ClosureParam> closure_params,
+	       std::unique_ptr<Type> closure_return_type,
+	       std::unique_ptr<Expr> closure_expr, bool has_move,
 	       AST::AttrVec outer_attribs, Location locus)
     : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
-      has_move (has_move), params (std::move (closure_params)), locus (locus)
+      has_move (has_move), params (std::move (closure_params)), locus (locus),
+      return_type (std::move (closure_return_type)),
+      expr (std::move (closure_expr))
   {}
 
-public:
+  // Copy constructor requires cloning
+  ClosureExpr (ClosureExpr const &other)
+    : ExprWithoutBlock (other.get_mappings (), other.get_outer_attrs ())
+  {
+    return_type
+      = other.has_return_type () ? other.return_type->clone_type () : nullptr;
+    expr = other.expr->clone_expr ();
+    params = other.params;
+    has_move = other.has_move;
+  }
+
+  // Overload assignment operator to clone unique_ptrs
+  ClosureExpr &operator= (ClosureExpr const &other)
+  {
+    mappings = other.mappings;
+    return_type
+      = other.has_return_type () ? other.return_type->clone_type () : nullptr;
+    expr = other.expr->clone_expr ();
+    params = other.params;
+    has_move = other.has_move;
+
+    return *this;
+  }
+
+  // move constructors
+  ClosureExpr (ClosureExpr &&other) = default;
+  ClosureExpr &operator= (ClosureExpr &&other) = default;
+
   std::string as_string () const override;
 
   Location get_locus () const override final { return locus; }
@@ -2059,47 +2119,17 @@ public:
   {
     return ExprType::Closure;
   }
-};
 
-// Represents a non-type-specified closure expression HIR node
-class ClosureExprInner : public ClosureExpr
-{
-  std::unique_ptr<Expr> closure_inner;
+  bool get_has_move () const { return has_move; }
 
-public:
-  std::string as_string () const override;
+  bool has_return_type () const { return return_type != nullptr; }
 
-  // Constructor for a ClosureExprInner
-  ClosureExprInner (Analysis::NodeMapping mappings,
-		    std::unique_ptr<Expr> closure_inner_expr,
-		    std::vector<ClosureParam> closure_params, Location locus,
-		    bool is_move = false,
-		    AST::AttrVec outer_attribs = AST::AttrVec ())
-    : ClosureExpr (std::move (mappings), std::move (closure_params), is_move,
-		   std::move (outer_attribs), locus),
-      closure_inner (std::move (closure_inner_expr))
-  {}
-
-  // Copy constructor must be defined to allow copying via cloning of unique_ptr
-  ClosureExprInner (ClosureExprInner const &other)
-    : ClosureExpr (other), closure_inner (other.closure_inner->clone_expr ())
-  {}
-
-  // Overload assignment operator to clone closure_inner
-  ClosureExprInner &operator= (ClosureExprInner const &other)
+  std::unique_ptr<Type> &get_return_type ()
   {
-    ClosureExpr::operator= (other);
-    closure_inner = other.closure_inner->clone_expr ();
-    // params = other.params;
-    // has_move = other.has_move;
-    // outer_attrs = other.outer_attrs;
-
-    return *this;
-  }
-
-  // move constructors
-  ClosureExprInner (ClosureExprInner &&other) = default;
-  ClosureExprInner &operator= (ClosureExprInner &&other) = default;
+    rust_assert (has_return_type ());
+    return return_type;
+  };
+  std::unique_ptr<Expr> &get_expr () { return expr; }
 
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
@@ -2107,16 +2137,16 @@ public:
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
-  ClosureExprInner *clone_expr_impl () const override
+  ClosureExpr *clone_expr_impl () const override
   {
-    return new ClosureExprInner (*this);
+    return new ClosureExpr (*this);
   }
 
   /* Use covariance to implement clone function as returning this object rather
    * than base */
-  ClosureExprInner *clone_expr_without_block_impl () const override
+  ClosureExpr *clone_expr_without_block_impl () const override
   {
-    return new ClosureExprInner (*this);
+    return new ClosureExpr (*this);
   }
 };
 
@@ -2239,71 +2269,6 @@ protected:
   }
 };
 
-// Represents a type-specified closure expression HIR node
-class ClosureExprInnerTyped : public ClosureExpr
-{
-  std::unique_ptr<Type> return_type;
-  std::unique_ptr<BlockExpr>
-    expr; // only used because may be polymorphic in future
-
-public:
-  std::string as_string () const override;
-
-  // Constructor potentially with a move
-  ClosureExprInnerTyped (Analysis::NodeMapping mappings,
-			 std::unique_ptr<Type> closure_return_type,
-			 std::unique_ptr<BlockExpr> closure_expr,
-			 std::vector<ClosureParam> closure_params,
-			 Location locus, bool is_move = false,
-			 AST::AttrVec outer_attribs = AST::AttrVec ())
-    : ClosureExpr (std::move (mappings), std::move (closure_params), is_move,
-		   std::move (outer_attribs), locus),
-      return_type (std::move (closure_return_type)),
-      expr (std::move (closure_expr))
-  {}
-
-  // Copy constructor requires cloning
-  ClosureExprInnerTyped (ClosureExprInnerTyped const &other)
-    : ClosureExpr (other), return_type (other.return_type->clone_type ()),
-      expr (other.expr->clone_block_expr ())
-  {}
-
-  // Overload assignment operator to clone unique_ptrs
-  ClosureExprInnerTyped &operator= (ClosureExprInnerTyped const &other)
-  {
-    ClosureExpr::operator= (other);
-    return_type = other.return_type->clone_type ();
-    expr = other.expr->clone_block_expr ();
-    // params = other.params;
-    // has_move = other.has_move;
-    // outer_attrs = other.outer_attrs;
-
-    return *this;
-  }
-
-  // move constructors
-  ClosureExprInnerTyped (ClosureExprInnerTyped &&other) = default;
-  ClosureExprInnerTyped &operator= (ClosureExprInnerTyped &&other) = default;
-
-  void accept_vis (HIRFullVisitor &vis) override;
-  void accept_vis (HIRExpressionVisitor &vis) override;
-
-protected:
-  /* Use covariance to implement clone function as returning this object rather
-   * than base */
-  ClosureExprInnerTyped *clone_expr_impl () const override
-  {
-    return new ClosureExprInnerTyped (*this);
-  }
-
-  /* Use covariance to implement clone function as returning this object rather
-   * than base */
-  ClosureExprInnerTyped *clone_expr_without_block_impl () const override
-  {
-    return new ClosureExprInnerTyped (*this);
-  }
-};
-
 // HIR node representing continue expression within loops
 class ContinueExpr : public ExprWithoutBlock
 {
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 3cb3ffeecee..70ee7538298 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -94,9 +94,7 @@ class MethodCallExpr;
 class FieldAccessExpr;
 struct ClosureParam;
 class ClosureExpr;
-class ClosureExprInner;
 class BlockExpr;
-class ClosureExprInnerTyped;
 class ContinueExpr;
 class BreakExpr;
 class RangeExpr;
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index 48af16a45e6..f6e27b9a35f 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -1133,15 +1133,8 @@ ClosureExpr::as_string () const
 	}
     }
 
-  return str;
-}
-
-std::string
-ClosureExprInnerTyped::as_string () const
-{
-  std::string str = ClosureExpr::as_string ();
-
-  str += "\n Return type: " + return_type->as_string ();
+  str += "\n Return type: "
+	 + (has_return_type () ? return_type->as_string () : "none");
 
   str += "\n Body: " + expr->as_string ();
 
@@ -1515,16 +1508,6 @@ UnsafeBlockExpr::as_string () const
   return str + "\n" + indent_spaces (out) + "}\n" + expr->as_string ();
 }
 
-std::string
-ClosureExprInner::as_string () const
-{
-  std::string str = ClosureExpr::as_string ();
-
-  str += "\n Expression: " + closure_inner->as_string ();
-
-  return str;
-}
-
 std::string
 IfExpr::as_string () const
 {
@@ -4038,7 +4021,7 @@ FieldAccessExpr::accept_vis (HIRFullVisitor &vis)
 }
 
 void
-ClosureExprInner::accept_vis (HIRFullVisitor &vis)
+ClosureExpr::accept_vis (HIRFullVisitor &vis)
 {
   vis.visit (*this);
 }
@@ -4049,12 +4032,6 @@ BlockExpr::accept_vis (HIRFullVisitor &vis)
   vis.visit (*this);
 }
 
-void
-ClosureExprInnerTyped::accept_vis (HIRFullVisitor &vis)
-{
-  vis.visit (*this);
-}
-
 void
 ContinueExpr::accept_vis (HIRFullVisitor &vis)
 {
@@ -4986,7 +4963,7 @@ IfExpr::accept_vis (HIRExpressionVisitor &vis)
 }
 
 void
-ClosureExprInner::accept_vis (HIRExpressionVisitor &vis)
+ClosureExpr::accept_vis (HIRExpressionVisitor &vis)
 {
   vis.visit (*this);
 }
@@ -5075,12 +5052,6 @@ QualifiedPathInExpression::accept_vis (HIRPatternVisitor &vis)
   vis.visit (*this);
 }
 
-void
-ClosureExprInnerTyped::accept_vis (HIRExpressionVisitor &vis)
-{
-  vis.visit (*this);
-}
-
 void
 ExprStmtWithBlock::accept_vis (HIRStmtVisitor &vis)
 {
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 187f0794ac1..ba6cad7614b 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -63,9 +63,8 @@ public:
   virtual void visit (CallExpr &expr) = 0;
   virtual void visit (MethodCallExpr &expr) = 0;
   virtual void visit (FieldAccessExpr &expr) = 0;
-  virtual void visit (ClosureExprInner &expr) = 0;
   virtual void visit (BlockExpr &expr) = 0;
-  virtual void visit (ClosureExprInnerTyped &expr) = 0;
+  virtual void visit (ClosureExpr &expr) = 0;
   virtual void visit (ContinueExpr &expr) = 0;
   virtual void visit (BreakExpr &expr) = 0;
   virtual void visit (RangeFromToExpr &expr) = 0;
@@ -206,9 +205,8 @@ public:
   virtual void visit (CallExpr &) override {}
   virtual void visit (MethodCallExpr &) override {}
   virtual void visit (FieldAccessExpr &) override {}
-  virtual void visit (ClosureExprInner &) override {}
+  virtual void visit (ClosureExpr &) override {}
   virtual void visit (BlockExpr &) override {}
-  virtual void visit (ClosureExprInnerTyped &) override {}
   virtual void visit (ContinueExpr &) override {}
   virtual void visit (BreakExpr &) override {}
   virtual void visit (RangeFromToExpr &) override {}
@@ -419,8 +417,7 @@ public:
 
   virtual void visit (HIR::QualifiedPathInExpression &expr) = 0;
   virtual void visit (HIR::PathInExpression &expr) = 0;
-  virtual void visit (ClosureExprInnerTyped &) = 0;
-  virtual void visit (ClosureExprInner &expr) = 0;
+  virtual void visit (ClosureExpr &) = 0;
   virtual void visit (StructExprStructFields &) = 0;
   virtual void visit (StructExprStruct &) = 0;
   virtual void visit (LiteralExpr &expr) = 0;
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index aa305f1590c..314aafb32d3 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -238,6 +238,7 @@ class ExprWithoutBlock;
 // Base expression HIR node - abstract
 class Expr : public Node
 {
+protected:
   AST::AttrVec outer_attrs;
   Analysis::NodeMapping mappings;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 4e377d52a0f..6b8c63b77f6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1418,6 +1418,12 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
     }
 }
 
+void
+TypeCheckExpr::visit (HIR::ClosureExpr &expr)
+{
+  gcc_unreachable ();
+}
+
 bool
 TypeCheckExpr::resolve_operator_overload (
   Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExprMeta expr,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 8a37512ec6e..7f787fa9766 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -69,10 +69,9 @@ public:
   void visit (HIR::RangeFullExpr &expr) override;
   void visit (HIR::RangeFromToInclExpr &expr) override;
   void visit (HIR::WhileLoopExpr &expr) override;
+  void visit (HIR::ClosureExpr &expr) override;
 
   // TODO
-  void visit (HIR::ClosureExprInnerTyped &) override {}
-  void visit (HIR::ClosureExprInner &expr) override {}
   void visit (HIR::ErrorPropagationExpr &expr) override {}
   void visit (HIR::RangeToInclExpr &expr) override {}
   void visit (HIR::WhileLetLoopExpr &expr) override {}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 045/103] gccrs: Formatting cleanup in HIR lowering pattern
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (43 preceding siblings ...)
  2023-02-21 12:01 ` [committed 044/103] gccrs: Refactor expression hir lowering into cc file arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 046/103] gccrs: Add name resolution for closures arthur.cohen
                   ` (57 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::ASTLoweringPattern):
	Improve formatting.
	(ASTLoweringPattern::translate): Likewise.
	* hir/rust-ast-lower-pattern.h: Likewise.
	* resolve/rust-ast-resolve-expr.h: Likewise.
---
 gcc/rust/hir/rust-ast-lower-pattern.cc   | 18 ++++++++++
 gcc/rust/hir/rust-ast-lower-pattern.h    | 24 ++-----------
 gcc/rust/resolve/rust-ast-resolve-expr.h | 43 ------------------------
 3 files changed, 20 insertions(+), 65 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 37bee38fd83..30a188286c8 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -22,6 +22,24 @@
 namespace Rust {
 namespace HIR {
 
+ASTLoweringPattern::ASTLoweringPattern () : translated (nullptr) {}
+
+HIR::Pattern *
+ASTLoweringPattern::translate (AST::Pattern *pattern)
+{
+  ASTLoweringPattern resolver;
+  pattern->accept_vis (resolver);
+
+  rust_assert (resolver.translated != nullptr);
+
+  resolver.mappings->insert_hir_pattern (resolver.translated);
+  resolver.mappings->insert_location (
+    resolver.translated->get_pattern_mappings ().get_hirid (),
+    pattern->get_locus ());
+
+  return resolver.translated;
+}
+
 void
 ASTLoweringPattern::visit (AST::IdentifierPattern &pattern)
 {
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.h b/gcc/rust/hir/rust-ast-lower-pattern.h
index f47699d15ea..8b191d56868 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.h
+++ b/gcc/rust/hir/rust-ast-lower-pattern.h
@@ -29,39 +29,19 @@ class ASTLoweringPattern : public ASTLoweringBase
   using Rust::HIR::ASTLoweringBase::visit;
 
 public:
-  static HIR::Pattern *translate (AST::Pattern *pattern)
-  {
-    ASTLoweringPattern resolver;
-    pattern->accept_vis (resolver);
-
-    rust_assert (resolver.translated != nullptr);
-
-    resolver.mappings->insert_hir_pattern (resolver.translated);
-    resolver.mappings->insert_location (
-      resolver.translated->get_pattern_mappings ().get_hirid (),
-      pattern->get_locus ());
-
-    return resolver.translated;
-  }
+  static HIR::Pattern *translate (AST::Pattern *pattern);
 
   void visit (AST::IdentifierPattern &pattern) override;
-
   void visit (AST::PathInExpression &pattern) override;
-
   void visit (AST::StructPattern &pattern) override;
-
   void visit (AST::TupleStructPattern &pattern) override;
-
   void visit (AST::WildcardPattern &pattern) override;
-
   void visit (AST::TuplePattern &pattern) override;
-
   void visit (AST::LiteralPattern &pattern) override;
-
   void visit (AST::RangePattern &pattern) override;
 
 private:
-  ASTLoweringPattern () : translated (nullptr) {}
+  ASTLoweringPattern ();
 
   HIR::Pattern *translated;
 };
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 57beab700d7..60ae1720811 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -34,89 +34,46 @@ public:
 		  const CanonicalPath &canonical_prefix);
 
   void visit (AST::TupleIndexExpr &expr) override;
-
   void visit (AST::TupleExpr &expr) override;
-
   void visit (AST::PathInExpression &expr) override;
-
   void visit (AST::QualifiedPathInExpression &expr) override;
-
   void visit (AST::ReturnExpr &expr) override;
-
   void visit (AST::CallExpr &expr) override;
-
   void visit (AST::MethodCallExpr &expr) override;
-
   void visit (AST::AssignmentExpr &expr) override;
-
   void visit (AST::IdentifierExpr &expr) override;
-
   void visit (AST::ArithmeticOrLogicalExpr &expr) override;
-
   void visit (AST::CompoundAssignmentExpr &expr) override;
-
   void visit (AST::ComparisonExpr &expr) override;
-
   void visit (AST::LazyBooleanExpr &expr) override;
-
   void visit (AST::NegationExpr &expr) override;
-
   void visit (AST::TypeCastExpr &expr) override;
-
   void visit (AST::IfExpr &expr) override;
-
   void visit (AST::IfExprConseqElse &expr) override;
-
   void visit (AST::IfExprConseqIf &expr) override;
-
   void visit (AST::IfLetExpr &expr) override;
-
   void visit (AST::BlockExpr &expr) override;
-
   void visit (AST::UnsafeBlockExpr &expr) override;
-
   void visit (AST::ArrayElemsValues &elems) override;
-
   void visit (AST::ArrayExpr &expr) override;
-
   void visit (AST::ArrayIndexExpr &expr) override;
-
   void visit (AST::ArrayElemsCopied &elems) override;
-
-  // this this an empty struct constructor like 'S {}'
   void visit (AST::StructExprStruct &struct_expr) override;
-
-  // this this a struct constructor with fields
   void visit (AST::StructExprStructFields &struct_expr) override;
-
   void visit (AST::GroupedExpr &expr) override;
-
   void visit (AST::FieldAccessExpr &expr) override;
-
   void visit (AST::LoopExpr &expr) override;
-
   void visit (AST::BreakExpr &expr) override;
-
   void visit (AST::WhileLoopExpr &expr) override;
-
   void visit (AST::ForLoopExpr &expr) override;
-
   void visit (AST::ContinueExpr &expr) override;
-
   void visit (AST::BorrowExpr &expr) override;
-
   void visit (AST::DereferenceExpr &expr) override;
-
   void visit (AST::MatchExpr &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;
 
 private:
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 046/103] gccrs: Add name resolution for closures
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (44 preceding siblings ...)
  2023-02-21 12:01 ` [committed 045/103] gccrs: Formatting cleanup in HIR lowering pattern arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 047/103] gccrs: Refactor method call type checking arthur.cohen
                   ` (56 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Visit closure properly when
	name resolving.
	(ResolveExpr::resolve_closure_param): Implement closure name resolving.
	* resolve/rust-ast-resolve-expr.h: Declare visitors for closure types.
---
 gcc/rust/resolve/rust-ast-resolve-expr.cc | 58 +++++++++++++++++++++++
 gcc/rust/resolve/rust-ast-resolve-expr.h  |  5 ++
 2 files changed, 63 insertions(+)

diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 40d4af09444..8ece5b63b6d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -565,6 +565,64 @@ ResolveExpr::visit (AST::RangeFromToInclExpr &expr)
   ResolveExpr::go (expr.get_to_expr ().get (), prefix, canonical_prefix);
 }
 
+void
+ResolveExpr::visit (AST::ClosureExprInner &expr)
+{
+  NodeId scope_node_id = expr.get_node_id ();
+  resolver->get_name_scope ().push (scope_node_id);
+  resolver->get_type_scope ().push (scope_node_id);
+  resolver->get_label_scope ().push (scope_node_id);
+  resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
+  resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+
+  for (auto &p : expr.get_params ())
+    {
+      resolve_closure_param (p);
+    }
+
+  ResolveExpr::go (expr.get_definition_expr ().get (), prefix,
+		   canonical_prefix);
+
+  resolver->get_name_scope ().pop ();
+  resolver->get_type_scope ().pop ();
+  resolver->get_label_scope ().pop ();
+}
+
+void
+ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
+{
+  NodeId scope_node_id = expr.get_node_id ();
+  resolver->get_name_scope ().push (scope_node_id);
+  resolver->get_type_scope ().push (scope_node_id);
+  resolver->get_label_scope ().push (scope_node_id);
+  resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
+  resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+
+  for (auto &p : expr.get_params ())
+    {
+      resolve_closure_param (p);
+    }
+
+  ResolveType::go (expr.get_return_type ().get ());
+  ResolveExpr::go (expr.get_definition_block ().get (), prefix,
+		   canonical_prefix);
+
+  resolver->get_name_scope ().pop ();
+  resolver->get_type_scope ().pop ();
+  resolver->get_label_scope ().pop ();
+}
+
+void
+ResolveExpr::resolve_closure_param (AST::ClosureParam &param)
+{
+  PatternDeclaration::go (param.get_pattern ().get ());
+
+  if (param.has_type_given ())
+    ResolveType::go (param.get_type ().get ());
+}
+
 ResolveExpr::ResolveExpr (const CanonicalPath &prefix,
 			  const CanonicalPath &canonical_prefix)
   : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 60ae1720811..9e3e7750119 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -75,6 +75,11 @@ public:
   void visit (AST::RangeToExpr &expr) override;
   void visit (AST::RangeFullExpr &expr) override;
   void visit (AST::RangeFromToInclExpr &expr) override;
+  void visit (AST::ClosureExprInner &expr) override;
+  void visit (AST::ClosureExprInnerTyped &expr) override;
+
+protected:
+  void resolve_closure_param (AST::ClosureParam &param);
 
 private:
   ResolveExpr (const CanonicalPath &prefix,
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 047/103] gccrs: Refactor method call type checking
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (45 preceding siblings ...)
  2023-02-21 12:01 ` [committed 046/103] gccrs: Add name resolution for closures arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 048/103] gccrs: Add closures to lints and error checking arthur.cohen
                   ` (55 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Simplify method
	call type checking 	by removing visitor and instead using one static cast. Use the
	new interface.
	* typecheck/rust-tyty-call.cc (TypeCheckMethodCallExpr::visit): Likewise.
	(TypeCheckMethodCallExpr::go): Likewise.
	(TypeCheckMethodCallExpr::check): Likewise.
	* typecheck/rust-tyty-call.h (class TypeCheckMethodCallExpr): Likewise.
	(class Argument): Likewise.
---
 .../typecheck/rust-hir-type-check-expr.cc     |  3 +-
 gcc/rust/typecheck/rust-tyty-call.cc          | 98 +++++++++++++------
 gcc/rust/typecheck/rust-tyty-call.h           | 79 +++++++--------
 3 files changed, 106 insertions(+), 74 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 6b8c63b77f6..9140b8b1305 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1162,7 +1162,8 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
   rust_debug ("type-checking method_call: {%s}", lookup->debug_str ().c_str ());
 
   TyTy::BaseType *function_ret_tyty
-    = TyTy::TypeCheckMethodCallExpr::go (lookup, expr, adjusted_self, context);
+    = TyTy::TypeCheckMethodCallExpr::go (static_cast<TyTy::FnType *> (lookup),
+					 expr, adjusted_self, context);
   if (function_ret_tyty == nullptr
       || function_ret_tyty->get_kind () == TyTy::TypeKind::ERROR)
     {
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index 96c6b93e5c2..0c9e9f488fd 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -216,29 +216,77 @@ TypeCheckCallExpr::visit (FnPtr &type)
 
 // method call checker
 
-void
-TypeCheckMethodCallExpr::visit (FnType &type)
+TypeCheckMethodCallExpr::TypeCheckMethodCallExpr (
+  Analysis::NodeMapping call_mappings, std::vector<Argument> &args,
+  Location call_locus, Location receiver_locus, TyTy::BaseType *adjusted_self,
+  Resolver::TypeCheckContext *context)
+  : call_mappings (call_mappings), arguments (args), call_locus (call_locus),
+    receiver_locus (receiver_locus), adjusted_self (adjusted_self),
+    context (context), mappings (Analysis::Mappings::get ())
+{}
+
+BaseType *
+TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
+			     TyTy::BaseType *adjusted_self,
+			     Resolver::TypeCheckContext *context)
+{
+  std::vector<Argument> args;
+  for (auto &arg : call.get_arguments ())
+    {
+      BaseType *argument_expr_tyty
+	= Resolver::TypeCheckExpr::Resolve (arg.get ());
+      if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
+	{
+	  rust_error_at (arg->get_locus (),
+			 "failed to resolve type for argument");
+	  return new ErrorType (ref->get_ref ());
+	}
+
+      Argument a (arg->get_mappings (), argument_expr_tyty, arg->get_locus ());
+      args.push_back (std::move (a));
+    }
+
+  TypeCheckMethodCallExpr checker (call.get_mappings (), args,
+				   call.get_locus (),
+				   call.get_receiver ()->get_locus (),
+				   adjusted_self, context);
+  return checker.check (*ref);
+}
+
+BaseType *
+TypeCheckMethodCallExpr::go (FnType *ref, Analysis::NodeMapping call_mappings,
+			     std::vector<Argument> &args, Location call_locus,
+			     Location receiver_locus,
+			     TyTy::BaseType *adjusted_self,
+			     Resolver::TypeCheckContext *context)
+{
+  TypeCheckMethodCallExpr checker (call_mappings, args, call_locus,
+				   receiver_locus, adjusted_self, context);
+  return checker.check (*ref);
+}
+
+BaseType *
+TypeCheckMethodCallExpr::check (FnType &type)
 {
   Resolver::TypeCheckBase::unify_site (
-    call.get_mappings ().get_hirid (), TyWithLocation (type.get_self_type ()),
-    TyWithLocation (adjusted_self, call.get_receiver ()->get_locus ()),
-    call.get_locus ());
+    call_mappings.get_hirid (), TyWithLocation (type.get_self_type ()),
+    TyWithLocation (adjusted_self, receiver_locus), call_locus);
 
   // +1 for the receiver self
-  size_t num_args_to_call = call.num_params () + 1;
+  size_t num_args_to_call = arguments.size () + 1;
   if (num_args_to_call != type.num_params ())
     {
-      rust_error_at (call.get_locus (),
+      rust_error_at (call_locus,
 		     "unexpected number of arguments %lu expected %lu",
-		     (unsigned long) call.num_params (),
+		     (unsigned long) num_args_to_call,
 		     (unsigned long) type.num_params ());
-      return;
+      return new ErrorType (type.get_ref ());
     }
 
   size_t i = 1;
-  for (auto &argument : call.get_arguments ())
+  for (auto &argument : arguments)
     {
-      Location arg_locus = argument->get_locus ();
+      Location arg_locus = argument.get_locus ();
 
       auto fnparam = type.param_at (i);
       HIR::Pattern *fn_param_pattern = fnparam.first;
@@ -248,25 +296,15 @@ TypeCheckMethodCallExpr::visit (FnType &type)
 	    ? mappings->lookup_location (param_ty->get_ref ())
 	    : fn_param_pattern->get_locus ();
 
-      auto argument_expr_tyty
-	= Resolver::TypeCheckExpr::Resolve (argument.get ());
-      if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
-	{
-	  rust_error_at (
-	    argument->get_locus (),
-	    "failed to resolve type for argument expr in CallExpr");
-	  return;
-	}
-
-      HirId coercion_side_id = argument->get_mappings ().get_hirid ();
+      auto argument_expr_tyty = argument.get_argument_type ();
+      HirId coercion_side_id = argument.get_mappings ().get_hirid ();
       auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
 	coercion_side_id, TyWithLocation (param_ty, param_locus),
-	TyWithLocation (argument_expr_tyty, arg_locus), argument->get_locus ());
+	TyWithLocation (argument_expr_tyty, arg_locus), arg_locus);
       if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
 	{
-	  rust_error_at (argument->get_locus (),
-			 "Type Resolution failure on parameter");
-	  return;
+	  rust_error_at (arg_locus, "Type Resolution failure on parameter");
+	  return new ErrorType (type.get_ref ());
 	}
 
       i++;
@@ -274,15 +312,15 @@ TypeCheckMethodCallExpr::visit (FnType &type)
 
   if (i != num_args_to_call)
     {
-      rust_error_at (call.get_locus (),
+      rust_error_at (call_locus,
 		     "unexpected number of arguments %lu expected %lu",
-		     (unsigned long) i, (unsigned long) call.num_params ());
-      return;
+		     (unsigned long) i, (unsigned long) arguments.size ());
+      return new ErrorType (type.get_ref ());
     }
 
   type.monomorphize ();
 
-  resolved = type.get_return_type ()->monomorphized_clone ();
+  return type.get_return_type ()->monomorphized_clone ();
 }
 
 } // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index aa47328424e..4d1c81112d6 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -84,58 +84,51 @@ private:
   Analysis::Mappings *mappings;
 };
 
-class TypeCheckMethodCallExpr : private TyVisitor
+class Argument
 {
 public:
-  // Resolve the Method parameters and return back the return type
-  static BaseType *go (BaseType *ref, HIR::MethodCallExpr &call,
-		       TyTy::BaseType *adjusted_self,
-		       Resolver::TypeCheckContext *context)
-  {
-    TypeCheckMethodCallExpr checker (call, adjusted_self, context);
-    ref->accept_vis (checker);
-    return checker.resolved;
-  }
+  Argument (Analysis::NodeMapping mapping, BaseType *argument_type,
+	    Location locus)
+    : mapping (mapping), argument_type (argument_type), locus (locus)
+  {}
 
-  void visit (InferType &) override { gcc_unreachable (); }
-  void visit (TupleType &) override { gcc_unreachable (); }
-  void visit (ArrayType &) override { gcc_unreachable (); }
-  void visit (SliceType &) override { gcc_unreachable (); }
-  void visit (BoolType &) override { gcc_unreachable (); }
-  void visit (IntType &) override { gcc_unreachable (); }
-  void visit (UintType &) override { gcc_unreachable (); }
-  void visit (FloatType &) override { gcc_unreachable (); }
-  void visit (USizeType &) override { gcc_unreachable (); }
-  void visit (ISizeType &) override { gcc_unreachable (); }
-  void visit (ErrorType &) override { gcc_unreachable (); }
-  void visit (ADTType &) override { gcc_unreachable (); };
-  void visit (CharType &) override { gcc_unreachable (); }
-  void visit (ReferenceType &) override { gcc_unreachable (); }
-  void visit (PointerType &) override { gcc_unreachable (); }
-  void visit (ParamType &) override { gcc_unreachable (); }
-  void visit (StrType &) override { gcc_unreachable (); }
-  void visit (NeverType &) override { gcc_unreachable (); }
-  void visit (PlaceholderType &) override { gcc_unreachable (); }
-  void visit (ProjectionType &) override { gcc_unreachable (); }
-  void visit (DynamicObjectType &) override { gcc_unreachable (); }
+  Location get_locus () const { return locus; }
 
-  // FIXME
-  void visit (FnPtr &type) override { gcc_unreachable (); }
+  BaseType *get_argument_type () { return argument_type; }
 
-  // call fns
-  void visit (FnType &type) override;
-  void visit (ClosureType &type) override { gcc_unreachable (); }
+  Analysis::NodeMapping get_mappings () const { return mapping; }
 
 private:
-  TypeCheckMethodCallExpr (HIR::MethodCallExpr &c,
+  Analysis::NodeMapping mapping;
+  BaseType *argument_type;
+  Location locus;
+};
+
+class TypeCheckMethodCallExpr
+{
+public:
+  static BaseType *go (FnType *ref, HIR::MethodCallExpr &call,
+		       TyTy::BaseType *adjusted_self,
+		       Resolver::TypeCheckContext *context);
+
+  static BaseType *go (FnType *ref, Analysis::NodeMapping call_mappings,
+		       std::vector<Argument> &args, Location call_locus,
+		       Location receiver_locus, TyTy::BaseType *adjusted_self,
+		       Resolver::TypeCheckContext *context);
+
+protected:
+  BaseType *check (FnType &type);
+
+  TypeCheckMethodCallExpr (Analysis::NodeMapping call_mappings,
+			   std::vector<Argument> &args, Location call_locus,
+			   Location receiver_locus,
 			   TyTy::BaseType *adjusted_self,
-			   Resolver::TypeCheckContext *context)
-    : resolved (nullptr), call (c), adjusted_self (adjusted_self),
-      context (context), mappings (Analysis::Mappings::get ())
-  {}
+			   Resolver::TypeCheckContext *context);
 
-  BaseType *resolved;
-  HIR::MethodCallExpr &call;
+  Analysis::NodeMapping call_mappings;
+  std::vector<Argument> &arguments;
+  Location call_locus;
+  Location receiver_locus;
   TyTy::BaseType *adjusted_self;
   Resolver::TypeCheckContext *context;
   Analysis::Mappings *mappings;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 048/103] gccrs: Add closures to lints and error checking
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (46 preceding siblings ...)
  2023-02-21 12:01 ` [committed 047/103] gccrs: Refactor method call type checking arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 049/103] gccrs: Initial Type resolution for closures arthur.cohen
                   ` (54 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* checks/errors/rust-const-checker.cc (ConstChecker::visit): Visit closures properly.
	* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise.
	* checks/lints/rust-lint-marklive.h: Likewise.
---
 gcc/rust/checks/errors/rust-const-checker.cc  | 4 +++-
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 4 +++-
 gcc/rust/checks/lints/rust-lint-marklive.h    | 5 +++++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 01dc2620767..9161fa1ea2a 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -383,7 +383,9 @@ ConstChecker::visit (FieldAccessExpr &expr)
 
 void
 ConstChecker::visit (ClosureExpr &expr)
-{}
+{
+  expr.get_expr ()->accept_vis (*this);
+}
 
 void
 ConstChecker::visit (BlockExpr &expr)
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 02868794cbc..3d534743eeb 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -454,7 +454,9 @@ UnsafeChecker::visit (FieldAccessExpr &expr)
 
 void
 UnsafeChecker::visit (ClosureExpr &expr)
-{}
+{
+  expr.get_expr ()->accept_vis (*this);
+}
 
 void
 UnsafeChecker::visit (BlockExpr &expr)
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.h b/gcc/rust/checks/lints/rust-lint-marklive.h
index 4caf18ce186..dcc625d0b9d 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.h
+++ b/gcc/rust/checks/lints/rust-lint-marklive.h
@@ -285,6 +285,11 @@ public:
       item->accept_vis (*this);
   }
 
+  void visit (HIR::ClosureExpr &expr) override
+  {
+    expr.get_expr ()->accept_vis (*this);
+  }
+
 private:
   std::vector<HirId> worklist;
   std::set<HirId> liveSymbols;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 049/103] gccrs: Initial Type resolution for closures
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (47 preceding siblings ...)
  2023-02-21 12:01 ` [committed 048/103] gccrs: Add closures to lints and error checking arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 050/103] gccrs: Closure support at CallExpr arthur.cohen
                   ` (53 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* hir/tree/rust-hir-expr.h: Add `get_params` method.
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Typecheck closure nodes.
	(TypeCheckExpr::resolve_fn_trait_call): New function.
	* typecheck/rust-hir-type-check-expr.h: Declare `resolve_fn_trait_call` and
	`resolve_possible_fn_trait_call_method_name`.
	* typecheck/rust-hir-type-check.h: Declare `get_context_type`.
	* typecheck/rust-tyctx.cc (TypeCheckContextItem::get_context_type): New function.
	* typecheck/rust-tyty-cmp.h: Visit closures properly.
	* typecheck/rust-tyty-rules.h: Likewise.
	* typecheck/rust-tyty.cc (BaseType::bounds_compatible): Add commented out assertin.
	(ClosureType::as_string): Implement it.
	(ClosureType::clone): Fix closure cloning.
	(ClosureType::setup_fn_once_output): New function.
	* typecheck/rust-tyty.h: Improve `ClosureType` class and declare `setup_fn_once_output`.
---
 gcc/rust/hir/tree/rust-hir-expr.h             |   2 +
 .../typecheck/rust-hir-type-check-expr.cc     | 308 +++++++++++++++++-
 gcc/rust/typecheck/rust-hir-type-check-expr.h |   7 +
 gcc/rust/typecheck/rust-hir-type-check.h      |   2 +
 gcc/rust/typecheck/rust-tyctx.cc              |  32 ++
 gcc/rust/typecheck/rust-tyty-cmp.h            |  23 ++
 gcc/rust/typecheck/rust-tyty-rules.h          |  40 ++-
 gcc/rust/typecheck/rust-tyty.cc               |  58 +++-
 gcc/rust/typecheck/rust-tyty.h                |  38 ++-
 9 files changed, 479 insertions(+), 31 deletions(-)

diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 4c5caf17ac3..227bacbe641 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -2131,6 +2131,8 @@ public:
   };
   std::unique_ptr<Expr> &get_expr () { return expr; }
 
+  std::vector<ClosureParam> &get_params () { return params; }
+
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 9140b8b1305..85590630378 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -178,16 +178,6 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
 {
   TyTy::BaseType *function_tyty = TypeCheckExpr::Resolve (expr.get_fnexpr ());
 
-  bool valid_tyty = function_tyty->get_kind () == TyTy::TypeKind::ADT
-		    || function_tyty->get_kind () == TyTy::TypeKind::FNDEF
-		    || function_tyty->get_kind () == TyTy::TypeKind::FNPTR;
-  if (!valid_tyty)
-    {
-      rust_error_at (expr.get_locus (),
-		     "Failed to resolve expression of function call");
-      return;
-    }
-
   rust_debug_loc (expr.get_locus (), "resolved_call_expr to: {%s}",
 		  function_tyty->get_name ().c_str ());
 
@@ -214,6 +204,24 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
 	  rust_assert (adt->number_of_variants () == 1);
 	  variant = *adt->get_variants ().at (0);
 	}
+
+      infered
+	= TyTy::TypeCheckCallExpr::go (function_tyty, expr, variant, context);
+      return;
+    }
+
+  bool resolved_fn_trait_call
+    = resolve_fn_trait_call (expr, function_tyty, &infered);
+  if (resolved_fn_trait_call)
+    return;
+
+  bool valid_tyty = function_tyty->get_kind () == TyTy::TypeKind::FNDEF
+		    || function_tyty->get_kind () == TyTy::TypeKind::FNPTR;
+  if (!valid_tyty)
+    {
+      rust_error_at (expr.get_locus (),
+		     "Failed to resolve expression of function call");
+      return;
     }
 
   infered = TyTy::TypeCheckCallExpr::go (function_tyty, expr, variant, context);
@@ -1422,7 +1430,123 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
 void
 TypeCheckExpr::visit (HIR::ClosureExpr &expr)
 {
-  gcc_unreachable ();
+  TypeCheckContextItem &current_context = context->peek_context ();
+  TyTy::FnType *current_context_fndecl = current_context.get_context_type ();
+
+  HirId ref = expr.get_mappings ().get_hirid ();
+  DefId id = expr.get_mappings ().get_defid ();
+  RustIdent ident{current_context_fndecl->get_ident ().path, expr.get_locus ()};
+
+  // get from parent context
+  std::vector<TyTy::SubstitutionParamMapping> subst_refs
+    = current_context_fndecl->clone_substs ();
+
+  std::vector<TyTy::TyVar> parameter_types;
+  for (auto &p : expr.get_params ())
+    {
+      if (p.has_type_given ())
+	{
+	  TyTy::BaseType *param_tyty
+	    = TypeCheckType::Resolve (p.get_type ().get ());
+	  TyTy::TyVar param_ty (param_tyty->get_ref ());
+	  parameter_types.push_back (param_ty);
+
+	  TypeCheckPattern::Resolve (p.get_pattern ().get (),
+				     param_ty.get_tyty ());
+	}
+      else
+	{
+	  TyTy::TyVar param_ty
+	    = TyTy::TyVar::get_implicit_infer_var (p.get_locus ());
+	  parameter_types.push_back (param_ty);
+
+	  TypeCheckPattern::Resolve (p.get_pattern ().get (),
+				     param_ty.get_tyty ());
+	}
+    }
+
+  // we generate an implicit hirid for the closure args
+  HirId implicit_args_id = mappings->get_next_hir_id ();
+  TyTy::TupleType *closure_args
+    = new TyTy::TupleType (implicit_args_id, expr.get_locus (),
+			   parameter_types);
+  context->insert_implicit_type (closure_args);
+
+  Location result_type_locus = expr.has_return_type ()
+				 ? expr.get_return_type ()->get_locus ()
+				 : expr.get_locus ();
+  TyTy::TyVar result_type
+    = expr.has_return_type ()
+	? TyTy::TyVar (
+	  TypeCheckType::Resolve (expr.get_return_type ().get ())->get_ref ())
+	: TyTy::TyVar::get_implicit_infer_var (expr.get_locus ());
+
+  // resolve the block
+  Location closure_expr_locus = expr.get_expr ()->get_locus ();
+  TyTy::BaseType *closure_expr_ty
+    = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+  coercion_site (expr.get_mappings ().get_hirid (),
+		 TyTy::TyWithLocation (result_type.get_tyty (),
+				       result_type_locus),
+		 TyTy::TyWithLocation (closure_expr_ty, closure_expr_locus),
+		 expr.get_locus ());
+
+  // generate the closure type
+  infered = new TyTy::ClosureType (ref, id, ident, closure_args, result_type,
+				   subst_refs);
+
+  // FIXME
+  // all closures automatically inherit the appropriate fn trait. Lets just
+  // assume FnOnce for now. I think this is based on the return type of the
+  // closure
+
+  Analysis::RustLangItem::ItemType lang_item_type
+    = Analysis::RustLangItem::ItemType::FN_ONCE;
+  DefId respective_lang_item_id = UNKNOWN_DEFID;
+  bool lang_item_defined
+    = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id);
+  if (!lang_item_defined)
+    {
+      // FIXME
+      // we need to have a unified way or error'ing when we are missing lang
+      // items that is useful
+      rust_fatal_error (
+	expr.get_locus (), "unable to find lang item: %<%s%>",
+	Analysis::RustLangItem::ToString (lang_item_type).c_str ());
+    }
+  rust_assert (lang_item_defined);
+
+  // these lang items are always traits
+  HIR::Item *item = mappings->lookup_defid (respective_lang_item_id);
+  rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
+  HIR::Trait *trait_item = static_cast<HIR::Trait *> (item);
+
+  TraitReference *trait = TraitResolver::Resolve (*trait_item);
+  rust_assert (!trait->is_error ());
+
+  TyTy::TypeBoundPredicate predicate (*trait, expr.get_locus ());
+
+  // resolve the trait bound where the <(Args)> are the parameter tuple type
+  HIR::GenericArgs args = HIR::GenericArgs::create_empty (expr.get_locus ());
+
+  // lets generate an implicit Type so that it resolves to the implict tuple
+  // type we have created
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, expr.get_mappings ().get_nodeid (),
+				 implicit_args_id, UNKNOWN_LOCAL_DEFID);
+  HIR::TupleType *implicit_tuple
+    = new HIR::TupleType (mapping,
+			  {} // we dont need to fill this out because it will
+			     // auto resolve because the hir id's match
+			  ,
+			  expr.get_locus ());
+  args.get_type_args ().push_back (std::unique_ptr<HIR::Type> (implicit_tuple));
+
+  // apply the arguments
+  predicate.apply_generic_arguments (&args);
+
+  // finally inherit the trait bound
+  infered->inherit_bounds ({predicate});
 }
 
 bool
@@ -1630,6 +1754,168 @@ TypeCheckExpr::resolve_operator_overload (
   return true;
 }
 
+HIR::PathIdentSegment
+TypeCheckExpr::resolve_possible_fn_trait_call_method_name (
+  const TyTy::BaseType &receiver)
+{
+  // Question
+  // do we need to probe possible bounds here? I think not, i think when we
+  // support Fn traits they are explicitly specified
+
+  // FIXME
+  // the logic to map the FnTrait to their respective call trait-item is
+  // duplicated over in the backend/rust-compile-expr.cc
+  for (const auto &bound : receiver.get_specified_bounds ())
+    {
+      bool found_fn = bound.get_name ().compare ("Fn") == 0;
+      bool found_fn_mut = bound.get_name ().compare ("FnMut") == 0;
+      bool found_fn_once = bound.get_name ().compare ("FnOnce") == 0;
+
+      if (found_fn)
+	{
+	  return HIR::PathIdentSegment ("call");
+	}
+      else if (found_fn_mut)
+	{
+	  return HIR::PathIdentSegment ("call_mut");
+	}
+      else if (found_fn_once)
+	{
+	  return HIR::PathIdentSegment ("call_once");
+	}
+    }
+
+  // nothing
+  return HIR::PathIdentSegment ("");
+}
+
+bool
+TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
+				      TyTy::BaseType *receiver_tyty,
+				      TyTy::BaseType **result)
+{
+  // we turn this into a method call expr
+  HIR::PathIdentSegment method_name
+    = resolve_possible_fn_trait_call_method_name (*receiver_tyty);
+  if (method_name.is_error ())
+    return false;
+
+  auto candidates = MethodResolver::Probe (receiver_tyty, method_name);
+  if (candidates.empty ())
+    return false;
+
+  if (candidates.size () > 1)
+    {
+      RichLocation r (expr.get_locus ());
+      for (auto &c : candidates)
+	r.add_range (c.candidate.locus);
+
+      rust_error_at (
+	r, "multiple candidates found for function trait method call %<%s%>",
+	method_name.as_string ().c_str ());
+      return false;
+    }
+
+  if (receiver_tyty->get_kind () == TyTy::TypeKind::CLOSURE)
+    {
+      const TyTy::ClosureType &closure
+	= static_cast<TyTy::ClosureType &> (*receiver_tyty);
+      closure.setup_fn_once_output ();
+    }
+
+  auto candidate = *candidates.begin ();
+  rust_debug_loc (expr.get_locus (),
+		  "resolved call-expr to fn trait: {%u} {%s}",
+		  candidate.candidate.ty->get_ref (),
+		  candidate.candidate.ty->debug_str ().c_str ());
+
+  // Get the adjusted self
+  Adjuster adj (receiver_tyty);
+  TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
+
+  // store the adjustments for code-generation to know what to do which must be
+  // stored onto the receiver to so as we don't trigger duplicate deref mappings
+  // ICE when an argument is a method call
+  HirId autoderef_mappings_id = expr.get_mappings ().get_hirid ();
+  context->insert_autoderef_mappings (autoderef_mappings_id,
+				      std::move (candidate.adjustments));
+  context->insert_receiver (expr.get_mappings ().get_hirid (), receiver_tyty);
+
+  PathProbeCandidate &resolved_candidate = candidate.candidate;
+  TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
+  NodeId resolved_node_id
+    = resolved_candidate.is_impl_candidate ()
+	? resolved_candidate.item.impl.impl_item->get_impl_mappings ()
+	    .get_nodeid ()
+	: resolved_candidate.item.trait.item_ref->get_mappings ().get_nodeid ();
+
+  if (lookup_tyty->get_kind () != TyTy::TypeKind::FNDEF)
+    {
+      RichLocation r (expr.get_locus ());
+      r.add_range (resolved_candidate.locus);
+      rust_error_at (r, "associated impl item is not a method");
+      return false;
+    }
+
+  TyTy::BaseType *lookup = lookup_tyty;
+  TyTy::FnType *fn = static_cast<TyTy::FnType *> (lookup);
+  if (!fn->is_method ())
+    {
+      RichLocation r (expr.get_locus ());
+      r.add_range (resolved_candidate.locus);
+      rust_error_at (r, "associated function is not a method");
+      return false;
+    }
+
+  // fn traits only support tuple argument passing so we need to implicitly set
+  // this up to get the same type checking we get in the rest of the pipeline
+
+  std::vector<TyTy::TyVar> call_args;
+  for (auto &arg : expr.get_arguments ())
+    {
+      TyTy::BaseType *a = TypeCheckExpr::Resolve (arg.get ());
+      call_args.push_back (TyTy::TyVar (a->get_ref ()));
+    }
+
+  // crate implicit tuple
+  HirId implicit_arg_id = mappings->get_next_hir_id ();
+  Analysis::NodeMapping mapping (mappings->get_current_crate (), UNKNOWN_NODEID,
+				 implicit_arg_id, UNKNOWN_LOCAL_DEFID);
+
+  TyTy::TupleType *tuple
+    = new TyTy::TupleType (implicit_arg_id, expr.get_locus (), call_args);
+  context->insert_implicit_type (implicit_arg_id, tuple);
+
+  std::vector<TyTy::Argument> args;
+  TyTy::Argument a (mapping, tuple,
+		    expr.get_locus () /*FIXME is there a better location*/);
+  args.push_back (std::move (a));
+
+  TyTy::BaseType *function_ret_tyty
+    = TyTy::TypeCheckMethodCallExpr::go (fn, expr.get_mappings (), args,
+					 expr.get_locus (), expr.get_locus (),
+					 adjusted_self, context);
+  if (function_ret_tyty == nullptr
+      || function_ret_tyty->get_kind () == TyTy::TypeKind::ERROR)
+    {
+      rust_error_at (expr.get_locus (),
+		     "failed check fn trait call-expr MethodCallExpr");
+      return false;
+    }
+
+  // store the expected fntype
+  context->insert_operator_overload (expr.get_mappings ().get_hirid (), fn);
+
+  // set up the resolved name on the path
+  resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
+				  resolved_node_id);
+
+  // return the result of the function back
+  *result = function_ret_tyty;
+
+  return true;
+}
+
 bool
 TypeCheckExpr::validate_arithmetic_type (
   const TyTy::BaseType *tyty, HIR::ArithmeticOrLogicalExpr::ExprType expr_type)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 7f787fa9766..d800549dea2 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -103,6 +103,13 @@ protected:
 			     HIR::OperatorExprMeta expr, TyTy::BaseType *lhs,
 			     TyTy::BaseType *rhs);
 
+  bool resolve_fn_trait_call (HIR::CallExpr &expr,
+			      TyTy::BaseType *function_tyty,
+			      TyTy::BaseType **result);
+
+  HIR::PathIdentSegment
+  resolve_possible_fn_trait_call_method_name (const TyTy::BaseType &receiver);
+
 private:
   TypeCheckExpr ();
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 2b47c6738b5..adec2f91961 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -70,6 +70,8 @@ public:
     return item.trait_item;
   }
 
+  TyTy::FnType *get_context_type ();
+
 private:
   union Item
   {
diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc
index a0b5c5e849e..886842b0623 100644
--- a/gcc/rust/typecheck/rust-tyctx.cc
+++ b/gcc/rust/typecheck/rust-tyctx.cc
@@ -154,5 +154,37 @@ TypeCheckContext::peek_context ()
   return return_type_stack.back ().first;
 }
 
+// TypeCheckContextItem
+
+TyTy::FnType *
+TypeCheckContextItem::get_context_type ()
+{
+  auto &context = *TypeCheckContext::get ();
+
+  HirId reference = UNKNOWN_HIRID;
+  switch (get_type ())
+    {
+    case ITEM:
+      reference = get_item ()->get_mappings ().get_hirid ();
+      break;
+
+    case IMPL_ITEM:
+      reference = get_impl_item ().second->get_mappings ().get_hirid ();
+      break;
+
+    case TRAIT_ITEM:
+      reference = get_trait_item ()->get_mappings ().get_hirid ();
+      break;
+    }
+
+  rust_assert (reference != UNKNOWN_HIRID);
+
+  TyTy::BaseType *lookup = nullptr;
+  bool ok = context.lookup_type (reference, &lookup);
+  rust_assert (ok);
+  rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
+  return static_cast<TyTy::FnType *> (lookup);
+}
+
 } // namespace Resolver
 } // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index 5dfd2d7184a..293c8bfa641 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -871,6 +871,29 @@ public:
     ok = true;
   }
 
+  void visit (const ClosureType &type) override
+  {
+    if (base->get_def_id () != type.get_def_id ())
+      {
+	BaseCmp::visit (type);
+	return;
+      }
+
+    if (!base->get_parameters ().can_eq (&type.get_parameters (), false))
+      {
+	BaseCmp::visit (type);
+	return;
+      }
+
+    if (!base->get_result_type ().can_eq (&type.get_result_type (), false))
+      {
+	BaseCmp::visit (type);
+	return;
+      }
+
+    ok = true;
+  }
+
 private:
   const BaseType *get_base () const override { return base; }
   const ClosureType *base;
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 7ffffc1dd59..4b1fe4fd418 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -624,7 +624,45 @@ class ClosureRules : public BaseRules
 public:
   ClosureRules (ClosureType *base) : BaseRules (base), base (base) {}
 
-  // TODO
+  void visit (InferType &type) override
+  {
+    if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
+      {
+	BaseRules::visit (type);
+	return;
+      }
+
+    resolved = base->clone ();
+    resolved->set_ref (type.get_ref ());
+  }
+
+  void visit (ClosureType &type) override
+  {
+    if (base->get_def_id () != type.get_def_id ())
+      {
+	BaseRules::visit (type);
+	return;
+      }
+
+    TyTy::BaseType *args_res
+      = base->get_parameters ().unify (&type.get_parameters ());
+    if (args_res == nullptr || args_res->get_kind () == TypeKind::ERROR)
+      {
+	BaseRules::visit (type);
+	return;
+      }
+
+    TyTy::BaseType *res
+      = base->get_result_type ().unify (&type.get_result_type ());
+    if (res == nullptr || res->get_kind () == TypeKind::ERROR)
+      {
+	BaseRules::visit (type);
+	return;
+      }
+
+    resolved = base->clone ();
+    resolved->set_ref (type.get_ref ());
+  }
 
 private:
   BaseType *get_base () override { return base; }
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 462c5bf91fd..0d96c0f04fd 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -27,6 +27,7 @@
 #include "rust-substitution-mapper.h"
 #include "rust-hir-trait-ref.h"
 #include "rust-hir-type-bounds.h"
+#include "rust-hir-trait-resolve.h"
 #include "options.h"
 
 namespace Rust {
@@ -200,6 +201,7 @@ BaseType::bounds_compatible (const BaseType &other, Location locus,
 	  rust_error_at (r,
 			 "bounds not satisfied for %s %<%s%> is not satisfied",
 			 other.get_name ().c_str (), missing_preds.c_str ());
+	  // rust_assert (!emit_error);
 	}
     }
 
@@ -1672,7 +1674,9 @@ ClosureType::accept_vis (TyConstVisitor &vis) const
 std::string
 ClosureType::as_string () const
 {
-  return "TODO";
+  std::string params_buf = parameters->as_string ();
+  return "|" + params_buf + "| {" + result_type.get_tyty ()->as_string ()
+	 + "} {" + raw_bounds_as_string () + "}";
 }
 
 BaseType *
@@ -1699,8 +1703,10 @@ ClosureType::is_equal (const BaseType &other) const
 BaseType *
 ClosureType::clone () const
 {
-  return new ClosureType (get_ref (), get_ty_ref (), ident, id, parameter_types,
-			  result_type, clone_substs (), get_combined_refs ());
+  return new ClosureType (get_ref (), get_ty_ref (), ident, id,
+			  (TyTy::TupleType *) parameters->clone (), result_type,
+			  clone_substs (), get_combined_refs (),
+			  specified_bounds);
 }
 
 BaseType *
@@ -1716,6 +1722,52 @@ ClosureType::handle_substitions (SubstitutionArgumentMappings mappings)
   return nullptr;
 }
 
+void
+ClosureType::setup_fn_once_output () const
+{
+  // lookup the lang items
+  auto fn_once_lang_item = Analysis::RustLangItem::ItemType::FN_ONCE;
+  auto fn_once_output_lang_item
+    = Analysis::RustLangItem::ItemType::FN_ONCE_OUTPUT;
+
+  DefId trait_id = UNKNOWN_DEFID;
+  bool trait_lang_item_defined
+    = mappings->lookup_lang_item (fn_once_lang_item, &trait_id);
+  rust_assert (trait_lang_item_defined);
+
+  DefId trait_item_id = UNKNOWN_DEFID;
+  bool trait_item_lang_item_defined
+    = mappings->lookup_lang_item (fn_once_output_lang_item, &trait_item_id);
+  rust_assert (trait_item_lang_item_defined);
+
+  // resolve to the trait
+  HIR::Item *item = mappings->lookup_defid (trait_id);
+  rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
+  HIR::Trait *trait = static_cast<HIR::Trait *> (item);
+
+  Resolver::TraitReference *trait_ref
+    = Resolver::TraitResolver::Resolve (*trait);
+  rust_assert (!trait_ref->is_error ());
+
+  // resolve to trait item
+  HIR::TraitItem *trait_item
+    = mappings->lookup_trait_item_defid (trait_item_id);
+  rust_assert (trait_item != nullptr);
+  rust_assert (trait_item->get_item_kind ()
+	       == HIR::TraitItem::TraitItemKind::TYPE);
+  std::string item_identifier = trait_item->trait_identifier ();
+
+  // setup associated types  #[lang = "fn_once_output"]
+  Resolver::TraitItemReference *item_reference = nullptr;
+  bool found = trait_ref->lookup_trait_item_by_type (
+    item_identifier, Resolver::TraitItemReference::TraitItemType::TYPE,
+    &item_reference);
+  rust_assert (found);
+
+  // setup
+  item_reference->associated_type_set (&get_result_type ());
+}
+
 void
 ArrayType::accept_vis (TyVisitor &vis)
 {
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index b17f01f67ea..5eaec352567 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1626,31 +1626,35 @@ class ClosureType : public BaseType, public SubstitutionRef
 {
 public:
   ClosureType (HirId ref, DefId id, RustIdent ident,
-	       std::vector<TyVar> parameter_types, TyVar result_type,
+	       TyTy::TupleType *parameters, TyVar result_type,
 	       std::vector<SubstitutionParamMapping> subst_refs,
-	       std::set<HirId> refs = std::set<HirId> ())
+	       std::set<HirId> refs = std::set<HirId> (),
+	       std::vector<TypeBoundPredicate> specified_bounds
+	       = std::vector<TypeBoundPredicate> ())
     : BaseType (ref, ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
 		       SubstitutionArgumentMappings::error ()),
-      parameter_types (std::move (parameter_types)),
-      result_type (std::move (result_type)), id (id)
+      parameters (parameters), result_type (std::move (result_type)), id (id)
   {
     LocalDefId local_def_id = id.localDefId;
     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
+    inherit_bounds (specified_bounds);
   }
 
   ClosureType (HirId ref, HirId ty_ref, RustIdent ident, DefId id,
-	       std::vector<TyVar> parameter_types, TyVar result_type,
+	       TyTy::TupleType *parameters, TyVar result_type,
 	       std::vector<SubstitutionParamMapping> subst_refs,
-	       std::set<HirId> refs = std::set<HirId> ())
+	       std::set<HirId> refs = std::set<HirId> (),
+	       std::vector<TypeBoundPredicate> specified_bounds
+	       = std::vector<TypeBoundPredicate> ())
     : BaseType (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
 		       SubstitutionArgumentMappings::error ()),
-      parameter_types (std::move (parameter_types)),
-      result_type (std::move (result_type)), id (id)
+      parameters (parameters), result_type (std::move (result_type)), id (id)
   {
     LocalDefId local_def_id = id.localDefId;
     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
+    inherit_bounds (specified_bounds);
   }
 
   void accept_vis (TyVisitor &vis) override;
@@ -1669,13 +1673,8 @@ public:
 
   bool is_concrete () const override final
   {
-    for (auto &param : parameter_types)
-      {
-	auto p = param.get_tyty ();
-	if (!p->is_concrete ())
-	  return false;
-      }
-    return result_type.get_tyty ()->is_concrete ();
+    return parameters->is_concrete ()
+	   && result_type.get_tyty ()->is_concrete ();
   }
 
   bool needs_generic_substitutions () const override final
@@ -1693,8 +1692,15 @@ public:
   ClosureType *
   handle_substitions (SubstitutionArgumentMappings mappings) override final;
 
+  TyTy::TupleType &get_parameters () const { return *parameters; }
+  TyTy::BaseType &get_result_type () const { return *result_type.get_tyty (); }
+
+  DefId get_def_id () const { return id; }
+
+  void setup_fn_once_output () const;
+
 private:
-  std::vector<TyVar> parameter_types;
+  TyTy::TupleType *parameters;
   TyVar result_type;
   DefId id;
 };
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 050/103] gccrs: Closure support at CallExpr
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (48 preceding siblings ...)
  2023-02-21 12:01 ` [committed 049/103] gccrs: Initial Type resolution for closures arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 051/103] gccrs: Add missing name resolution to Function type-path segments arthur.cohen
                   ` (52 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-compile-context.h: Add new functions: `insert_closure_decl` and
	`lookup_closure_decl`.
	* backend/rust-compile-expr.cc (CompileExpr::visit): Start compiling Closures properly.
	(CompileExpr::generate_closure_function): New function.
	(CompileExpr::generate_closure_fntype): Likewise.
	* backend/rust-compile-expr.h: Declare `generate_closure_function` and
	`generate_closure_fntype`.
	* backend/rust-compile-type.cc (TyTyResolveCompile::visit): Visit closure types properly.
	* backend/rust-mangle.cc (legacy_mangle_name): Add support for closures.
	* backend/rust-tree.h (RS_CLOSURE_FLAG): Add new tree macro.
	(RS_CLOSURE_TYPE_P): And checking for it on tree nodes.
	* typecheck/rust-tyty.cc (ClosureType::is_equal): Add implementation.

gcc/testsuite/ChangeLog:

	* rust/execute/torture/closure1.rs: New test.
---
 gcc/rust/backend/rust-compile-context.h       |  31 ++
 gcc/rust/backend/rust-compile-expr.cc         | 280 +++++++++++++++++-
 gcc/rust/backend/rust-compile-expr.h          |  10 +
 gcc/rust/backend/rust-compile-type.cc         |  10 +-
 gcc/rust/backend/rust-mangle.cc               |   6 +
 gcc/rust/backend/rust-tree.h                  |   5 +
 gcc/rust/typecheck/rust-tyty.cc               |  13 +-
 .../rust/execute/torture/closure1.rs          |  18 ++
 8 files changed, 361 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/closure1.rs

diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 49f78e19b20..d2d3a53f182 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -147,6 +147,35 @@ public:
     mono_fns[dId].push_back ({ref, fn});
   }
 
+  void insert_closure_decl (const TyTy::ClosureType *ref, tree fn)
+  {
+    auto dId = ref->get_def_id ();
+    auto it = mono_closure_fns.find (dId);
+    if (it == mono_closure_fns.end ())
+      mono_closure_fns[dId] = {};
+
+    mono_closure_fns[dId].push_back ({ref, fn});
+  }
+
+  tree lookup_closure_decl (const TyTy::ClosureType *ref)
+  {
+    auto dId = ref->get_def_id ();
+    auto it = mono_closure_fns.find (dId);
+    if (it == mono_closure_fns.end ())
+      return error_mark_node;
+
+    for (auto &i : it->second)
+      {
+	const TyTy::ClosureType *t = i.first;
+	tree fn = i.second;
+
+	if (ref->is_equal (*t))
+	  return fn;
+      }
+
+    return error_mark_node;
+  }
+
   bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
 			     const TyTy::BaseType *ref = nullptr,
 			     const std::string &asm_name = std::string ())
@@ -343,6 +372,8 @@ private:
   std::vector<tree> loop_begin_labels;
   std::map<DefId, std::vector<std::pair<const TyTy::BaseType *, tree>>>
     mono_fns;
+  std::map<DefId, std::vector<std::pair<const TyTy::ClosureType *, tree>>>
+    mono_closure_fns;
   std::map<HirId, tree> implicit_pattern_bindings;
   std::map<hashval_t, tree> main_variants;
 
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 724a93a68bd..d2d9ae0a233 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1589,9 +1589,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
     }
 
   // must be a tuple constructor
-  bool is_fn = tyty->get_kind () == TyTy::TypeKind::FNDEF
-	       || tyty->get_kind () == TyTy::TypeKind::FNPTR;
-  bool is_adt_ctor = !is_fn;
+  bool is_adt_ctor = tyty->get_kind () == TyTy::TypeKind::ADT;
   if (is_adt_ctor)
     {
       rust_assert (tyty->get_kind () == TyTy::TypeKind::ADT);
@@ -1692,6 +1690,57 @@ CompileExpr::visit (HIR::CallExpr &expr)
     return true;
   };
 
+  auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx);
+
+  // is this a closure call?
+  if (RS_CLOSURE_TYPE_P (TREE_TYPE (fn_address)))
+    {
+      rust_assert (tyty->get_kind () == TyTy::TypeKind::CLOSURE);
+      TyTy::ClosureType *closure = static_cast<TyTy::ClosureType *> (tyty);
+
+      std::vector<tree> tuple_arg_vals;
+      for (auto &argument : expr.get_arguments ())
+	{
+	  auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+	  tuple_arg_vals.push_back (rvalue);
+	}
+
+      tree tuple_args_tyty
+	= TyTyResolveCompile::compile (ctx, &closure->get_parameters ());
+      tree tuple_args
+	= ctx->get_backend ()->constructor_expression (tuple_args_tyty, false,
+						       tuple_arg_vals, -1,
+						       expr.get_locus ());
+
+      // need to apply any autoderef's to the self argument
+      HirId autoderef_mappings_id = expr.get_mappings ().get_hirid ();
+      std::vector<Resolver::Adjustment> *adjustments = nullptr;
+      bool ok
+	= ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
+							&adjustments);
+      rust_assert (ok);
+
+      // apply adjustments for the fn call
+      tree self
+	= resolve_adjustements (*adjustments, fn_address, expr.get_locus ());
+
+      // args are always self, and the tuple of the args we are passing where
+      // self is the path of the call-expr in this case the fn_address
+      std::vector<tree> args;
+      args.push_back (self);
+      args.push_back (tuple_args);
+
+      // get the fn call address
+      tree closure_call_site = ctx->lookup_closure_decl (closure);
+      tree closure_call_address
+	= address_expression (closure_call_site, expr.get_locus ());
+      translated
+	= ctx->get_backend ()->call_expression (closure_call_address, args,
+						nullptr /* static chain ?*/,
+						expr.get_locus ());
+      return;
+    }
+
   bool is_varadic = false;
   if (tyty->get_kind () == TyTy::TypeKind::FNDEF)
     {
@@ -1699,13 +1748,13 @@ CompileExpr::visit (HIR::CallExpr &expr)
       is_varadic = fn->is_varadic ();
     }
 
-  size_t required_num_args;
+  size_t required_num_args = expr.get_arguments ().size ();
   if (tyty->get_kind () == TyTy::TypeKind::FNDEF)
     {
       const TyTy::FnType *fn = static_cast<const TyTy::FnType *> (tyty);
       required_num_args = fn->num_params ();
     }
-  else
+  else if (tyty->get_kind () == TyTy::TypeKind::FNPTR)
     {
       const TyTy::FnPtr *fn = static_cast<const TyTy::FnPtr *> (tyty);
       required_num_args = fn->num_params ();
@@ -1746,8 +1795,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
       args.push_back (rvalue);
     }
 
-  // must be a call to a function
-  auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx);
+  // must be a regular call to a function
   translated = ctx->get_backend ()->call_expression (fn_address, args, nullptr,
 						     expr.get_locus ());
 }
@@ -2806,7 +2854,223 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
 void
 CompileExpr::visit (HIR::ClosureExpr &expr)
 {
-  gcc_unreachable ();
+  TyTy::BaseType *closure_expr_ty = nullptr;
+  if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+				       &closure_expr_ty))
+    {
+      rust_fatal_error (expr.get_locus (),
+			"did not resolve type for this ClosureExpr");
+      return;
+    }
+  rust_assert (closure_expr_ty->get_kind () == TyTy::TypeKind::CLOSURE);
+  TyTy::ClosureType *closure_tyty
+    = static_cast<TyTy::ClosureType *> (closure_expr_ty);
+  tree compiled_closure_tyty = TyTyResolveCompile::compile (ctx, closure_tyty);
+
+  // generate closure function
+  generate_closure_function (expr, *closure_tyty, compiled_closure_tyty);
+
+  // lets ignore state capture for now we need to instantiate the struct anyway
+  // then generate the function
+
+  std::vector<tree> vals;
+  // TODO
+  // setup argument captures based on the mode?
+
+  translated
+    = ctx->get_backend ()->constructor_expression (compiled_closure_tyty, false,
+						   vals, -1, expr.get_locus ());
+}
+
+tree
+CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
+					TyTy::ClosureType &closure_tyty,
+					tree compiled_closure_tyty)
+{
+  TyTy::FnType *fn_tyty = nullptr;
+  tree compiled_fn_type
+    = generate_closure_fntype (expr, closure_tyty, compiled_closure_tyty,
+			       &fn_tyty);
+  if (compiled_fn_type == error_mark_node)
+    return error_mark_node;
+
+  const Resolver::CanonicalPath &parent_canonical_path
+    = closure_tyty.get_ident ().path;
+  Resolver::CanonicalPath path = parent_canonical_path.append (
+    Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "{{closure}}"));
+
+  std::string ir_symbol_name = path.get ();
+  std::string asm_name = ctx->mangle_item (&closure_tyty, path);
+
+  unsigned int flags = 0;
+  tree fndecl
+    = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name,
+				     flags, expr.get_locus ());
+
+  // insert into the context
+  ctx->insert_function_decl (fn_tyty, fndecl);
+  ctx->insert_closure_decl (&closure_tyty, fndecl);
+
+  // setup the parameters
+  std::vector<Bvariable *> param_vars;
+
+  // closure self
+  Bvariable *self_param
+    = ctx->get_backend ()->parameter_variable (fndecl, "$closure",
+					       compiled_closure_tyty,
+					       expr.get_locus ());
+  DECL_ARTIFICIAL (self_param->get_decl ()) = 1;
+  param_vars.push_back (self_param);
+
+  // setup the implicit argument captures
+  // TODO
+
+  // args tuple
+  tree args_type
+    = TyTyResolveCompile::compile (ctx, &closure_tyty.get_parameters ());
+  Bvariable *args_param
+    = ctx->get_backend ()->parameter_variable (fndecl, "args", args_type,
+					       expr.get_locus ());
+  param_vars.push_back (args_param);
+
+  // setup the implicit mappings for the arguments. Since argument passing to
+  // closure functions is done via passing a tuple but the closure body expects
+  // just normal arguments this means we need to destructure them similar to
+  // what we do in MatchExpr's. This means when we have a closure-param of a we
+  // actually setup the destructure to take from the args tuple
+
+  tree args_param_expr = args_param->get_tree (expr.get_locus ());
+  size_t i = 0;
+  for (auto &closure_param : expr.get_params ())
+    {
+      tree compiled_param_var = ctx->get_backend ()->struct_field_expression (
+	args_param_expr, i, closure_param.get_locus ());
+
+      const HIR::Pattern &param_pattern = *closure_param.get_pattern ();
+      ctx->insert_pattern_binding (
+	param_pattern.get_pattern_mappings ().get_hirid (), compiled_param_var);
+      i++;
+    }
+
+  if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
+    return error_mark_node;
+
+  // lookup locals
+  HIR::Expr *function_body = expr.get_expr ().get ();
+  auto body_mappings = function_body->get_mappings ();
+  Resolver::Rib *rib = nullptr;
+  bool ok
+    = ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (), &rib);
+  rust_assert (ok);
+
+  std::vector<Bvariable *> locals
+    = compile_locals_for_block (ctx, *rib, fndecl);
+
+  tree enclosing_scope = NULL_TREE;
+  Location start_location = function_body->get_locus ();
+  Location end_location = function_body->get_locus ();
+  bool is_block_expr
+    = function_body->get_expression_type () == HIR::Expr::ExprType::Block;
+  if (is_block_expr)
+    {
+      HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body);
+      start_location = body->get_locus ();
+      end_location = body->get_end_locus ();
+    }
+
+  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+						start_location, end_location);
+  ctx->push_block (code_block);
+
+  TyTy::BaseType *tyret = &closure_tyty.get_result_type ();
+  bool function_has_return = !closure_tyty.get_result_type ().is_unit ();
+  Bvariable *return_address = nullptr;
+  if (function_has_return)
+    {
+      tree return_type = TyTyResolveCompile::compile (ctx, tyret);
+
+      bool address_is_taken = false;
+      tree ret_var_stmt = NULL_TREE;
+
+      return_address = ctx->get_backend ()->temporary_variable (
+	fndecl, code_block, return_type, NULL, address_is_taken,
+	expr.get_locus (), &ret_var_stmt);
+
+      ctx->add_statement (ret_var_stmt);
+    }
+
+  ctx->push_fn (fndecl, return_address);
+
+  if (is_block_expr)
+    {
+      HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body);
+      compile_function_body (ctx, fndecl, *body, true);
+    }
+  else
+    {
+      tree value = CompileExpr::Compile (function_body, ctx);
+      tree return_expr
+	= ctx->get_backend ()->return_statement (fndecl, {value},
+						 function_body->get_locus ());
+      ctx->add_statement (return_expr);
+    }
+
+  tree bind_tree = ctx->pop_block ();
+
+  gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
+  DECL_SAVED_TREE (fndecl) = bind_tree;
+
+  ctx->pop_fn ();
+  ctx->push_function (fndecl);
+
+  return fndecl;
+}
+
+tree
+CompileExpr::generate_closure_fntype (HIR::ClosureExpr &expr,
+				      const TyTy::ClosureType &closure_tyty,
+				      tree compiled_closure_tyty,
+				      TyTy::FnType **fn_tyty)
+{
+  // grab the specified_bound
+  rust_assert (closure_tyty.num_specified_bounds () == 1);
+  const TyTy::TypeBoundPredicate &predicate
+    = *closure_tyty.get_specified_bounds ().begin ();
+
+  // ensure the fn_once_output associated type is set
+  closure_tyty.setup_fn_once_output ();
+
+  // the function signature is based on the trait bound that the closure
+  // implements which is determined at the type resolution time
+  //
+  // https://github.com/rust-lang/rust/blob/7807a694c2f079fd3f395821bcc357eee8650071/library/core/src/ops/function.rs#L54-L71
+
+  TyTy::TypeBoundPredicateItem item = TyTy::TypeBoundPredicateItem::error ();
+  if (predicate.get_name ().compare ("FnOnce") == 0)
+    {
+      item = predicate.lookup_associated_item ("call_once");
+    }
+  else if (predicate.get_name ().compare ("FnMut") == 0)
+    {
+      item = predicate.lookup_associated_item ("call_mut");
+    }
+  else if (predicate.get_name ().compare ("Fn") == 0)
+    {
+      item = predicate.lookup_associated_item ("call");
+    }
+  else
+    {
+      // FIXME error message?
+      gcc_unreachable ();
+      return error_mark_node;
+    }
+
+  rust_assert (!item.is_error ());
+
+  TyTy::BaseType *item_tyty = item.get_tyty_for_receiver (&closure_tyty);
+  rust_assert (item_tyty->get_kind () == TyTy::TypeKind::FNDEF);
+  *fn_tyty = static_cast<TyTy::FnType *> (item_tyty);
+  return TyTyResolveCompile::compile (ctx, item_tyty);
 }
 
 } // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 7fc3f5e7f4d..c734406e0da 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -142,6 +142,16 @@ protected:
 			  const TyTy::ArrayType &array_tyty, tree array_type,
 			  HIR::ArrayElemsCopied &elems);
 
+protected:
+  tree generate_closure_function (HIR::ClosureExpr &expr,
+				  TyTy::ClosureType &closure_tyty,
+				  tree compiled_closure_tyty);
+
+  tree generate_closure_fntype (HIR::ClosureExpr &expr,
+				const TyTy::ClosureType &closure_tyty,
+				tree compiled_closure_tyty,
+				TyTy::FnType **fn_tyty);
+
 private:
   CompileExpr (Context *ctx);
 
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index fe1b7ce95e3..824cb3a56ef 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -97,9 +97,15 @@ TyTyResolveCompile::visit (const TyTy::InferType &)
 }
 
 void
-TyTyResolveCompile::visit (const TyTy::ClosureType &)
+TyTyResolveCompile::visit (const TyTy::ClosureType &type)
 {
-  gcc_unreachable ();
+  std::vector<Backend::typed_identifier> fields;
+  tree type_record = ctx->get_backend ()->struct_type (fields);
+  RS_CLOSURE_FLAG (type_record) = 1;
+
+  std::string named_struct_str = type.get_ident ().path.get () + "{{closure}}";
+  translated = ctx->get_backend ()->named_type (named_struct_str, type_record,
+						type.get_ident ().locus);
 }
 
 void
diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc
index 4d202078a70..83aefa7997a 100644
--- a/gcc/rust/backend/rust-mangle.cc
+++ b/gcc/rust/backend/rust-mangle.cc
@@ -13,6 +13,8 @@ static const std::string kMangledRef = "$RF$";
 static const std::string kMangledPtr = "$BP$";
 static const std::string kMangledLeftSqParen = "$u5b$";	 // [
 static const std::string kMangledRightSqParen = "$u5d$"; // ]
+static const std::string kMangledLeftBrace = "$u7b$";	 // {
+static const std::string kMangledRightBrace = "$u7d$";	 // }
 static const std::string kQualPathBegin = "_" + kMangledSubstBegin;
 static const std::string kMangledComma = "$C$";
 
@@ -66,6 +68,10 @@ legacy_mangle_name (const std::string &name)
 	m = kMangledLeftSqParen;
       else if (c == ']')
 	m = kMangledRightSqParen;
+      else if (c == '{')
+	m = kMangledLeftBrace;
+      else if (c == '}')
+	m = kMangledRightBrace;
       else if (c == ',')
 	m = kMangledComma;
       else if (c == ':')
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 41dd012bd6d..284fd873c1c 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -82,6 +82,11 @@
 #define SLICE_TYPE_P(TYPE)                                                     \
   (TREE_CODE (TYPE) == RECORD_TYPE && TREE_LANG_FLAG_0 (TYPE))
 
+// lambda?
+#define RS_CLOSURE_FLAG TREE_LANG_FLAG_1
+#define RS_CLOSURE_TYPE_P(TYPE)                                                \
+  (TREE_CODE (TYPE) == RECORD_TYPE && TREE_LANG_FLAG_1 (TYPE))
+
 /* Returns true if NODE is a pointer to member function type.  */
 #define TYPE_PTRMEMFUNC_P(NODE)                                                \
   (TREE_CODE (NODE) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (NODE))
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 0d96c0f04fd..bdb2d909b86 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -1696,8 +1696,17 @@ ClosureType::can_eq (const BaseType *other, bool emit_errors) const
 bool
 ClosureType::is_equal (const BaseType &other) const
 {
-  gcc_unreachable ();
-  return false;
+  if (other.get_kind () != TypeKind::CLOSURE)
+    return false;
+
+  const ClosureType &other2 = static_cast<const ClosureType &> (other);
+  if (get_def_id () != other2.get_def_id ())
+    return false;
+
+  if (!get_parameters ().is_equal (other2.get_parameters ()))
+    return false;
+
+  return get_result_type ().is_equal (other2.get_result_type ());
 }
 
 BaseType *
diff --git a/gcc/testsuite/rust/execute/torture/closure1.rs b/gcc/testsuite/rust/execute/torture/closure1.rs
new file mode 100644
index 00000000000..62afa78a038
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/closure1.rs
@@ -0,0 +1,18 @@
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn main() -> i32 {
+    let closure_annotated = |i: i32| -> i32 { i + 1 };
+
+    let i = 1;
+    closure_annotated(i) - 2
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 051/103] gccrs: Add missing name resolution to Function type-path segments
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (49 preceding siblings ...)
  2023-02-21 12:01 ` [committed 050/103] gccrs: Closure support at CallExpr arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 052/103] gccrs: Add missing hir lowering to function " arthur.cohen
                   ` (51 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): Add missing handling of
	function case.
---
 gcc/rust/resolve/rust-ast-resolve-type.cc | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index d227b8b539a..e5c712aba07 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -149,7 +149,20 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
 	  break;
 
 	case AST::TypePathSegment::SegmentType::FUNCTION:
-	  gcc_unreachable ();
+	  AST::TypePathSegmentFunction *fnseg
+	    = static_cast<AST::TypePathSegmentFunction *> (segment.get ());
+
+	  AST::TypePathFunction &fn = fnseg->get_type_path_function ();
+	  for (auto &param : fn.get_params ())
+	    {
+	      ResolveType::go (param.get ());
+	    }
+
+	  if (fn.has_return_type ())
+	    {
+	      ResolveType::go (fn.get_return_type ().get ());
+	    }
+
 	  break;
 	}
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 052/103] gccrs: Add missing hir lowering to function type-path segments
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (50 preceding siblings ...)
  2023-02-21 12:01 ` [committed 051/103] gccrs: Add missing name resolution to Function type-path segments arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 053/103] gccrs: Add missing type resolution for function type segments arthur.cohen
                   ` (50 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* Make-lang.in: Compile rust-ast-lower-type.cc.
	* ast/rust-path.h: Add `get_locus` method to `TypePathFunction`.
	* hir/rust-ast-lower-base.cc (ASTLowerTypePath::visit): Move implementation to
	rust-ast-lower-type.cc.
	(ASTLowerQualifiedPathInType::visit): Likewise.
	(ASTLoweringType::visit): Likewise.
	* hir/rust-ast-lower-type.h: Move implementations to source file.
	* hir/tree/rust-hir-path.h: Likewise.
	* hir/rust-ast-lower-type.cc: New file.
---
 gcc/rust/Make-lang.in               |   1 +
 gcc/rust/ast/rust-path.h            |   2 +
 gcc/rust/hir/rust-ast-lower-base.cc | 113 --------------
 gcc/rust/hir/rust-ast-lower-type.cc | 232 ++++++++++++++++++++++++++++
 gcc/rust/hir/rust-ast-lower-type.h  |  63 +-------
 gcc/rust/hir/tree/rust-hir-path.h   |  68 ++++----
 6 files changed, 269 insertions(+), 210 deletions(-)
 create mode 100644 gcc/rust/hir/rust-ast-lower-type.cc

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 2f4f409f54f..dddc70a26ec 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -95,6 +95,7 @@ GRS_OBJS = \
     rust/rust-ast-lower-pattern.o \
     rust/rust-ast-lower-item.o \
     rust/rust-ast-lower-expr.o \
+    rust/rust-ast-lower-type.o \
     rust/rust-early-name-resolver.o \
     rust/rust-name-resolver.o \
     rust/rust-ast-resolve.o \
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 9683ad6ad68..b5c9c3aab3a 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -898,6 +898,8 @@ public:
     rust_assert (has_return_type ());
     return return_type;
   }
+
+  Location get_locus () const { return locus; }
 };
 
 // Segment used in type path with a function argument
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 098014ff92b..f5402efe066 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -658,119 +658,6 @@ ASTLoweringBase::lower_self (AST::SelfParam &self)
 			 self.get_locus ());
 }
 
-void
-ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment)
-{
-  std::vector<HIR::GenericArgsBinding> binding_args; // TODO
-
-  std::string segment_name = segment.get_ident_segment ().as_string ();
-  bool has_separating_scope_resolution
-    = segment.get_separating_scope_resolution ();
-
-  auto generic_args = lower_generic_args (segment.get_generic_args ());
-
-  auto crate_num = mappings->get_current_crate ();
-  auto hirid = mappings->get_next_hir_id (crate_num);
-  Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
-				 UNKNOWN_LOCAL_DEFID);
-
-  translated_segment
-    = new HIR::TypePathSegmentGeneric (std::move (mapping), segment_name,
-				       has_separating_scope_resolution,
-				       generic_args, segment.get_locus ());
-}
-
-void
-ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path)
-{
-  auto crate_num = mappings->get_current_crate ();
-  auto hirid = mappings->get_next_hir_id (crate_num);
-  Analysis::NodeMapping qual_mappings (
-    crate_num, path.get_qualified_path_type ().get_node_id (), hirid,
-    UNKNOWN_LOCAL_DEFID);
-
-  HIR::Type *qual_type = ASTLoweringType::translate (
-    path.get_qualified_path_type ().get_type ().get ());
-  HIR::TypePath *qual_trait = ASTLowerTypePath::translate (
-    path.get_qualified_path_type ().get_as_type_path ());
-
-  HIR::QualifiedPathType qual_path_type (
-    qual_mappings, std::unique_ptr<HIR::Type> (qual_type),
-    std::unique_ptr<HIR::TypePath> (qual_trait),
-    path.get_qualified_path_type ().get_locus ());
-
-  translated_segment = nullptr;
-  path.get_associated_segment ()->accept_vis (*this);
-  if (translated_segment == nullptr)
-    {
-      rust_fatal_error (path.get_associated_segment ()->get_locus (),
-			"failed to translate AST TypePathSegment");
-      return;
-    }
-  std::unique_ptr<HIR::TypePathSegment> associated_segment (translated_segment);
-
-  std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments;
-  for (auto &seg : path.get_segments ())
-    {
-      translated_segment = nullptr;
-      seg->accept_vis (*this);
-      if (translated_segment == nullptr)
-	{
-	  rust_fatal_error (seg->get_locus (),
-			    "failed to translte AST TypePathSegment");
-	}
-      translated_segments.push_back (
-	std::unique_ptr<HIR::TypePathSegment> (translated_segment));
-    }
-
-  Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid,
-				 mappings->get_next_localdef_id (crate_num));
-  translated = new HIR::QualifiedPathInType (std::move (mapping),
-					     std::move (qual_path_type),
-					     std::move (associated_segment),
-					     std::move (translated_segments),
-					     path.get_locus ());
-}
-
-void
-ASTLoweringType::visit (AST::TraitObjectTypeOneBound &type)
-{
-  std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
-  HIR::TypeParamBound *translated_bound
-    = ASTLoweringTypeBounds::translate (&type.get_trait_bound ());
-  bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (translated_bound));
-
-  auto crate_num = mappings->get_current_crate ();
-  Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
-				 mappings->get_next_hir_id (crate_num),
-				 mappings->get_next_localdef_id (crate_num));
-
-  translated = new HIR::TraitObjectType (mapping, std::move (bounds),
-					 type.get_locus (), type.is_dyn ());
-}
-
-void
-ASTLoweringType::visit (AST::TraitObjectType &type)
-{
-  std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
-
-  for (auto &bound : type.get_type_param_bounds ())
-    {
-      HIR::TypeParamBound *translated_bound
-	= ASTLoweringTypeBounds::translate (bound.get ());
-      bounds.push_back (
-	std::unique_ptr<HIR::TypeParamBound> (translated_bound));
-    }
-
-  auto crate_num = mappings->get_current_crate ();
-  Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
-				 mappings->get_next_hir_id (crate_num),
-				 mappings->get_next_localdef_id (crate_num));
-
-  translated = new HIR::TraitObjectType (mapping, std::move (bounds),
-					 type.get_locus (), type.is_dyn ());
-}
-
 HIR::Type *
 ASTLoweringBase::lower_type_no_bounds (AST::TypeNoBounds *type)
 {
diff --git a/gcc/rust/hir/rust-ast-lower-type.cc b/gcc/rust/hir/rust-ast-lower-type.cc
new file mode 100644
index 00000000000..92a14f4dacf
--- /dev/null
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -0,0 +1,232 @@
+// Copyright (C) 2020-2022 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-lower-type.h"
+
+namespace Rust {
+namespace HIR {
+
+HIR::TypePath *
+ASTLowerTypePath::translate (AST::TypePath &type)
+{
+  ASTLowerTypePath resolver;
+  type.accept_vis (resolver);
+  rust_assert (resolver.translated != nullptr);
+  return resolver.translated;
+}
+
+void
+ASTLowerTypePath::visit (AST::TypePathSegmentFunction &segment)
+{
+  auto crate_num = mappings->get_current_crate ();
+  auto hirid = mappings->get_next_hir_id (crate_num);
+  Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
+
+  AST::TypePathFunction &fn = segment.get_type_path_function ();
+  std::vector<std::unique_ptr<HIR::Type>> inputs;
+  for (auto &param : fn.get_params ())
+    {
+      HIR::Type *hir_type = ASTLoweringType::translate (param.get ());
+      inputs.push_back (std::unique_ptr<HIR::Type> (hir_type));
+    }
+
+  HIR::Type *result_type
+    = fn.has_return_type ()
+	? ASTLoweringType::translate (fn.get_return_type ().get ())
+	: nullptr;
+
+  HIR::TypePathFunction function_path (std::move (inputs),
+				       std::unique_ptr<HIR::Type> (
+					 result_type));
+
+  translated_segment = new HIR::TypePathSegmentFunction (
+    mapping, std::move (ident), segment.get_separating_scope_resolution (),
+    std::move (function_path), segment.get_locus ());
+}
+
+void
+ASTLowerTypePath::visit (AST::TypePathSegment &segment)
+{
+  auto crate_num = mappings->get_current_crate ();
+  auto hirid = mappings->get_next_hir_id (crate_num);
+  Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
+				 UNKNOWN_LOCAL_DEFID);
+
+  HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
+  translated_segment
+    = new HIR::TypePathSegment (std::move (mapping), ident,
+				segment.get_separating_scope_resolution (),
+				segment.get_locus ());
+}
+
+void
+ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment)
+{
+  std::vector<HIR::GenericArgsBinding> binding_args; // TODO
+
+  std::string segment_name = segment.get_ident_segment ().as_string ();
+  bool has_separating_scope_resolution
+    = segment.get_separating_scope_resolution ();
+
+  auto generic_args = lower_generic_args (segment.get_generic_args ());
+
+  auto crate_num = mappings->get_current_crate ();
+  auto hirid = mappings->get_next_hir_id (crate_num);
+  Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated_segment
+    = new HIR::TypePathSegmentGeneric (std::move (mapping), segment_name,
+				       has_separating_scope_resolution,
+				       generic_args, segment.get_locus ());
+}
+
+void
+ASTLowerTypePath::visit (AST::TypePath &path)
+{
+  std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments;
+
+  for (auto &seg : path.get_segments ())
+    {
+      translated_segment = nullptr;
+      seg->accept_vis (*this);
+      if (translated_segment == nullptr)
+	{
+	  rust_fatal_error (seg->get_locus (),
+			    "failed to translate AST TypePathSegment");
+	}
+      translated_segments.push_back (
+	std::unique_ptr<HIR::TypePathSegment> (translated_segment));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  auto hirid = mappings->get_next_hir_id (crate_num);
+  Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid,
+				 mappings->get_next_localdef_id (crate_num));
+
+  translated
+    = new HIR::TypePath (std::move (mapping), std::move (translated_segments),
+			 path.get_locus (),
+			 path.has_opening_scope_resolution_op ());
+}
+
+HIR::QualifiedPathInType *
+ASTLowerQualifiedPathInType::translate (AST::QualifiedPathInType &type)
+{
+  ASTLowerQualifiedPathInType resolver;
+  type.accept_vis (resolver);
+  rust_assert (resolver.translated != nullptr);
+  return resolver.translated;
+}
+
+void
+ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path)
+{
+  auto crate_num = mappings->get_current_crate ();
+  auto hirid = mappings->get_next_hir_id (crate_num);
+  Analysis::NodeMapping qual_mappings (
+    crate_num, path.get_qualified_path_type ().get_node_id (), hirid,
+    UNKNOWN_LOCAL_DEFID);
+
+  HIR::Type *qual_type = ASTLoweringType::translate (
+    path.get_qualified_path_type ().get_type ().get ());
+  HIR::TypePath *qual_trait = ASTLowerTypePath::translate (
+    path.get_qualified_path_type ().get_as_type_path ());
+
+  HIR::QualifiedPathType qual_path_type (
+    qual_mappings, std::unique_ptr<HIR::Type> (qual_type),
+    std::unique_ptr<HIR::TypePath> (qual_trait),
+    path.get_qualified_path_type ().get_locus ());
+
+  translated_segment = nullptr;
+  path.get_associated_segment ()->accept_vis (*this);
+  if (translated_segment == nullptr)
+    {
+      rust_fatal_error (path.get_associated_segment ()->get_locus (),
+			"failed to translate AST TypePathSegment");
+      return;
+    }
+  std::unique_ptr<HIR::TypePathSegment> associated_segment (translated_segment);
+
+  std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments;
+  for (auto &seg : path.get_segments ())
+    {
+      translated_segment = nullptr;
+      seg->accept_vis (*this);
+      if (translated_segment == nullptr)
+	{
+	  rust_fatal_error (seg->get_locus (),
+			    "failed to translte AST TypePathSegment");
+	}
+      translated_segments.push_back (
+	std::unique_ptr<HIR::TypePathSegment> (translated_segment));
+    }
+
+  Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid,
+				 mappings->get_next_localdef_id (crate_num));
+  translated = new HIR::QualifiedPathInType (std::move (mapping),
+					     std::move (qual_path_type),
+					     std::move (associated_segment),
+					     std::move (translated_segments),
+					     path.get_locus ());
+}
+
+void
+ASTLoweringType::visit (AST::TraitObjectTypeOneBound &type)
+{
+  std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
+  HIR::TypeParamBound *translated_bound
+    = ASTLoweringTypeBounds::translate (&type.get_trait_bound ());
+  bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (translated_bound));
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  translated = new HIR::TraitObjectType (mapping, std::move (bounds),
+					 type.get_locus (), type.is_dyn ());
+}
+
+void
+ASTLoweringType::visit (AST::TraitObjectType &type)
+{
+  std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
+
+  for (auto &bound : type.get_type_param_bounds ())
+    {
+      HIR::TypeParamBound *translated_bound
+	= ASTLoweringTypeBounds::translate (bound.get ());
+      bounds.push_back (
+	std::unique_ptr<HIR::TypeParamBound> (translated_bound));
+    }
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  translated = new HIR::TraitObjectType (mapping, std::move (bounds),
+					 type.get_locus (), type.is_dyn ());
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 56442110e07..a0761023ce8 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -32,59 +32,12 @@ protected:
   using Rust::HIR::ASTLoweringBase::visit;
 
 public:
-  static HIR::TypePath *translate (AST::TypePath &type)
-  {
-    ASTLowerTypePath resolver;
-    type.accept_vis (resolver);
-    rust_assert (resolver.translated != nullptr);
-    return resolver.translated;
-  }
-
-  void visit (AST::TypePathSegmentFunction &) override { gcc_unreachable (); }
-
-  void visit (AST::TypePathSegment &segment) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    auto hirid = mappings->get_next_hir_id (crate_num);
-    Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
-				   UNKNOWN_LOCAL_DEFID);
-
-    HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
-    translated_segment
-      = new HIR::TypePathSegment (std::move (mapping), ident,
-				  segment.get_separating_scope_resolution (),
-				  segment.get_locus ());
-  }
+  static HIR::TypePath *translate (AST::TypePath &type);
 
+  void visit (AST::TypePathSegmentFunction &segment) override;
+  void visit (AST::TypePathSegment &segment) override;
   void visit (AST::TypePathSegmentGeneric &segment) override;
-
-  void visit (AST::TypePath &path) override
-  {
-    std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments;
-
-    for (auto &seg : path.get_segments ())
-      {
-	translated_segment = nullptr;
-	seg->accept_vis (*this);
-	if (translated_segment == nullptr)
-	  {
-	    rust_fatal_error (seg->get_locus (),
-			      "failed to translate AST TypePathSegment");
-	  }
-	translated_segments.push_back (
-	  std::unique_ptr<HIR::TypePathSegment> (translated_segment));
-      }
-
-    auto crate_num = mappings->get_current_crate ();
-    auto hirid = mappings->get_next_hir_id (crate_num);
-    Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid,
-				   mappings->get_next_localdef_id (crate_num));
-
-    translated
-      = new HIR::TypePath (std::move (mapping), std::move (translated_segments),
-			   path.get_locus (),
-			   path.has_opening_scope_resolution_op ());
-  }
+  void visit (AST::TypePath &path) override;
 
 protected:
   HIR::TypePathSegment *translated_segment;
@@ -98,13 +51,7 @@ class ASTLowerQualifiedPathInType : public ASTLowerTypePath
   using ASTLowerTypePath::visit;
 
 public:
-  static HIR::QualifiedPathInType *translate (AST::QualifiedPathInType &type)
-  {
-    ASTLowerQualifiedPathInType resolver;
-    type.accept_vis (resolver);
-    rust_assert (resolver.translated != nullptr);
-    return resolver.translated;
-  }
+  static HIR::QualifiedPathInType *translate (AST::QualifiedPathInType &type);
 
   void visit (AST::QualifiedPathInType &path) override;
 
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index 64df6f7fd02..fa8347b2cf8 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -529,24 +529,9 @@ protected:
 struct TypePathFunction
 {
 private:
-  // TODO: remove
-  /*bool has_inputs;
-  TypePathFnInputs inputs;*/
-  // inlined from TypePathFnInputs
   std::vector<std::unique_ptr<Type> > inputs;
-
-  // bool has_type;
   std::unique_ptr<Type> return_type;
 
-  // FIXME: think of better way to mark as invalid than taking up storage
-  bool is_invalid;
-
-  // TODO: should this have location info?
-
-protected:
-  // Constructor only used to create invalid type path functions.
-  TypePathFunction (bool is_invalid) : is_invalid (is_invalid) {}
-
 public:
   // Returns whether the return type of the function has been specified.
   bool has_return_type () const { return return_type != nullptr; }
@@ -554,31 +539,19 @@ public:
   // Returns whether the function has inputs.
   bool has_inputs () const { return !inputs.empty (); }
 
-  // Returns whether function is in an error state.
-  bool is_error () const { return is_invalid; }
-
-  // Creates an error state function.
-  static TypePathFunction create_error () { return TypePathFunction (true); }
-
-  // Constructor
-  TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
-		    Type *type = nullptr)
-    : inputs (std::move (inputs)), return_type (type), is_invalid (false)
-  {}
-  // FIXME: deprecated
-
   // Constructor
   TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
-		    std::unique_ptr<Type> type = nullptr)
-    : inputs (std::move (inputs)), return_type (std::move (type)),
-      is_invalid (false)
+		    std::unique_ptr<Type> type)
+    : inputs (std::move (inputs)), return_type (std::move (type))
   {}
 
   // Copy constructor with clone
   TypePathFunction (TypePathFunction const &other)
-    : return_type (other.return_type->clone_type ()),
-      is_invalid (other.is_invalid)
   {
+    return_type = other.has_return_type ()
+		    ? other.get_return_type ()->clone_type ()
+		    : nullptr;
+
     inputs.reserve (other.inputs.size ());
     for (const auto &e : other.inputs)
       inputs.push_back (e->clone_type ());
@@ -589,8 +562,9 @@ public:
   // Overloaded assignment operator to clone type
   TypePathFunction &operator= (TypePathFunction const &other)
   {
-    return_type = other.return_type->clone_type ();
-    is_invalid = other.is_invalid;
+    return_type = other.has_return_type ()
+		    ? other.get_return_type ()->clone_type ()
+		    : nullptr;
 
     inputs.reserve (other.inputs.size ());
     for (const auto &e : other.inputs)
@@ -604,6 +578,23 @@ public:
   TypePathFunction &operator= (TypePathFunction &&other) = default;
 
   std::string as_string () const;
+
+  const std::vector<std::unique_ptr<Type> > &get_params () const
+  {
+    return inputs;
+  };
+  std::vector<std::unique_ptr<Type> > &get_params () { return inputs; };
+
+  const std::unique_ptr<Type> &get_return_type () const
+  {
+    rust_assert (has_return_type ());
+    return return_type;
+  };
+  std::unique_ptr<Type> &get_return_type ()
+  {
+    rust_assert (has_return_type ());
+    return return_type;
+  };
 };
 
 // Segment used in type path with a function argument
@@ -638,10 +629,9 @@ public:
 
   void accept_vis (HIRFullVisitor &vis) override;
 
-  virtual SegmentType get_type () const override final
-  {
-    return SegmentType::FUNCTION;
-  }
+  SegmentType get_type () const override final { return SegmentType::FUNCTION; }
+
+  TypePathFunction &get_function_path () { return function_path; }
 
 protected:
   // Use covariance to override base class method
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 053/103] gccrs: Add missing type resolution for function type segments
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (51 preceding siblings ...)
  2023-02-21 12:01 ` [committed 052/103] gccrs: Add missing hir lowering to function " arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 054/103] gccrs: Support Closure calls as generic trait bounds arthur.cohen
                   ` (49 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* typecheck/rust-tyty-bounds.cc (TypeCheckBase::get_predicate_from_bound): Add missing
	implementation.
---
 gcc/rust/typecheck/rust-tyty-bounds.cc | 69 +++++++++++++++++++++++---
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 1a2ed3b7422..20a81ada6c4 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -84,16 +84,71 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path)
     = HIR::GenericArgs::create_empty (type_path.get_locus ());
 
   auto &final_seg = type_path.get_final_segment ();
-  if (final_seg->is_generic_segment ())
+  switch (final_seg->get_type ())
     {
-      auto final_generic_seg
-	= static_cast<HIR::TypePathSegmentGeneric *> (final_seg.get ());
-      if (final_generic_seg->has_generic_args ())
-	{
-	  args = final_generic_seg->get_generic_args ();
-	}
+      case HIR::TypePathSegment::SegmentType::GENERIC: {
+	auto final_generic_seg
+	  = static_cast<HIR::TypePathSegmentGeneric *> (final_seg.get ());
+	if (final_generic_seg->has_generic_args ())
+	  {
+	    args = final_generic_seg->get_generic_args ();
+	  }
+      }
+      break;
+
+      case HIR::TypePathSegment::SegmentType::FUNCTION: {
+	auto final_function_seg
+	  = static_cast<HIR::TypePathSegmentFunction *> (final_seg.get ());
+	auto &fn = final_function_seg->get_function_path ();
+
+	// we need to make implicit generic args which must be an implicit Tuple
+	auto crate_num = mappings->get_current_crate ();
+	HirId implicit_args_id = mappings->get_next_hir_id ();
+	Analysis::NodeMapping mapping (crate_num,
+				       final_seg->get_mappings ().get_nodeid (),
+				       implicit_args_id, UNKNOWN_LOCAL_DEFID);
+
+	std::vector<std::unique_ptr<HIR::Type>> params_copy;
+	for (auto &p : fn.get_params ())
+	  {
+	    params_copy.push_back (p->clone_type ());
+	  }
+
+	HIR::TupleType *implicit_tuple
+	  = new HIR::TupleType (mapping, std::move (params_copy),
+				final_seg->get_locus ());
+
+	std::vector<std::unique_ptr<HIR::Type>> inputs;
+	inputs.push_back (std::unique_ptr<HIR::Type> (implicit_tuple));
+
+	args = HIR::GenericArgs ({} /* lifetimes */,
+				 std::move (inputs) /* type_args*/,
+				 {} /* binding_args*/, {} /* const_args */,
+				 final_seg->get_locus ());
+
+	// resolve the fn_once_output type
+	TyTy::BaseType *fn_once_output_ty
+	  = fn.has_return_type ()
+	      ? TypeCheckType::Resolve (fn.get_return_type ().get ())
+	      : TyTy::TupleType::get_unit_type (
+		final_seg->get_mappings ().get_hirid ());
+	context->insert_implicit_type (final_seg->get_mappings ().get_hirid (),
+				       fn_once_output_ty);
+
+	// setup the associated type.. ??
+	// fn_once_output_ty->debug ();
+      }
+      break;
+
+    default:
+      /* nothing to do */
+      break;
     }
 
+  // FIXME
+  // I think this should really be just be if the !args.is_empty() because
+  // someone might wrongly apply generic arguments where they should not and
+  // they will be missing error diagnostics
   if (predicate.requires_generic_args ())
     {
       // this is applying generic arguments to a trait reference
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 054/103] gccrs: Support Closure calls as generic trait bounds
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (52 preceding siblings ...)
  2023-02-21 12:01 ` [committed 053/103] gccrs: Add missing type resolution for function type segments arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 055/103] gccrs: Implement the inline visitor arthur.cohen
                   ` (48 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-compile-expr.cc (CompileExpr::visit): Refactor checking of closures.
	(CompileExpr::generate_possible_fn_trait_call): New function.
	* backend/rust-compile-expr.h: Declare `generate_possible_fn_trait_call`.

gcc/testsuite/ChangeLog:

	* rust/execute/torture/closure2.rs: New test.
---
 gcc/rust/backend/rust-compile-expr.cc         | 116 +++++++++++-------
 gcc/rust/backend/rust-compile-expr.h          |   3 +
 .../rust/execute/torture/closure2.rs          |  32 +++++
 3 files changed, 104 insertions(+), 47 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/closure2.rs

diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index d2d9ae0a233..8169ba02b84 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1693,53 +1693,10 @@ CompileExpr::visit (HIR::CallExpr &expr)
   auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx);
 
   // is this a closure call?
-  if (RS_CLOSURE_TYPE_P (TREE_TYPE (fn_address)))
-    {
-      rust_assert (tyty->get_kind () == TyTy::TypeKind::CLOSURE);
-      TyTy::ClosureType *closure = static_cast<TyTy::ClosureType *> (tyty);
-
-      std::vector<tree> tuple_arg_vals;
-      for (auto &argument : expr.get_arguments ())
-	{
-	  auto rvalue = CompileExpr::Compile (argument.get (), ctx);
-	  tuple_arg_vals.push_back (rvalue);
-	}
-
-      tree tuple_args_tyty
-	= TyTyResolveCompile::compile (ctx, &closure->get_parameters ());
-      tree tuple_args
-	= ctx->get_backend ()->constructor_expression (tuple_args_tyty, false,
-						       tuple_arg_vals, -1,
-						       expr.get_locus ());
-
-      // need to apply any autoderef's to the self argument
-      HirId autoderef_mappings_id = expr.get_mappings ().get_hirid ();
-      std::vector<Resolver::Adjustment> *adjustments = nullptr;
-      bool ok
-	= ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
-							&adjustments);
-      rust_assert (ok);
-
-      // apply adjustments for the fn call
-      tree self
-	= resolve_adjustements (*adjustments, fn_address, expr.get_locus ());
-
-      // args are always self, and the tuple of the args we are passing where
-      // self is the path of the call-expr in this case the fn_address
-      std::vector<tree> args;
-      args.push_back (self);
-      args.push_back (tuple_args);
-
-      // get the fn call address
-      tree closure_call_site = ctx->lookup_closure_decl (closure);
-      tree closure_call_address
-	= address_expression (closure_call_site, expr.get_locus ());
-      translated
-	= ctx->get_backend ()->call_expression (closure_call_address, args,
-						nullptr /* static chain ?*/,
-						expr.get_locus ());
-      return;
-    }
+  bool possible_trait_call
+    = generate_possible_fn_trait_call (expr, fn_address, &translated);
+  if (possible_trait_call)
+    return;
 
   bool is_varadic = false;
   if (tyty->get_kind () == TyTy::TypeKind::FNDEF)
@@ -3073,5 +3030,70 @@ CompileExpr::generate_closure_fntype (HIR::ClosureExpr &expr,
   return TyTyResolveCompile::compile (ctx, item_tyty);
 }
 
+bool
+CompileExpr::generate_possible_fn_trait_call (HIR::CallExpr &expr,
+					      tree receiver, tree *result)
+{
+  TyTy::FnType *fn_sig = nullptr;
+  bool found_overload = ctx->get_tyctx ()->lookup_operator_overload (
+    expr.get_mappings ().get_hirid (), &fn_sig);
+  if (!found_overload)
+    return false;
+
+  auto id = fn_sig->get_ty_ref ();
+  auto dId = fn_sig->get_id ();
+
+  tree function = error_mark_node;
+  bool found_closure = ctx->lookup_function_decl (id, &function, dId, fn_sig);
+  if (!found_closure)
+    {
+      // something went wrong we still return true as this was meant to be an fn
+      // trait call
+      *result = error_mark_node;
+      return true;
+    }
+
+  // need to apply any autoderef's to the self argument
+  HirId autoderef_mappings_id = expr.get_mappings ().get_hirid ();
+  std::vector<Resolver::Adjustment> *adjustments = nullptr;
+  bool ok = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
+							  &adjustments);
+  rust_assert (ok);
+
+  // apply adjustments for the fn call
+  tree self = resolve_adjustements (*adjustments, receiver, expr.get_locus ());
+
+  // resolve the arguments
+  std::vector<tree> tuple_arg_vals;
+  for (auto &argument : expr.get_arguments ())
+    {
+      auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+      tuple_arg_vals.push_back (rvalue);
+    }
+
+  // this is always the 2nd argument in the function signature
+  tree fnty = TREE_TYPE (function);
+  tree fn_arg_tys = TYPE_ARG_TYPES (fnty);
+  tree tuple_args_tyty_chain = TREE_CHAIN (fn_arg_tys);
+  tree tuple_args_tyty = TREE_VALUE (tuple_args_tyty_chain);
+
+  tree tuple_args
+    = ctx->get_backend ()->constructor_expression (tuple_args_tyty, false,
+						   tuple_arg_vals, -1,
+						   expr.get_locus ());
+
+  // args are always self, and the tuple of the args we are passing where
+  // self is the path of the call-expr in this case the fn_address
+  std::vector<tree> args;
+  args.push_back (self);
+  args.push_back (tuple_args);
+
+  tree call_address = address_expression (function, expr.get_locus ());
+  *result = ctx->get_backend ()->call_expression (call_address, args,
+						  nullptr /* static chain ?*/,
+						  expr.get_locus ());
+  return true;
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index c734406e0da..150a7a4788a 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -152,6 +152,9 @@ protected:
 				tree compiled_closure_tyty,
 				TyTy::FnType **fn_tyty);
 
+  bool generate_possible_fn_trait_call (HIR::CallExpr &expr, tree receiver,
+					tree *result);
+
 private:
   CompileExpr (Context *ctx);
 
diff --git a/gcc/testsuite/rust/execute/torture/closure2.rs b/gcc/testsuite/rust/execute/torture/closure2.rs
new file mode 100644
index 00000000000..45b3b5ce8b4
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/closure2.rs
@@ -0,0 +1,32 @@
+// { dg-output "3\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn f<F: FnOnce(i32) -> i32>(g: F) {
+    let call = g(1);
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, call);
+    }
+}
+
+pub fn main() -> i32 {
+    let a = |i: i32| {
+        let b = i + 2;
+        b
+    };
+    f(a);
+    0
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 055/103] gccrs: Implement the inline visitor
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (53 preceding siblings ...)
  2023-02-21 12:01 ` [committed 054/103] gccrs: Support Closure calls as generic trait bounds arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 056/103] gccrs: rust: Allow gccrs to build on x86_64-apple-darwin with clang/libc++ arthur.cohen
                   ` (47 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, YizhePKU

From: YizhePKU <yizhe@pku.edu.cn>

gcc/rust/ChangeLog:

	* util/rust-inline-visitor.h: New file.
---
 gcc/rust/util/rust-inline-visitor.h | 95 +++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 gcc/rust/util/rust-inline-visitor.h

diff --git a/gcc/rust/util/rust-inline-visitor.h b/gcc/rust/util/rust-inline-visitor.h
new file mode 100644
index 00000000000..18920d9f93a
--- /dev/null
+++ b/gcc/rust/util/rust-inline-visitor.h
@@ -0,0 +1,95 @@
+// Copyright (C) 2021-2022 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/>.
+
+// An improved implementation of the inline visitor.
+// Original idea from https://members.accu.org/index.php/articles/2021
+
+#ifndef RUST_INLINE_VISITOR
+#define RUST_INLINE_VISITOR
+
+#include <utility>
+#include <type_traits>
+
+namespace Rust {
+
+// Wrapper for the target Visitor we're matching against.
+// Consumes the final nullptr of the _args linked list.
+template <typename TargetVisitor> struct EmptyVisitor : TargetVisitor
+{
+  EmptyVisitor (std::nullptr_t ptr) {}
+
+  using TargetVisitor::visit;
+};
+
+// Wrapper for a (possibly incomplete) Visitor.
+template <typename BaseVisitor, typename Args> struct VisitorWrapper
+{
+  // Lambdas are stored in _args as a linked list and passed to the actual
+  // visitor when end_visitor() is called.
+  Args _args;
+
+  // The actual visitor being created.
+  // Each visitor inherits from the last one and implements one more visit().
+  template <typename T, typename F> struct Visitor : BaseVisitor
+  {
+    F _f;
+
+    Visitor (std::pair<F, Args> &&args)
+      : BaseVisitor (std::move (args.second)), _f (std::move (args.first))
+    {}
+
+    using BaseVisitor::visit;
+    virtual void visit (T &t) final override { _f (t); }
+  };
+
+  VisitorWrapper (Args &&args) : _args (std::move (args)) {}
+
+  // Add another visit() method to the visitor.
+  // _args will be moved over, so don't keep the old wrapper around.
+  template <typename T, typename F>
+  VisitorWrapper<Visitor<T, F>, std::pair<F, Args>> on (F &&f)
+  {
+    return VisitorWrapper<Visitor<T, F>, std::pair<F, Args>> (
+      std::make_pair (std::move (f), std::move (_args)));
+  }
+
+  // Returns the finished visitor.
+  // NOTE: The reference implementation has a bug that exposes this method even
+  // when BaseVisitor is still an abstract class. The C++11 standard states that
+  // "An abstract class shall not be used [...] as a function return type". GCC
+  // rejects the buggy code as expected, but Clang accepts the code as long as
+  // the method is not actually called. Maybe this is a bug in Clang?
+  template <typename T = BaseVisitor>
+  typename std::enable_if<std::is_constructible<T, Args>::value, T>::type
+  end_visitor ()
+  {
+    return T (std::move (_args));
+  }
+};
+
+// The entry point.
+template <typename TargetVisitor>
+VisitorWrapper<EmptyVisitor<TargetVisitor>, std::nullptr_t>
+begin_visitor ()
+{
+  return VisitorWrapper<EmptyVisitor<TargetVisitor>, std::nullptr_t> (nullptr);
+}
+
+} // namespace Rust
+
+#endif
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 056/103] gccrs: rust: Allow gccrs to build on x86_64-apple-darwin with clang/libc++
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (54 preceding siblings ...)
  2023-02-21 12:01 ` [committed 055/103] gccrs: Implement the inline visitor arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 057/103] gccrs: builtins: Rename all bang macro handlers arthur.cohen
                   ` (46 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Simon Cook

From: Simon Cook <simon.cook@embecosm.com>

gcc/rust/ChangeLog:

	* util/rust-inline-visitor.h: Remove some offending system includes.
---
 gcc/rust/util/rust-inline-visitor.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/gcc/rust/util/rust-inline-visitor.h b/gcc/rust/util/rust-inline-visitor.h
index 18920d9f93a..105a67b8c5c 100644
--- a/gcc/rust/util/rust-inline-visitor.h
+++ b/gcc/rust/util/rust-inline-visitor.h
@@ -22,9 +22,6 @@
 #ifndef RUST_INLINE_VISITOR
 #define RUST_INLINE_VISITOR
 
-#include <utility>
-#include <type_traits>
-
 namespace Rust {
 
 // Wrapper for the target Visitor we're matching against.
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 057/103] gccrs: builtins: Rename all bang macro handlers
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (55 preceding siblings ...)
  2023-02-21 12:01 ` [committed 056/103] gccrs: rust: Allow gccrs to build on x86_64-apple-darwin with clang/libc++ arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 058/103] gccrs: intrinsics: Add `sorry_handler` intrinsic handler arthur.cohen
                   ` (45 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* expand/rust-macro-builtins.cc (MacroBuiltin::assert): Rename to...
	(MacroBuiltin::assert_handler): ..this.
	(MacroBuiltin::file): Rename to...
	(MacroBuiltin::file_handler): ..this.
	(MacroBuiltin::column): Rename to...
	(MacroBuiltin::column_handler): ..this.
	(MacroBuiltin::include_bytes): Rename to...
	(MacroBuiltin::include_bytes_handler): ..this.
	(MacroBuiltin::include_str): Rename to...
	(MacroBuiltin::include_str_handler): ..this.
	(MacroBuiltin::compile_error): Rename to...
	(MacroBuiltin::compile_error_handler): ..this.
	(MacroBuiltin::concat): Rename to...
	(MacroBuiltin::concat_handler): ..this.
	(MacroBuiltin::env): Rename to...
	(MacroBuiltin::env_handler): ..this.
	(MacroBuiltin::cfg): Rename to...
	(MacroBuiltin::cfg_handler): ..this.
	(MacroBuiltin::include): Rename to...
	(MacroBuiltin::include_handler): ..this.
	(MacroBuiltin::line): Rename to...
	(MacroBuiltin::line_handler): ..this.
	* expand/rust-macro-builtins.h: Rename all handlers.
	* util/rust-hir-map.cc (Mappings::insert_macro_def): Use new handler
	names.
---
 gcc/rust/expand/rust-macro-builtins.cc | 25 ++++++++------
 gcc/rust/expand/rust-macro-builtins.h  | 47 ++++++++++++--------------
 gcc/rust/util/rust-hir-map.cc          | 22 ++++++------
 3 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index a2129e84a46..9bed3ddbe79 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -265,7 +265,7 @@ load_file_bytes (const char *filename)
 } // namespace
 
 AST::Fragment
-MacroBuiltin::assert (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::assert_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   rust_debug ("assert!() called");
 
@@ -273,7 +273,7 @@ MacroBuiltin::assert (Location invoc_locus, AST::MacroInvocData &invoc)
 }
 
 AST::Fragment
-MacroBuiltin::file (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::file_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto current_file
     = Session::get_instance ().linemap->location_file (invoc_locus);
@@ -283,7 +283,7 @@ MacroBuiltin::file (Location invoc_locus, AST::MacroInvocData &invoc)
 }
 
 AST::Fragment
-MacroBuiltin::column (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::column_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto current_column
     = Session::get_instance ().linemap->location_to_column (invoc_locus);
@@ -300,7 +300,8 @@ MacroBuiltin::column (Location invoc_locus, AST::MacroInvocData &invoc)
    &'static [u8; N].  */
 
 AST::Fragment
-MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::include_bytes_handler (Location invoc_locus,
+				     AST::MacroInvocData &invoc)
 {
   /* Get target filename from the macro invocation, which is treated as a path
      relative to the include!-ing file (currently being compiled).  */
@@ -343,7 +344,8 @@ MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc)
    expression of type &'static str.  */
 
 AST::Fragment
-MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::include_str_handler (Location invoc_locus,
+				   AST::MacroInvocData &invoc)
 {
   /* Get target filename from the macro invocation, which is treated as a path
      relative to the include!-ing file (currently being compiled).  */
@@ -368,7 +370,8 @@ MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc)
 /* Expand builtin macro compile_error!("error"), which forces a compile error
    during the compile time. */
 AST::Fragment
-MacroBuiltin::compile_error (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::compile_error_handler (Location invoc_locus,
+				     AST::MacroInvocData &invoc)
 {
   auto lit_expr
     = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus,
@@ -386,7 +389,7 @@ MacroBuiltin::compile_error (Location invoc_locus, AST::MacroInvocData &invoc)
    into a string with no delimiter. */
 
 AST::Fragment
-MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::concat_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto invoc_token_tree = invoc.get_delim_tok_tree ();
   MacroInvocLexer lex (invoc_token_tree.to_token_stream ());
@@ -437,7 +440,7 @@ MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc)
    compile time. */
 
 AST::Fragment
-MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::env_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto invoc_token_tree = invoc.get_delim_tok_tree ();
   MacroInvocLexer lex (invoc_token_tree.to_token_stream ());
@@ -495,7 +498,7 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc)
 }
 
 AST::Fragment
-MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::cfg_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   // only parse if not already parsed
   if (!invoc.is_parsed ())
@@ -534,7 +537,7 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc)
  scope compile time. */
 
 AST::Fragment
-MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::include_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   /* Get target filename from the macro invocation, which is treated as a path
      relative to the include!-ing file (currently being compiled).  */
@@ -588,7 +591,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
 }
 
 AST::Fragment
-MacroBuiltin::line (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::line_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {
   auto current_line
     = Session::get_instance ().linemap->location_to_line (invoc_locus);
diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h
index c65bd940189..6d7a0123ab3 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -60,45 +60,42 @@
  * of the `Mappings` class.
  */
 
-/* If assert is defined as a macro this file will not parse, so undefine this
-   before continuing.  */
-// TODO: Rename all functions here `*_handler`
-#ifdef assert
-#undef assert
-#endif
-
 namespace Rust {
 class MacroBuiltin
 {
 public:
-  static AST::Fragment assert (Location invoc_locus,
-			       AST::MacroInvocData &invoc);
+  static AST::Fragment assert_handler (Location invoc_locus,
+				       AST::MacroInvocData &invoc);
 
-  static AST::Fragment file (Location invoc_locus, AST::MacroInvocData &invoc);
+  static AST::Fragment file_handler (Location invoc_locus,
+				     AST::MacroInvocData &invoc);
 
-  static AST::Fragment column (Location invoc_locus,
-			       AST::MacroInvocData &invoc);
+  static AST::Fragment column_handler (Location invoc_locus,
+				       AST::MacroInvocData &invoc);
 
-  static AST::Fragment include_bytes (Location invoc_locus,
-				      AST::MacroInvocData &invoc);
+  static AST::Fragment include_bytes_handler (Location invoc_locus,
+					      AST::MacroInvocData &invoc);
 
-  static AST::Fragment include_str (Location invoc_locus,
-				    AST::MacroInvocData &invoc);
+  static AST::Fragment include_str_handler (Location invoc_locus,
+					    AST::MacroInvocData &invoc);
 
-  static AST::Fragment compile_error (Location invoc_locus,
-				      AST::MacroInvocData &invoc);
+  static AST::Fragment compile_error_handler (Location invoc_locus,
+					      AST::MacroInvocData &invoc);
 
-  static AST::Fragment concat (Location invoc_locus,
-			       AST::MacroInvocData &invoc);
+  static AST::Fragment concat_handler (Location invoc_locus,
+				       AST::MacroInvocData &invoc);
 
-  static AST::Fragment env (Location invoc_locus, AST::MacroInvocData &invoc);
+  static AST::Fragment env_handler (Location invoc_locus,
+				    AST::MacroInvocData &invoc);
 
-  static AST::Fragment cfg (Location invoc_locus, AST::MacroInvocData &invoc);
+  static AST::Fragment cfg_handler (Location invoc_locus,
+				    AST::MacroInvocData &invoc);
 
-  static AST::Fragment include (Location invoc_locus,
-				AST::MacroInvocData &invoc);
+  static AST::Fragment include_handler (Location invoc_locus,
+					AST::MacroInvocData &invoc);
 
-  static AST::Fragment line (Location invoc_locus, AST::MacroInvocData &invoc);
+  static AST::Fragment line_handler (Location invoc_locus,
+				     AST::MacroInvocData &invoc);
 };
 } // namespace Rust
 
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index bee0682e9b4..1fc32038d19 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -843,17 +843,17 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
   static std::map<
     std::string, std::function<AST::Fragment (Location, AST::MacroInvocData &)>>
     builtin_macros = {
-      {"assert", MacroBuiltin::assert},
-      {"file", MacroBuiltin::file},
-      {"line", MacroBuiltin::line},
-      {"column", MacroBuiltin::column},
-      {"include_bytes", MacroBuiltin::include_bytes},
-      {"include_str", MacroBuiltin::include_str},
-      {"compile_error", MacroBuiltin::compile_error},
-      {"concat", MacroBuiltin::concat},
-      {"env", MacroBuiltin::env},
-      {"cfg", MacroBuiltin::cfg},
-      {"include", MacroBuiltin::include},
+      {"assert", MacroBuiltin::assert_handler},
+      {"file", MacroBuiltin::file_handler},
+      {"line", MacroBuiltin::line_handler},
+      {"column", MacroBuiltin::column_handler},
+      {"include_bytes", MacroBuiltin::include_bytes_handler},
+      {"include_str", MacroBuiltin::include_str_handler},
+      {"compile_error", MacroBuiltin::compile_error_handler},
+      {"concat", MacroBuiltin::concat_handler},
+      {"env", MacroBuiltin::env_handler},
+      {"cfg", MacroBuiltin::cfg_handler},
+      {"include", MacroBuiltin::include_handler},
     };
 
   auto outer_attrs = macro->get_outer_attrs ();
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 058/103] gccrs: intrinsics: Add `sorry_handler` intrinsic handler
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (56 preceding siblings ...)
  2023-02-21 12:01 ` [committed 057/103] gccrs: builtins: Rename all bang macro handlers arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 059/103] gccrs: constexpr: Add `rust_sorry_at` in places relying on init values arthur.cohen
                   ` (44 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-compile-intrinsic.cc (sorry_handler): New intrinsic handler.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/intrinsics-3.rs: New test.
---
 gcc/rust/backend/rust-compile-intrinsic.cc         | 10 ++++++++++
 gcc/testsuite/rust/compile/torture/intrinsics-3.rs |  9 +++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/torture/intrinsics-3.rs

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index a418b863210..2a2091ccc25 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -93,6 +93,15 @@ prefetch_write_data (Context *ctx, TyTy::FnType *fntype)
   return prefetch_data_handler (ctx, fntype, Prefetch::Write);
 }
 
+static inline tree
+sorry_handler (Context *ctx, TyTy::FnType *fntype)
+{
+  rust_sorry_at (fntype->get_locus (), "intrinsic %qs is not yet implemented",
+		 fntype->get_identifier ().c_str ());
+
+  return error_mark_node;
+}
+
 static const std::map<std::string,
 		      std::function<tree (Context *, TyTy::FnType *)>>
   generic_intrinsics = {
@@ -107,6 +116,7 @@ static const std::map<std::string,
     {"copy_nonoverlapping", &copy_nonoverlapping_handler},
     {"prefetch_read_data", &prefetch_read_data},
     {"prefetch_write_data", &prefetch_write_data},
+    {"atomic_load", &sorry_handler},
 };
 
 Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-3.rs b/gcc/testsuite/rust/compile/torture/intrinsics-3.rs
new file mode 100644
index 00000000000..1acb3533c08
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-3.rs
@@ -0,0 +1,9 @@
+extern "rust-intrinsic" {
+    fn not_an_intrinsic();
+    fn atomic_load(); // { dg-message "sorry, unimplemented: intrinsic .atomic_load. is not yet implemented" }
+}
+
+fn main() {
+    unsafe { not_an_intrinsic() }; // { dg-error "unknown builtin intrinsic: not_an_intrinsic" }
+    unsafe { atomic_load() };
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 059/103] gccrs: constexpr: Add `rust_sorry_at` in places relying on init values
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (57 preceding siblings ...)
  2023-02-21 12:01 ` [committed 058/103] gccrs: intrinsics: Add `sorry_handler` intrinsic handler arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 060/103] gccrs: intrinsics: Add early implementation for atomic_store_{seqcst, relaxed, release} arthur.cohen
                   ` (43 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-constexpr.cc (build_anon_member_initialization): Workaround uninitialized
	values.
	(build_data_member_initialization): Likewise.
---
 gcc/rust/backend/rust-constexpr.cc | 96 +++++++++++++++---------------
 1 file changed, 49 insertions(+), 47 deletions(-)

diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 8623816236c..23d940d04ce 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -3658,49 +3658,48 @@ eval_call_expression (const constexpr_ctx *ctx, tree t, bool lval,
    whose constructor we are processing.  Add the initializer to the vector
    and return true to indicate success.  */
 
-static bool
-build_anon_member_initialization (tree member, tree init,
-				  vec<constructor_elt, va_gc> **vec_outer)
-{
-  /* MEMBER presents the relevant fields from the inside out, but we need
-     to build up the initializer from the outside in so that we can reuse
-     previously built CONSTRUCTORs if this is, say, the second field in an
-     anonymous struct.  So we use a vec as a stack.  */
-  auto_vec<tree, 2> fields;
-  do
-    {
-      fields.safe_push (TREE_OPERAND (member, 1));
-      member = TREE_OPERAND (member, 0);
-    }
-  while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
-	 && TREE_CODE (member) == COMPONENT_REF);
-
-  /* VEC has the constructor elements vector for the context of FIELD.
-     If FIELD is an anonymous aggregate, we will push inside it.  */
-  vec<constructor_elt, va_gc> **vec = vec_outer;
-  tree field;
-  while (field = fields.pop (), ANON_AGGR_TYPE_P (TREE_TYPE (field)))
-    {
-      tree ctor;
-      /* If there is already an outer constructor entry for the anonymous
-	 aggregate FIELD, use it; otherwise, insert one.  */
-      if (vec_safe_is_empty (*vec) || (*vec)->last ().index != field)
-	{
-	  ctor = build_constructor (TREE_TYPE (field), NULL);
-	  CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
-	}
-      else
-	ctor = (*vec)->last ().value;
-      vec = &CONSTRUCTOR_ELTS (ctor);
-    }
-
-  /* Now we're at the innermost field, the one that isn't an anonymous
-     aggregate.  Add its initializer to the CONSTRUCTOR and we're done.  */
-  gcc_assert (fields.is_empty ());
-  CONSTRUCTOR_APPEND_ELT (*vec, field, init);
-
-  return true;
-}
+// static bool
+// build_anon_member_initialization (tree member, tree init,
+// 				  vec<constructor_elt, va_gc> **vec_outer)
+// {
+//   /* MEMBER presents the relevant fields from the inside out, but we need
+//      to build up the initializer from the outside in so that we can reuse
+//      previously built CONSTRUCTORs if this is, say, the second field in an
+//      anonymous struct.  So we use a vec as a stack.  */
+//   auto_vec<tree, 2> fields;
+//   do
+//     {
+//       fields.safe_push (TREE_OPERAND (member, 1));
+//       member = TREE_OPERAND (member, 0);
+//   } while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
+// 	   && TREE_CODE (member) == COMPONENT_REF);
+//
+//   /* VEC has the constructor elements vector for the context of FIELD.
+//      If FIELD is an anonymous aggregate, we will push inside it.  */
+//   vec<constructor_elt, va_gc> **vec = vec_outer;
+//   tree field;
+//   while (field = fields.pop (), ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+//     {
+//       tree ctor;
+//       /* If there is already an outer constructor entry for the anonymous
+// 	 aggregate FIELD, use it; otherwise, insert one.  */
+//       if (vec_safe_is_empty (*vec) || (*vec)->last ().index != field)
+// 	{
+// 	  ctor = build_constructor (TREE_TYPE (field), NULL);
+// 	  CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
+// 	}
+//       else
+// 	ctor = (*vec)->last ().value;
+//       vec = &CONSTRUCTOR_ELTS (ctor);
+//     }
+//
+//   /* Now we're at the innermost field, the one that isn't an anonymous
+//      aggregate.  Add its initializer to the CONSTRUCTOR and we're done.  */
+//   gcc_assert (fields.is_empty ());
+//   CONSTRUCTOR_APPEND_ELT (*vec, field, init);
+//
+//   return true;
+// }
 
 ///* V is a vector of constructor elements built up for the base and member
 //   initializers of a constructor for TYPE.  They need to be in increasing
@@ -3750,7 +3749,7 @@ build_anon_member_initialization (tree member, tree init,
 static bool
 build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
 {
-  tree member, init;
+  tree member;
   if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
     t = TREE_OPERAND (t, 0);
   if (TREE_CODE (t) == EXPR_STMT)
@@ -3835,7 +3834,8 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
 	member = TREE_OPERAND (member, 1);
       else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
 	/* Initializing a member of an anonymous union.  */
-	return build_anon_member_initialization (member, init, vec);
+	rust_sorry_at (Location (), "cannot handle value initialization yet");
+      // return build_anon_member_initialization (member, init, vec);
       else
 	/* We're initializing a vtable pointer in a base.  Leave it as
 	   COMPONENT_REF so we remember the path to get to the vfield.  */
@@ -3845,9 +3845,11 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
   /* Value-initialization can produce multiple initializers for the
      same field; use the last one.  */
   if (!vec_safe_is_empty (*vec) && (*vec)->last ().index == member)
-    (*vec)->last ().value = init;
+    rust_sorry_at (Location (), "cannot handle value initialization yet");
+  // (*vec)->last ().value = init;
   else
-    CONSTRUCTOR_APPEND_ELT (*vec, member, init);
+    rust_sorry_at (Location (), "cannot handle value initialization yet");
+  // CONSTRUCTOR_APPEND_ELT (*vec, member, init);
   return true;
 }
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 060/103] gccrs: intrinsics: Add early implementation for atomic_store_{seqcst, relaxed, release}
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (58 preceding siblings ...)
  2023-02-21 12:01 ` [committed 059/103] gccrs: constexpr: Add `rust_sorry_at` in places relying on init values arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 061/103] gccrs: intrinsics: Add unchecked operation intrinsics arthur.cohen
                   ` (42 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-builtins.cc (BuiltinsContext::setup_atomic_fns): New function.
	(BuiltinsContext::setup): Call `setup_atomic_fns`.
	* backend/rust-builtins.h: Declare `setup_atomic_fns`.
	* backend/rust-compile-intrinsic.cc (atomic_store_handler_inner): New function.
	(atomic_store_handler): New handler.
	(make_unsigned_long_tree): Add helper around making unsigned long trees.
	(prefetch_data_handler): Use `make_unsigned_long_tree`.
	(build_atomic_builtin_name): New function.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/intrinsics-4.rs: New test.
	* rust/compile/torture/intrinsics-5.rs: New test.
	* rust/execute/torture/atomic_store.rs: New test.
---
 gcc/rust/backend/rust-builtins.cc             |  36 ++++
 gcc/rust/backend/rust-builtins.h              |   2 +-
 gcc/rust/backend/rust-compile-intrinsic.cc    | 165 +++++++++++++++---
 .../rust/compile/torture/intrinsics-4.rs      |  20 +++
 .../rust/compile/torture/intrinsics-5.rs      |  35 ++++
 .../rust/execute/torture/atomic_store.rs      |  32 ++++
 6 files changed, 268 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/torture/intrinsics-4.rs
 create mode 100644 gcc/testsuite/rust/compile/torture/intrinsics-5.rs
 create mode 100644 gcc/testsuite/rust/execute/torture/atomic_store.rs

diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
index d6f8cb6f495..64e06e1a240 100644
--- a/gcc/rust/backend/rust-builtins.cc
+++ b/gcc/rust/backend/rust-builtins.cc
@@ -68,11 +68,47 @@ BuiltinsContext::setup_math_fns ()
 		  math_function_type_f32, builtin_const);
 }
 
+void
+BuiltinsContext::setup_atomic_fns ()
+{
+  define_builtin ("atomic_store", BUILT_IN_ATOMIC_STORE, "__atomic_store", NULL,
+		  build_function_type_list (void_type_node, size_type_node,
+					    build_pointer_type (void_type_node),
+					    const_ptr_type_node,
+					    integer_type_node, NULL_TREE),
+		  0);
+  define_builtin ("atomic_store_n", BUILT_IN_ATOMIC_STORE_N, "__atomic_store_n",
+		  NULL,
+		  build_varargs_function_type_list (void_type_node, NULL_TREE),
+		  0);
+  define_builtin ("atomic_store_1", BUILT_IN_ATOMIC_STORE_1, "__atomic_store_1",
+		  NULL,
+		  build_varargs_function_type_list (void_type_node, NULL_TREE),
+		  0);
+  define_builtin ("atomic_store_2", BUILT_IN_ATOMIC_STORE_2, "__atomic_store_2",
+		  NULL,
+		  build_varargs_function_type_list (void_type_node, NULL_TREE),
+		  0);
+  define_builtin ("atomic_store_4", BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4",
+		  NULL,
+		  build_varargs_function_type_list (void_type_node, NULL_TREE),
+		  0);
+  define_builtin ("atomic_store_8", BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8",
+		  NULL,
+		  build_varargs_function_type_list (void_type_node, NULL_TREE),
+		  0);
+  define_builtin ("atomic_store_16", BUILT_IN_ATOMIC_STORE_16,
+		  "__atomic_store_16", NULL,
+		  build_varargs_function_type_list (void_type_node, NULL_TREE),
+		  0);
+}
+
 void
 BuiltinsContext::setup ()
 {
   setup_math_fns ();
   setup_overflow_fns ();
+  setup_atomic_fns ();
 
   define_builtin ("unreachable", BUILT_IN_UNREACHABLE, "__builtin_unreachable",
 		  NULL, build_function_type (void_type_node, void_list_node),
diff --git a/gcc/rust/backend/rust-builtins.h b/gcc/rust/backend/rust-builtins.h
index e421fa43755..c2825107faf 100644
--- a/gcc/rust/backend/rust-builtins.h
+++ b/gcc/rust/backend/rust-builtins.h
@@ -86,8 +86,8 @@ private:
   BuiltinsContext ();
 
   void setup_overflow_fns ();
-
   void setup_math_fns ();
+  void setup_atomic_fns ();
 
   void setup ();
 
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 2a2091ccc25..7c592dabb38 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -93,6 +93,17 @@ prefetch_write_data (Context *ctx, TyTy::FnType *fntype)
   return prefetch_data_handler (ctx, fntype, Prefetch::Write);
 }
 
+static tree
+atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering);
+
+static inline std::function<tree (Context *, TyTy::FnType *)>
+atomic_store_handler (int ordering)
+{
+  return [ordering] (Context *ctx, TyTy::FnType *fntype) {
+    return atomic_store_handler_inner (ctx, fntype, ordering);
+  };
+}
+
 static inline tree
 sorry_handler (Context *ctx, TyTy::FnType *fntype)
 {
@@ -105,18 +116,22 @@ sorry_handler (Context *ctx, TyTy::FnType *fntype)
 static const std::map<std::string,
 		      std::function<tree (Context *, TyTy::FnType *)>>
   generic_intrinsics = {
-    {"offset", &offset_handler},
-    {"size_of", &sizeof_handler},
-    {"transmute", &transmute_handler},
-    {"rotate_left", &rotate_left_handler},
-    {"rotate_right", &rotate_right_handler},
-    {"wrapping_add", &wrapping_add_handler},
-    {"wrapping_sub", &wrapping_sub_handler},
-    {"wrapping_mul", &wrapping_mul_handler},
-    {"copy_nonoverlapping", &copy_nonoverlapping_handler},
-    {"prefetch_read_data", &prefetch_read_data},
-    {"prefetch_write_data", &prefetch_write_data},
-    {"atomic_load", &sorry_handler},
+    {"offset", offset_handler},
+    {"size_of", sizeof_handler},
+    {"transmute", transmute_handler},
+    {"rotate_left", rotate_left_handler},
+    {"rotate_right", rotate_right_handler},
+    {"wrapping_add", wrapping_add_handler},
+    {"wrapping_sub", wrapping_sub_handler},
+    {"wrapping_mul", wrapping_mul_handler},
+    {"copy_nonoverlapping", copy_nonoverlapping_handler},
+    {"prefetch_read_data", prefetch_read_data},
+    {"prefetch_write_data", prefetch_write_data},
+    {"atomic_load", sorry_handler},
+    {"atomic_store_seqcst", atomic_store_handler (__ATOMIC_SEQ_CST)},
+    {"atomic_store_release", atomic_store_handler (__ATOMIC_RELEASE)},
+    {"atomic_store_relaxed", atomic_store_handler (__ATOMIC_RELAXED)},
+    {"atomic_store_unordered", atomic_store_handler (__ATOMIC_RELAXED)},
 };
 
 Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -551,6 +566,16 @@ copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype)
   return fndecl;
 }
 
+static tree
+make_unsigned_long_tree (Context *ctx, unsigned long value)
+{
+  mpz_t mpz_value;
+  mpz_init_set_ui (mpz_value, value);
+
+  return ctx->get_backend ()->integer_constant_expression (integer_type_node,
+							   mpz_value);
+}
+
 static tree
 prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
 {
@@ -576,16 +601,8 @@ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
 
   auto addr = ctx->get_backend ()->var_expression (args[0], Location ());
   auto locality = ctx->get_backend ()->var_expression (args[1], Location ());
+  auto rw_flag = make_unsigned_long_tree (ctx, kind == Prefetch::Write ? 1 : 0);
 
-  mpz_t zero;
-  mpz_t one;
-  mpz_init_set_ui (zero, 0);
-  mpz_init_set_ui (one, 1);
-
-  auto rw_flag_value = kind == Prefetch::Write ? one : zero;
-  auto rw_flag
-    = ctx->get_backend ()->integer_constant_expression (integer_type_node,
-							rw_flag_value);
   auto prefetch_raw = NULL_TREE;
   auto ok
     = BuiltinsContext::get ().lookup_simple_builtin ("prefetch", &prefetch_raw);
@@ -597,6 +614,9 @@ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
     = ctx->get_backend ()->call_expression (prefetch, {addr, rw_flag, locality},
 					    nullptr, Location ());
 
+  TREE_READONLY (prefetch_call) = 0;
+  TREE_SIDE_EFFECTS (prefetch_call) = 1;
+
   ctx->add_statement (prefetch_call);
 
   finalize_intrinsic_block (ctx, fndecl);
@@ -604,5 +624,108 @@ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
   return fndecl;
 }
 
+static std::string
+build_atomic_builtin_name (Location locus, tree operand_type)
+{
+  static const std::map<std::string, std::string> allowed_types = {
+    {"i8", "1"},    {"i16", "2"},   {"i32", "4"},   {"i64", "8"},
+    {"i128", "16"}, {"isize", "8"}, {"u8", "1"},    {"u16", "2"},
+    {"u32", "4"},   {"u64", "8"},   {"u128", "16"}, {"usize", "8"},
+  };
+
+  // TODO: Can we maybe get the generic version (atomic_store_n) to work... This
+  // would be so much better
+
+  std::string result = "atomic_store_";
+
+  auto type_name = std::string (TYPE_NAME_STRING (operand_type));
+  if (type_name == "usize" || type_name == "isize")
+    {
+      rust_sorry_at (
+	locus, "atomics are not yet available for size types (usize, isize)");
+      return "";
+    }
+
+  // FIXME: Can we have a better looking name here?
+  // Instead of `<crate>::<module>::<type>`?
+  // Maybe instead of giving the tree node, pass the resolved Tyty before it
+  // gets compiled?
+  //
+  // Or should we perform this check somwhere else in the compiler?
+  auto type_size_str = allowed_types.find (type_name);
+  if (type_size_str == allowed_types.end ())
+    {
+      rust_error_at (locus,
+		     "atomic intrinsics are only available for basic integer "
+		     "types: got type %qs",
+		     type_name.c_str ());
+      return "";
+    }
+
+  result += type_size_str->second;
+
+  return result;
+}
+
+static tree
+atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering)
+{
+  rust_assert (fntype->get_params ().size () == 2);
+  rust_assert (fntype->get_num_substitutions () == 1);
+
+  tree lookup = NULL_TREE;
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
+
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+  // Most intrinsic functions are pure but not the atomic ones
+  TREE_READONLY (fndecl) = 0;
+  TREE_SIDE_EFFECTS (fndecl) = 1;
+
+  // setup the params
+  std::vector<Bvariable *> param_vars;
+  std::vector<tree> types;
+  compile_fn_params (ctx, fntype, fndecl, &param_vars, &types);
+
+  auto ok = ctx->get_backend ()->function_set_parameters (fndecl, param_vars);
+  rust_assert (ok);
+
+  enter_intrinsic_block (ctx, fndecl);
+
+  auto dst = ctx->get_backend ()->var_expression (param_vars[0], Location ());
+  TREE_READONLY (dst) = 0;
+
+  auto value = ctx->get_backend ()->var_expression (param_vars[1], Location ());
+  auto memorder = make_unsigned_long_tree (ctx, ordering);
+
+  auto builtin_name
+    = build_atomic_builtin_name (fntype->get_locus (), TREE_TYPE (types[0]));
+  if (builtin_name.empty ())
+    return error_mark_node;
+
+  tree atomic_store_raw = nullptr;
+  BuiltinsContext::get ().lookup_simple_builtin (builtin_name,
+						 &atomic_store_raw);
+  rust_assert (atomic_store_raw);
+
+  auto atomic_store
+    = build_fold_addr_expr_loc (Location ().gcc_location (), atomic_store_raw);
+
+  auto store_call
+    = ctx->get_backend ()->call_expression (atomic_store,
+					    {dst, value, memorder}, nullptr,
+					    Location ());
+
+  TREE_READONLY (store_call) = 0;
+  TREE_SIDE_EFFECTS (store_call) = 1;
+
+  ctx->add_statement (store_call);
+
+  finalize_intrinsic_block (ctx, fndecl);
+
+  return fndecl;
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-4.rs b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
new file mode 100644
index 00000000000..243d4460089
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
@@ -0,0 +1,20 @@
+trait Copy {}
+
+extern "rust-intrinsic" {
+    pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
+    // pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
+}
+
+fn main() {
+    let mut dst = 15;
+    let new_value = 14;
+
+    unsafe {
+        atomic_store_seqcst(&mut dst, new_value);
+        atomic_store_release(&mut dst, new_value);
+        atomic_store_relaxed(&mut dst, new_value);
+        // atomic_store_unordered(&mut dst, new_value);
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
new file mode 100644
index 00000000000..e0087720cc4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
@@ -0,0 +1,35 @@
+trait Copy {}
+
+extern "rust-intrinsic" {
+    pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, value: T);
+    // { dg-error "atomic intrinsics are only available for basic integer types: got type .intrinsics_5::VeryLargeType." "" { target *-*-* } .-1 }
+    // { dg-error "atomic intrinsics are only available for basic integer types: got type .bool." "" { target *-*-* } .-2 }
+}
+
+struct VeryLargeType {
+    a0: i128,
+    a1: i128,
+    a2: i128,
+    a3: i128,
+}
+
+impl VeryLargeType {
+    pub fn new(value: i128) -> VeryLargeType {
+        VeryLargeType {
+            a0: value,
+            a1: 0,
+            a2: 0,
+            a3: 0,
+        }
+    }
+}
+
+fn main() {
+    let mut dst = VeryLargeType::new(0);
+    let mut b = false;
+
+    unsafe {
+        atomic_store_seqcst(&mut dst, VeryLargeType::new(1));
+        atomic_store_seqcst(&mut b, true);
+    }
+}
diff --git a/gcc/testsuite/rust/execute/torture/atomic_store.rs b/gcc/testsuite/rust/execute/torture/atomic_store.rs
new file mode 100644
index 00000000000..9f248b4f823
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/atomic_store.rs
@@ -0,0 +1,32 @@
+trait Copy {}
+
+extern "rust-intrinsic" {
+    pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
+}
+
+fn main() -> i32 {
+    let mut dst = 15;
+    let one;
+    let two;
+    let three;
+    let four;
+
+    unsafe {
+        atomic_store_seqcst(&mut dst, 1);
+        one = dst;
+
+        atomic_store_release(&mut dst, 2);
+        two = dst;
+
+        atomic_store_relaxed(&mut dst, 3);
+        three = dst;
+
+        atomic_store_unordered(&mut dst, 4);
+        four = dst;
+    }
+
+    (four + three + two + one) - 10
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 061/103] gccrs: intrinsics: Add unchecked operation intrinsics
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (59 preceding siblings ...)
  2023-02-21 12:01 ` [committed 060/103] gccrs: intrinsics: Add early implementation for atomic_store_{seqcst, relaxed, release} arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 062/103] gccrs: intrinsics: Use lambdas for wrapping_<op> intrinsics arthur.cohen
                   ` (41 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-compile-intrinsic.cc (is_basic_integer_type): New function.
	(unchecked_op_inner): New handler.
	(unchecked_op_handler): New handler.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/intrinsics-6.rs: New test.
	* rust/compile/torture/intrinsics-7.rs: New test.
---
 gcc/rust/backend/rust-compile-intrinsic.cc    | 80 +++++++++++++++++++
 .../rust/compile/torture/intrinsics-6.rs      | 21 +++++
 .../rust/compile/torture/intrinsics-7.rs      | 10 +++
 3 files changed, 111 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/torture/intrinsics-6.rs
 create mode 100644 gcc/testsuite/rust/compile/torture/intrinsics-7.rs

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 7c592dabb38..46ea5b3f795 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -34,6 +34,22 @@
 namespace Rust {
 namespace Compile {
 
+static bool
+is_basic_integer_type (TyTy::BaseType *type)
+{
+  switch (type->get_kind ())
+    {
+    case TyTy::INT:
+    case TyTy::UINT:
+    case TyTy::USIZE:
+    case TyTy::ISIZE:
+      return true;
+    default:
+      return false;
+      break;
+    }
+}
+
 static tree
 offset_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
@@ -104,6 +120,17 @@ atomic_store_handler (int ordering)
   };
 }
 
+static inline tree
+unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op);
+
+const static std::function<tree (Context *, TyTy::FnType *)>
+unchecked_op_handler (tree_code op)
+{
+  return [op] (Context *ctx, TyTy::FnType *fntype) {
+    return unchecked_op_inner (ctx, fntype, op);
+  };
+}
+
 static inline tree
 sorry_handler (Context *ctx, TyTy::FnType *fntype)
 {
@@ -132,6 +159,13 @@ static const std::map<std::string,
     {"atomic_store_release", atomic_store_handler (__ATOMIC_RELEASE)},
     {"atomic_store_relaxed", atomic_store_handler (__ATOMIC_RELAXED)},
     {"atomic_store_unordered", atomic_store_handler (__ATOMIC_RELAXED)},
+    {"unchecked_add", unchecked_op_handler (PLUS_EXPR)},
+    {"unchecked_sub", unchecked_op_handler (MINUS_EXPR)},
+    {"unchecked_mul", unchecked_op_handler (MULT_EXPR)},
+    {"unchecked_div", unchecked_op_handler (TRUNC_DIV_EXPR)},
+    {"unchecked_rem", unchecked_op_handler (TRUNC_MOD_EXPR)},
+    {"unchecked_shl", unchecked_op_handler (LSHIFT_EXPR)},
+    {"unchecked_shr", unchecked_op_handler (RSHIFT_EXPR)},
 };
 
 Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -721,6 +755,52 @@ atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering)
   TREE_SIDE_EFFECTS (store_call) = 1;
 
   ctx->add_statement (store_call);
+  finalize_intrinsic_block (ctx, fndecl);
+
+  return fndecl;
+}
+
+static inline tree
+unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op)
+{
+  rust_assert (fntype->get_params ().size () == 2);
+  rust_assert (fntype->get_num_substitutions () == 1);
+
+  tree lookup = NULL_TREE;
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
+
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+  // setup the params
+  std::vector<Bvariable *> param_vars;
+  compile_fn_params (ctx, fntype, fndecl, &param_vars);
+
+  if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
+    return error_mark_node;
+
+  enter_intrinsic_block (ctx, fndecl);
+
+  // BUILTIN unchecked_<op> BODY BEGIN
+
+  auto x = ctx->get_backend ()->var_expression (param_vars[0], Location ());
+  auto y = ctx->get_backend ()->var_expression (param_vars[1], Location ());
+
+  auto *monomorphized_type
+    = fntype->get_substs ().at (0).get_param_ty ()->resolve ();
+  if (!is_basic_integer_type (monomorphized_type))
+    rust_error_at (fntype->get_locus (),
+		   "unchecked operation intrinsics can only be used with "
+		   "basic integer types (got %qs)",
+		   monomorphized_type->get_name ().c_str ());
+
+  auto expr = build2 (op, TREE_TYPE (x), x, y);
+  auto return_statement
+    = ctx->get_backend ()->return_statement (fndecl, {expr}, Location ());
+
+  ctx->add_statement (return_statement);
+
+  // BUILTIN unchecked_<op> BODY END
 
   finalize_intrinsic_block (ctx, fndecl);
 
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-6.rs b/gcc/testsuite/rust/compile/torture/intrinsics-6.rs
new file mode 100644
index 00000000000..143b62a2b27
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-6.rs
@@ -0,0 +1,21 @@
+extern "rust-intrinsic" {
+    pub fn unchecked_add<T>(x: T, y: T) -> T;
+    pub fn unchecked_sub<T>(x: T, y: T) -> T;
+    pub fn unchecked_mul<T>(x: T, y: T) -> T;
+    pub fn unchecked_div<T>(x: T, y: T) -> T;
+    pub fn unchecked_rem<T>(x: T, y: T) -> T;
+    pub fn unchecked_shl<T>(x: T, y: T) -> T;
+    pub fn unchecked_shr<T>(x: T, y: T) -> T;
+}
+
+fn main() -> i32 {
+    let zero0 = unsafe { (1 + 5) - unchecked_add(1, 5) };
+    let zero1 = unsafe { (1 - 5) - unchecked_sub(1, 5) };
+    let zero2 = unsafe { (1 * 5) - unchecked_mul(1, 5) };
+    let zero3 = unsafe { (1 / 5) - unchecked_div(1, 5) };
+    let zero4 = unsafe { (1 % 5) - unchecked_rem(1, 5) };
+    let zero5 = unsafe { (1 << 5) - unchecked_shl(1, 5) };
+    let zero6 = unsafe { (1 >> 5) - unchecked_shr(1, 5) };
+
+    zero0 + zero1 + zero2 + zero3 + zero4 + zero5 + zero6
+}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-7.rs b/gcc/testsuite/rust/compile/torture/intrinsics-7.rs
new file mode 100644
index 00000000000..8e8c5fe0cdf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-7.rs
@@ -0,0 +1,10 @@
+extern "rust-intrinsic" {
+    pub fn unchecked_add<T>(x: T, y: T) -> T;
+    // { dg-error "unchecked operation intrinsics can only be used with basic integer types .got .NotAdd.." "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    struct NotAdd;
+
+    unsafe { unchecked_add(NotAdd, NotAdd) };
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 062/103] gccrs: intrinsics: Use lambdas for wrapping_<op> intrinsics
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (60 preceding siblings ...)
  2023-02-21 12:01 ` [committed 061/103] gccrs: intrinsics: Add unchecked operation intrinsics arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 063/103] gccrs: intrinsics: Cleanup error handling around atomic_store_* arthur.cohen
                   ` (40 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-compile-intrinsic.cc (wrapping_op_handler): Refactor to return
	an `std::function`.
	(wrapping_op_handler_inner): Rename.
	(wrapping_add_handler): Remove function.
	(wrapping_sub_handler): Likewise.
	(wrapping_mul_handler): Likewise.
---
 gcc/rust/backend/rust-compile-intrinsic.cc | 29 ++++++++--------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 46ea5b3f795..142a2173672 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -59,7 +59,7 @@ transmute_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
 rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
 static tree
-wrapping_op_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
+wrapping_op_handler_inner (Context *ctx, TyTy::FnType *fntype, tree_code op);
 static tree
 copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype);
 
@@ -83,21 +83,14 @@ rotate_right_handler (Context *ctx, TyTy::FnType *fntype)
   return rotate_handler (ctx, fntype, RROTATE_EXPR);
 }
 
-static inline tree
-wrapping_add_handler (Context *ctx, TyTy::FnType *fntype)
-{
-  return wrapping_op_handler (ctx, fntype, PLUS_EXPR);
-}
-static inline tree
-wrapping_sub_handler (Context *ctx, TyTy::FnType *fntype)
-{
-  return wrapping_op_handler (ctx, fntype, MINUS_EXPR);
-}
-static inline tree
-wrapping_mul_handler (Context *ctx, TyTy::FnType *fntype)
+const static std::function<tree (Context *, TyTy::FnType *)>
+wrapping_op_handler (tree_code op)
 {
-  return wrapping_op_handler (ctx, fntype, MULT_EXPR);
+  return [op] (Context *ctx, TyTy::FnType *fntype) {
+    return wrapping_op_handler_inner (ctx, fntype, op);
+  };
 }
+
 static inline tree
 prefetch_read_data (Context *ctx, TyTy::FnType *fntype)
 {
@@ -148,9 +141,9 @@ static const std::map<std::string,
     {"transmute", transmute_handler},
     {"rotate_left", rotate_left_handler},
     {"rotate_right", rotate_right_handler},
-    {"wrapping_add", wrapping_add_handler},
-    {"wrapping_sub", wrapping_sub_handler},
-    {"wrapping_mul", wrapping_mul_handler},
+    {"wrapping_add", wrapping_op_handler (PLUS_EXPR)},
+    {"wrapping_sub", wrapping_op_handler (MINUS_EXPR)},
+    {"wrapping_mul", wrapping_op_handler (MULT_EXPR)},
     {"copy_nonoverlapping", copy_nonoverlapping_handler},
     {"prefetch_read_data", prefetch_read_data},
     {"prefetch_write_data", prefetch_write_data},
@@ -493,7 +486,7 @@ rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op)
  * pub fn wrapping_{add, sub, mul}<T>(lhs: T, rhs: T) -> T;
  */
 static tree
-wrapping_op_handler (Context *ctx, TyTy::FnType *fntype, tree_code op)
+wrapping_op_handler_inner (Context *ctx, TyTy::FnType *fntype, tree_code op)
 {
   // wrapping_<op> intrinsics have two parameter
   rust_assert (fntype->get_params ().size () == 2);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 063/103] gccrs: intrinsics: Cleanup error handling around atomic_store_*
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (61 preceding siblings ...)
  2023-02-21 12:01 ` [committed 062/103] gccrs: intrinsics: Use lambdas for wrapping_<op> intrinsics arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 064/103] gccrs: intrinsics: Implement atomic_load intrinsics arthur.cohen
                   ` (39 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-compile-intrinsic.cc (check_for_basic_integer_type): New function.
	(build_atomic_builtin_name): Use HIR Type instead of `tree`.
	(atomic_store_handler_inner): Cleanup error handling.
	(unchecked_op_inner): Likewise.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/intrinsics-5.rs: Fix error message.
---
 gcc/rust/backend/rust-compile-intrinsic.cc    | 50 +++++++++++--------
 .../rust/compile/torture/intrinsics-5.rs      |  4 +-
 2 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 142a2173672..b0c6015bee2 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -50,6 +50,22 @@ is_basic_integer_type (TyTy::BaseType *type)
     }
 }
 
+static bool
+check_for_basic_integer_type (const std::string &intrinsic_str, Location locus,
+			      TyTy::BaseType *type)
+{
+  auto is_basic_integer = is_basic_integer_type (type);
+  if (!is_basic_integer)
+    {
+      rust_error_at (
+	locus,
+	"%s intrinsics can only be used with basic integer types (got %qs)",
+	intrinsic_str.c_str (), type->get_name ().c_str ());
+    }
+
+  return is_basic_integer;
+}
+
 static tree
 offset_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
@@ -652,7 +668,7 @@ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
 }
 
 static std::string
-build_atomic_builtin_name (Location locus, tree operand_type)
+build_atomic_builtin_name (Location locus, TyTy::BaseType *operand_type)
 {
   static const std::map<std::string, std::string> allowed_types = {
     {"i8", "1"},    {"i16", "2"},   {"i32", "4"},   {"i64", "8"},
@@ -665,7 +681,7 @@ build_atomic_builtin_name (Location locus, tree operand_type)
 
   std::string result = "atomic_store_";
 
-  auto type_name = std::string (TYPE_NAME_STRING (operand_type));
+  auto type_name = operand_type->get_name ();
   if (type_name == "usize" || type_name == "isize")
     {
       rust_sorry_at (
@@ -673,21 +689,10 @@ build_atomic_builtin_name (Location locus, tree operand_type)
       return "";
     }
 
-  // FIXME: Can we have a better looking name here?
-  // Instead of `<crate>::<module>::<type>`?
-  // Maybe instead of giving the tree node, pass the resolved Tyty before it
-  // gets compiled?
-  //
-  // Or should we perform this check somwhere else in the compiler?
   auto type_size_str = allowed_types.find (type_name);
-  if (type_size_str == allowed_types.end ())
-    {
-      rust_error_at (locus,
-		     "atomic intrinsics are only available for basic integer "
-		     "types: got type %qs",
-		     type_name.c_str ());
-      return "";
-    }
+
+  if (!check_for_basic_integer_type ("atomic", locus, operand_type))
+    return "";
 
   result += type_size_str->second;
 
@@ -726,8 +731,11 @@ atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering)
   auto value = ctx->get_backend ()->var_expression (param_vars[1], Location ());
   auto memorder = make_unsigned_long_tree (ctx, ordering);
 
+  auto monomorphized_type
+    = fntype->get_substs ()[0].get_param_ty ()->resolve ();
+
   auto builtin_name
-    = build_atomic_builtin_name (fntype->get_locus (), TREE_TYPE (types[0]));
+    = build_atomic_builtin_name (fntype->get_locus (), monomorphized_type);
   if (builtin_name.empty ())
     return error_mark_node;
 
@@ -781,11 +789,9 @@ unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op)
 
   auto *monomorphized_type
     = fntype->get_substs ().at (0).get_param_ty ()->resolve ();
-  if (!is_basic_integer_type (monomorphized_type))
-    rust_error_at (fntype->get_locus (),
-		   "unchecked operation intrinsics can only be used with "
-		   "basic integer types (got %qs)",
-		   monomorphized_type->get_name ().c_str ());
+
+  check_for_basic_integer_type ("unchecked operation", fntype->get_locus (),
+				monomorphized_type);
 
   auto expr = build2 (op, TREE_TYPE (x), x, y);
   auto return_statement
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
index e0087720cc4..7fd84dcd635 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
@@ -2,8 +2,8 @@ trait Copy {}
 
 extern "rust-intrinsic" {
     pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, value: T);
-    // { dg-error "atomic intrinsics are only available for basic integer types: got type .intrinsics_5::VeryLargeType." "" { target *-*-* } .-1 }
-    // { dg-error "atomic intrinsics are only available for basic integer types: got type .bool." "" { target *-*-* } .-2 }
+    // { dg-error "atomic intrinsics can only be used with basic integer types .got .VeryLargeType.." "" { target *-*-* } .-1 }
+    // { dg-error "atomic intrinsics can only be used with basic integer types .got .bool.." "" { target *-*-* } .-2 }
 }
 
 struct VeryLargeType {
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 064/103] gccrs: intrinsics: Implement atomic_load intrinsics
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (62 preceding siblings ...)
  2023-02-21 12:01 ` [committed 063/103] gccrs: intrinsics: Cleanup error handling around atomic_store_* arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 065/103] gccrs: ast: visitor pattern -> overload syntax compatibility layer arthur.cohen
                   ` (38 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* backend/rust-builtins.cc (BuiltinsContext::setup_atomic_fns): Declare atomic
	load intrinsics.
	* backend/rust-compile-intrinsic.cc (atomic_load_handler_inner): New handler.
	(atomic_load_handler): Likewise.
	(unchecked_op_handler): Remove `static` function qualifier.
	(build_atomic_builtin_name): Handle load intrinsics.
	(atomic_store_handler_inner): New handler.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/intrinsics-3.rs:
	* rust/execute/torture/atomic_load.rs: New test.
---
 gcc/rust/backend/rust-builtins.cc             | 56 ++++++------
 gcc/rust/backend/rust-compile-intrinsic.cc    | 88 +++++++++++++++++--
 .../rust/compile/torture/intrinsics-3.rs      |  2 -
 .../rust/execute/torture/atomic_load.rs       | 31 +++++++
 4 files changed, 144 insertions(+), 33 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/atomic_load.rs

diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
index 64e06e1a240..66b3becc47a 100644
--- a/gcc/rust/backend/rust-builtins.cc
+++ b/gcc/rust/backend/rust-builtins.cc
@@ -71,36 +71,42 @@ BuiltinsContext::setup_math_fns ()
 void
 BuiltinsContext::setup_atomic_fns ()
 {
-  define_builtin ("atomic_store", BUILT_IN_ATOMIC_STORE, "__atomic_store", NULL,
-		  build_function_type_list (void_type_node, size_type_node,
-					    build_pointer_type (void_type_node),
-					    const_ptr_type_node,
-					    integer_type_node, NULL_TREE),
-		  0);
-  define_builtin ("atomic_store_n", BUILT_IN_ATOMIC_STORE_N, "__atomic_store_n",
-		  NULL,
-		  build_varargs_function_type_list (void_type_node, NULL_TREE),
-		  0);
+  auto atomic_store_type
+    = build_varargs_function_type_list (void_type_node, NULL_TREE);
+  auto atomic_load_type = [] (tree ret_type_node) {
+    return build_function_type_list (ret_type_node,
+				     ptr_type_node, // const_ptr_type_node?
+				     integer_type_node, NULL_TREE);
+  };
+
+  // FIXME: These should be the definition for the generic version of the
+  // atomic_store builtins, but I cannot get them to work properly. Revisit
+  // later. define_builtin ("atomic_store", BUILT_IN_ATOMIC_STORE,
+  // "__atomic_store", NULL,
+  //   atomic_store_type, 0);
+  // define_builtin ("atomic_store_n", BUILT_IN_ATOMIC_STORE_N,
+  // "__atomic_store_n",
+  //   NULL, atomic_store_type, 0);
+
   define_builtin ("atomic_store_1", BUILT_IN_ATOMIC_STORE_1, "__atomic_store_1",
-		  NULL,
-		  build_varargs_function_type_list (void_type_node, NULL_TREE),
-		  0);
+		  NULL, atomic_store_type, 0);
   define_builtin ("atomic_store_2", BUILT_IN_ATOMIC_STORE_2, "__atomic_store_2",
-		  NULL,
-		  build_varargs_function_type_list (void_type_node, NULL_TREE),
-		  0);
+		  NULL, atomic_store_type, 0);
   define_builtin ("atomic_store_4", BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4",
-		  NULL,
-		  build_varargs_function_type_list (void_type_node, NULL_TREE),
-		  0);
+		  NULL, atomic_store_type, 0);
   define_builtin ("atomic_store_8", BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8",
-		  NULL,
-		  build_varargs_function_type_list (void_type_node, NULL_TREE),
-		  0);
+		  NULL, atomic_store_type, 0);
   define_builtin ("atomic_store_16", BUILT_IN_ATOMIC_STORE_16,
-		  "__atomic_store_16", NULL,
-		  build_varargs_function_type_list (void_type_node, NULL_TREE),
-		  0);
+		  "__atomic_store_16", NULL, atomic_store_type, 0);
+
+  define_builtin ("atomic_load_1", BUILT_IN_ATOMIC_LOAD_1, "__atomic_load_1",
+		  NULL, atomic_load_type (integer_type_node), 0);
+  define_builtin ("atomic_load_2", BUILT_IN_ATOMIC_LOAD_2, "__atomic_load_2",
+		  NULL, atomic_load_type (integer_type_node), 0);
+  define_builtin ("atomic_load_4", BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4",
+		  NULL, atomic_load_type (integer_type_node), 0);
+  define_builtin ("atomic_load_8", BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8",
+		  NULL, atomic_load_type (integer_type_node), 0);
 }
 
 void
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index b0c6015bee2..55222116366 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -120,6 +120,8 @@ prefetch_write_data (Context *ctx, TyTy::FnType *fntype)
 
 static tree
 atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering);
+static tree
+atomic_load_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering);
 
 static inline std::function<tree (Context *, TyTy::FnType *)>
 atomic_store_handler (int ordering)
@@ -129,6 +131,14 @@ atomic_store_handler (int ordering)
   };
 }
 
+static inline std::function<tree (Context *, TyTy::FnType *)>
+atomic_load_handler (int ordering)
+{
+  return [ordering] (Context *ctx, TyTy::FnType *fntype) {
+    return atomic_load_handler_inner (ctx, fntype, ordering);
+  };
+}
+
 static inline tree
 unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op);
 
@@ -140,7 +150,7 @@ unchecked_op_handler (tree_code op)
   };
 }
 
-static inline tree
+inline tree
 sorry_handler (Context *ctx, TyTy::FnType *fntype)
 {
   rust_sorry_at (fntype->get_locus (), "intrinsic %qs is not yet implemented",
@@ -163,11 +173,14 @@ static const std::map<std::string,
     {"copy_nonoverlapping", copy_nonoverlapping_handler},
     {"prefetch_read_data", prefetch_read_data},
     {"prefetch_write_data", prefetch_write_data},
-    {"atomic_load", sorry_handler},
     {"atomic_store_seqcst", atomic_store_handler (__ATOMIC_SEQ_CST)},
     {"atomic_store_release", atomic_store_handler (__ATOMIC_RELEASE)},
     {"atomic_store_relaxed", atomic_store_handler (__ATOMIC_RELAXED)},
     {"atomic_store_unordered", atomic_store_handler (__ATOMIC_RELAXED)},
+    {"atomic_load_seqcst", atomic_load_handler (__ATOMIC_SEQ_CST)},
+    {"atomic_load_acquire", atomic_load_handler (__ATOMIC_ACQUIRE)},
+    {"atomic_load_relaxed", atomic_load_handler (__ATOMIC_RELAXED)},
+    {"atomic_load_unordered", atomic_load_handler (__ATOMIC_RELAXED)},
     {"unchecked_add", unchecked_op_handler (PLUS_EXPR)},
     {"unchecked_sub", unchecked_op_handler (MINUS_EXPR)},
     {"unchecked_mul", unchecked_op_handler (MULT_EXPR)},
@@ -668,7 +681,8 @@ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
 }
 
 static std::string
-build_atomic_builtin_name (Location locus, TyTy::BaseType *operand_type)
+build_atomic_builtin_name (const std::string &prefix, Location locus,
+			   TyTy::BaseType *operand_type)
 {
   static const std::map<std::string, std::string> allowed_types = {
     {"i8", "1"},    {"i16", "2"},   {"i32", "4"},   {"i64", "8"},
@@ -679,7 +693,7 @@ build_atomic_builtin_name (Location locus, TyTy::BaseType *operand_type)
   // TODO: Can we maybe get the generic version (atomic_store_n) to work... This
   // would be so much better
 
-  std::string result = "atomic_store_";
+  std::string result = prefix;
 
   auto type_name = operand_type->get_name ();
   if (type_name == "usize" || type_name == "isize")
@@ -735,7 +749,8 @@ atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering)
     = fntype->get_substs ()[0].get_param_ty ()->resolve ();
 
   auto builtin_name
-    = build_atomic_builtin_name (fntype->get_locus (), monomorphized_type);
+    = build_atomic_builtin_name ("atomic_store_", fntype->get_locus (),
+				 monomorphized_type);
   if (builtin_name.empty ())
     return error_mark_node;
 
@@ -751,7 +766,6 @@ atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering)
     = ctx->get_backend ()->call_expression (atomic_store,
 					    {dst, value, memorder}, nullptr,
 					    Location ());
-
   TREE_READONLY (store_call) = 0;
   TREE_SIDE_EFFECTS (store_call) = 1;
 
@@ -761,6 +775,68 @@ atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering)
   return fndecl;
 }
 
+static tree
+atomic_load_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering)
+{
+  rust_assert (fntype->get_params ().size () == 1);
+  rust_assert (fntype->get_num_substitutions () == 1);
+
+  tree lookup = NULL_TREE;
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
+
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+  // Most intrinsic functions are pure but not the atomic ones
+  // FIXME: Is atomic_load_* pure? Feels like it shouldn't so
+  TREE_READONLY (fndecl) = 0;
+  TREE_SIDE_EFFECTS (fndecl) = 1;
+
+  // setup the params
+  std::vector<Bvariable *> param_vars;
+  std::vector<tree> types;
+  compile_fn_params (ctx, fntype, fndecl, &param_vars, &types);
+
+  auto ok = ctx->get_backend ()->function_set_parameters (fndecl, param_vars);
+  rust_assert (ok);
+
+  enter_intrinsic_block (ctx, fndecl);
+
+  auto src = ctx->get_backend ()->var_expression (param_vars[0], Location ());
+  auto memorder = make_unsigned_long_tree (ctx, ordering);
+
+  auto monomorphized_type
+    = fntype->get_substs ()[0].get_param_ty ()->resolve ();
+
+  auto builtin_name
+    = build_atomic_builtin_name ("atomic_load_", fntype->get_locus (),
+				 monomorphized_type);
+  if (builtin_name.empty ())
+    return error_mark_node;
+
+  tree atomic_load_raw = nullptr;
+  BuiltinsContext::get ().lookup_simple_builtin (builtin_name,
+						 &atomic_load_raw);
+  rust_assert (atomic_load_raw);
+
+  auto atomic_load
+    = build_fold_addr_expr_loc (Location ().gcc_location (), atomic_load_raw);
+
+  auto load_call
+    = ctx->get_backend ()->call_expression (atomic_load, {src, memorder},
+					    nullptr, Location ());
+  auto return_statement
+    = ctx->get_backend ()->return_statement (fndecl, {load_call}, Location ());
+
+  TREE_READONLY (load_call) = 0;
+  TREE_SIDE_EFFECTS (load_call) = 1;
+
+  ctx->add_statement (return_statement);
+  finalize_intrinsic_block (ctx, fndecl);
+
+  return fndecl;
+}
+
 static inline tree
 unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op)
 {
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-3.rs b/gcc/testsuite/rust/compile/torture/intrinsics-3.rs
index 1acb3533c08..5c131bd8aa2 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-3.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-3.rs
@@ -1,9 +1,7 @@
 extern "rust-intrinsic" {
     fn not_an_intrinsic();
-    fn atomic_load(); // { dg-message "sorry, unimplemented: intrinsic .atomic_load. is not yet implemented" }
 }
 
 fn main() {
     unsafe { not_an_intrinsic() }; // { dg-error "unknown builtin intrinsic: not_an_intrinsic" }
-    unsafe { atomic_load() };
 }
diff --git a/gcc/testsuite/rust/execute/torture/atomic_load.rs b/gcc/testsuite/rust/execute/torture/atomic_load.rs
new file mode 100644
index 00000000000..28ed8ae78f1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/atomic_load.rs
@@ -0,0 +1,31 @@
+trait Copy {}
+
+extern "rust-intrinsic" {
+    pub fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
+}
+
+fn main() -> i32 {
+    let one;
+    let two;
+    let three;
+    let four;
+
+    unsafe {
+        let mut src = 1;
+        one = atomic_load_seqcst(&src);
+
+        src = 2;
+        two = atomic_load_acquire(&src);
+
+        src = 3;
+        three = atomic_load_relaxed(&src);
+
+        src = 4;
+        four = atomic_load_unordered(&src);
+    }
+
+    (four + three + two + one) - 10
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 065/103] gccrs: ast: visitor pattern -> overload syntax compatibility layer
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (63 preceding siblings ...)
  2023-02-21 12:01 ` [committed 064/103] gccrs: intrinsics: Implement atomic_load intrinsics arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 066/103] gccrs: ast: transform helper methods to visits and add methods to simplify repeated patterns arthur.cohen
                   ` (37 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add new visit function for overloading.
	* ast/rust-ast-dump.h: Add documentation for layer.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 7 +++++++
 gcc/rust/ast/rust-ast-dump.h  | 8 ++++++++
 2 files changed, 15 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 4817962f767..9771f432ea0 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -62,6 +62,13 @@ Dump::go (AST::Item &item)
   item.accept_vis (*this);
 }
 
+template <typename T>
+void
+Dump::visit (std::unique_ptr<T> &node)
+{
+  node->accept_vis (*this);
+}
+
 void
 Dump::format_function_param (FunctionParam &param)
 {
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 9fe8ee95493..7cd922e0ac9 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -72,6 +72,14 @@ private:
   std::ostream &stream;
   Indent indentation;
 
+  /**
+   * Compatibility layer for using the visitor pattern on polymorphic classes
+   * with a unified overload syntax. This allows us to call `visit` both on
+   * types implementing `accept_vis` method and for classes for which the
+   * `visit` method is directly implemented.
+   */
+  template <typename T> void visit (std::unique_ptr<T> &node);
+
   /**
    * Format together common items of functions: Parameters, return type, block
    */
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 066/103] gccrs: ast: transform helper methods to visits and add methods to simplify repeated patterns
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (64 preceding siblings ...)
  2023-02-21 12:01 ` [committed 065/103] gccrs: ast: visitor pattern -> overload syntax compatibility layer arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 067/103] gccrs: ast: refer correctly to arguments in docs-strings arthur.cohen
                   ` (36 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::go): Use new API.
	(Dump::format_function_param): Refactor.
	(Dump::visit_items_joined_by_separator): New function.
	(Dump::emit_attrib): Refactor.
	(Dump::visit_as_line): New function.
	(Dump::visit_items_as_lines): Likewise.
	(Dump::visit_items_as_block): Likewise.
	(Dump::visit): Use new API.
	(Dump::emit_visibility): Likewise.
	(Dump::emit_indented_string): Likewise.
	(Dump::emit_generic_params): Likewise.
	(Dump::format_tuple_field): Likewise.
	(Dump::format_struct_field): Likewise.
	(Dump::format_function_common): Likewise.
	(Dump::visit_function_common): Likewise.
	* ast/rust-ast-dump.h: Declare new functions and add documentation.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 559 ++++++++++++----------------------
 gcc/rust/ast/rust-ast-dump.h  |  63 ++--
 2 files changed, 235 insertions(+), 387 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 9771f432ea0..191e328b134 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -48,12 +48,7 @@ Dump::Dump (std::ostream &stream) : stream (stream), indentation (Indent ()) {}
 void
 Dump::go (AST::Crate &crate)
 {
-  for (auto &item : crate.items)
-    {
-      stream << indentation;
-      item->accept_vis (*this);
-      stream << '\n';
-    }
+  visit_items_as_lines (crate.items, "");
 }
 
 void
@@ -69,28 +64,75 @@ Dump::visit (std::unique_ptr<T> &node)
   node->accept_vis (*this);
 }
 
+template <typename T>
 void
-Dump::format_function_param (FunctionParam &param)
+Dump::visit_items_joined_by_separator (T &collection,
+				       const std::string &separator,
+				       size_t start_offset, size_t end_offset)
 {
-  param.get_pattern ()->accept_vis (*this);
-  stream << ": ";
-  param.get_type ()->accept_vis (*this);
+  if (collection.size () > start_offset)
+    {
+      visit (collection.at (start_offset));
+      auto size = collection.size () - end_offset;
+      for (size_t i = start_offset + 1; i < size; i++)
+	{
+	  stream << separator;
+	  visit (collection.at (i));
+	}
+    }
 }
 
+template <typename T>
 void
-Dump::emit_attrib (const Attribute &attrib)
+Dump::visit_as_line (T &item, const std::string &trailing)
 {
-  stream << "#[";
+  stream << indentation;
+  visit (item);
+  stream << trailing << '\n';
+}
 
-  for (size_t i = 0; i < attrib.get_path ().get_segments ().size (); i++)
+template <typename T>
+void
+Dump::visit_items_as_lines (T &collection, const std::string &trailing)
+{
+  for (auto &item : collection)
+    visit_as_line (item, trailing);
+}
+
+template <typename T>
+void
+Dump::visit_items_as_block (T &collection, const std::string &line_trailing,
+			    char left_brace, char right_brace)
+{
+  if (collection.empty ())
     {
-      const auto &seg = attrib.get_path ().get_segments ().at (i);
-      bool has_next = (i + 1) < attrib.get_path ().get_segments ().size ();
+      stream << left_brace << right_brace << '\n';
+    }
+  else
+    {
+      stream << left_brace << '\n';
+
+      indentation.increment ();
+      visit_items_as_lines (collection, line_trailing);
+      indentation.decrement ();
 
-      stream << seg.get_segment_name ();
-      if (has_next)
-	stream << "::";
+      stream << indentation << right_brace << '\n';
     }
+}
+
+void
+Dump::visit (FunctionParam &param)
+{
+  visit (param.get_pattern ());
+  stream << ": ";
+  visit (param.get_type ());
+}
+
+void
+Dump::visit (const Attribute &attrib)
+{
+  stream << "#[";
+  visit_items_joined_by_separator (attrib.get_path ().get_segments (), "::");
 
   if (attrib.has_attr_input ())
     {
@@ -116,7 +158,13 @@ Dump::emit_attrib (const Attribute &attrib)
 }
 
 void
-Dump::emit_visibility (const Visibility &vis)
+Dump::visit (const SimplePathSegment &segment)
+{
+  stream << segment.get_segment_name ();
+}
+
+void
+Dump::visit (const Visibility &vis)
 {
   switch (vis.get_vis_type ())
     {
@@ -140,44 +188,36 @@ Dump::emit_visibility (const Visibility &vis)
     }
 }
 
-std::ostream &
-Dump::emit_indented_string (const std::string &value,
-			    const std::string &comment)
+void
+Dump::visit (NamedFunctionParam &param)
 {
-  return stream << indentation << value << comment;
+  stream << param.get_name () << ": ";
+  visit (param.get_type ());
 }
 
 void
-Dump::emit_generic_params (std::vector<std::unique_ptr<GenericParam>> &params)
+Dump::visit (std::vector<std::unique_ptr<GenericParam>> &params)
 {
   stream << "<";
-  for (size_t i = 0; i < params.size (); i++)
-    {
-      auto &param = params.at (i);
-      param->accept_vis (*this);
-
-      bool has_next = (i + 1) < params.size ();
-      if (has_next)
-	stream << ", ";
-    }
+  visit_items_joined_by_separator (params, ", ");
   stream << ">";
 }
 
 void
-Dump::format_tuple_field (TupleField &field)
+Dump::visit (TupleField &field)
 {
   // TODO: do we need to emit outer attrs here?
-  emit_visibility (field.get_visibility ());
-  field.get_field_type ()->accept_vis (*this);
+  visit (field.get_visibility ());
+  visit (field.get_field_type ());
 }
 
 void
-Dump::format_struct_field (StructField &field)
+Dump::visit (StructField &field)
 {
   // TODO: do we need to emit outer attrs here?
-  emit_visibility (field.get_visibility ());
+  visit (field.get_visibility ());
   stream << field.get_field_name () << ": ";
-  field.get_field_type ()->accept_vis (*this);
+  visit (field.get_field_type ());
 }
 
 void
@@ -189,16 +229,11 @@ Dump::visit (Token &tok)
 void
 Dump::visit (DelimTokenTree &delim_tok_tree)
 {
-  auto tokens = delim_tok_tree.to_token_stream ();
-
   indentation.increment ();
   stream << '\n' << indentation;
 
-  for (const auto &tok : tokens)
-    {
-      stream << ' ';
-      tok->accept_vis (*this);
-    }
+  auto tokens = delim_tok_tree.to_token_stream ();
+  visit_items_joined_by_separator (tokens, " ");
 
   indentation.decrement ();
   stream << '\n' << indentation;
@@ -289,20 +324,20 @@ Dump::visit (BorrowExpr &expr)
   if (expr.get_is_mut ())
     stream << "mut ";
 
-  expr.get_borrowed_expr ()->accept_vis (*this);
+  visit (expr.get_borrowed_expr ());
 }
 
 void
 Dump::visit (DereferenceExpr &expr)
 {
   stream << '*';
-  expr.get_dereferenced_expr ()->accept_vis (*this);
+  visit (expr.get_dereferenced_expr ());
 }
 
 void
 Dump::visit (ErrorPropagationExpr &expr)
 {
-  expr.get_propagating_expr ()->accept_vis (*this);
+  visit (expr.get_propagating_expr ());
   stream << '?';
 }
 
@@ -318,7 +353,7 @@ Dump::visit (NegationExpr &expr)
       stream << '!';
       break;
     }
-  expr.get_negated_expr ()->accept_vis (*this);
+  visit (expr.get_negated_expr ());
 }
 
 void
@@ -368,9 +403,9 @@ Dump::visit (ArithmeticOrLogicalExpr &expr)
       break;
     }
 
-  expr.get_left_expr ()->accept_vis (*this);
+  visit (expr.get_left_expr ());
   stream << " " << op << " ";
-  expr.get_right_expr ()->accept_vis (*this);
+  visit (expr.get_right_expr ());
 }
 
 void
@@ -403,9 +438,9 @@ Dump::visit (ComparisonExpr &expr)
       break;
     }
 
-  expr.get_left_expr ()->accept_vis (*this);
+  visit (expr.get_left_expr ());
   stream << " " << op << " ";
-  expr.get_right_expr ()->accept_vis (*this);
+  visit (expr.get_right_expr ());
 }
 
 void
@@ -422,17 +457,17 @@ Dump::visit (LazyBooleanExpr &expr)
       break;
     }
 
-  expr.get_left_expr ()->accept_vis (*this);
+  visit (expr.get_left_expr ());
   stream << " " << op << " ";
-  expr.get_right_expr ()->accept_vis (*this);
+  visit (expr.get_right_expr ());
 }
 
 void
 Dump::visit (TypeCastExpr &expr)
 {
-  expr.get_casted_expr ()->accept_vis (*this);
+  visit (expr.get_casted_expr ());
   stream << " as ";
-  expr.get_type_to_cast_to ()->accept_vis (*this);
+  visit (expr.get_type_to_cast_to ());
 }
 
 void
@@ -490,56 +525,47 @@ Dump::visit (CompoundAssignmentExpr &expr)
       break;
     }
 
-  expr.get_left_expr ()->accept_vis (*this);
+  visit (expr.get_left_expr ());
   stream << " " << op << "= ";
-  expr.get_right_expr ()->accept_vis (*this);
+  visit (expr.get_right_expr ());
 }
 
 void
 Dump::visit (GroupedExpr &expr)
 {
   stream << '(';
-  expr.get_expr_in_parens ()->accept_vis (*this);
+  visit (expr.get_expr_in_parens ());
   stream << ')';
 }
 
 void
 Dump::visit (ArrayElemsValues &elems)
 {
-  auto &vals = elems.get_values ();
-  if (vals.size () >= 1)
-    {
-      vals[0]->accept_vis (*this);
-      for (size_t i = 1; i < vals.size (); i++)
-	{
-	  stream << ", ";
-	  vals[i]->accept_vis (*this);
-	}
-    }
+  visit_items_joined_by_separator (elems.get_values (), ", ");
 }
 
 void
 Dump::visit (ArrayElemsCopied &elems)
 {
-  elems.get_elem_to_copy ()->accept_vis (*this);
+  visit (elems.get_elem_to_copy ());
   stream << "; ";
-  elems.get_num_copies ()->accept_vis (*this);
+  visit (elems.get_num_copies ());
 }
 
 void
 Dump::visit (ArrayExpr &expr)
 {
   stream << '[';
-  expr.get_array_elems ()->accept_vis (*this);
+  visit (expr.get_array_elems ());
   stream << ']';
 }
 
 void
 Dump::visit (ArrayIndexExpr &expr)
 {
-  expr.get_array_expr ()->accept_vis (*this);
+  visit (expr.get_array_expr ());
   stream << '[';
-  expr.get_index_expr ()->accept_vis (*this);
+  visit (expr.get_index_expr ());
   stream << ']';
 }
 
@@ -578,21 +604,15 @@ Dump::visit (StructExprStructBase &expr)
 void
 Dump::visit (CallExpr &expr)
 {
-  expr.get_function_expr ()->accept_vis (*this);
-  stream << '(';
+  visit (expr.get_function_expr ());
 
+  stream << '(' << '\n';
   indentation.increment ();
 
-  for (auto &arg : expr.get_params ())
-    {
-      stream << '\n' << indentation;
-      arg->accept_vis (*this);
-      stream << ',';
-    }
+  visit_items_as_lines (expr.get_params (), ",");
 
   indentation.decrement ();
-
-  stream << '\n' << indentation << ')';
+  stream << indentation << ')';
 }
 
 void
@@ -613,19 +633,10 @@ Dump::visit (BlockExpr &expr)
   stream << "{\n";
   indentation.increment ();
 
-  for (auto &stmt : expr.get_statements ())
-    {
-      stream << indentation;
-      stmt->accept_vis (*this);
-      stream << "; /* stmt */\n";
-    }
+  visit_items_as_lines (expr.get_statements (), "; /* stmt */");
 
   if (expr.has_tail_expr ())
-    {
-      stream << indentation;
-      expr.get_tail_expr ()->accept_vis (*this);
-      stream << " /* tail expr */\n";
-    }
+    visit_as_line (expr.get_tail_expr (), " /* tail expr */\n");
 
   indentation.decrement ();
   stream << indentation << "}\n";
@@ -646,15 +657,15 @@ Dump::visit (BreakExpr &expr)
 void
 Dump::visit (RangeFromToExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
+  visit (expr.get_from_expr ());
   stream << "..";
-  expr.get_to_expr ()->accept_vis (*this);
+  visit (expr.get_to_expr ());
 }
 
 void
 Dump::visit (RangeFromExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
+  visit (expr.get_from_expr ());
   stream << "..";
 }
 
@@ -662,7 +673,7 @@ void
 Dump::visit (RangeToExpr &expr)
 {
   stream << "..";
-  expr.get_to_expr ()->accept_vis (*this);
+  visit (expr.get_to_expr ());
 }
 
 void
@@ -674,16 +685,16 @@ Dump::visit (RangeFullExpr &expr)
 void
 Dump::visit (RangeFromToInclExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
+  visit (expr.get_from_expr ());
   stream << "..=";
-  expr.get_to_expr ()->accept_vis (*this);
+  visit (expr.get_to_expr ());
 }
 
 void
 Dump::visit (RangeToInclExpr &expr)
 {
   stream << "..=";
-  expr.get_to_expr ()->accept_vis (*this);
+  visit (expr.get_to_expr ());
 }
 
 void
@@ -714,32 +725,32 @@ void
 Dump::visit (IfExpr &expr)
 {
   stream << "if ";
-  expr.vis_if_condition (*this);
+  visit (expr.get_condition_expr ());
   stream << " ";
-  expr.vis_if_block (*this);
+  visit (expr.get_if_block ());
 }
 
 void
 Dump::visit (IfExprConseqElse &expr)
 {
   stream << "if ";
-  expr.vis_if_condition (*this);
+  visit (expr.get_condition_expr ());
   stream << " ";
-  expr.vis_if_block (*this);
+  visit (expr.get_if_block ());
   stream << indentation << "else ";
-  expr.vis_else_block (*this);
+  visit (expr.get_else_block ());
 }
 
 void
 Dump::visit (IfExprConseqIf &expr)
 {
   stream << "if ";
-  expr.vis_if_condition (*this);
+  visit (expr.get_condition_expr ());
   stream << " ";
-  expr.vis_if_block (*this);
+  visit (expr.get_if_block ());
   stream << indentation << "else ";
   // The "if" part of the "else if" is printed by the next visitor
-  expr.vis_conseq_if_expr (*this);
+  visit (expr.get_conseq_if_expr ());
 }
 
 void
@@ -782,7 +793,7 @@ Dump::visit (TypeParam &param)
   if (param.has_type ())
     {
       stream << " = ";
-      param.get_type ()->accept_vis (*this);
+      visit (param.get_type ());
     }
 }
 
@@ -799,25 +810,18 @@ Dump::visit (Method &method)
 {
   // FIXME: Do we really need to dump the indentation here?
   stream << indentation;
-  emit_visibility (method.get_visibility ());
+  visit (method.get_visibility ());
   stream << "fn " << method.get_method_name () << '(';
 
-  auto &self = method.get_self_param ();
-  stream << self.as_string ();
-
-  auto &params = method.get_function_params ();
-  for (auto &param : params)
-    {
-      stream << ", ";
-      format_function_param (param);
-    }
+  stream << method.get_self_param ().as_string () << ", ";
+  visit_items_joined_by_separator (method.get_function_params (), ", ");
 
   stream << ") ";
 
   if (method.has_return_type ())
     {
       stream << "-> ";
-      method.get_return_type ()->accept_vis (*this);
+      visit (method.get_return_type ());
       stream << " ";
     }
 
@@ -825,7 +829,7 @@ Dump::visit (Method &method)
   if (!block)
     stream << ';';
   else
-    block->accept_vis (*this);
+    visit (block);
 
   stream << '\n';
 }
@@ -840,7 +844,7 @@ Dump::visit (Module &module)
   //	  Item*
   //	}
 
-  emit_visibility (module.get_visibility ());
+  visit (module.get_visibility ());
   stream << "mod " << module.get_name ();
 
   if (module.get_kind () == Module::UNLOADED)
@@ -853,19 +857,8 @@ Dump::visit (Module &module)
 
       indentation.increment ();
 
-      for (auto &item : module.get_inner_attrs ())
-	{
-	  stream << indentation;
-	  emit_attrib (item);
-	  stream << '\n';
-	}
-
-      for (auto &item : module.get_items ())
-	{
-	  stream << indentation;
-	  item->accept_vis (*this);
-	  stream << '\n';
-	}
+      visit_items_as_lines (module.get_inner_attrs ());
+      visit_items_as_lines (module.get_items ());
 
       indentation.decrement ();
 
@@ -896,30 +889,20 @@ Dump::visit (UseDeclaration &use_decl)
 void
 Dump::visit (Function &function)
 {
-  emit_visibility (function.get_visibility ());
+  visit (function.get_visibility ());
 
   stream << "fn " << function.get_function_name ();
   if (function.has_generics ())
-    emit_generic_params (function.get_generic_params ());
+    visit (function.get_generic_params ());
 
   stream << '(';
-  auto &params = function.get_function_params ();
-  if (params.size () >= 1)
-    {
-      format_function_param (params[0]);
-      for (size_t i = 1; i < params.size (); i++)
-	{
-	  stream << ", ";
-	  format_function_param (params[i]);
-	}
-    }
-
+  visit_items_joined_by_separator (function.get_function_params ());
   stream << ") ";
 
   if (function.has_return_type ())
     {
       stream << "-> ";
-      function.get_return_type ()->accept_vis (*this);
+      visit (function.get_return_type ());
       stream << " ";
     }
 
@@ -927,7 +910,7 @@ Dump::visit (Function &function)
   if (!block)
     stream << ';';
   else
-    block->accept_vis (*this);
+    visit (block);
 
   stream << '\n';
 }
@@ -941,15 +924,15 @@ Dump::visit (TypeAlias &type_alias)
   // Note: Associated types are handled by `AST::TraitItemType`.
 
   if (type_alias.has_visibility ())
-    emit_visibility (type_alias.get_visibility ());
+    visit (type_alias.get_visibility ());
   stream << "type " << type_alias.get_new_type_name ();
   if (type_alias.has_generics ())
-    emit_generic_params (type_alias.get_generic_params ());
+    visit (type_alias.get_generic_params ());
   if (type_alias.has_where_clause ())
     {
     } // FIXME: WhereClause
   stream << " = ";
-  type_alias.get_type_aliased ()->accept_vis (*this);
+  visit (type_alias.get_type_aliased ());
   stream << ";\n";
 }
 
@@ -958,26 +941,11 @@ Dump::visit (StructStruct &struct_item)
 {
   stream << "struct " << struct_item.get_identifier ();
   if (struct_item.has_generics ())
-    emit_generic_params (struct_item.get_generic_params ());
+    visit (struct_item.get_generic_params ());
 
   // FIXME: where-clause
 
-  stream << " {";
-
-  auto &fields = struct_item.get_fields ();
-
-  indentation.increment ();
-  for (auto &field : fields)
-    {
-      stream << '\n' << indentation;
-      format_struct_field (field);
-      stream << ',';
-    }
-  indentation.decrement ();
-
-  if (fields.size () > 0)
-    stream << '\n' << indentation;
-  stream << "}\n";
+  visit_items_as_block (struct_item.get_fields (), ",");
 }
 
 void
@@ -985,22 +953,12 @@ Dump::visit (TupleStruct &tuple_struct)
 {
   stream << "struct " << tuple_struct.get_identifier ();
   if (tuple_struct.has_generics ())
-    emit_generic_params (tuple_struct.get_generic_params ());
+    visit (tuple_struct.get_generic_params ());
 
   // FIXME: where-clause
 
   stream << '(';
-
-  auto &fields = tuple_struct.get_fields ();
-  if (fields.size () >= 1)
-    {
-      format_tuple_field (fields[0]);
-      for (size_t i = 1; i < fields.size (); i++)
-	{
-	  stream << ", ";
-	  format_tuple_field (fields[i]);
-	}
-    }
+  visit_items_joined_by_separator (tuple_struct.get_fields (), ", ");
   stream << ");\n";
 }
 
@@ -1014,45 +972,22 @@ void
 Dump::visit (EnumItemTuple &item)
 {
   stream << item.get_identifier () << '(';
-  auto &fields = item.get_tuple_fields ();
-  if (fields.size () >= 1)
-    {
-      format_tuple_field (fields[0]);
-      for (size_t i = 1; i < fields.size (); i++)
-	{
-	  stream << ", ";
-	  format_tuple_field (fields[i]);
-	}
-    }
+  visit_items_joined_by_separator (item.get_tuple_fields (), ", ");
   stream << ')';
 }
 
 void
 Dump::visit (EnumItemStruct &item)
 {
-  stream << item.get_identifier () << " {";
-
-  auto &fields = item.get_struct_fields ();
-
-  indentation.increment ();
-  for (auto &field : fields)
-    {
-      stream << '\n' << indentation;
-      format_struct_field (field);
-      stream << ',';
-    }
-  indentation.decrement ();
-
-  if (fields.size () > 0)
-    stream << '\n' << indentation;
-  stream << '}';
+  stream << item.get_identifier ();
+  visit_items_as_block (item.get_struct_fields (), ",");
 }
 
 void
 Dump::visit (EnumItemDiscriminant &item)
 {
   stream << item.get_identifier () << " = ";
-  item.get_expr ()->accept_vis (*this);
+  visit (item.get_expr ());
 }
 
 void
@@ -1060,26 +995,11 @@ Dump::visit (Enum &enum_item)
 {
   stream << "enum " << enum_item.get_identifier ();
   if (enum_item.has_generics ())
-    emit_generic_params (enum_item.get_generic_params ());
+    visit (enum_item.get_generic_params ());
 
   // FIXME: where-clause
 
-  stream << " {";
-  auto &variants = enum_item.get_variants ();
-  if (variants.size () >= 1)
-    {
-      stream << '\n';
-      indentation.increment ();
-      for (auto &var : variants)
-	{
-	  stream << indentation;
-	  var->accept_vis (*this);
-	  stream << ",\n";
-	}
-      indentation.decrement ();
-    }
-
-  stream << "}\n";
+  visit_items_as_block (enum_item.get_variants (), ",");
 }
 
 void
@@ -1087,21 +1007,11 @@ Dump::visit (Union &union_item)
 {
   stream << "union " << union_item.get_identifier ();
   if (union_item.has_generics ())
-    emit_generic_params (union_item.get_generic_params ());
+    visit (union_item.get_generic_params ());
 
   // FIXME: where-clause
 
-  stream << " {";
-  indentation.increment ();
-  for (auto &field : union_item.get_variants ())
-    {
-      stream << '\n' << indentation;
-      format_struct_field (field);
-      stream << ',';
-    }
-  indentation.decrement ();
-
-  stream << '\n' << indentation << "}\n";
+  visit_items_as_block (union_item.get_variants (), ",");
 }
 
 void
@@ -1113,14 +1023,14 @@ Dump::visit (StaticItem &static_item)
 {}
 
 void
-Dump::format_function_common (std::unique_ptr<Type> &return_type,
-			      std::unique_ptr<BlockExpr> &block)
+Dump::visit_function_common (std::unique_ptr<Type> &return_type,
+			     std::unique_ptr<BlockExpr> &block)
 {
   // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
   if (return_type)
     {
       stream << "-> ";
-      return_type->accept_vis (*this);
+      visit (return_type);
     }
 
   if (block)
@@ -1128,7 +1038,7 @@ Dump::format_function_common (std::unique_ptr<Type> &return_type,
       if (return_type)
 	{
 	  stream << ' ';
-	  block->accept_vis (*this);
+	  visit (block);
 	}
     }
   else
@@ -1141,16 +1051,11 @@ Dump::visit (TraitItemFunc &item)
   auto func = item.get_trait_function_decl ();
   stream << indentation << "fn " << func.get_identifier () << '(';
 
-  auto &params = func.get_function_params ();
-  for (auto &param : params)
-    {
-      stream << ", ";
-      format_function_param (param);
-    }
+  visit_items_joined_by_separator (func.get_function_params ());
 
   stream << ") ";
 
-  format_function_common (func.get_return_type (), item.get_definition ());
+  visit_function_common (func.get_return_type (), item.get_definition ());
 }
 
 void
@@ -1165,26 +1070,20 @@ Dump::visit (TraitItemMethod &item)
   // emit_visibility (method.get_visibility ());
   stream << "fn " << method.get_identifier () << '(';
 
-  auto &self = method.get_self_param ();
-  stream << self.as_string ();
+  stream << method.get_self_param ().as_string () << ", ";
 
-  auto &params = method.get_function_params ();
-  for (auto &param : params)
-    {
-      stream << ", ";
-      format_function_param (param);
-    }
+  visit_items_joined_by_separator (method.get_function_params (), ", ");
 
   stream << ") ";
 
-  format_function_common (method.get_return_type (), item.get_definition ());
+  visit_function_common (method.get_return_type (), item.get_definition ());
 }
 
 void
 Dump::visit (TraitItemConst &item)
 {
   stream << indentation << "const " << item.get_identifier () << ": ";
-  item.get_type ()->accept_vis (*this);
+  visit (item.get_type ());
   stream << ";\n";
 }
 
@@ -1199,40 +1098,24 @@ Dump::visit (Trait &trait)
 {
   for (const auto &attr : trait.get_outer_attrs ())
     {
-      emit_attrib (attr);
+      visit (attr);
       stream << "\n" << indentation;
     }
 
-  emit_visibility (trait.get_visibility ());
+  visit (trait.get_visibility ());
 
   stream << "trait " << trait.get_identifier ();
 
-  // Traits actually have an implicit Self thrown at the start so we must expect
-  // the number of generic params to be > 1
+  // Traits actually have an implicit Self thrown at the start, so we must
+  // expect the number of generic params to be > 1
   if (trait.get_generic_params ().size () > 1)
     {
       stream << "<";
-      for (size_t i = 1; i < trait.get_generic_params ().size (); i++)
-	{
-	  auto &param = trait.get_generic_params ().at (i);
-	  param->accept_vis (*this);
-
-	  bool has_next = (i + 1) < trait.get_generic_params ().size ();
-	  if (has_next)
-	    stream << ", ";
-	}
+      visit_items_joined_by_separator (trait.get_generic_params (), ", ", 1);
       stream << ">";
     }
 
-  stream << " {\n";
-
-  indentation.increment ();
-
-  for (auto &item : trait.get_trait_items ())
-    item->accept_vis (*this);
-
-  indentation.decrement ();
-  stream << "\n}\n";
+  visit_items_as_block (trait.get_trait_items (), "");
 }
 
 void
@@ -1242,28 +1125,21 @@ Dump::visit (InherentImpl &impl)
 
   // FIXME: Handle generics
 
-  impl.get_type ()->accept_vis (*this);
+  visit (impl.get_type ());
 
   // FIXME: Handle where-clause
   // FIXME: Handle inner attributes
 
-  stream << " {\n";
-  indentation.increment ();
-
-  for (auto &item : impl.get_impl_items ())
-    item->accept_vis (*this);
-
-  indentation.decrement ();
-  stream << "\n}\n";
+  visit_items_as_block (impl.get_impl_items (), "");
 }
 
 void
 Dump::visit (TraitImpl &impl)
 {
   stream << "impl ";
-  impl.get_trait_path ().accept_vis (*this);
+  visit (impl.get_trait_path ());
   stream << " for ";
-  impl.get_type ()->accept_vis (*this);
+  visit (impl.get_type ());
   stream << " {\n";
 
   indentation.increment ();
@@ -1271,7 +1147,7 @@ Dump::visit (TraitImpl &impl)
   for (auto &item : impl.get_impl_items ())
     {
       stream << indentation;
-      item->accept_vis (*this);
+      visit (item);
     }
 
   indentation.decrement ();
@@ -1285,27 +1161,17 @@ Dump::visit (ExternalStaticItem &item)
 void
 Dump::visit (ExternalFunctionItem &function)
 {
-  emit_visibility (function.get_visibility ());
+  visit (function.get_visibility ());
 
   stream << "fn " << function.get_identifier () << '(';
 
-  for (size_t i = 0; i < function.get_function_params ().size (); i++)
-    {
-      auto &param = function.get_function_params ().at (i);
-      bool has_next = (i + 1) < function.get_function_params ().size ();
-
-      stream << param.get_name () << ": ";
-      param.get_type ()->accept_vis (*this);
-
-      if (has_next)
-	stream << ", ";
-    }
+  visit_items_joined_by_separator (function.get_function_params ());
 
   stream << ')';
   if (function.has_return_type ())
     {
       stream << "-> ";
-      function.get_return_type ()->accept_vis (*this);
+      visit (function.get_return_type ());
     }
 }
 
@@ -1317,18 +1183,7 @@ Dump::visit (ExternBlock &block)
   if (block.has_abi ())
     stream << "\"" << block.get_abi () << "\" ";
 
-  stream << "{\n";
-  indentation.increment ();
-
-  for (auto &item : block.get_extern_items ())
-    {
-      stream << indentation;
-      item->accept_vis (*this);
-      stream << ";\n";
-    }
-
-  indentation.decrement ();
-  stream << "\n" << indentation << "}\n";
+  visit_items_as_block (block.get_extern_items (), ";");
 }
 
 static std::pair<char, char>
@@ -1368,11 +1223,7 @@ Dump::visit (MacroMatchRepetition &repetition)
 {
   stream << "$(";
 
-  for (auto &match : repetition.get_matches ())
-    {
-      match->accept_vis (*this);
-      stream << ' ';
-    }
+  visit_items_joined_by_separator (repetition.get_matches (), " ");
 
   auto op_char = '\0';
   switch (repetition.get_op ())
@@ -1405,41 +1256,29 @@ Dump::visit (MacroMatcher &matcher)
 
   stream << delimiters.first;
 
-  for (auto &match : matcher.get_matches ())
-    {
-      match->accept_vis (*this);
-      stream << ' ';
-    }
+  visit_items_joined_by_separator (matcher.get_matches (), " ");
 
   stream << delimiters.second;
 }
 
+void
+Dump::visit (MacroRule &rule)
+{
+  visit (rule.get_matcher ());
+  stream << " => ";
+  visit (rule.get_transcriber ().get_token_tree ());
+  stream << ";";
+}
+
 void
 Dump::visit (MacroRulesDefinition &rules_def)
 {
   for (auto &outer_attr : rules_def.get_outer_attrs ())
-    emit_attrib (outer_attr);
-
-  stream << "macro_rules! " << rules_def.get_rule_name () << " {\n";
-
-  indentation.increment ();
+    visit (outer_attr);
 
-  for (auto &rule : rules_def.get_rules ())
-    {
-      stream << indentation;
-
-      rule.get_matcher ().accept_vis (*this);
-
-      stream << " => ";
-
-      rule.get_transcriber ().get_token_tree ().accept_vis (*this);
-
-      stream << ";\n";
-    }
-
-  indentation.decrement ();
+  stream << "macro_rules! " << rules_def.get_rule_name ();
 
-  stream << "}\n";
+  visit_items_as_block (rules_def.get_rules (), ";");
 }
 
 void
@@ -1572,31 +1411,31 @@ Dump::visit (LetStmt &stmt)
   stream << "let ";
   auto &pattern = stmt.get_pattern ();
   if (pattern)
-    pattern->accept_vis (*this);
+    visit (pattern);
 
   if (stmt.has_type ())
     {
       stream << ": ";
-      stmt.get_type ()->accept_vis (*this);
+      visit (stmt.get_type ());
     }
 
   if (stmt.has_init_expr ())
     {
       stream << " = ";
-      stmt.get_init_expr ()->accept_vis (*this);
+      visit (stmt.get_init_expr ());
     }
 }
 
 void
 Dump::visit (ExprStmtWithoutBlock &stmt)
 {
-  stmt.get_expr ()->accept_vis (*this);
+  visit (stmt.get_expr ());
 }
 
 void
 Dump::visit (ExprStmtWithBlock &stmt)
 {
-  stmt.get_expr ()->accept_vis (*this);
+  visit (stmt.get_expr ());
 }
 
 // rust-type.h
@@ -1639,19 +1478,19 @@ Dump::visit (RawPointerType &type)
 void
 Dump::visit (ReferenceType &type)
 {
-  type.get_type_referenced ()->accept_vis (*this);
+  visit (type.get_type_referenced ());
 }
 
 void
 Dump::visit (ArrayType &type)
 {
-  type.get_elem_type ()->accept_vis (*this);
+  visit (type.get_elem_type ());
 }
 
 void
 Dump::visit (SliceType &type)
 {
-  type.get_elem_type ()->accept_vis (*this);
+  visit (type.get_elem_type ());
 }
 
 void
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 7cd922e0ac9..7a8058b195e 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -81,46 +81,55 @@ private:
   template <typename T> void visit (std::unique_ptr<T> &node);
 
   /**
-   * Format together common items of functions: Parameters, return type, block
+   * Visit all items in given collection, placing the separator in between but
+   * not at the end.
+   * Start and end offset allow to visit only a "slice" from the collection.
    */
-  void format_function_common (std::unique_ptr<Type> &return_type,
-			       std::unique_ptr<BlockExpr> &block);
+  template <typename T>
+  void visit_items_joined_by_separator (T &collection,
+					const std::string &separator = "",
+					size_t start_offset = 0,
+					size_t end_offset = 0);
 
   /**
-   * Format a function's definition parameter
+   * Visit item placing indentation before and trailing string + end of line
+   * after.
    */
-  void format_function_param (FunctionParam &param);
+  template <typename T>
+  void visit_as_line (T &item, const std::string &trailing = "");
 
   /**
-   * Emit an attribute
+   * Visit each item in a collection "as line".
+   *
+   * @see visit_as_line
    */
-  void emit_attrib (const Attribute &attrib);
+  template <typename T>
+  void visit_items_as_lines (T &collection, const std::string &trailing = "");
 
   /**
-   * Emit an item's visibility
+   * Visit each item in collection as lines inside a block delimited by braces
+   * with increased indentation. Also includes special handling for empty
+   * collection to print only the delimiters with no new line inside.
    */
-  void emit_visibility (const Visibility &vis);
+  template <typename T>
+  void visit_items_as_block (T &collection, const std::string &line_trailing,
+			     char left_brace = '{', char right_brace = '}');
 
   /**
-   * Emit an indented string with an optional extra comment
+   * Visit common items of functions: Parameters, return type, block
    */
-  std::ostream &emit_indented_string (const std::string &value,
-				      const std::string &comment = "");
-
-  /**
-   * Emit formatted string for generic parameters
-   */
-  void emit_generic_params (std::vector<std::unique_ptr<GenericParam>> &params);
-
-  /**
-   * Format a single field of a tuple
-   */
-  void format_tuple_field (TupleField &field);
-
-  /**
-   * Format a single field of a struct
-   */
-  void format_struct_field (StructField &field);
+  void visit_function_common (std::unique_ptr<Type> &return_type,
+			      std::unique_ptr<BlockExpr> &block);
+
+  void visit (FunctionParam &param);
+  void visit (const Attribute &attrib);
+  void visit (const Visibility &vis);
+  void visit (std::vector<std::unique_ptr<GenericParam>> &params);
+  void visit (TupleField &field);
+  void visit (StructField &field);
+  void visit (const SimplePathSegment &segment);
+  void visit (NamedFunctionParam &param);
+  void visit (MacroRule &rule);
 
   // rust-ast.h
   void visit (Token &tok);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 067/103] gccrs: ast: refer correctly to arguments in docs-strings
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (65 preceding siblings ...)
  2023-02-21 12:01 ` [committed 066/103] gccrs: ast: transform helper methods to visits and add methods to simplify repeated patterns arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 068/103] gccrs: ast: Dump unit struct arthur.cohen
                   ` (35 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.h: Fix documentation.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 7a8058b195e..13c92123ea9 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -81,7 +81,7 @@ private:
   template <typename T> void visit (std::unique_ptr<T> &node);
 
   /**
-   * Visit all items in given collection, placing the separator in between but
+   * Visit all items in given @collection, placing the separator in between but
    * not at the end.
    * Start and end offset allow to visit only a "slice" from the collection.
    */
@@ -99,7 +99,7 @@ private:
   void visit_as_line (T &item, const std::string &trailing = "");
 
   /**
-   * Visit each item in a collection "as line".
+   * Visit each item in @collection "as line".
    *
    * @see visit_as_line
    */
@@ -107,7 +107,7 @@ private:
   void visit_items_as_lines (T &collection, const std::string &trailing = "");
 
   /**
-   * Visit each item in collection as lines inside a block delimited by braces
+   * Visit each item in @collection as lines inside a block delimited by braces
    * with increased indentation. Also includes special handling for empty
    * collection to print only the delimiters with no new line inside.
    */
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 068/103] gccrs: ast: Dump unit struct
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (66 preceding siblings ...)
  2023-02-21 12:01 ` [committed 067/103] gccrs: ast: refer correctly to arguments in docs-strings arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:01 ` [committed 069/103] gccrs: add lang item "phantom_data" arthur.cohen
                   ` (34 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add handling for unit structures.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 191e328b134..df42481c248 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -945,7 +945,10 @@ Dump::visit (StructStruct &struct_item)
 
   // FIXME: where-clause
 
-  visit_items_as_block (struct_item.get_fields (), ",");
+  if (struct_item.is_unit_struct ())
+    stream << ";\n";
+  else
+    visit_items_as_block (struct_item.get_fields (), ",");
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 069/103] gccrs: add lang item "phantom_data"
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (67 preceding siblings ...)
  2023-02-21 12:01 ` [committed 068/103] gccrs: ast: Dump unit struct arthur.cohen
@ 2023-02-21 12:01 ` arthur.cohen
  2023-02-21 12:02 ` [committed 070/103] gccrs: add Location to AST::Visibility arthur.cohen
                   ` (33 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Raiki Tamura

From: Raiki Tamura <tamaron1203@gmail.com>

gcc/rust/ChangeLog:

	* util/rust-lang-item.h: Add handling for `phantom_data` lang item.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/phantom_data.rs: New test.
---
 gcc/rust/util/rust-lang-item.h                     |  9 +++++++++
 gcc/testsuite/rust/compile/torture/phantom_data.rs | 11 +++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/torture/phantom_data.rs

diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 02eeaee60df..ea0c91aa5f2 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -73,6 +73,9 @@ public:
     MUT_PTR,
     CONST_SLICE_PTR,
 
+    // https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs
+    PHANTOM_DATA,
+
     // functions
     FN_ONCE,
     FN_ONCE_OUTPUT,
@@ -222,6 +225,10 @@ public:
       {
 	return ItemType::CONST_SLICE_PTR;
       }
+    else if (item.compare ("phantom_data") == 0)
+      {
+	return ItemType::PHANTOM_DATA;
+      }
     else if (item.compare ("fn_once") == 0)
       {
 	return ItemType::FN_ONCE;
@@ -308,6 +315,8 @@ public:
 	return "mut_ptr";
       case CONST_SLICE_PTR:
 	return "const_slice_ptr";
+      case PHANTOM_DATA:
+	return "phantom_data";
       case FN_ONCE:
 	return "fn_once";
       case FN_ONCE_OUTPUT:
diff --git a/gcc/testsuite/rust/compile/torture/phantom_data.rs b/gcc/testsuite/rust/compile/torture/phantom_data.rs
new file mode 100644
index 00000000000..89e76aeb5eb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/phantom_data.rs
@@ -0,0 +1,11 @@
+// { dg-options "-w" }
+#[lang = "phantom_data"]
+struct PhantomData<T>;
+
+trait Hash {
+    fn hash<H>(&self, state: &mut H);
+}
+
+impl<T> Hash for PhantomData<T> {
+    fn hash<H>(&self, state: &mut H) {}
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 070/103] gccrs: add Location to AST::Visibility
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (68 preceding siblings ...)
  2023-02-21 12:01 ` [committed 069/103] gccrs: add lang item "phantom_data" arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 071/103] gccrs: typecheck: Fix overzealous `delete` call arthur.cohen
                   ` (32 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Dave

From: Dave <dme2223@gmail.com>

gcc/rust/ChangeLog:

	* ast/rust-item.h: Add location member.
	* hir/rust-ast-lower.cc (translate_visibility): Pass location argument.
	* hir/tree/rust-hir-item.h: Fix constructor to accept Location argument.
---
 gcc/rust/ast/rust-item.h          | 19 +++++++++++++------
 gcc/rust/hir/rust-ast-lower.cc    |  3 ++-
 gcc/rust/hir/tree/rust-hir-item.h |  6 ++++--
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index d66dd615319..17d11e4de38 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -625,13 +625,15 @@ private:
   VisType vis_type;
   // Only assigned if vis_type is IN_PATH
   SimplePath in_path;
+  Location locus;
 
   // should this store location info?
 
 public:
   // Creates a Visibility - TODO make constructor protected or private?
-  Visibility (VisType vis_type, SimplePath in_path)
-    : vis_type (vis_type), in_path (std::move (in_path))
+  Visibility (VisType vis_type, SimplePath in_path,
+	      Location locus = Location ())
+    : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
   {}
 
   VisType get_vis_type () const { return vis_type; }
@@ -648,6 +650,8 @@ public:
   // Returns whether visibility is public or not.
   bool is_public () const { return vis_type != PRIV && !is_error (); }
 
+  Location get_locus () const { return locus; }
+
   // Creates an error visibility.
   static Visibility create_error ()
   {
@@ -672,21 +676,24 @@ public:
   static Visibility create_crate (Location crate_tok_location)
   {
     return Visibility (PUB_CRATE,
-		       SimplePath::from_str ("crate", crate_tok_location));
+		       SimplePath::from_str ("crate", crate_tok_location),
+		       crate_tok_location);
   }
 
   // Creates a public visibility with self-relative paths
   static Visibility create_self (Location self_tok_location)
   {
     return Visibility (PUB_SELF,
-		       SimplePath::from_str ("self", self_tok_location));
+		       SimplePath::from_str ("self", self_tok_location),
+		       self_tok_location);
   }
 
   // Creates a public visibility with parent module-relative paths
   static Visibility create_super (Location super_tok_location)
   {
     return Visibility (PUB_SUPER,
-		       SimplePath::from_str ("super", super_tok_location));
+		       SimplePath::from_str ("super", super_tok_location),
+		       super_tok_location);
   }
 
   // Creates a private visibility
@@ -698,7 +705,7 @@ public:
   // Creates a public visibility with a given path or whatever.
   static Visibility create_in_path (SimplePath in_path)
   {
-    return Visibility (PUB_IN_PATH, std::move (in_path));
+    return Visibility (PUB_IN_PATH, std::move (in_path), in_path.get_locus ());
   }
 
   std::string as_string () const;
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index fdf8abe3ed3..2e25be75a5a 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -50,7 +50,8 @@ translate_visibility (const AST::Visibility &vis)
     case AST::Visibility::PUB_SUPER:
     case AST::Visibility::PUB_IN_PATH:
       return Visibility (Visibility::VisType::RESTRICTED,
-			 ASTLoweringSimplePath::translate (vis.get_path ()));
+			 ASTLoweringSimplePath::translate (vis.get_path ()),
+			 vis.get_locus ());
       break;
     }
 
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 7f665159572..f7bf1f879c8 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -571,13 +571,15 @@ public:
 private:
   VisType vis_type;
   HIR::SimplePath path;
+  Location locus;
 
   // should this store location info?
 
 public:
   Visibility (VisType vis_type,
-	      HIR::SimplePath path = HIR::SimplePath::create_empty ())
-    : vis_type (vis_type), path (std::move (path))
+	      HIR::SimplePath path = HIR::SimplePath::create_empty (),
+	      Location locus = Location ())
+    : vis_type (vis_type), path (std::move (path)), locus (locus)
   {}
 
   // Returns whether visibility is in an error state.
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 071/103] gccrs: typecheck: Fix overzealous `delete` call
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (69 preceding siblings ...)
  2023-02-21 12:02 ` [committed 070/103] gccrs: add Location to AST::Visibility arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 072/103] gccrs: ast: add visit overload for references arthur.cohen
                   ` (31 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Fix extra call
	to `delete`.
---
 gcc/rust/typecheck/rust-tyty-call.cc | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index 0c9e9f488fd..d520b595e43 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -68,7 +68,6 @@ TypeCheckCallExpr::visit (ADTType &type)
 	  return;
 	}
 
-      delete res;
       i++;
     }
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 072/103] gccrs: ast: add visit overload for references
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (70 preceding siblings ...)
  2023-02-21 12:02 ` [committed 071/103] gccrs: typecheck: Fix overzealous `delete` call arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 073/103] gccrs: ast: Dump where clause and recursively needed nodes arthur.cohen
                   ` (30 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

This is currently needed for lifetimes to use the existing infrastructure.

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add new reference visitor wrapper.
	* ast/rust-ast-dump.h: Declare it.
	* ast/rust-item.h: Add mutable visibility getters.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 15 +++++++++++----
 gcc/rust/ast/rust-ast-dump.h  | 11 ++++++++---
 gcc/rust/ast/rust-item.h      |  4 ++++
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index df42481c248..16c4a79dc6e 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -64,6 +64,13 @@ Dump::visit (std::unique_ptr<T> &node)
   node->accept_vis (*this);
 }
 
+template <typename T>
+void
+Dump::visit (T &node)
+{
+  node.accept_vis (*this);
+}
+
 template <typename T>
 void
 Dump::visit_items_joined_by_separator (T &collection,
@@ -129,7 +136,7 @@ Dump::visit (FunctionParam &param)
 }
 
 void
-Dump::visit (const Attribute &attrib)
+Dump::visit (Attribute &attrib)
 {
   stream << "#[";
   visit_items_joined_by_separator (attrib.get_path ().get_segments (), "::");
@@ -158,13 +165,13 @@ Dump::visit (const Attribute &attrib)
 }
 
 void
-Dump::visit (const SimplePathSegment &segment)
+Dump::visit (SimplePathSegment &segment)
 {
   stream << segment.get_segment_name ();
 }
 
 void
-Dump::visit (const Visibility &vis)
+Dump::visit (Visibility &vis)
 {
   switch (vis.get_vis_type ())
     {
@@ -1099,7 +1106,7 @@ Dump::visit (TraitItemType &item)
 void
 Dump::visit (Trait &trait)
 {
-  for (const auto &attr : trait.get_outer_attrs ())
+  for (auto &attr : trait.get_outer_attrs ())
     {
       visit (attr);
       stream << "\n" << indentation;
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 13c92123ea9..57419b75347 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -80,6 +80,11 @@ private:
    */
   template <typename T> void visit (std::unique_ptr<T> &node);
 
+  /**
+   * @see visit<std::unique_ptr<T>>
+   */
+  template <typename T> void visit (T &node);
+
   /**
    * Visit all items in given @collection, placing the separator in between but
    * not at the end.
@@ -122,12 +127,12 @@ private:
 			      std::unique_ptr<BlockExpr> &block);
 
   void visit (FunctionParam &param);
-  void visit (const Attribute &attrib);
-  void visit (const Visibility &vis);
+  void visit (Attribute &attrib);
+  void visit (Visibility &vis);
   void visit (std::vector<std::unique_ptr<GenericParam>> &params);
   void visit (TupleField &field);
   void visit (StructField &field);
-  void visit (const SimplePathSegment &segment);
+  void visit (SimplePathSegment &segment);
   void visit (NamedFunctionParam &param);
   void visit (MacroRule &rule);
 
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 17d11e4de38..4e237f2e21e 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -908,6 +908,7 @@ public:
 
   FunctionQualifiers get_qualifiers () { return qualifiers; }
 
+  Visibility &get_visibility () { return vis; }
   const Visibility &get_visibility () const { return vis; }
 
 protected:
@@ -1982,6 +1983,7 @@ public:
     return field_type;
   }
 
+  Visibility &get_visibility () { return visibility; }
   const Visibility &get_visibility () const { return visibility; }
 
   NodeId get_node_id () const { return node_id; }
@@ -2116,6 +2118,7 @@ public:
 
   NodeId get_node_id () const { return node_id; }
 
+  Visibility &get_visibility () { return visibility; }
   const Visibility &get_visibility () const { return visibility; }
 
   Location get_locus () const { return locus; }
@@ -4157,6 +4160,7 @@ public:
 
   Location get_locus () const { return locus; }
 
+  Visibility &get_visibility () { return visibility; }
   const Visibility &get_visibility () const { return visibility; }
 
   ExternalFunctionItem (
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 073/103] gccrs: ast: Dump where clause and recursively needed nodes
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (71 preceding siblings ...)
  2023-02-21 12:02 ` [committed 072/103] gccrs: ast: add visit overload for references arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 074/103] gccrs: ast: Dump slice type arthur.cohen
                   ` (29 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

This is currently needed for lifetimes to use the existing infrastructure.

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitors.
	* ast/rust-ast-dump.h: Likewise.
	* ast/rust-ast.h: Add `get_lifetime_bounds` method.
	* ast/rust-item.h: Add missing getter for lifetimes.
	* ast/rust-type.h: Likewise.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 140 +++++++++++++++++++++++++++++-----
 gcc/rust/ast/rust-ast-dump.h  |   2 +
 gcc/rust/ast/rust-ast.h       |   2 +
 gcc/rust/ast/rust-item.h      |   2 +
 gcc/rust/ast/rust-type.h      |   2 +
 5 files changed, 131 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 16c4a79dc6e..e5e051a46d8 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -227,6 +227,28 @@ Dump::visit (StructField &field)
   visit (field.get_field_type ());
 }
 
+// TODO is this unique by type?
+void
+Dump::visit (std::vector<LifetimeParam> &for_lifetimes)
+{
+  // ForLifetimes :
+  //     for GenericParams
+  //
+  // GenericParams :
+  //      < >
+  //   | < (GenericParam ,)* GenericParam ,? >
+  //
+  // GenericParam :
+  //   OuterAttribute* ( LifetimeParam | TypeParam | ConstParam )
+  //
+  // LifetimeParam :
+  //   LIFETIME_OR_LABEL ( : LifetimeBounds )?
+
+  stream << "for <";
+  visit_items_joined_by_separator (for_lifetimes, " + ");
+  stream << "> ";
+}
+
 void
 Dump::visit (Token &tok)
 {
@@ -258,11 +280,35 @@ Dump::visit (IdentifierExpr &ident_expr)
 
 void
 Dump::visit (Lifetime &lifetime)
-{}
+{
+  // Syntax:
+  // Lifetime :
+  // 	LIFETIME_OR_LABEL
+  // 	| 'static
+  // 	| '_
+  stream << lifetime.as_string ();
+}
 
 void
 Dump::visit (LifetimeParam &lifetime_param)
-{}
+{
+  // Syntax:
+  //   LIFETIME_OR_LABEL ( : LifetimeBounds )?
+  // LifetimeBounds :
+  //   ( Lifetime + )* Lifetime?
+
+  // TODO what to do with outer attr? They are not mentioned in the reference.
+
+  auto lifetime = lifetime_param.get_lifetime ();
+  visit (lifetime);
+
+  if (lifetime_param.has_lifetime_bounds ())
+    {
+      stream << ": ";
+      visit_items_joined_by_separator (lifetime_param.get_lifetime_bounds (),
+				       " + ");
+    }
+}
 
 void
 Dump::visit (ConstGenericParam &lifetime_param)
@@ -804,13 +850,52 @@ Dump::visit (TypeParam &param)
     }
 }
 
+void
+Dump::visit (WhereClause &rule)
+{
+  // Syntax:
+  // 	where ( WhereClauseItem , )* WhereClauseItem ?
+  // WhereClauseItem :
+  // 	LifetimeWhereClauseItem
+  //  	| TypeBoundWhereClauseItem
+
+  stream << " where\n";
+  indentation.increment ();
+  visit_items_as_lines (rule.get_items (), ",");
+  indentation.decrement ();
+}
+
 void
 Dump::visit (LifetimeWhereClauseItem &item)
-{}
+{
+  // Syntax:
+  // 	Lifetime : LifetimeBounds
+  // LifetimeBounds :
+  //   ( Lifetime + )* Lifetime?
+
+  visit (item.get_lifetime ());
+  stream << ": ";
+  visit_items_joined_by_separator (item.get_lifetime_bounds (), " + ");
+}
 
 void
 Dump::visit (TypeBoundWhereClauseItem &item)
-{}
+{
+  // Syntax:
+  // 	ForLifetimes? Type : TypeParamBounds?
+  // TypeParamBounds :
+  // 	TypeParamBound ( + TypeParamBound )* +?
+  // TypeParamBound :
+  //    Lifetime | TraitBound
+
+  if (item.has_for_lifetimes ())
+    visit (item.get_for_lifetimes ());
+
+  visit (item.get_type ());
+  stream << ": ";
+
+  visit_items_joined_by_separator (item.get_type_param_bounds (), " + ");
+}
 
 void
 Dump::visit (Method &method)
@@ -896,6 +981,12 @@ Dump::visit (UseDeclaration &use_decl)
 void
 Dump::visit (Function &function)
 {
+  // Syntax:
+  //   FunctionQualifiers fn IDENTIFIER GenericParams?
+  //      ( FunctionParameters? )
+  //      FunctionReturnType? WhereClause?
+  //      ( BlockExpression | ; )
+
   visit (function.get_visibility ());
 
   stream << "fn " << function.get_function_name ();
@@ -913,6 +1004,9 @@ Dump::visit (Function &function)
       stream << " ";
     }
 
+  if (function.has_where_clause ())
+    visit (function.get_where_clause ());
+
   auto &block = function.get_definition ();
   if (!block)
     stream << ';';
@@ -936,8 +1030,7 @@ Dump::visit (TypeAlias &type_alias)
   if (type_alias.has_generics ())
     visit (type_alias.get_generic_params ());
   if (type_alias.has_where_clause ())
-    {
-    } // FIXME: WhereClause
+    visit (type_alias.get_where_clause ());
   stream << " = ";
   visit (type_alias.get_type_aliased ());
   stream << ";\n";
@@ -949,9 +1042,8 @@ Dump::visit (StructStruct &struct_item)
   stream << "struct " << struct_item.get_identifier ();
   if (struct_item.has_generics ())
     visit (struct_item.get_generic_params ());
-
-  // FIXME: where-clause
-
+  if (struct_item.has_where_clause ())
+    visit (struct_item.get_where_clause ());
   if (struct_item.is_unit_struct ())
     stream << ";\n";
   else
@@ -964,8 +1056,8 @@ Dump::visit (TupleStruct &tuple_struct)
   stream << "struct " << tuple_struct.get_identifier ();
   if (tuple_struct.has_generics ())
     visit (tuple_struct.get_generic_params ());
-
-  // FIXME: where-clause
+  if (tuple_struct.has_where_clause ())
+    visit (tuple_struct.get_where_clause ());
 
   stream << '(';
   visit_items_joined_by_separator (tuple_struct.get_fields (), ", ");
@@ -1006,8 +1098,8 @@ Dump::visit (Enum &enum_item)
   stream << "enum " << enum_item.get_identifier ();
   if (enum_item.has_generics ())
     visit (enum_item.get_generic_params ());
-
-  // FIXME: where-clause
+  if (enum_item.has_where_clause ())
+    visit (enum_item.get_where_clause ());
 
   visit_items_as_block (enum_item.get_variants (), ",");
 }
@@ -1018,8 +1110,8 @@ Dump::visit (Union &union_item)
   stream << "union " << union_item.get_identifier ();
   if (union_item.has_generics ())
     visit (union_item.get_generic_params ());
-
-  // FIXME: where-clause
+  if (union_item.has_where_clause ())
+    visit (union_item.get_where_clause ());
 
   visit_items_as_block (union_item.get_variants (), ",");
 }
@@ -1137,7 +1229,9 @@ Dump::visit (InherentImpl &impl)
 
   visit (impl.get_type ());
 
-  // FIXME: Handle where-clause
+  if (impl.has_where_clause ())
+    visit (impl.get_where_clause ());
+
   // FIXME: Handle inner attributes
 
   visit_items_as_block (impl.get_impl_items (), "");
@@ -1451,7 +1545,19 @@ Dump::visit (ExprStmtWithBlock &stmt)
 // rust-type.h
 void
 Dump::visit (TraitBound &bound)
-{}
+{
+  // Syntax:
+  //      ?? ForLifetimes? TypePath
+  //   | ( ?? ForLifetimes? TypePath )
+
+  if (bound.has_opening_question_mark ())
+    stream << "? ";
+
+  if (bound.has_for_lifetimes ())
+    visit (bound.get_for_lifetimes ());
+
+  visit (bound.get_type_path ());
+}
 
 void
 Dump::visit (ImplTraitType &type)
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 57419b75347..2bd3b31d09a 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -135,6 +135,8 @@ private:
   void visit (SimplePathSegment &segment);
   void visit (NamedFunctionParam &param);
   void visit (MacroRule &rule);
+  void visit (WhereClause &rule);
+  void visit (std::vector<LifetimeParam> &for_lifetimes);
 
   // rust-ast.h
   void visit (Token &tok);
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 3d602b1a379..aa86f2f9826 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1310,6 +1310,8 @@ public:
   // Returns whether the lifetime param has any lifetime bounds.
   bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
 
+  std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
+
   // Returns whether the lifetime param has an outer attribute.
   bool has_outer_attribute () const { return !outer_attr.is_empty (); }
 
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 4e237f2e21e..96201d668de 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -236,6 +236,8 @@ public:
   // Returns whether the item has ForLifetimes
   bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
 
+  std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+
   // Returns whether the item has type param bounds
   bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
 
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 0b91cafbfd1..05a78956b57 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -46,6 +46,8 @@ public:
   // Returns whether trait bound has "for" lifetimes
   bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
 
+  std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+
   TraitBound (TypePath type_path, Location locus, bool in_parens = false,
 	      bool opening_question_mark = false,
 	      std::vector<LifetimeParam> for_lifetimes
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 074/103] gccrs: ast: Dump slice type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (72 preceding siblings ...)
  2023-02-21 12:02 ` [committed 073/103] gccrs: ast: Dump where clause and recursively needed nodes arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 075/103] gccrs: ast: Dump array type arthur.cohen
                   ` (28 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing slice visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index e5e051a46d8..b017c6ea592 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1606,7 +1606,12 @@ Dump::visit (ArrayType &type)
 void
 Dump::visit (SliceType &type)
 {
+  // Syntax:
+  //    [ Type ]
+
+  stream << '[';
   visit (type.get_elem_type ());
+  stream << ']';
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 075/103] gccrs: ast: Dump array type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (73 preceding siblings ...)
  2023-02-21 12:02 ` [committed 074/103] gccrs: ast: Dump slice type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 076/103] gccrs: ast: Dump raw pointer type arthur.cohen
                   ` (27 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing array visitor

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index b017c6ea592..9f73d0565ac 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1600,7 +1600,14 @@ Dump::visit (ReferenceType &type)
 void
 Dump::visit (ArrayType &type)
 {
+  // Syntax:
+  //    [ Type ; Expression ]
+
+  stream << '[';
   visit (type.get_elem_type ());
+  stream << "; ";
+  visit(type.get_size_expr());
+  stream << ']';
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 076/103] gccrs: ast: Dump raw pointer type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (74 preceding siblings ...)
  2023-02-21 12:02 ` [committed 075/103] gccrs: ast: Dump array type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 077/103] gccrs: ast: Dump never type arthur.cohen
                   ` (26 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing RawPointer visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 200 +++++++++++++++++++---------------
 1 file changed, 112 insertions(+), 88 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 9f73d0565ac..e6d6e070709 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -269,7 +269,7 @@ Dump::visit (DelimTokenTree &delim_tok_tree)
 }
 
 void
-Dump::visit (AttrInputMetaItemContainer &input)
+Dump::visit (AttrInputMetaItemContainer &)
 {}
 
 void
@@ -311,7 +311,7 @@ Dump::visit (LifetimeParam &lifetime_param)
 }
 
 void
-Dump::visit (ConstGenericParam &lifetime_param)
+Dump::visit (ConstGenericParam &)
 {}
 
 // rust-path.h
@@ -322,15 +322,15 @@ Dump::visit (PathInExpression &path)
 }
 
 void
-Dump::visit (TypePathSegment &segment)
+Dump::visit (TypePathSegment &)
 {}
 
 void
-Dump::visit (TypePathSegmentGeneric &segment)
+Dump::visit (TypePathSegmentGeneric &)
 {}
 
 void
-Dump::visit (TypePathSegmentFunction &segment)
+Dump::visit (TypePathSegmentFunction &)
 {}
 
 void
@@ -346,7 +346,7 @@ Dump::visit (QualifiedPathInExpression &path)
 }
 
 void
-Dump::visit (QualifiedPathInType &path)
+Dump::visit (QualifiedPathInType &)
 {}
 
 // rust-expr.h
@@ -357,15 +357,15 @@ Dump::visit (LiteralExpr &expr)
 }
 
 void
-Dump::visit (AttrInputLiteral &attr_input)
+Dump::visit (AttrInputLiteral &)
 {}
 
 void
-Dump::visit (MetaItemLitExpr &meta_item)
+Dump::visit (MetaItemLitExpr &)
 {}
 
 void
-Dump::visit (MetaItemPathLit &meta_item)
+Dump::visit (MetaItemPathLit &)
 {}
 
 void
@@ -623,35 +623,35 @@ Dump::visit (ArrayIndexExpr &expr)
 }
 
 void
-Dump::visit (TupleExpr &expr)
+Dump::visit (TupleExpr &)
 {}
 
 void
-Dump::visit (TupleIndexExpr &expr)
+Dump::visit (TupleIndexExpr &)
 {}
 
 void
-Dump::visit (StructExprStruct &expr)
+Dump::visit (StructExprStruct &)
 {}
 
 void
-Dump::visit (StructExprFieldIdentifier &field)
+Dump::visit (StructExprFieldIdentifier &)
 {}
 
 void
-Dump::visit (StructExprFieldIdentifierValue &field)
+Dump::visit (StructExprFieldIdentifierValue &)
 {}
 
 void
-Dump::visit (StructExprFieldIndexValue &field)
+Dump::visit (StructExprFieldIndexValue &)
 {}
 
 void
-Dump::visit (StructExprStructFields &expr)
+Dump::visit (StructExprStructFields &)
 {}
 
 void
-Dump::visit (StructExprStructBase &expr)
+Dump::visit (StructExprStructBase &)
 {}
 
 void
@@ -669,15 +669,15 @@ Dump::visit (CallExpr &expr)
 }
 
 void
-Dump::visit (MethodCallExpr &expr)
+Dump::visit (MethodCallExpr &)
 {}
 
 void
-Dump::visit (FieldAccessExpr &expr)
+Dump::visit (FieldAccessExpr &)
 {}
 
 void
-Dump::visit (ClosureExprInner &expr)
+Dump::visit (ClosureExprInner &)
 {}
 
 void
@@ -696,15 +696,15 @@ Dump::visit (BlockExpr &expr)
 }
 
 void
-Dump::visit (ClosureExprInnerTyped &expr)
+Dump::visit (ClosureExprInnerTyped &)
 {}
 
 void
-Dump::visit (ContinueExpr &expr)
+Dump::visit (ContinueExpr &)
 {}
 
 void
-Dump::visit (BreakExpr &expr)
+Dump::visit (BreakExpr &)
 {}
 
 void
@@ -730,7 +730,7 @@ Dump::visit (RangeToExpr &expr)
 }
 
 void
-Dump::visit (RangeFullExpr &expr)
+Dump::visit (RangeFullExpr &)
 {
   stream << "..";
 }
@@ -751,27 +751,27 @@ Dump::visit (RangeToInclExpr &expr)
 }
 
 void
-Dump::visit (ReturnExpr &expr)
+Dump::visit (ReturnExpr &)
 {}
 
 void
-Dump::visit (UnsafeBlockExpr &expr)
+Dump::visit (UnsafeBlockExpr &)
 {}
 
 void
-Dump::visit (LoopExpr &expr)
+Dump::visit (LoopExpr &)
 {}
 
 void
-Dump::visit (WhileLoopExpr &expr)
+Dump::visit (WhileLoopExpr &)
 {}
 
 void
-Dump::visit (WhileLetLoopExpr &expr)
+Dump::visit (WhileLetLoopExpr &)
 {}
 
 void
-Dump::visit (ForLoopExpr &expr)
+Dump::visit (ForLoopExpr &)
 {}
 
 void
@@ -807,35 +807,35 @@ Dump::visit (IfExprConseqIf &expr)
 }
 
 void
-Dump::visit (IfExprConseqIfLet &expr)
+Dump::visit (IfExprConseqIfLet &)
 {}
 
 void
-Dump::visit (IfLetExpr &expr)
+Dump::visit (IfLetExpr &)
 {}
 
 void
-Dump::visit (IfLetExprConseqElse &expr)
+Dump::visit (IfLetExprConseqElse &)
 {}
 
 void
-Dump::visit (IfLetExprConseqIf &expr)
+Dump::visit (IfLetExprConseqIf &)
 {}
 
 void
-Dump::visit (IfLetExprConseqIfLet &expr)
+Dump::visit (IfLetExprConseqIfLet &)
 {}
 
 void
-Dump::visit (MatchExpr &expr)
+Dump::visit (MatchExpr &)
 {}
 
 void
-Dump::visit (AwaitExpr &expr)
+Dump::visit (AwaitExpr &)
 {}
 
 void
-Dump::visit (AsyncBlockExpr &expr)
+Dump::visit (AsyncBlockExpr &)
 {}
 
 // rust-item.h
@@ -959,23 +959,23 @@ Dump::visit (Module &module)
 }
 
 void
-Dump::visit (ExternCrate &crate)
+Dump::visit (ExternCrate &)
 {}
 
 void
-Dump::visit (UseTreeGlob &use_tree)
+Dump::visit (UseTreeGlob &)
 {}
 
 void
-Dump::visit (UseTreeList &use_tree)
+Dump::visit (UseTreeList &)
 {}
 
 void
-Dump::visit (UseTreeRebind &use_tree)
+Dump::visit (UseTreeRebind &)
 {}
 
 void
-Dump::visit (UseDeclaration &use_decl)
+Dump::visit (UseDeclaration &)
 {}
 
 void
@@ -1117,11 +1117,11 @@ Dump::visit (Union &union_item)
 }
 
 void
-Dump::visit (ConstantItem &const_item)
+Dump::visit (ConstantItem &)
 {}
 
 void
-Dump::visit (StaticItem &static_item)
+Dump::visit (StaticItem &)
 {}
 
 void
@@ -1259,7 +1259,7 @@ Dump::visit (TraitImpl &impl)
 }
 
 void
-Dump::visit (ExternalStaticItem &item)
+Dump::visit (ExternalStaticItem &)
 {}
 
 void
@@ -1386,36 +1386,36 @@ Dump::visit (MacroRulesDefinition &rules_def)
 }
 
 void
-Dump::visit (MacroInvocation &macro_invoc)
+Dump::visit (MacroInvocation &)
 {}
 
 void
-Dump::visit (MetaItemPath &meta_item)
+Dump::visit (MetaItemPath &)
 {}
 
 void
-Dump::visit (MetaItemSeq &meta_item)
+Dump::visit (MetaItemSeq &)
 {}
 
 void
-Dump::visit (MetaWord &meta_item)
+Dump::visit (MetaWord &)
 {}
 
 void
-Dump::visit (MetaNameValueStr &meta_item)
+Dump::visit (MetaNameValueStr &)
 {}
 
 void
-Dump::visit (MetaListPaths &meta_item)
+Dump::visit (MetaListPaths &)
 {}
 
 void
-Dump::visit (MetaListNameValueStr &meta_item)
+Dump::visit (MetaListNameValueStr &)
 {}
 
 // rust-pattern.h
 void
-Dump::visit (LiteralPattern &pattern)
+Dump::visit (LiteralPattern &)
 {}
 
 void
@@ -1425,88 +1425,88 @@ Dump::visit (IdentifierPattern &pattern)
 }
 
 void
-Dump::visit (WildcardPattern &pattern)
+Dump::visit (WildcardPattern &)
 {}
 
-// void Dump::visit(RangePatternBound& bound){}
+// void Dump::visit(RangePatternBound& ){}
 
 void
-Dump::visit (RangePatternBoundLiteral &bound)
+Dump::visit (RangePatternBoundLiteral &)
 {}
 
 void
-Dump::visit (RangePatternBoundPath &bound)
+Dump::visit (RangePatternBoundPath &)
 {}
 
 void
-Dump::visit (RangePatternBoundQualPath &bound)
+Dump::visit (RangePatternBoundQualPath &)
 {}
 
 void
-Dump::visit (RangePattern &pattern)
+Dump::visit (RangePattern &)
 {}
 
 void
-Dump::visit (ReferencePattern &pattern)
+Dump::visit (ReferencePattern &)
 {}
 
-// void Dump::visit(StructPatternField& field){}
+// void Dump::visit(StructPatternField& ){}
 
 void
-Dump::visit (StructPatternFieldTuplePat &field)
+Dump::visit (StructPatternFieldTuplePat &)
 {}
 
 void
-Dump::visit (StructPatternFieldIdentPat &field)
+Dump::visit (StructPatternFieldIdentPat &)
 {}
 
 void
-Dump::visit (StructPatternFieldIdent &field)
+Dump::visit (StructPatternFieldIdent &)
 {}
 
 void
-Dump::visit (StructPattern &pattern)
+Dump::visit (StructPattern &)
 {}
 
-// void Dump::visit(TupleStructItems& tuple_items){}
+// void Dump::visit(TupleStructItems& ){}
 
 void
-Dump::visit (TupleStructItemsNoRange &tuple_items)
+Dump::visit (TupleStructItemsNoRange &)
 {}
 
 void
-Dump::visit (TupleStructItemsRange &tuple_items)
+Dump::visit (TupleStructItemsRange &)
 {}
 
 void
-Dump::visit (TupleStructPattern &pattern)
+Dump::visit (TupleStructPattern &)
 {}
 
-// void Dump::visit(TuplePatternItems& tuple_items){}
+// void Dump::visit(TuplePatternItems& ){}
 
 void
-Dump::visit (TuplePatternItemsMultiple &tuple_items)
+Dump::visit (TuplePatternItemsMultiple &)
 {}
 
 void
-Dump::visit (TuplePatternItemsRanged &tuple_items)
+Dump::visit (TuplePatternItemsRanged &)
 {}
 
 void
-Dump::visit (TuplePattern &pattern)
+Dump::visit (TuplePattern &)
 {}
 
 void
-Dump::visit (GroupedPattern &pattern)
+Dump::visit (GroupedPattern &)
 {}
 
 void
-Dump::visit (SlicePattern &pattern)
+Dump::visit (SlicePattern &)
 {}
 
 // rust-stmt.h
 void
-Dump::visit (EmptyStmt &stmt)
+Dump::visit (EmptyStmt &)
 {}
 
 void
@@ -1560,40 +1560,64 @@ Dump::visit (TraitBound &bound)
 }
 
 void
-Dump::visit (ImplTraitType &type)
+Dump::visit (ImplTraitType &)
 {}
 
 void
-Dump::visit (TraitObjectType &type)
+Dump::visit (TraitObjectType &)
 {}
 
 void
-Dump::visit (ParenthesisedType &type)
+Dump::visit (ParenthesisedType &)
 {}
 
 void
-Dump::visit (ImplTraitTypeOneBound &type)
+Dump::visit (ImplTraitTypeOneBound &)
 {}
 
 void
-Dump::visit (TraitObjectTypeOneBound &type)
+Dump::visit (TraitObjectTypeOneBound &)
 {}
 
 void
-Dump::visit (TupleType &type)
+Dump::visit (TupleType &)
 {}
 
 void
-Dump::visit (NeverType &type)
+Dump::visit (NeverType &)
 {}
 
 void
 Dump::visit (RawPointerType &type)
-{}
+{
+  // Syntax:
+  //    * ( mut | const ) TypeNoBounds
+
+  if (type.get_pointer_type () == RawPointerType::MUT)
+    stream << "*mut ";
+  else /* RawPointerType::CONST */
+    stream << "*const ";
+
+  visit (type.get_type_pointed_to ());
+}
 
 void
 Dump::visit (ReferenceType &type)
 {
+  // Syntax:
+  //    & Lifetime? mut? TypeNoBounds
+
+  stream << '&';
+
+  if (type.has_lifetime ())
+    {
+      visit (type.get_lifetime ());
+      stream << ' ';
+    }
+
+  if (type.get_has_mut ())
+    stream << "mut ";
+
   visit (type.get_type_referenced ());
 }
 
@@ -1606,7 +1630,7 @@ Dump::visit (ArrayType &type)
   stream << '[';
   visit (type.get_elem_type ());
   stream << "; ";
-  visit(type.get_size_expr());
+  visit (type.get_size_expr ());
   stream << ']';
 }
 
@@ -1622,13 +1646,13 @@ Dump::visit (SliceType &type)
 }
 
 void
-Dump::visit (InferredType &type)
+Dump::visit (InferredType &)
 {
   stream << "_";
 }
 
 void
-Dump::visit (BareFunctionType &type)
+Dump::visit (BareFunctionType &)
 {}
 
 } // namespace AST
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 077/103] gccrs: ast: Dump never type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (75 preceding siblings ...)
  2023-02-21 12:02 ` [committed 076/103] gccrs: ast: Dump raw pointer type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 078/103] gccrs: ast: Dump tuple type arthur.cohen
                   ` (25 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing never type visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index e6d6e070709..3af4895269c 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1585,7 +1585,12 @@ Dump::visit (TupleType &)
 
 void
 Dump::visit (NeverType &)
-{}
+{
+    // Syntax:
+    //  !
+
+    stream << '!';
+}
 
 void
 Dump::visit (RawPointerType &type)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 078/103] gccrs: ast: Dump tuple type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (76 preceding siblings ...)
  2023-02-21 12:02 ` [committed 077/103] gccrs: ast: Dump never type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 079/103] gccrs: ast: Dump inferred type arthur.cohen
                   ` (24 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing tuple type visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 3af4895269c..9393f957aa2 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1580,16 +1580,24 @@ Dump::visit (TraitObjectTypeOneBound &)
 {}
 
 void
-Dump::visit (TupleType &)
-{}
+Dump::visit (TupleType &type)
+{
+  // Syntax:
+  //   ( )
+  //   | ( ( Type , )+ Type? )
+
+  stream << '(';
+  visit_items_joined_by_separator (type.get_elems (), ", ");
+  stream << ')';
+}
 
 void
 Dump::visit (NeverType &)
 {
-    // Syntax:
-    //  !
+  // Syntax:
+  //  !
 
-    stream << '!';
+  stream << '!';
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 079/103] gccrs: ast: Dump inferred type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (77 preceding siblings ...)
  2023-02-21 12:02 ` [committed 078/103] gccrs: ast: Dump tuple type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 080/103] gccrs: ast: Dump bare function type arthur.cohen
                   ` (23 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 9393f957aa2..a37d5addbc4 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1661,6 +1661,9 @@ Dump::visit (SliceType &type)
 void
 Dump::visit (InferredType &)
 {
+  // Syntax:
+  //    _
+
   stream << "_";
 }
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 080/103] gccrs: ast: Dump bare function type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (78 preceding siblings ...)
  2023-02-21 12:02 ` [committed 079/103] gccrs: ast: Dump inferred type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 081/103] gccrs: ast: Dump impl trait type one bound arthur.cohen
                   ` (22 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

+ Return FunctionQualifiers as ref to work in ast dump

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.
	* ast/rust-ast-dump.h: Add missing getter declaration.
	* ast/rust-ast-full-test.cc (BareFunctionType::as_string): Fix bare function
	string representation.
	* ast/rust-type.h (class BareFunctionType): Declare said getter.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc      | 94 +++++++++++++++++++++++++++++-
 gcc/rust/ast/rust-ast-dump.h       |  2 +
 gcc/rust/ast/rust-ast-full-test.cc |  2 +-
 gcc/rust/ast/rust-type.h           | 22 +++++--
 4 files changed, 111 insertions(+), 9 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index a37d5addbc4..5dae38ccef9 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -249,6 +249,56 @@ Dump::visit (std::vector<LifetimeParam> &for_lifetimes)
   stream << "> ";
 }
 
+void
+Dump::visit (FunctionQualifiers &qualifiers)
+{
+  // Syntax:
+  //    `const`? `async`? `unsafe`? (`extern` Abi?)?
+  //    unsafe? (extern Abi?)?
+
+  switch (qualifiers.get_const_status ())
+    {
+    case NONE:
+      break;
+    case CONST_FN:
+      stream << "const ";
+      break;
+    case ASYNC_FN:
+      stream << "async ";
+      break;
+    }
+
+  if (qualifiers.is_unsafe ())
+    stream << "unsafe ";
+  if (qualifiers.is_extern ())
+    {
+      stream << "extern ";
+      if (qualifiers.has_abi ())
+	stream << "\"" << qualifiers.get_extern_abi () << "\" ";
+    }
+} // namespace AST
+
+void
+Dump::visit (MaybeNamedParam &param)
+{
+  // Syntax:
+  //     OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
+
+  visit_items_joined_by_separator (param.get_outer_attrs (), " ");
+  switch (param.get_param_kind ())
+    {
+    case MaybeNamedParam::UNNAMED:
+      break;
+    case MaybeNamedParam::IDENTIFIER:
+      stream << " " << param.get_name () << ": ";
+      break;
+    case MaybeNamedParam::WILDCARD:
+      stream << " _: ";
+      break;
+    }
+  visit (param.get_type ());
+}
+
 void
 Dump::visit (Token &tok)
 {
@@ -1668,8 +1718,48 @@ Dump::visit (InferredType &)
 }
 
 void
-Dump::visit (BareFunctionType &)
-{}
+Dump::visit (BareFunctionType &type)
+{
+  // Syntax:
+  //    ForLifetimes? FunctionTypeQualifiers fn
+  //      ( FunctionParametersMaybeNamedVariadic? ) BareFunctionReturnType?
+  //
+  //    BareFunctionReturnType:
+  //      -> TypeNoBounds
+  //
+  //    FunctionParametersMaybeNamedVariadic :
+  //      MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic
+  //
+  //    MaybeNamedFunctionParameters :
+  //      MaybeNamedParam ( , MaybeNamedParam )* ,?
+  //
+  //    MaybeNamedFunctionParametersVariadic :
+  //      ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
+
+  if (type.has_for_lifetimes ())
+    visit (type.get_for_lifetimes ());
+
+  visit (type.get_function_qualifiers ());
+
+  stream << "fn (";
+
+  visit_items_joined_by_separator (type.get_function_params (), ", ");
+
+  if (type.is_variadic ())
+    {
+      stream << ", ";
+      visit_items_joined_by_separator (type.get_variadic_attr (), " ");
+      stream << "...";
+    }
+
+  stream << ')';
+
+  if (type.has_return_type ())
+    {
+      stream << " -> ";
+      visit (type.get_return_type ());
+    }
+}
 
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 2bd3b31d09a..6c2f13c8c01 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -137,6 +137,8 @@ private:
   void visit (MacroRule &rule);
   void visit (WhereClause &rule);
   void visit (std::vector<LifetimeParam> &for_lifetimes);
+  void visit (FunctionQualifiers &qualifiers);
+  void visit (MaybeNamedParam &param);
 
   // rust-ast.h
   void visit (Token &tok);
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index a4e059f1c0c..4f593dcbd49 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -3071,7 +3071,7 @@ BareFunctionType::as_string () const
     }
 
   str += "\n Is variadic: ";
-  if (is_variadic)
+  if (_is_variadic)
     str += "true";
   else
     str += "false";
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 05a78956b57..efe59bd6f79 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -835,7 +835,7 @@ public:
 };
 
 /* A function pointer type - can be created via coercion from function items and
- * non- capturing closures. */
+ * non-capturing closures. */
 class BareFunctionType : public TypeNoBounds
 {
   // bool has_for_lifetimes;
@@ -844,7 +844,7 @@ class BareFunctionType : public TypeNoBounds
 
   FunctionQualifiers function_qualifiers;
   std::vector<MaybeNamedParam> params;
-  bool is_variadic;
+  bool _is_variadic;
   std::vector<Attribute> variadic_attrs;
 
   // bool has_return_type;
@@ -860,6 +860,16 @@ public:
   // Whether the function has ForLifetimes.
   bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
 
+  std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+
+  bool is_variadic () const { return _is_variadic; }
+
+  std::vector<Attribute> &get_variadic_attr () { return variadic_attrs; };
+  const std::vector<Attribute> &get_variadic_attr () const
+  {
+    return variadic_attrs;
+  };
+
   BareFunctionType (std::vector<LifetimeParam> lifetime_params,
 		    FunctionQualifiers qualifiers,
 		    std::vector<MaybeNamedParam> named_params, bool is_variadic,
@@ -867,7 +877,7 @@ public:
 		    std::unique_ptr<TypeNoBounds> type, Location locus)
     : for_lifetimes (std::move (lifetime_params)),
       function_qualifiers (std::move (qualifiers)),
-      params (std::move (named_params)), is_variadic (is_variadic),
+      params (std::move (named_params)), _is_variadic (is_variadic),
       variadic_attrs (std::move (variadic_attrs)),
       return_type (std::move (type)), locus (locus)
   {
@@ -879,7 +889,7 @@ public:
   BareFunctionType (BareFunctionType const &other)
     : for_lifetimes (other.for_lifetimes),
       function_qualifiers (other.function_qualifiers), params (other.params),
-      is_variadic (other.is_variadic), variadic_attrs (other.variadic_attrs),
+      _is_variadic (other._is_variadic), variadic_attrs (other.variadic_attrs),
       locus (other.locus)
   {
     // guard to prevent null dereference
@@ -893,7 +903,7 @@ public:
     for_lifetimes = other.for_lifetimes;
     function_qualifiers = other.function_qualifiers;
     params = other.params;
-    is_variadic = other.is_variadic;
+    _is_variadic = other._is_variadic;
     variadic_attrs = other.variadic_attrs;
     locus = other.locus;
 
@@ -930,7 +940,7 @@ public:
     return return_type;
   }
 
-  FunctionQualifiers get_function_qualifiers () { return function_qualifiers; }
+  FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 081/103] gccrs: ast: Dump impl trait type one bound
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (79 preceding siblings ...)
  2023-02-21 12:02 ` [committed 080/103] gccrs: ast: Dump bare function type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 082/103] gccrs: ast: Dump impl trait type arthur.cohen
                   ` (21 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 5dae38ccef9..2f01c72460d 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1622,8 +1622,14 @@ Dump::visit (ParenthesisedType &)
 {}
 
 void
-Dump::visit (ImplTraitTypeOneBound &)
-{}
+Dump::visit (ImplTraitTypeOneBound &type)
+{
+  // Syntax:
+  //    impl TraitBound
+
+  stream << "impl ";
+  visit (type.get_trait_bound());
+}
 
 void
 Dump::visit (TraitObjectTypeOneBound &)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 082/103] gccrs: ast: Dump impl trait type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (80 preceding siblings ...)
  2023-02-21 12:02 ` [committed 081/103] gccrs: ast: Dump impl trait type one bound arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 083/103] gccrs: ast: Dump trait object type arthur.cohen
                   ` (20 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 2f01c72460d..1d593d4b749 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1610,8 +1610,16 @@ Dump::visit (TraitBound &bound)
 }
 
 void
-Dump::visit (ImplTraitType &)
-{}
+Dump::visit (ImplTraitType &type)
+{
+  // Syntax:
+  //    impl TypeParamBounds
+  // TypeParamBounds :
+  //    TypeParamBound ( + TypeParamBound )* +?
+
+  stream << "impl ";
+  visit_items_joined_by_separator(type.get_type_param_bounds (), " + ");
+}
 
 void
 Dump::visit (TraitObjectType &)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 083/103] gccrs: ast: Dump trait object type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (81 preceding siblings ...)
  2023-02-21 12:02 ` [committed 082/103] gccrs: ast: Dump impl trait type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 084/103] gccrs: ast: Dump parenthesised type arthur.cohen
                   ` (19 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 1d593d4b749..0ae57fdb744 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1618,12 +1618,21 @@ Dump::visit (ImplTraitType &type)
   //    TypeParamBound ( + TypeParamBound )* +?
 
   stream << "impl ";
-  visit_items_joined_by_separator(type.get_type_param_bounds (), " + ");
+  visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
 }
 
 void
-Dump::visit (TraitObjectType &)
-{}
+Dump::visit (TraitObjectType &type)
+{
+  // Syntax:
+  //   dyn? TypeParamBounds
+  // TypeParamBounds :
+  //   TypeParamBound ( + TypeParamBound )* +?
+
+  if (type.is_dyn ())
+    stream << "dyn ";
+  visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
+}
 
 void
 Dump::visit (ParenthesisedType &)
@@ -1636,7 +1645,7 @@ Dump::visit (ImplTraitTypeOneBound &type)
   //    impl TraitBound
 
   stream << "impl ";
-  visit (type.get_trait_bound());
+  visit (type.get_trait_bound ());
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 084/103] gccrs: ast: Dump parenthesised type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (82 preceding siblings ...)
  2023-02-21 12:02 ` [committed 083/103] gccrs: ast: Dump trait object type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 085/103] gccrs: ast: Dump trait object type one bound arthur.cohen
                   ` (18 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 0ae57fdb744..8e06bf38a6a 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1635,8 +1635,15 @@ Dump::visit (TraitObjectType &type)
 }
 
 void
-Dump::visit (ParenthesisedType &)
-{}
+Dump::visit (ParenthesisedType &type)
+{
+  // Syntax:
+  //    ( Type )
+
+  stream << "(";
+  visit (type.get_type_in_parens ());
+  stream << ")";
+}
 
 void
 Dump::visit (ImplTraitTypeOneBound &type)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 085/103] gccrs: ast: Dump trait object type one bound
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (83 preceding siblings ...)
  2023-02-21 12:02 ` [committed 084/103] gccrs: ast: Dump parenthesised type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 086/103] gccrs: ast: Dump type param type arthur.cohen
                   ` (17 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 8e06bf38a6a..7d62571b778 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1656,8 +1656,15 @@ Dump::visit (ImplTraitTypeOneBound &type)
 }
 
 void
-Dump::visit (TraitObjectTypeOneBound &)
-{}
+Dump::visit (TraitObjectTypeOneBound &type)
+{
+  // Syntax:
+  //    dyn? TraitBound
+
+  if (type.is_dyn ())
+    stream << "dyn ";
+  visit(type.get_trait_bound());
+}
 
 void
 Dump::visit (TupleType &type)
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 086/103] gccrs: ast: Dump type param type
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (84 preceding siblings ...)
  2023-02-21 12:02 ` [committed 085/103] gccrs: ast: Dump trait object type one bound arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 087/103] gccrs: ast: Dump generic parameters arthur.cohen
                   ` (16 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 7d62571b778..216f0a43dc3 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -892,7 +892,19 @@ Dump::visit (AsyncBlockExpr &)
 void
 Dump::visit (TypeParam &param)
 {
+  // Syntax:
+  //    IDENTIFIER( : TypeParamBounds? )? ( = Type )?
+  // TypeParamBounds :
+  //    TypeParamBound ( + TypeParamBound )* +?
+
+  // FIXME this outputs things like "Ambiguous: String" - this comes from
+  // Token::str
   stream << param.get_type_representation ();
+  if (param.has_type_param_bounds ())
+    {
+      stream << ": ";
+      visit_items_joined_by_separator (param.get_type_param_bounds (), " + ");
+    }
   if (param.has_type ())
     {
       stream << " = ";
@@ -1663,7 +1675,7 @@ Dump::visit (TraitObjectTypeOneBound &type)
 
   if (type.is_dyn ())
     stream << "dyn ";
-  visit(type.get_trait_bound());
+  visit (type.get_trait_bound ());
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 087/103] gccrs: ast: Dump generic parameters
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (85 preceding siblings ...)
  2023-02-21 12:02 ` [committed 086/103] gccrs: ast: Dump type param type arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 088/103] gccrs: ast: Remove unused include in rust-ast-dump.cc arthur.cohen
                   ` (15 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Add missing visitor.
	* ast/rust-ast-dump.h: Likewise.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 129 +++++++++++++++++++++++++++++++---
 gcc/rust/ast/rust-ast-dump.h  |   3 +
 2 files changed, 123 insertions(+), 9 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 216f0a43dc3..03a57d416c4 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -372,21 +372,134 @@ Dump::visit (PathInExpression &path)
 }
 
 void
-Dump::visit (TypePathSegment &)
-{}
+Dump::visit (TypePathSegment &segment)
+{
+  // Syntax:
+  //    PathIdentSegment
+
+  stream << segment.get_ident_segment ().as_string ();
+}
 
 void
-Dump::visit (TypePathSegmentGeneric &)
-{}
+Dump::visit (TypePathSegmentGeneric &segment)
+{
+  // Syntax:
+  //    PathIdentSegment `::`? (GenericArgs)?
+  // GenericArgs :
+  //    `<` `>`
+  //    | `<` ( GenericArg `,` )* GenericArg `,`? `>`
+
+  stream << segment.get_ident_segment ().as_string ();
+
+  if (segment.get_separating_scope_resolution ())
+    stream << "::";
+
+  stream << "<";
+
+  {
+    // Here we join 3 lists (each possibly empty) with a separator.
+
+    auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
+    auto &generic_args = segment.get_generic_args ().get_generic_args ();
+    auto &binding_args = segment.get_generic_args ().get_binding_args ();
+
+    visit_items_joined_by_separator (lifetime_args, ", ");
+    if (!lifetime_args.empty ()
+	&& (!generic_args.empty () || !binding_args.empty ()))
+      {
+	// Insert separator if some items have been already emitted and some
+	// more are to be emitted from any of the following collections.
+	stream << ", ";
+      }
+    visit_items_joined_by_separator (generic_args, ", ");
+    if (!generic_args.empty () && !binding_args.empty ())
+      {
+	// Insert separator if some item vas emitted from the previous
+	// collection and more are to be emitted from the last.
+	stream << ", ";
+      }
+    visit_items_joined_by_separator (binding_args, ", ");
+  }
+
+  stream << ">";
+}
 
 void
-Dump::visit (TypePathSegmentFunction &)
-{}
+Dump::visit (GenericArgsBinding &binding)
+{
+  // Syntax:
+  //    IDENTIFIER `=` Type
+
+  stream << binding.get_identifier () << " << ";
+  visit (binding.get_type ());
+}
+
+void
+Dump::visit (GenericArg &arg)
+{
+  // `GenericArg` implements `accept_vis` but it is not useful for this case as
+  // it ignores unresolved cases (`Kind::Either`).
+
+  switch (arg.get_kind ())
+    {
+    case GenericArg::Kind::Const:
+      visit (arg.get_expression ());
+      break;
+    case GenericArg::Kind::Type:
+      visit (arg.get_type ());
+      break;
+    case GenericArg::Kind::Either:
+      stream << arg.get_path ();
+      break;
+    case GenericArg::Kind::Error:
+      gcc_unreachable ();
+    }
+} // namespace AST
+
+void
+Dump::visit (TypePathSegmentFunction &segment)
+{
+  // Syntax:
+  //   PathIdentSegment `::`? (TypePathFn)?
+
+  stream << segment.get_ident_segment ().as_string ();
+
+  if (segment.get_separating_scope_resolution ())
+    stream << "::";
+
+  if (!segment.is_ident_only ())
+    visit (segment.get_type_path_function ());
+}
+
+void
+Dump::visit (TypePathFunction &type_path_fn)
+{
+  // Syntax:
+  //   `(` TypePathFnInputs? `)` (`->` Type)?
+  // TypePathFnInputs :
+  //   Type (`,` Type)* `,`?
+
+  stream << '(';
+  if (type_path_fn.has_inputs ())
+    visit_items_joined_by_separator (type_path_fn.get_params (), ", ");
+  stream << ')';
+
+  if (type_path_fn.has_return_type ())
+    {
+      stream << "->";
+      visit (type_path_fn.get_return_type ());
+    }
+}
 
 void
 Dump::visit (TypePath &path)
 {
-  stream << path.as_string ();
+  // Syntax:
+  //    `::`? TypePathSegment (`::` TypePathSegment)*
+
+  if (path.has_opening_scope_resolution_op ())
+    stream << "::";
+  visit_items_joined_by_separator (path.get_segments (), "::");
 }
 
 void
@@ -897,8 +1010,6 @@ Dump::visit (TypeParam &param)
   // TypeParamBounds :
   //    TypeParamBound ( + TypeParamBound )* +?
 
-  // FIXME this outputs things like "Ambiguous: String" - this comes from
-  // Token::str
   stream << param.get_type_representation ();
   if (param.has_type_param_bounds ())
     {
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 6c2f13c8c01..4bc322cda98 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -139,6 +139,9 @@ private:
   void visit (std::vector<LifetimeParam> &for_lifetimes);
   void visit (FunctionQualifiers &qualifiers);
   void visit (MaybeNamedParam &param);
+  void visit (TypePathFunction &type_path_fn);
+  void visit (GenericArgsBinding &binding);
+  void visit (GenericArg &arg);
 
   // rust-ast.h
   void visit (Token &tok);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 088/103] gccrs: ast: Remove unused include in rust-ast-dump.cc
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (86 preceding siblings ...)
  2023-02-21 12:02 ` [committed 087/103] gccrs: ast: Dump generic parameters arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 089/103] gccrs: ast: Dump remove /* stmp */ comment to not clutter the dump arthur.cohen
                   ` (14 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc: Remove unused include.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 03a57d416c4..477805f19f3 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -17,7 +17,6 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-ast-dump.h"
-#include "rust-diagnostics.h"
 
 namespace Rust {
 namespace AST {
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 089/103] gccrs: ast: Dump remove /* stmp */ comment to not clutter the dump
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (87 preceding siblings ...)
  2023-02-21 12:02 ` [committed 088/103] gccrs: ast: Remove unused include in rust-ast-dump.cc arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 090/103] gccrs: ast: Dump no comma after self in fn params if it is the last one arthur.cohen
                   ` (13 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Remove extraneous string when
	dumping statements.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 477805f19f3..9ec847c4f88 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -848,7 +848,7 @@ Dump::visit (BlockExpr &expr)
   stream << "{\n";
   indentation.increment ();
 
-  visit_items_as_lines (expr.get_statements (), "; /* stmt */");
+  visit_items_as_lines (expr.get_statements (), ";");
 
   if (expr.has_tail_expr ())
     visit_as_line (expr.get_tail_expr (), " /* tail expr */\n");
@@ -1205,7 +1205,6 @@ Dump::visit (TypeAlias &type_alias)
     visit (type_alias.get_where_clause ());
   stream << " = ";
   visit (type_alias.get_type_aliased ());
-  stream << ";\n";
 }
 
 void
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 090/103] gccrs: ast: Dump no comma after self in fn params if it is the last one
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (88 preceding siblings ...)
  2023-02-21 12:02 ` [committed 089/103] gccrs: ast: Dump remove /* stmp */ comment to not clutter the dump arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 091/103] gccrs: Remove default location. Add visibility location to create_* functions arthur.cohen
                   ` (12 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* ast/rust-ast-dump.cc (Dump::visit): Fix dumping of fn params.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/ast/rust-ast-dump.cc | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 9ec847c4f88..131e23ea180 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1077,8 +1077,12 @@ Dump::visit (Method &method)
   visit (method.get_visibility ());
   stream << "fn " << method.get_method_name () << '(';
 
-  stream << method.get_self_param ().as_string () << ", ";
-  visit_items_joined_by_separator (method.get_function_params (), ", ");
+  stream << method.get_self_param ().as_string ();
+  if (!method.get_function_params ().empty ())
+    {
+      stream << ", ";
+      visit_items_joined_by_separator (method.get_function_params (), ", ");
+    }
 
   stream << ") ";
 
@@ -1343,9 +1347,13 @@ Dump::visit (TraitItemMethod &item)
   // emit_visibility (method.get_visibility ());
   stream << "fn " << method.get_identifier () << '(';
 
-  stream << method.get_self_param ().as_string () << ", ";
+  stream << method.get_self_param ().as_string ();
 
-  visit_items_joined_by_separator (method.get_function_params (), ", ");
+  if (!method.get_function_params ().empty ())
+    {
+      stream << ", ";
+      visit_items_joined_by_separator (method.get_function_params (), ", ");
+    }
 
   stream << ") ";
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 091/103] gccrs: Remove default location. Add visibility location to create_* functions
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (89 preceding siblings ...)
  2023-02-21 12:02 ` [committed 090/103] gccrs: ast: Dump no comma after self in fn params if it is the last one arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 092/103] gccrs: Improve lexer dump arthur.cohen
                   ` (11 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Dave

From: Dave <dme2223@gmail.com>

gcc/rust/ChangeLog:

	* ast/rust-item.h: Remoe default location for Visibility class.
	* parse/rust-parse-impl.h (Parser::parse_visibility): Pass proper location
	when instantiating visibilities.
---
 gcc/rust/ast/rust-item.h         | 33 ++++++++++++++++++--------------
 gcc/rust/parse/rust-parse-impl.h | 11 ++++++-----
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 96201d668de..7ea7b86562f 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -633,8 +633,7 @@ private:
 
 public:
   // Creates a Visibility - TODO make constructor protected or private?
-  Visibility (VisType vis_type, SimplePath in_path,
-	      Location locus = Location ())
+  Visibility (VisType vis_type, SimplePath in_path, Location locus)
     : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
   {}
 
@@ -654,10 +653,11 @@ public:
 
   Location get_locus () const { return locus; }
 
+  // empty?
   // Creates an error visibility.
   static Visibility create_error ()
   {
-    return Visibility (PUB_IN_PATH, SimplePath::create_empty ());
+    return Visibility (PUB_IN_PATH, SimplePath::create_empty (), Location ());
   }
 
   // Unique pointer custom clone function
@@ -669,45 +669,50 @@ public:
    * is one idea but may be too resource-intensive. */
 
   // Creates a public visibility with no further features/arguments.
-  static Visibility create_public ()
+  // empty?
+  static Visibility create_public (Location pub_vis_location)
   {
-    return Visibility (PUB, SimplePath::create_empty ());
+    return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
   }
 
   // Creates a public visibility with crate-relative paths
-  static Visibility create_crate (Location crate_tok_location)
+  static Visibility create_crate (Location crate_tok_location,
+				  Location crate_vis_location)
   {
     return Visibility (PUB_CRATE,
 		       SimplePath::from_str ("crate", crate_tok_location),
-		       crate_tok_location);
+		       crate_vis_location);
   }
 
   // Creates a public visibility with self-relative paths
-  static Visibility create_self (Location self_tok_location)
+  static Visibility create_self (Location self_tok_location,
+				 Location self_vis_location)
   {
     return Visibility (PUB_SELF,
 		       SimplePath::from_str ("self", self_tok_location),
-		       self_tok_location);
+		       self_vis_location);
   }
 
   // Creates a public visibility with parent module-relative paths
-  static Visibility create_super (Location super_tok_location)
+  static Visibility create_super (Location super_tok_location,
+				  Location super_vis_location)
   {
     return Visibility (PUB_SUPER,
 		       SimplePath::from_str ("super", super_tok_location),
-		       super_tok_location);
+		       super_vis_location);
   }
 
   // Creates a private visibility
   static Visibility create_private ()
   {
-    return Visibility (PRIV, SimplePath::create_empty ());
+    return Visibility (PRIV, SimplePath::create_empty (), Location ());
   }
 
   // Creates a public visibility with a given path or whatever.
-  static Visibility create_in_path (SimplePath in_path)
+  static Visibility create_in_path (SimplePath in_path,
+				    Location in_path_vis_location)
   {
-    return Visibility (PUB_IN_PATH, std::move (in_path), in_path.get_locus ());
+    return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
   }
 
   std::string as_string () const;
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index a4a912f8c1d..ee0282bdab3 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2137,12 +2137,13 @@ Parser<ManagedTokenSource>::parse_visibility ()
       return AST::Visibility::create_private ();
     }
 
+  auto vis_loc = lexer.peek_token ()->get_locus ();
   lexer.skip_token ();
 
   // create simple pub visibility if no parentheses
   if (lexer.peek_token ()->get_id () != LEFT_PAREN)
     {
-      return AST::Visibility::create_public ();
+      return AST::Visibility::create_public (vis_loc);
       // or whatever
     }
 
@@ -2158,19 +2159,19 @@ Parser<ManagedTokenSource>::parse_visibility ()
 
       skip_token (RIGHT_PAREN);
 
-      return AST::Visibility::create_crate (path_loc);
+      return AST::Visibility::create_crate (path_loc, vis_loc);
     case SELF:
       lexer.skip_token ();
 
       skip_token (RIGHT_PAREN);
 
-      return AST::Visibility::create_self (path_loc);
+      return AST::Visibility::create_self (path_loc, vis_loc);
     case SUPER:
       lexer.skip_token ();
 
       skip_token (RIGHT_PAREN);
 
-      return AST::Visibility::create_super (path_loc);
+      return AST::Visibility::create_super (path_loc, vis_loc);
       case IN: {
 	lexer.skip_token ();
 
@@ -2188,7 +2189,7 @@ Parser<ManagedTokenSource>::parse_visibility ()
 
 	skip_token (RIGHT_PAREN);
 
-	return AST::Visibility::create_in_path (std::move (path));
+	return AST::Visibility::create_in_path (std::move (path), vis_loc);
       }
     default:
       add_error (Error (t->get_locus (), "unexpected token %qs in visibility",
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 092/103] gccrs: Improve lexer dump
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (90 preceding siblings ...)
  2023-02-21 12:02 ` [committed 091/103] gccrs: Remove default location. Add visibility location to create_* functions arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 093/103] gccrs: Get rid of make builtin macro arthur.cohen
                   ` (10 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Raiki Tamura

From: Raiki Tamura <tamaron1203@gmail.com>

gcc/rust/ChangeLog:

	* lex/rust-lex.cc (Lexer::Lexer): Add `dump_lex` boolean flag.
	(Lexer::skip_token): Dump tokens if flag is enabled.
	(Lexer::dump_and_skip): New function.
	* lex/rust-lex.h: Include optional.h and declare functions.
	* parse/rust-parse-impl.h (Parser::debug_dump_lex_output): Remove old
	unused function.
	* parse/rust-parse.h: Likewise.
	* rust-session-manager.cc (Session::compile_crate): Pass lexer dump
	option to lexer.
	(Session::dump_lex): New function.
	* util/rust-optional.h: Add missing constructor.

Signed-off-by: Raiki Tamura <tamaron1203@gmail.com>
---
 gcc/rust/lex/rust-lex.cc         | 47 ++++++++++++++++++++++++++++++--
 gcc/rust/lex/rust-lex.h          | 12 ++++++--
 gcc/rust/parse/rust-parse-impl.h | 41 ----------------------------
 gcc/rust/parse/rust-parse.h      |  2 --
 gcc/rust/rust-session-manager.cc | 41 ++++++++++++----------------
 gcc/rust/util/rust-optional.h    |  1 +
 6 files changed, 72 insertions(+), 72 deletions(-)

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 3467a3160ed..53c7aecd25b 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -118,13 +118,15 @@ is_non_decimal_int_literal_separator (char character)
 
 Lexer::Lexer (const std::string &input)
   : input (RAIIFile::create_error ()), current_line (1), current_column (1),
-    line_map (nullptr), raw_input_source (new BufferInputSource (input, 0)),
+    line_map (nullptr), dump_lex_out (Optional<std::ofstream &>::none ()),
+    raw_input_source (new BufferInputSource (input, 0)),
     input_queue{*raw_input_source}, token_queue (TokenSource (this))
 {}
 
-Lexer::Lexer (const char *filename, RAIIFile file_input, Linemap *linemap)
+Lexer::Lexer (const char *filename, RAIIFile file_input, Linemap *linemap,
+	      Optional<std::ofstream &> dump_lex_opt)
   : input (std::move (file_input)), current_line (1), current_column (1),
-    line_map (linemap),
+    line_map (linemap), dump_lex_out (dump_lex_opt),
     raw_input_source (new FileInputSource (input.get_raw ())),
     input_queue{*raw_input_source}, token_queue (TokenSource (this))
 {
@@ -186,6 +188,45 @@ Lexer::skip_input ()
   skip_input (0);
 }
 
+void
+Lexer::skip_token (int n)
+{
+  // dump tokens if dump-lex option is enabled
+  if (dump_lex_out.is_some ())
+    dump_and_skip (n);
+  else
+    token_queue.skip (n);
+}
+
+void
+Lexer::dump_and_skip (int n)
+{
+  std::ofstream &out = dump_lex_out.get ();
+  bool found_eof = false;
+  const_TokenPtr tok;
+  for (int i = 0; i < n + 1; i++)
+    {
+      if (!found_eof)
+	{
+	  tok = peek_token ();
+	  found_eof |= tok->get_id () == Rust::END_OF_FILE;
+
+	  Location loc = tok->get_locus ();
+
+	  out << "<id=";
+	  out << tok->token_id_to_str ();
+	  out << (tok->has_str () ? (std::string (", text=") + tok->get_str ()
+				     + std::string (", typehint=")
+				     + std::string (tok->get_type_hint_str ()))
+				  : "")
+	      << " ";
+	  out << get_line_map ()->to_string (loc) << " ";
+	}
+
+      token_queue.skip (0);
+    }
+}
+
 void
 Lexer::replace_current_token (TokenPtr replacement)
 {
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index 6e8c5999f51..a170e91f2cc 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -22,6 +22,7 @@
 #include "rust-linemap.h"
 #include "rust-buffered-queue.h"
 #include "rust-token.h"
+#include "rust-optional.h"
 
 namespace Rust {
 // Simple wrapper for FILE* that simplifies destruction.
@@ -139,7 +140,9 @@ private:
 
 public:
   // Construct lexer with input file and filename provided
-  Lexer (const char *filename, RAIIFile input, Linemap *linemap);
+  Lexer (const char *filename, RAIIFile input, Linemap *linemap,
+	 Optional<std::ofstream &> dump_lex_opt
+	 = Optional<std::ofstream &>::none ());
 
   // Lex the contents of a string instead of a file
   Lexer (const std::string &input);
@@ -161,10 +164,13 @@ public:
   const_TokenPtr peek_token () { return peek_token (0); }
 
   // Advances current token to n + 1 tokens ahead of current position.
-  void skip_token (int n) { token_queue.skip (n); }
+  void skip_token (int n);
   // Skips the current token.
   void skip_token () { skip_token (0); }
 
+  // Dumps and advances by n + 1 tokens.
+  void dump_and_skip (int n);
+
   // Replaces the current token with a specified token.
   void replace_current_token (TokenPtr replacement);
   // FIXME: don't use anymore
@@ -197,6 +203,8 @@ private:
    * allocating new linemap */
   static const int max_column_hint = 80;
 
+  Optional<std::ofstream &> dump_lex_out;
+
   // Input source wrapper thing.
   class InputSource
   {
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index ee0282bdab3..cbd40efcc9b 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -14897,47 +14897,6 @@ Parser<ManagedTokenSource>::done_end ()
   return (t->get_id () == RIGHT_CURLY || t->get_id () == END_OF_FILE);
 }
 
-// Dumps lexer output to stderr.
-template <typename ManagedTokenSource>
-void
-Parser<ManagedTokenSource>::debug_dump_lex_output (std::ostream &out)
-{
-  /* TODO: a better implementation of "lexer dump" (as in dump what was
-   * actually tokenised) would actually be to "write" a token to a file every
-   * time skip_token() here was called. This would reflect the parser
-   * modifications to the token stream, such as fixing the template angle
-   * brackets. */
-
-  const_TokenPtr tok = lexer.peek_token ();
-
-  while (true)
-    {
-      if (tok->get_id () == Rust::END_OF_FILE)
-	break;
-
-      bool has_text = tok->get_id () == Rust::IDENTIFIER
-		      || tok->get_id () == Rust::INT_LITERAL
-		      || tok->get_id () == Rust::FLOAT_LITERAL
-		      || tok->get_id () == Rust::STRING_LITERAL
-		      || tok->get_id () == Rust::CHAR_LITERAL
-		      || tok->get_id () == Rust::BYTE_STRING_LITERAL
-		      || tok->get_id () == Rust::BYTE_CHAR_LITERAL;
-
-      Location loc = tok->get_locus ();
-
-      out << "<id=";
-      out << tok->token_id_to_str ();
-      out << has_text ? (std::string (", text=") + tok->get_str ()
-			 + std::string (", typehint=")
-			 + std::string (tok->get_type_hint_str ()))
-		      : "";
-      out << lexer.get_line_map ()->to_string (loc);
-
-      lexer.skip_token ();
-      tok = lexer.peek_token ();
-    }
-}
-
 // Parses crate and dumps AST to stderr, recursively.
 template <typename ManagedTokenSource>
 void
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index e4c5a2c5c9f..8449181b12f 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -671,8 +671,6 @@ public:
   // Main entry point for parser.
   std::unique_ptr<AST::Crate> parse_crate ();
 
-  // Dumps all lexer output.
-  void debug_dump_lex_output (std::ostream &out);
   void debug_dump_ast_output (AST::Crate &crate, std::ostream &out);
 
   // Returns whether any parsing errors have occurred.
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 6f51bd2e5a1..732aabe1f26 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -455,7 +455,22 @@ Session::compile_crate (const char *filename)
   // parse file here
   /* create lexer and parser - these are file-specific and so aren't instance
    * variables */
-  Lexer lex (filename, std::move (file_wrap), linemap);
+  Optional<std::ofstream &> dump_lex_opt = Optional<std::ofstream &>::none ();
+  std::ofstream dump_lex_stream;
+  if (options.dump_option_enabled (CompileOptions::LEXER_DUMP))
+    {
+      dump_lex_stream.open (kLexDumpFile);
+      if (dump_lex_stream.fail ())
+	{
+	  rust_error_at (Linemap::unknown_location (),
+			 "cannot open %s:%m; ignored", kLexDumpFile);
+	}
+      auto stream = Optional<std::ofstream &>::some (dump_lex_stream);
+      dump_lex_opt = std::move (stream);
+    }
+
+  Lexer lex (filename, std::move (file_wrap), linemap, dump_lex_opt);
+
   Parser<Lexer> parser (lex);
 
   // generate crate from parser
@@ -464,11 +479,7 @@ Session::compile_crate (const char *filename)
   // handle crate name
   handle_crate_name (*ast_crate.get ());
 
-  // dump options
-  if (options.dump_option_enabled (CompileOptions::LEXER_DUMP))
-    {
-      dump_lex (parser);
-    }
+  // dump options except lexer dump
   if (options.dump_option_enabled (CompileOptions::PARSER_AST_DUMP))
     {
       dump_ast (parser, *ast_crate.get ());
@@ -835,24 +846,6 @@ Session::expansion (AST::Crate &crate)
   rust_debug ("finished expansion");
 }
 
-void
-Session::dump_lex (Parser<Lexer> &parser) const
-{
-  std::ofstream out;
-  out.open (kLexDumpFile);
-  if (out.fail ())
-    {
-      rust_error_at (Linemap::unknown_location (), "cannot open %s:%m; ignored",
-		     kLexDumpFile);
-      return;
-    }
-
-  // TODO: rewrite lexer dump or something so that it allows for the crate
-  // to already be parsed
-  parser.debug_dump_lex_output (out);
-  out.close ();
-}
-
 void
 Session::dump_ast (Parser<Lexer> &parser, AST::Crate &crate) const
 {
diff --git a/gcc/rust/util/rust-optional.h b/gcc/rust/util/rust-optional.h
index eba3a7886ac..d7349820b38 100644
--- a/gcc/rust/util/rust-optional.h
+++ b/gcc/rust/util/rust-optional.h
@@ -194,6 +194,7 @@ private:
 public:
   Optional (const Optional &other) = default;
   Optional (Optional &&other) = default;
+  Optional &operator= (Optional &&other) = default;
 
   static Optional<T &> some (T &value)
   {
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 093/103] gccrs: Get rid of make builtin macro
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (91 preceding siblings ...)
  2023-02-21 12:02 ` [committed 092/103] gccrs: Improve lexer dump arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 094/103] gccrs: Refactor name resolver to take a Rib::ItemType arthur.cohen
                   ` (9 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

This macro is a mess and a helper method is much better for this case.

gcc/rust/ChangeLog:

	* resolve/rust-name-resolver.cc (MKBUILTIN_TYPE): Remove macro.
	(Rib::Rib): Remove `mappings` field.
	(Resolver::generate_builtins): Use `setup_builtin` instead of macro.
	(Resolver::setup_builtin): New function.
	* resolve/rust-name-resolver.h: Declare `setup_builtin`, add FIXME
	comment.
---
 gcc/rust/resolve/rust-name-resolver.cc | 87 +++++++++++++-------------
 gcc/rust/resolve/rust-name-resolver.h  |  7 ++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc
index b94713d3c30..cc1ec2b9dc7 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -19,40 +19,17 @@
 #include "rust-name-resolver.h"
 #include "rust-ast-full.h"
 
-#define MKBUILTIN_TYPE(_X, _R, _TY)                                            \
-  do                                                                           \
-    {                                                                          \
-      AST::PathIdentSegment seg (_X, Linemap::predeclared_location ());        \
-      auto typePath = ::std::unique_ptr<AST::TypePathSegment> (                \
-	new AST::TypePathSegment (::std::move (seg), false,                    \
-				  Linemap::predeclared_location ()));          \
-      ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs;           \
-      segs.push_back (::std::move (typePath));                                 \
-      auto builtin_type                                                        \
-	= new AST::TypePath (::std::move (segs),                               \
-			     Linemap::predeclared_location (), false);         \
-      _R.push_back (builtin_type);                                             \
-      tyctx->insert_builtin (_TY->get_ref (), builtin_type->get_node_id (),    \
-			     _TY);                                             \
-      mappings->insert_node_to_hir (builtin_type->get_node_id (),              \
-				    _TY->get_ref ());                          \
-      mappings->insert_canonical_path (                                        \
-	builtin_type->get_node_id (),                                          \
-	CanonicalPath::new_seg (builtin_type->get_node_id (), _X));            \
-    }                                                                          \
-  while (0)
-
 namespace Rust {
 namespace Resolver {
 
 Rib::Rib (CrateNum crateNum, NodeId node_id)
-  : crate_num (crateNum), node_id (node_id),
-    mappings (Analysis::Mappings::get ())
+  : crate_num (crateNum), node_id (node_id)
 {}
 
 void
 Rib::insert_name (
   const CanonicalPath &path, NodeId id, Location locus, bool shadow,
+
   std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
 {
   auto it = path_mappings.find (path);
@@ -69,8 +46,8 @@ Rib::insert_name (
     }
 
   path_mappings[path] = id;
-  reverse_path_mappings.insert (std::pair<NodeId, CanonicalPath> (id, path));
-  decls_within_rib.insert (std::pair<NodeId, Location> (id, locus));
+  reverse_path_mappings.insert ({id, path});
+  decls_within_rib.insert ({id, locus});
   references[id] = {};
 }
 
@@ -387,24 +364,24 @@ Resolver::generate_builtins ()
   auto str = new TyTy::StrType (mappings->get_next_hir_id ());
   auto never = new TyTy::NeverType (mappings->get_next_hir_id ());
 
-  MKBUILTIN_TYPE ("u8", builtins, u8);
-  MKBUILTIN_TYPE ("u16", builtins, u16);
-  MKBUILTIN_TYPE ("u32", builtins, u32);
-  MKBUILTIN_TYPE ("u64", builtins, u64);
-  MKBUILTIN_TYPE ("u128", builtins, u128);
-  MKBUILTIN_TYPE ("i8", builtins, i8);
-  MKBUILTIN_TYPE ("i16", builtins, i16);
-  MKBUILTIN_TYPE ("i32", builtins, i32);
-  MKBUILTIN_TYPE ("i64", builtins, i64);
-  MKBUILTIN_TYPE ("i128", builtins, i128);
-  MKBUILTIN_TYPE ("bool", builtins, rbool);
-  MKBUILTIN_TYPE ("f32", builtins, f32);
-  MKBUILTIN_TYPE ("f64", builtins, f64);
-  MKBUILTIN_TYPE ("usize", builtins, usize);
-  MKBUILTIN_TYPE ("isize", builtins, isize);
-  MKBUILTIN_TYPE ("char", builtins, char_tyty);
-  MKBUILTIN_TYPE ("str", builtins, str);
-  MKBUILTIN_TYPE ("!", builtins, never);
+  setup_builtin ("u8", u8);
+  setup_builtin ("u16", u16);
+  setup_builtin ("u32", u32);
+  setup_builtin ("u64", u64);
+  setup_builtin ("u128", u128);
+  setup_builtin ("i8", i8);
+  setup_builtin ("i16", i16);
+  setup_builtin ("i32", i32);
+  setup_builtin ("i64", i64);
+  setup_builtin ("i128", i128);
+  setup_builtin ("bool", rbool);
+  setup_builtin ("f32", f32);
+  setup_builtin ("f64", f64);
+  setup_builtin ("usize", usize);
+  setup_builtin ("isize", isize);
+  setup_builtin ("char", char_tyty);
+  setup_builtin ("str", str);
+  setup_builtin ("!", never);
 
   // unit type ()
   TyTy::TupleType *unit_tyty
@@ -418,6 +395,26 @@ Resolver::generate_builtins ()
   set_unit_type_node_id (unit_type->get_node_id ());
 }
 
+void
+Resolver::setup_builtin (const std::string &name, TyTy::BaseType *tyty)
+{
+  AST::PathIdentSegment seg (name, Linemap::predeclared_location ());
+  auto typePath = ::std::unique_ptr<AST::TypePathSegment> (
+    new AST::TypePathSegment (::std::move (seg), false,
+			      Linemap::predeclared_location ()));
+  ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs;
+  segs.push_back (::std::move (typePath));
+  auto builtin_type
+    = new AST::TypePath (::std::move (segs), Linemap::predeclared_location (),
+			 false);
+  builtins.push_back (builtin_type);
+  tyctx->insert_builtin (tyty->get_ref (), builtin_type->get_node_id (), tyty);
+  mappings->insert_node_to_hir (builtin_type->get_node_id (), tyty->get_ref ());
+  mappings->insert_canonical_path (
+    builtin_type->get_node_id (),
+    CanonicalPath::new_seg (builtin_type->get_node_id (), name));
+}
+
 void
 Resolver::insert_resolved_name (NodeId refId, NodeId defId)
 {
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 302b0de15cc..d2f740e0315 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -30,8 +30,9 @@ namespace Resolver {
 class Rib
 {
 public:
-  // Rust uses local_def_ids assigned by def_collector on the AST
-  // lets use NodeId instead
+  // FIXME
+  // Rust uses local_def_ids assigned by def_collector on the AST. Consider
+  // moving to a local-def-id
   Rib (CrateNum crateNum, NodeId node_id);
 
   // this takes the relative paths of items within a compilation unit for lookup
@@ -59,7 +60,6 @@ private:
   std::map<NodeId, CanonicalPath> reverse_path_mappings;
   std::map<NodeId, Location> decls_within_rib;
   std::map<NodeId, std::set<NodeId>> references;
-  Analysis::Mappings *mappings;
 };
 
 class Scope
@@ -172,6 +172,7 @@ private:
   Resolver ();
 
   void generate_builtins ();
+  void setup_builtin (const std::string &name, TyTy::BaseType *tyty);
 
   Analysis::Mappings *mappings;
   TypeCheckContext *tyctx;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 094/103] gccrs: Refactor name resolver to take a Rib::ItemType
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (92 preceding siblings ...)
  2023-02-21 12:02 ` [committed 093/103] gccrs: Get rid of make builtin macro arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 095/103] gccrs: Add closure binding's tracking to name resolution arthur.cohen
                   ` (8 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

This allows us to track the type of declaration that is stored within a
Rib.

gcc/rust/ChangeLog:

	* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Add Rib argument.
	(ResolveExpr::resolve_closure_param): Likewise.
	* resolve/rust-ast-resolve-implitem.h: Likewise.
	* resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit): Likewise.
	(ResolveItem::visit): Likewise.
	* resolve/rust-ast-resolve-pattern.cc (PatternDeclaration::visit): Likewise.
	* resolve/rust-ast-resolve-pattern.h: Likewise.
	* resolve/rust-ast-resolve-stmt.h: Likewise.
	* resolve/rust-ast-resolve-toplevel.h: Likewise.
	* resolve/rust-ast-resolve-type.h: Likewise.
	* resolve/rust-name-resolver.cc (Rib::lookup_decl_type): Likewise.
	(Scope::insert): Likewise.
	(Resolver::insert_builtin_types): Likewise.
	* resolve/rust-name-resolver.h: Likewise.
---
 gcc/rust/resolve/rust-ast-resolve-expr.cc    | 14 +++++------
 gcc/rust/resolve/rust-ast-resolve-implitem.h | 12 ++++++++--
 gcc/rust/resolve/rust-ast-resolve-item.cc    | 19 ++++++++-------
 gcc/rust/resolve/rust-ast-resolve-pattern.cc |  2 +-
 gcc/rust/resolve/rust-ast-resolve-pattern.h  | 12 ++++++----
 gcc/rust/resolve/rust-ast-resolve-stmt.h     | 19 ++++++++++-----
 gcc/rust/resolve/rust-ast-resolve-toplevel.h | 21 ++++++++++++----
 gcc/rust/resolve/rust-ast-resolve-type.h     |  2 +-
 gcc/rust/resolve/rust-name-resolver.cc       | 23 ++++++++++++++----
 gcc/rust/resolve/rust-name-resolver.h        | 25 +++++++++++++++++++-
 10 files changed, 108 insertions(+), 41 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 8ece5b63b6d..293c63f5628 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -209,7 +209,7 @@ ResolveExpr::visit (AST::IfLetExpr &expr)
 
   for (auto &pattern : expr.get_patterns ())
     {
-      PatternDeclaration::go (pattern.get ());
+      PatternDeclaration::go (pattern.get (), Rib::ItemType::Var);
     }
 
   ResolveExpr::go (expr.get_if_block ().get (), prefix, canonical_prefix);
@@ -343,7 +343,7 @@ ResolveExpr::visit (AST::LoopExpr &expr)
       auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
       resolver->get_label_scope ().insert (
 	CanonicalPath::new_seg (expr.get_node_id (), label_name),
-	label_lifetime_node_id, label.get_locus (), false,
+	label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
 	[&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	  rust_error_at (label.get_locus (), "label redefined multiple times");
 	  rust_error_at (locus, "was defined here");
@@ -400,7 +400,7 @@ ResolveExpr::visit (AST::WhileLoopExpr &expr)
       auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
       resolver->get_label_scope ().insert (
 	CanonicalPath::new_seg (label.get_node_id (), label_name),
-	label_lifetime_node_id, label.get_locus (), false,
+	label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
 	[&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	  rust_error_at (label.get_locus (), "label redefined multiple times");
 	  rust_error_at (locus, "was defined here");
@@ -429,7 +429,7 @@ ResolveExpr::visit (AST::ForLoopExpr &expr)
       auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
       resolver->get_label_scope ().insert (
 	CanonicalPath::new_seg (label.get_node_id (), label_name),
-	label_lifetime_node_id, label.get_locus (), false,
+	label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
 	[&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	  rust_error_at (label.get_locus (), "label redefined multiple times");
 	  rust_error_at (locus, "was defined here");
@@ -446,7 +446,7 @@ ResolveExpr::visit (AST::ForLoopExpr &expr)
   resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
 
   // resolve the expression
-  PatternDeclaration::go (expr.get_pattern ().get ());
+  PatternDeclaration::go (expr.get_pattern ().get (), Rib::ItemType::Var);
   ResolveExpr::go (expr.get_iterator_expr ().get (), prefix, canonical_prefix);
   ResolveExpr::go (expr.get_loop_block ().get (), prefix, canonical_prefix);
 
@@ -520,7 +520,7 @@ ResolveExpr::visit (AST::MatchExpr &expr)
       // insert any possible new patterns
       for (auto &pattern : arm.get_patterns ())
 	{
-	  PatternDeclaration::go (pattern.get ());
+	  PatternDeclaration::go (pattern.get (), Rib::ItemType::Var);
 	}
 
       // resolve the body
@@ -617,7 +617,7 @@ ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
 void
 ResolveExpr::resolve_closure_param (AST::ClosureParam &param)
 {
-  PatternDeclaration::go (param.get_pattern ().get ());
+  PatternDeclaration::go (param.get_pattern ().get (), Rib::ItemType::Param);
 
   if (param.has_type_given ())
     ResolveType::go (param.get_type ().get ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 52e025672bd..9cad8aa41a5 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -56,7 +56,7 @@ public:
     auto path = prefix.append (decl);
 
     resolver->get_type_scope ().insert (
-      path, type.get_node_id (), type.get_locus (), false,
+      path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (type.get_locus ());
 	r.add_range (locus);
@@ -72,6 +72,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, constant.get_node_id (), constant.get_locus (), false,
+      Rib::ItemType::Const,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (constant.get_locus ());
 	r.add_range (locus);
@@ -87,6 +88,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, function.get_node_id (), function.get_locus (), false,
+      Rib::ItemType::Function,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (function.get_locus ());
 	r.add_range (locus);
@@ -102,6 +104,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, method.get_node_id (), method.get_locus (), false,
+      Rib::ItemType::Function,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (method.get_locus ());
 	r.add_range (locus);
@@ -141,6 +144,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, function.get_node_id (), function.get_locus (), false,
+      Rib::ItemType::Function,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (function.get_locus ());
 	r.add_range (locus);
@@ -159,6 +163,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, method.get_node_id (), method.get_locus (), false,
+      Rib::ItemType::Function,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (method.get_locus ());
 	r.add_range (locus);
@@ -177,6 +182,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, constant.get_node_id (), constant.get_locus (), false,
+      Rib::ItemType::Const,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (constant.get_locus ());
 	r.add_range (locus);
@@ -194,7 +200,7 @@ public:
     auto cpath = canonical_prefix.append (decl);
 
     resolver->get_type_scope ().insert (
-      path, type.get_node_id (), type.get_locus (), false,
+      path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (type.get_locus ());
 	r.add_range (locus);
@@ -233,6 +239,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, function.get_node_id (), function.get_locus (), false,
+      Rib::ItemType::Function,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (function.get_locus ());
 	r.add_range (locus);
@@ -251,6 +258,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, item.get_node_id (), item.get_locus (), false,
+      Rib::ItemType::Static,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 193e6834334..0be9a02a6f6 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -82,7 +82,8 @@ ResolveTraitItems::visit (AST::TraitItemFunc &func)
   for (auto &param : function.get_function_params ())
     {
       ResolveType::go (param.get_type ().get ());
-      PatternDeclaration::go (param.get_pattern ().get ());
+      PatternDeclaration::go (param.get_pattern ().get (),
+			      Rib::ItemType::Param);
     }
 
   if (function.has_where_clause ())
@@ -138,14 +139,15 @@ ResolveTraitItems::visit (AST::TraitItemMethod &func)
   AST::TypePath self_type_path (std::move (segments), self_param.get_locus ());
 
   ResolveType::go (&self_type_path);
-  PatternDeclaration::go (&self_pattern);
+  PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
 
   // we make a new scope so the names of parameters are resolved and shadowed
   // correctly
   for (auto &param : function.get_function_params ())
     {
       ResolveType::go (param.get_type ().get ());
-      PatternDeclaration::go (param.get_pattern ().get ());
+      PatternDeclaration::go (param.get_pattern ().get (),
+			      Rib::ItemType::Param);
     }
 
   if (function.has_where_clause ())
@@ -499,10 +501,8 @@ ResolveItem::visit (AST::Function &function)
   for (auto &param : function.get_function_params ())
     {
       ResolveType::go (param.get_type ().get ());
-      PatternDeclaration::go (param.get_pattern ().get ());
-
-      // the mutability checker needs to verify for immutable decls the number
-      // of assignments are <1. This marks an implicit assignment
+      PatternDeclaration::go (param.get_pattern ().get (),
+			      Rib::ItemType::Param);
     }
 
   // resolve the function body
@@ -631,14 +631,15 @@ ResolveItem::visit (AST::Method &method)
   AST::TypePath self_type_path (std::move (segments), self_param.get_locus ());
 
   ResolveType::go (&self_type_path);
-  PatternDeclaration::go (&self_pattern);
+  PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
 
   // we make a new scope so the names of parameters are resolved and shadowed
   // correctly
   for (auto &param : method.get_function_params ())
     {
       ResolveType::go (param.get_type ().get ());
-      PatternDeclaration::go (param.get_pattern ().get ());
+      PatternDeclaration::go (param.get_pattern ().get (),
+			      Rib::ItemType::Param);
     }
 
   // resolve any where clause items
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index 483d1908822..10f4fd8a61b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -49,7 +49,7 @@ PatternDeclaration::visit (AST::TupleStructPattern &pattern)
 
 	for (auto &inner_pattern : items_no_range.get_patterns ())
 	  {
-	    PatternDeclaration::go (inner_pattern.get ());
+	    PatternDeclaration::go (inner_pattern.get (), type);
 	  }
       }
       break;
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
index ea99c63b1ca..5f2b7293cf2 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -55,9 +55,9 @@ class PatternDeclaration : public ResolverBase
   using Rust::Resolver::ResolverBase::visit;
 
 public:
-  static void go (AST::Pattern *pattern)
+  static void go (AST::Pattern *pattern, Rib::ItemType type)
   {
-    PatternDeclaration resolver;
+    PatternDeclaration resolver (type);
     pattern->accept_vis (resolver);
   };
 
@@ -67,14 +67,14 @@ public:
     // as new refs to this decl will match back here so it is ok to overwrite
     resolver->get_name_scope ().insert (
       CanonicalPath::new_seg (pattern.get_node_id (), pattern.get_ident ()),
-      pattern.get_node_id (), pattern.get_locus ());
+      pattern.get_node_id (), pattern.get_locus (), type);
   }
 
   void visit (AST::WildcardPattern &pattern) override
   {
     resolver->get_name_scope ().insert (
       CanonicalPath::new_seg (pattern.get_node_id (), "_"),
-      pattern.get_node_id (), pattern.get_locus ());
+      pattern.get_node_id (), pattern.get_locus (), type);
   }
 
   // cases in a match expression
@@ -89,7 +89,9 @@ public:
   void visit (AST::RangePattern &pattern) override;
 
 private:
-  PatternDeclaration () : ResolverBase () {}
+  PatternDeclaration (Rib::ItemType type) : ResolverBase (), type (type) {}
+
+  Rib::ItemType type;
 };
 
 } // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index be93b008996..28c547f410b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -64,6 +64,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, constant.get_node_id (), constant.get_locus (), false,
+      Rib::ItemType::Const,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (constant.get_locus ());
 	r.add_range (locus);
@@ -82,7 +83,7 @@ public:
 			 canonical_prefix);
       }
 
-    PatternDeclaration::go (stmt.get_pattern ().get ());
+    PatternDeclaration::go (stmt.get_pattern ().get (), Rib::ItemType::Var);
     if (stmt.has_type ())
       ResolveType::go (stmt.get_type ().get ());
   }
@@ -97,6 +98,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (struct_decl.get_locus ());
 	r.add_range (locus);
@@ -128,6 +130,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (enum_decl.get_locus ());
 	r.add_range (locus);
@@ -158,7 +161,7 @@ public:
     mappings->insert_canonical_path (item.get_node_id (), cpath);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -177,7 +180,7 @@ public:
     mappings->insert_canonical_path (item.get_node_id (), cpath);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -202,7 +205,7 @@ public:
     mappings->insert_canonical_path (item.get_node_id (), cpath);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -227,7 +230,7 @@ public:
     mappings->insert_canonical_path (item.get_node_id (), cpath);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -247,6 +250,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (struct_decl.get_locus ());
 	r.add_range (locus);
@@ -283,6 +287,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, union_decl.get_node_id (), union_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (union_decl.get_locus ());
 	r.add_range (locus);
@@ -317,6 +322,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, function.get_node_id (), function.get_locus (), false,
+      Rib::ItemType::Function,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (function.get_locus ());
 	r.add_range (locus);
@@ -343,7 +349,8 @@ public:
     for (auto &param : function.get_function_params ())
       {
 	ResolveType::go (param.get_type ().get ());
-	PatternDeclaration::go (param.get_pattern ().get ());
+	PatternDeclaration::go (param.get_pattern ().get (),
+				Rib::ItemType::Param);
       }
 
     // resolve the function body
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 4cc51011777..d751318ee54 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -57,6 +57,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, module.get_node_id (), module.get_locus (), false,
+      Rib::ItemType::Module,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (module.get_locus ());
 	r.add_range (locus);
@@ -85,6 +86,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, alias.get_node_id (), alias.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (alias.get_locus ());
 	r.add_range (locus);
@@ -105,6 +107,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (struct_decl.get_locus ());
 	r.add_range (locus);
@@ -125,6 +128,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (enum_decl.get_locus ());
 	r.add_range (locus);
@@ -147,7 +151,7 @@ public:
     auto cpath = canonical_prefix.append (decl);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -165,7 +169,7 @@ public:
     auto cpath = canonical_prefix.append (decl);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -183,7 +187,7 @@ public:
     auto cpath = canonical_prefix.append (decl);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -201,7 +205,7 @@ public:
     auto cpath = canonical_prefix.append (decl);
 
     resolver->get_type_scope ().insert (
-      path, item.get_node_id (), item.get_locus (), false,
+      path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (item.get_locus ());
 	r.add_range (locus);
@@ -220,6 +224,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (struct_decl.get_locus ());
 	r.add_range (locus);
@@ -240,6 +245,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, union_decl.get_node_id (), union_decl.get_locus (), false,
+      Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (union_decl.get_locus ());
 	r.add_range (locus);
@@ -259,7 +265,7 @@ public:
     auto cpath = canonical_prefix.append (decl);
 
     resolver->get_name_scope ().insert (
-      path, var.get_node_id (), var.get_locus (), false,
+      path, var.get_node_id (), var.get_locus (), false, Rib::ItemType::Static,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (var.get_locus ());
 	r.add_range (locus);
@@ -280,6 +286,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, constant.get_node_id (), constant.get_locus (), false,
+      Rib::ItemType::Const,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (constant.get_locus ());
 	r.add_range (locus);
@@ -300,6 +307,7 @@ public:
 
     resolver->get_name_scope ().insert (
       path, function.get_node_id (), function.get_locus (), false,
+      Rib::ItemType::Function,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (function.get_locus ());
 	r.add_range (locus);
@@ -343,6 +351,7 @@ public:
 
     resolver->get_name_scope ().insert (
       impl_prefix, impl_block.get_node_id (), impl_block.get_locus (), false,
+      Rib::ItemType::TraitImpl,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (impl_block.get_locus ());
 	r.add_range (locus);
@@ -362,6 +371,7 @@ public:
 
     resolver->get_type_scope ().insert (
       path, trait.get_node_id (), trait.get_locus (), false,
+      Rib::ItemType::Trait,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (trait.get_locus ());
 	r.add_range (locus);
@@ -437,6 +447,7 @@ public:
 
     resolver->get_type_scope ().insert (
       decl, resolved_crate, extern_crate.get_locus (), false,
+      Rib::ItemType::ExternCrate,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	RichLocation r (extern_crate.get_locus ());
 	r.add_range (locus);
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 424233fa3df..bb1178362fb 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -177,7 +177,7 @@ public:
     auto seg = CanonicalPath::new_seg (param.get_node_id (),
 				       param.get_type_representation ());
     resolver->get_type_scope ().insert (
-      seg, param.get_node_id (), param.get_locus (), false,
+      seg, param.get_node_id (), param.get_locus (), false, Rib::ItemType::Type,
       [&] (const CanonicalPath &, NodeId, Location locus) -> void {
 	rust_error_at (param.get_locus (),
 		       "generic param redefined multiple times");
diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc
index cc1ec2b9dc7..cf3028ef271 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -29,7 +29,7 @@ Rib::Rib (CrateNum crateNum, NodeId node_id)
 void
 Rib::insert_name (
   const CanonicalPath &path, NodeId id, Location locus, bool shadow,
-
+  ItemType type,
   std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
 {
   auto it = path_mappings.find (path);
@@ -49,6 +49,7 @@ Rib::insert_name (
   reverse_path_mappings.insert ({id, path});
   decls_within_rib.insert ({id, locus});
   references[id] = {};
+  decl_type_mappings.insert ({id, type});
 }
 
 bool
@@ -105,6 +106,17 @@ Rib::decl_was_declared_here (NodeId def) const
   return false;
 }
 
+bool
+Rib::lookup_decl_type (NodeId def, ItemType *type) const
+{
+  auto it = decl_type_mappings.find (def);
+  if (it == decl_type_mappings.end ())
+    return false;
+
+  *type = it->second;
+  return true;
+}
+
 void
 Rib::debug () const
 {
@@ -128,15 +140,17 @@ Scope::Scope (CrateNum crate_num) : crate_num (crate_num) {}
 void
 Scope::insert (
   const CanonicalPath &ident, NodeId id, Location locus, bool shadow,
+  Rib::ItemType type,
   std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
 {
-  peek ()->insert_name (ident, id, locus, shadow, dup_cb);
+  peek ()->insert_name (ident, id, locus, shadow, type, dup_cb);
 }
 
 void
-Scope::insert (const CanonicalPath &ident, NodeId id, Location locus)
+Scope::insert (const CanonicalPath &ident, NodeId id, Location locus,
+	       Rib::ItemType type)
 {
-  peek ()->insert_name (ident, id, locus, true,
+  peek ()->insert_name (ident, id, locus, true, type,
 			[] (const CanonicalPath &, NodeId, Location) -> void {
 			});
 }
@@ -321,6 +335,7 @@ Resolver::insert_builtin_types (Rib *r)
 				  builtin->as_string ());
       r->insert_name (builtin_path, builtin->get_node_id (),
 		      Linemap::predeclared_location (), false,
+		      Rib::ItemType::Type,
 		      [] (const CanonicalPath &, NodeId, Location) -> void {});
     }
 }
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index d2f740e0315..54d59544b1d 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -30,6 +30,24 @@ namespace Resolver {
 class Rib
 {
 public:
+  enum ItemType
+  {
+    Var,
+    Param,
+    Function,
+    Type,
+    Module,
+    Static,
+    Const,
+    Trait,
+    Impl,
+    TraitImpl,
+    ExternCrate,
+    MacroDecl,
+    Label,
+    Unknown
+  };
+
   // FIXME
   // Rust uses local_def_ids assigned by def_collector on the AST. Consider
   // moving to a local-def-id
@@ -38,6 +56,7 @@ public:
   // this takes the relative paths of items within a compilation unit for lookup
   void insert_name (
     const CanonicalPath &path, NodeId id, Location locus, bool shadow,
+    ItemType type,
     std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
 
   bool lookup_canonical_path (const NodeId &id, CanonicalPath *ident);
@@ -46,6 +65,7 @@ public:
   void append_reference_for_def (NodeId def, NodeId ref);
   bool have_references_for_node (NodeId def) const;
   bool decl_was_declared_here (NodeId def) const;
+  bool lookup_decl_type (NodeId def, ItemType *type) const;
   void debug () const;
   std::string debug_str () const;
 
@@ -60,6 +80,7 @@ private:
   std::map<NodeId, CanonicalPath> reverse_path_mappings;
   std::map<NodeId, Location> decls_within_rib;
   std::map<NodeId, std::set<NodeId>> references;
+  std::map<NodeId, ItemType> decl_type_mappings;
 };
 
 class Scope
@@ -69,9 +90,11 @@ public:
 
   void
   insert (const CanonicalPath &ident, NodeId id, Location locus, bool shadow,
+	  Rib::ItemType type,
 	  std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
 
-  void insert (const CanonicalPath &ident, NodeId id, Location locus);
+  void insert (const CanonicalPath &ident, NodeId id, Location locus,
+	       Rib::ItemType type = Rib::ItemType::Unknown);
   bool lookup (const CanonicalPath &ident, NodeId *id);
 
   void iterate (std::function<bool (Rib *)> cb);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 095/103] gccrs: Add closure binding's tracking to name resolution
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (93 preceding siblings ...)
  2023-02-21 12:02 ` [committed 094/103] gccrs: Refactor name resolver to take a Rib::ItemType arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 096/103] gccrs: Add capture tracking to the type info for closures arthur.cohen
                   ` (7 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

When we have a closure block referencing variables in a parent function,
we must track what these are. We do this by having a context of closures
so if we have a variable reference and its declared in a rib whose node id
is less than the node id of the closure's node id we know it must be a
captured variable. We also need to iterate all possible closure contexts
as we might be in the case of a nested closure.

Addresses #195

gcc/rust/ChangeLog:

	* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Use proper closure
	contexts.
	* resolve/rust-name-resolver.cc (Scope::lookup_decl_type): New function.
	(Scope::lookup_rib_for_decl): Likewise.
	(Resolver::insert_resolved_name): Insert captured items.
	(Resolver::push_closure_context): New function.
	(Resolver::pop_closure_context): Likewise.
	(Resolver::insert_captured_item): Likewise.
	(Resolver::decl_needs_capture): Likewise.
	(Resolver::get_captures): Likewise.
	* resolve/rust-name-resolver.h: Declare new functions.
---
 gcc/rust/resolve/rust-ast-resolve-expr.cc |   9 ++
 gcc/rust/resolve/rust-name-resolver.cc    | 133 ++++++++++++++++++++++
 gcc/rust/resolve/rust-name-resolver.h     |  17 +++
 3 files changed, 159 insertions(+)

diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 293c63f5628..536c828beb4 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -581,9 +581,13 @@ ResolveExpr::visit (AST::ClosureExprInner &expr)
       resolve_closure_param (p);
     }
 
+  resolver->push_closure_context (expr.get_node_id ());
+
   ResolveExpr::go (expr.get_definition_expr ().get (), prefix,
 		   canonical_prefix);
 
+  resolver->pop_closure_context ();
+
   resolver->get_name_scope ().pop ();
   resolver->get_type_scope ().pop ();
   resolver->get_label_scope ().pop ();
@@ -606,9 +610,14 @@ ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
     }
 
   ResolveType::go (expr.get_return_type ().get ());
+
+  resolver->push_closure_context (expr.get_node_id ());
+
   ResolveExpr::go (expr.get_definition_block ().get (), prefix,
 		   canonical_prefix);
 
+  resolver->pop_closure_context ();
+
   resolver->get_name_scope ().pop ();
   resolver->get_type_scope ().pop ();
   resolver->get_label_scope ().pop ();
diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc
index cf3028ef271..b8ed3538f74 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -169,6 +169,39 @@ Scope::lookup (const CanonicalPath &ident, NodeId *id)
   return lookup != UNKNOWN_NODEID;
 }
 
+bool
+Scope::lookup_decl_type (NodeId id, Rib::ItemType *type)
+{
+  bool found = false;
+  iterate ([&] (const Rib *r) -> bool {
+    if (r->decl_was_declared_here (id))
+      {
+	bool ok = r->lookup_decl_type (id, type);
+	rust_assert (ok);
+	found = true;
+	return false;
+      }
+    return true;
+  });
+  return found;
+}
+
+bool
+Scope::lookup_rib_for_decl (NodeId id, const Rib **rib)
+{
+  bool found = false;
+  iterate ([&] (const Rib *r) -> bool {
+    if (r->decl_was_declared_here (id))
+      {
+	*rib = r;
+	found = true;
+	return false;
+      }
+    return true;
+  });
+  return found;
+}
+
 void
 Scope::iterate (std::function<bool (Rib *)> cb)
 {
@@ -435,6 +468,7 @@ Resolver::insert_resolved_name (NodeId refId, NodeId defId)
 {
   resolved_names[refId] = defId;
   get_name_scope ().append_reference_for_def (refId, defId);
+  insert_captured_item (defId);
 }
 
 bool
@@ -531,5 +565,104 @@ Resolver::lookup_resolved_misc (NodeId refId, NodeId *defId)
   return true;
 }
 
+void
+Resolver::push_closure_context (NodeId closure_expr_id)
+{
+  auto it = closures_capture_mappings.find (closure_expr_id);
+  rust_assert (it == closures_capture_mappings.end ());
+
+  closures_capture_mappings.insert ({closure_expr_id, {}});
+  closure_context.push_back (closure_expr_id);
+}
+
+void
+Resolver::pop_closure_context ()
+{
+  rust_assert (!closure_context.empty ());
+  closure_context.pop_back ();
+}
+
+void
+Resolver::insert_captured_item (NodeId id)
+{
+  // nothing to do unless we are in a closure context
+  if (closure_context.empty ())
+    return;
+
+  // check that this is a VAR_DECL?
+  Scope &name_scope = get_name_scope ();
+  Rib::ItemType type = Rib::ItemType::Unknown;
+  bool found = name_scope.lookup_decl_type (id, &type);
+  if (!found)
+    return;
+
+  // RIB Function { let a, let b } id = 1;
+  //   RIB Closure { let c } id = 2;
+  //     RIB IfStmt { <bind a>} id = 3;
+  //   RIB ... { ... } id = 4
+  //
+  // if we have a resolved_node_id of 'a' and the current rib is '3' we know
+  // this is binding exists in a rib with id < the closure rib id, other wise
+  // its just a normal binding and we don't care
+  //
+  // Problem the node id's dont work like this because the inner most items are
+  // created first so this means the root will have a larger id and a simple
+  // less than or greater than check wont work for more complex scoping cases
+  // but we can use our current rib context to figure this out by checking if
+  // the rib id the decl we care about exists prior to the rib for the closure
+  // id
+
+  const Rib *r = nullptr;
+  bool ok = name_scope.lookup_rib_for_decl (id, &r);
+  rust_assert (ok);
+  NodeId decl_rib_node_id = r->get_node_id ();
+
+  // iterate the closure context and add in the mapping for all to handle the
+  // case of nested closures
+  for (auto &closure_expr_id : closure_context)
+    {
+      if (!decl_needs_capture (decl_rib_node_id, closure_expr_id, name_scope))
+	continue;
+
+      // is this a valid binding to take
+      bool is_var_decl_p = type == Rib::ItemType::Var;
+      if (!is_var_decl_p)
+	{
+	  // FIXME is this an error case?
+	  return;
+	}
+
+      // append it to the context info
+      auto it = closures_capture_mappings.find (closure_expr_id);
+      rust_assert (it != closures_capture_mappings.end ());
+
+      it->second.insert (id);
+    }
+}
+
+bool
+Resolver::decl_needs_capture (NodeId decl_rib_node_id,
+			      NodeId closure_rib_node_id, const Scope &scope)
+{
+  for (const auto &rib : scope.get_context ())
+    {
+      bool rib_is_closure = rib->get_node_id () == closure_rib_node_id;
+      bool rib_is_decl = rib->get_node_id () == decl_rib_node_id;
+      if (rib_is_closure)
+	return false;
+      else if (rib_is_decl)
+	return true;
+    }
+  return false;
+}
+
+const std::set<NodeId> &
+Resolver::get_captures (NodeId id) const
+{
+  auto it = closures_capture_mappings.find (id);
+  rust_assert (it != closures_capture_mappings.end ());
+  return it->second;
+}
+
 } // namespace Resolver
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 54d59544b1d..f38cbb941bf 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -96,6 +96,8 @@ public:
   void insert (const CanonicalPath &ident, NodeId id, Location locus,
 	       Rib::ItemType type = Rib::ItemType::Unknown);
   bool lookup (const CanonicalPath &ident, NodeId *id);
+  bool lookup_decl_type (NodeId id, Rib::ItemType *type);
+  bool lookup_rib_for_decl (NodeId id, const Rib **rib);
 
   void iterate (std::function<bool (Rib *)> cb);
   void iterate (std::function<bool (const Rib *)> cb) const;
@@ -109,6 +111,8 @@ public:
 
   CrateNum get_crate_num () const { return crate_num; }
 
+  const std::vector<Rib *> &get_context () const { return stack; };
+
 private:
   CrateNum crate_num;
   std::vector<Rib *> stack;
@@ -191,6 +195,15 @@ public:
     return current_module_stack.at (current_module_stack.size () - 2);
   }
 
+  void push_closure_context (NodeId closure_expr_id);
+  void pop_closure_context ();
+  void insert_captured_item (NodeId id);
+  const std::set<NodeId> &get_captures (NodeId id) const;
+
+protected:
+  bool decl_needs_capture (NodeId decl_rib_node_id, NodeId closure_rib_node_id,
+			   const Scope &scope);
+
 private:
   Resolver ();
 
@@ -234,6 +247,10 @@ private:
 
   // keep track of the current module scope ids
   std::vector<NodeId> current_module_stack;
+
+  // captured variables mappings
+  std::vector<NodeId> closure_context;
+  std::map<NodeId, std::set<NodeId>> closures_capture_mappings;
 };
 
 } // namespace Resolver
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 096/103] gccrs: Add capture tracking to the type info for closures
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (94 preceding siblings ...)
  2023-02-21 12:02 ` [committed 095/103] gccrs: Add closure binding's tracking to name resolution arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 097/103] gccrs: Add initial support for argument capture of closures arthur.cohen
                   ` (6 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Pass captures
	properly to `TyTy::ClosureType` constructor.
	* typecheck/rust-tyty.cc (ClosureType::as_string): Fix string representation.
	(ClosureType::clone): Pass `captures` argument.
	* typecheck/rust-tyty.h: Add `captures` field.
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc |  4 +++-
 gcc/rust/typecheck/rust-tyty.cc                |  5 ++---
 gcc/rust/typecheck/rust-tyty.h                 | 11 +++++++++--
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 85590630378..0b0db3296a0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1492,8 +1492,10 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
 		 expr.get_locus ());
 
   // generate the closure type
+  NodeId closure_node_id = expr.get_mappings ().get_nodeid ();
+  const std::set<NodeId> &captures = resolver->get_captures (closure_node_id);
   infered = new TyTy::ClosureType (ref, id, ident, closure_args, result_type,
-				   subst_refs);
+				   subst_refs, captures);
 
   // FIXME
   // all closures automatically inherit the appropriate fn trait. Lets just
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index bdb2d909b86..71f0de1bbab 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -1675,8 +1675,7 @@ std::string
 ClosureType::as_string () const
 {
   std::string params_buf = parameters->as_string ();
-  return "|" + params_buf + "| {" + result_type.get_tyty ()->as_string ()
-	 + "} {" + raw_bounds_as_string () + "}";
+  return "|" + params_buf + "| {" + result_type.get_tyty ()->as_string () + "}";
 }
 
 BaseType *
@@ -1714,7 +1713,7 @@ ClosureType::clone () const
 {
   return new ClosureType (get_ref (), get_ty_ref (), ident, id,
 			  (TyTy::TupleType *) parameters->clone (), result_type,
-			  clone_substs (), get_combined_refs (),
+			  clone_substs (), captures, get_combined_refs (),
 			  specified_bounds);
 }
 
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 5eaec352567..b9a1fdfa5c7 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1628,13 +1628,15 @@ public:
   ClosureType (HirId ref, DefId id, RustIdent ident,
 	       TyTy::TupleType *parameters, TyVar result_type,
 	       std::vector<SubstitutionParamMapping> subst_refs,
+	       std::set<NodeId> captures,
 	       std::set<HirId> refs = std::set<HirId> (),
 	       std::vector<TypeBoundPredicate> specified_bounds
 	       = std::vector<TypeBoundPredicate> ())
     : BaseType (ref, ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
 		       SubstitutionArgumentMappings::error ()),
-      parameters (parameters), result_type (std::move (result_type)), id (id)
+      parameters (parameters), result_type (std::move (result_type)), id (id),
+      captures (captures)
   {
     LocalDefId local_def_id = id.localDefId;
     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
@@ -1644,13 +1646,15 @@ public:
   ClosureType (HirId ref, HirId ty_ref, RustIdent ident, DefId id,
 	       TyTy::TupleType *parameters, TyVar result_type,
 	       std::vector<SubstitutionParamMapping> subst_refs,
+	       std::set<NodeId> captures,
 	       std::set<HirId> refs = std::set<HirId> (),
 	       std::vector<TypeBoundPredicate> specified_bounds
 	       = std::vector<TypeBoundPredicate> ())
     : BaseType (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
 		       SubstitutionArgumentMappings::error ()),
-      parameters (parameters), result_type (std::move (result_type)), id (id)
+      parameters (parameters), result_type (std::move (result_type)), id (id),
+      captures (captures)
   {
     LocalDefId local_def_id = id.localDefId;
     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
@@ -1699,10 +1703,13 @@ public:
 
   void setup_fn_once_output () const;
 
+  const std::set<NodeId> &get_captures () const { return captures; }
+
 private:
   TyTy::TupleType *parameters;
   TyVar result_type;
   DefId id;
+  std::set<NodeId> captures;
 };
 
 class ArrayType : public BaseType
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 097/103] gccrs: Add initial support for argument capture of closures
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (95 preceding siblings ...)
  2023-02-21 12:02 ` [committed 096/103] gccrs: Add capture tracking to the type info for closures arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 098/103] gccrs: Fix undefined behaviour issues on macos arthur.cohen
                   ` (5 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

When we have a closure expression that captures a parent function's
variable we must setup the closure data to contain this. Ignoring
moveability and mutability requires for now, this patch creates the closure
structure with fields for each of the captured variables. When it comes to
compilation of the closure expression in order to support nested closures
we must setup a context of implicit mappings so that for all path
resolution we hit this implicit closure mappings lookups code before any
lookup_var_decl as this decl will not exist so the order here is important
during path resolution which is a similar problem to match expression
destructuring.

Fixes #195

gcc/rust/ChangeLog:

	* backend/rust-compile-context.cc (Context::push_closure_context): New function.
	(Context::pop_closure_context): Likewise.
	(Context::insert_closure_binding): Likewise.
	(Context::lookup_closure_binding): Likewise.
	* backend/rust-compile-context.h: Declare new functions and closure mappings.
	* backend/rust-compile-expr.cc (CompileExpr::visit): Visit captures properly.
	(CompileExpr::generate_closure_function): Compile captures properly.
	* backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve): Check for
	closure bindings.
	* backend/rust-compile-type.cc (TyTyResolveCompile::visit): Compile capture list's
	types as well.

gcc/testsuite/ChangeLog:

	* rust/execute/torture/closure3.rs: New test.
---
 gcc/rust/backend/rust-compile-context.cc      | 47 +++++++++++++++++
 gcc/rust/backend/rust-compile-context.h       |  9 ++++
 gcc/rust/backend/rust-compile-expr.cc         | 50 +++++++++++++++++--
 gcc/rust/backend/rust-compile-resolve-path.cc |  8 +++
 gcc/rust/backend/rust-compile-type.cc         | 31 +++++++++++-
 .../rust/execute/torture/closure3.rs          | 33 ++++++++++++
 6 files changed, 172 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/closure3.rs

diff --git a/gcc/rust/backend/rust-compile-context.cc b/gcc/rust/backend/rust-compile-context.cc
index b989741fe4b..018897e39b2 100644
--- a/gcc/rust/backend/rust-compile-context.cc
+++ b/gcc/rust/backend/rust-compile-context.cc
@@ -142,5 +142,52 @@ Context::type_hasher (tree type)
   return hstate.end ();
 }
 
+void
+Context::push_closure_context (HirId id)
+{
+  auto it = closure_bindings.find (id);
+  rust_assert (it == closure_bindings.end ());
+
+  closure_bindings.insert ({id, {}});
+  closure_scope_bindings.push_back (id);
+}
+
+void
+Context::pop_closure_context ()
+{
+  rust_assert (!closure_scope_bindings.empty ());
+
+  HirId ref = closure_scope_bindings.back ();
+  closure_scope_bindings.pop_back ();
+  closure_bindings.erase (ref);
+}
+
+void
+Context::insert_closure_binding (HirId id, tree expr)
+{
+  rust_assert (!closure_scope_bindings.empty ());
+
+  HirId ref = closure_scope_bindings.back ();
+  closure_bindings[ref].insert ({id, expr});
+}
+
+bool
+Context::lookup_closure_binding (HirId id, tree *expr)
+{
+  if (closure_scope_bindings.empty ())
+    return false;
+
+  HirId ref = closure_scope_bindings.back ();
+  auto it = closure_bindings.find (ref);
+  rust_assert (it != closure_bindings.end ());
+
+  auto iy = it->second.find (id);
+  if (iy == it->second.end ())
+    return false;
+
+  *expr = iy->second;
+  return true;
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index d2d3a53f182..8e8fac80d59 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -345,6 +345,11 @@ public:
     return mangler.mangle_item (ty, path);
   }
 
+  void push_closure_context (HirId id);
+  void pop_closure_context ();
+  void insert_closure_binding (HirId id, tree expr);
+  bool lookup_closure_binding (HirId id, tree *expr);
+
   std::vector<tree> &get_type_decls () { return type_decls; }
   std::vector<::Bvariable *> &get_var_decls () { return var_decls; }
   std::vector<tree> &get_const_decls () { return const_decls; }
@@ -377,6 +382,10 @@ private:
   std::map<HirId, tree> implicit_pattern_bindings;
   std::map<hashval_t, tree> main_variants;
 
+  // closure bindings
+  std::vector<HirId> closure_scope_bindings;
+  std::map<HirId, std::map<HirId, tree>> closure_bindings;
+
   // To GCC middle-end
   std::vector<tree> type_decls;
   std::vector<::Bvariable *> var_decls;
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 8169ba02b84..436fc924a13 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2829,10 +2829,25 @@ CompileExpr::visit (HIR::ClosureExpr &expr)
 
   // lets ignore state capture for now we need to instantiate the struct anyway
   // then generate the function
-
   std::vector<tree> vals;
-  // TODO
-  // setup argument captures based on the mode?
+  for (const auto &capture : closure_tyty->get_captures ())
+    {
+      // lookup the HirId
+      HirId ref = UNKNOWN_HIRID;
+      bool ok = ctx->get_mappings ()->lookup_node_to_hir (capture, &ref);
+      rust_assert (ok);
+
+      // lookup the var decl
+      Bvariable *var = nullptr;
+      bool found = ctx->lookup_var_decl (ref, &var);
+      rust_assert (found);
+
+      // FIXME
+      // this should bes based on the closure move-ability
+      tree var_expr = var->get_tree (expr.get_locus ());
+      tree val = address_expression (var_expr, expr.get_locus ());
+      vals.push_back (val);
+    }
 
   translated
     = ctx->get_backend ()->constructor_expression (compiled_closure_tyty, false,
@@ -2879,8 +2894,29 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
   DECL_ARTIFICIAL (self_param->get_decl ()) = 1;
   param_vars.push_back (self_param);
 
+  // push a new context
+  ctx->push_closure_context (expr.get_mappings ().get_hirid ());
+
   // setup the implicit argument captures
-  // TODO
+  size_t idx = 0;
+  for (const auto &capture : closure_tyty.get_captures ())
+    {
+      // lookup the HirId
+      HirId ref = UNKNOWN_HIRID;
+      bool ok = ctx->get_mappings ()->lookup_node_to_hir (capture, &ref);
+      rust_assert (ok);
+
+      // get the assessor
+      tree binding = ctx->get_backend ()->struct_field_expression (
+	self_param->get_tree (expr.get_locus ()), idx, expr.get_locus ());
+      tree indirection = indirect_expression (binding, expr.get_locus ());
+
+      // insert bindings
+      ctx->insert_closure_binding (ref, indirection);
+
+      // continue
+      idx++;
+    }
 
   // args tuple
   tree args_type
@@ -2910,7 +2946,10 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
     }
 
   if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
-    return error_mark_node;
+    {
+      ctx->pop_closure_context ();
+      return error_mark_node;
+    }
 
   // lookup locals
   HIR::Expr *function_body = expr.get_expr ().get ();
@@ -2977,6 +3016,7 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
   gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
   DECL_SAVED_TREE (fndecl) = bind_tree;
 
+  ctx->pop_closure_context ();
   ctx->pop_fn ();
   ctx->push_function (fndecl);
 
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index ab8e628c75c..8857df2f3a5 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -121,6 +121,14 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
       return constant_expr;
     }
 
+  // maybe closure binding
+  tree closure_binding = error_mark_node;
+  if (ctx->lookup_closure_binding (ref, &closure_binding))
+    {
+      TREE_USED (closure_binding) = 1;
+      return closure_binding;
+    }
+
   // this might be a variable reference or a function reference
   Bvariable *var = nullptr;
   if (ctx->lookup_var_decl (ref, &var))
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index 824cb3a56ef..c8e1d3b4036 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -19,6 +19,7 @@
 #include "rust-compile-type.h"
 #include "rust-compile-expr.h"
 #include "rust-constexpr.h"
+#include "rust-gcc.h"
 
 #include "tree.h"
 
@@ -99,11 +100,39 @@ TyTyResolveCompile::visit (const TyTy::InferType &)
 void
 TyTyResolveCompile::visit (const TyTy::ClosureType &type)
 {
+  auto mappings = ctx->get_mappings ();
+
   std::vector<Backend::typed_identifier> fields;
+
+  size_t i = 0;
+  for (const auto &capture : type.get_captures ())
+    {
+      // lookup the HirId
+      HirId ref = UNKNOWN_HIRID;
+      bool ok = mappings->lookup_node_to_hir (capture, &ref);
+      rust_assert (ok);
+
+      // lookup the var decl type
+      TyTy::BaseType *lookup = nullptr;
+      bool found = ctx->get_tyctx ()->lookup_type (ref, &lookup);
+      rust_assert (found);
+
+      // FIXME get the var pattern name
+      std::string mappings_name = "capture_" + std::to_string (i);
+
+      // FIXME
+      // this should be based on the closure move-ability
+      tree decl_type = TyTyResolveCompile::compile (ctx, lookup);
+      tree capture_type = build_reference_type (decl_type);
+      fields.push_back (Backend::typed_identifier (mappings_name, capture_type,
+						   type.get_ident ().locus));
+    }
+
   tree type_record = ctx->get_backend ()->struct_type (fields);
   RS_CLOSURE_FLAG (type_record) = 1;
 
-  std::string named_struct_str = type.get_ident ().path.get () + "{{closure}}";
+  std::string named_struct_str
+    = type.get_ident ().path.get () + "::{{closure}}";
   translated = ctx->get_backend ()->named_type (named_struct_str, type_record,
 						type.get_ident ().locus);
 }
diff --git a/gcc/testsuite/rust/execute/torture/closure3.rs b/gcc/testsuite/rust/execute/torture/closure3.rs
new file mode 100644
index 00000000000..62cf3a082cf
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/closure3.rs
@@ -0,0 +1,33 @@
+// { dg-output "3\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn f<F: FnOnce(i32) -> i32>(g: F) {
+    let call = g(1);
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, call);
+    }
+}
+
+pub fn main() -> i32 {
+    let capture = 2;
+    let a = |i: i32| {
+        let b = i + capture;
+        b
+    };
+    f(a);
+    0
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 098/103] gccrs: Fix undefined behaviour issues on macos
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (96 preceding siblings ...)
  2023-02-21 12:02 ` [committed 097/103] gccrs: Add initial support for argument capture of closures arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 099/103] gccrs: Skip this debug test case which is failing on the latest mac-os devtools and its only for debug info arthur.cohen
                   ` (4 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

This adds missing copy constructors to HIR::PathExprSegment which were
wrongly defaulting to empty vectors when apply specified generic arguments
to method calls.

gcc/rust/ChangeLog:

	* hir/tree/rust-hir-expr.h: Add const `get_method_name`.
	* hir/tree/rust-hir-full-decls.h (struct GenericArgs): Move from `struct`...
	(class GenericArgs): ...to `class`.
	* hir/tree/rust-hir-path.h (struct GenericArgs): Likewise.
	(class GenericArgs): Clear `type_args` in copy constructor.
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Reorder
	debug print.
	* typecheck/rust-tyty.h: Add default constructors for `SubstitutionArgumentMappings`.
---
 gcc/rust/hir/tree/rust-hir-expr.h             |  3 +-
 gcc/rust/hir/tree/rust-hir-full-decls.h       |  2 +-
 gcc/rust/hir/tree/rust-hir-path.h             | 37 ++++++++++++++-----
 .../typecheck/rust-hir-type-check-expr.cc     |  5 ++-
 gcc/rust/typecheck/rust-tyty.h                |  4 ++
 5 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 227bacbe641..cc884420bef 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -1872,7 +1872,8 @@ public:
 
   std::unique_ptr<Expr> &get_receiver () { return receiver; }
 
-  PathExprSegment get_method_name () const { return method_name; };
+  PathExprSegment &get_method_name () { return method_name; };
+  const PathExprSegment &get_method_name () const { return method_name; };
 
   size_t num_params () const { return params.size (); }
 
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 70ee7538298..7870a5497ed 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -43,7 +43,7 @@ class PathExpr;
 // rust-path.h
 class PathIdentSegment;
 struct GenericArgsBinding;
-struct GenericArgs;
+class GenericArgs;
 class PathExprSegment;
 class PathPattern;
 class PathInExpression;
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index fa8347b2cf8..17eedb8d741 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -140,8 +140,7 @@ private:
   Location locus;
 };
 
-// Generic arguments allowed in each path expression segment - inline?
-struct GenericArgs
+class GenericArgs
 {
   std::vector<Lifetime> lifetime_args;
   std::vector<std::unique_ptr<Type> > type_args;
@@ -172,6 +171,7 @@ public:
     : lifetime_args (other.lifetime_args), binding_args (other.binding_args),
       const_args (other.const_args), locus (other.locus)
   {
+    type_args.clear ();
     type_args.reserve (other.type_args.size ());
 
     for (const auto &e : other.type_args)
@@ -188,6 +188,7 @@ public:
     const_args = other.const_args;
     locus = other.locus;
 
+    type_args.clear ();
     type_args.reserve (other.type_args.size ());
     for (const auto &e : other.type_args)
       type_args.push_back (e->clone_type ());
@@ -235,26 +236,44 @@ private:
   Location locus;
 
 public:
-  // Returns true if there are any generic arguments
-  bool has_generic_args () const { return generic_args.has_generic_args (); }
-
-  // Constructor for segment (from IdentSegment and GenericArgs)
   PathExprSegment (Analysis::NodeMapping mappings,
-		   PathIdentSegment segment_name, Location locus = Location (),
-		   GenericArgs generic_args = GenericArgs::create_empty ())
+		   PathIdentSegment segment_name, Location locus,
+		   GenericArgs generic_args)
     : mappings (std::move (mappings)), segment_name (std::move (segment_name)),
       generic_args (std::move (generic_args)), locus (locus)
   {}
 
+  PathExprSegment (PathExprSegment const &other)
+    : mappings (other.mappings), segment_name (other.segment_name),
+      generic_args (other.generic_args), locus (other.locus)
+  {}
+
+  PathExprSegment &operator= (PathExprSegment const &other)
+  {
+    mappings = other.mappings;
+    segment_name = other.segment_name;
+    generic_args = other.generic_args;
+    locus = other.locus;
+
+    return *this;
+  }
+
+  // move constructors
+  PathExprSegment (PathExprSegment &&other) = default;
+  PathExprSegment &operator= (PathExprSegment &&other) = default;
+
   std::string as_string () const;
 
   Location get_locus () const { return locus; }
 
-  PathIdentSegment get_segment () const { return segment_name; }
+  PathIdentSegment &get_segment () { return segment_name; }
+  const PathIdentSegment &get_segment () const { return segment_name; }
 
   GenericArgs &get_generic_args () { return generic_args; }
 
   const Analysis::NodeMapping &get_mappings () const { return mappings; }
+
+  bool has_generic_args () const { return generic_args.has_generic_args (); }
 };
 
 // HIR node representing a pattern that involves a "path" - abstract base class
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 0b0db3296a0..5c43cc8c7b4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1149,10 +1149,11 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
   // apply any remaining generic arguments
   if (expr.get_method_name ().has_generic_args ())
     {
-      rust_debug_loc (expr.get_method_name ().get_generic_args ().get_locus (),
+      HIR::GenericArgs &args = expr.get_method_name ().get_generic_args ();
+      rust_debug_loc (args.get_locus (),
 		      "applying generic arguments to method_call: {%s}",
 		      lookup->debug_str ().c_str ());
-      HIR::GenericArgs &args = expr.get_method_name ().get_generic_args ();
+
       lookup
 	= SubstMapper::Resolve (lookup, expr.get_method_name ().get_locus (),
 				&args);
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index b9a1fdfa5c7..0fd664c8d46 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -699,6 +699,10 @@ public:
     return *this;
   }
 
+  SubstitutionArgumentMappings (SubstitutionArgumentMappings &&other) = default;
+  SubstitutionArgumentMappings &operator= (SubstitutionArgumentMappings &&other)
+    = default;
+
   static SubstitutionArgumentMappings error ()
   {
     return SubstitutionArgumentMappings ({}, Location (), nullptr, false);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 099/103] gccrs: Skip this debug test case which is failing on the latest mac-os devtools and its only for debug info
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (97 preceding siblings ...)
  2023-02-21 12:02 ` [committed 098/103] gccrs: Fix undefined behaviour issues on macos arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 100/103] gccrs: Cleanup unused parameters to fix the bootstrap build arthur.cohen
                   ` (3 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

gcc/testsuite/ChangeLog:

	* rust/debug/chartype.rs: Skip testcases on Darwin architectures.
---
 gcc/testsuite/rust/debug/chartype.rs | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/gcc/testsuite/rust/debug/chartype.rs b/gcc/testsuite/rust/debug/chartype.rs
index 69e7ab0b17f..3300925d4e0 100644
--- a/gcc/testsuite/rust/debug/chartype.rs
+++ b/gcc/testsuite/rust/debug/chartype.rs
@@ -1,10 +1,11 @@
-// 'char' should use DW_ATE_UTF
-fn main () {
-    let c = 'x';
 // { dg-do compile }
-// Use -w to avoid warnings about the unused variables
-// DW_ATE_UTF entered in DWARF 4.
+// { dg-skip-if "see https://github.com/Rust-GCC/gccrs/pull/1632" { *-*-darwin* } }
 // { dg-options "-w -gdwarf-4 -dA" }
-// DW_ATE_UTF = 0x10
-// { dg-final { scan-assembler "0x10\[ \t]\[^\n\r]* DW_AT_encoding" } } */
+// 'char' should use DW_ATE_UTF
+fn main() {
+    let c = 'x';
+    // Use -w to avoid warnings about the unused variables
+    // DW_ATE_UTF entered in DWARF 4.
+    // DW_ATE_UTF = 0x10
+    // { dg-final { scan-assembler "0x10\[ \t]\[^\n\r]* DW_AT_encoding" } } */
 }
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 100/103] gccrs: Cleanup unused parameters to fix the bootstrap build
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (98 preceding siblings ...)
  2023-02-21 12:02 ` [committed 099/103] gccrs: Skip this debug test case which is failing on the latest mac-os devtools and its only for debug info arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 101/103] gccrs: Repair 'gcc/rust/lang.opt' comment arthur.cohen
                   ` (2 subsequent siblings)
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

gcc/rust/ChangeLog:

	* backend/rust-compile-type.cc (TyTyResolveCompile::visit): Remove unused parameters.
	* backend/rust-constexpr.cc (constant_value_1): Likewise.
	(fold_non_dependent_init): Likewise.
	* backend/rust-tree.cc (publicly_uniquely_derived_p): Likewise.
	(instantiation_dependent_expression_p): Likewise.
	(type_has_nontrivial_copy_init): Likewise.
	(is_normal_capture_proxy): Likewise.
	(resolve_nondeduced_context): Likewise.
	(undeduced_auto_decl): Likewise.
	(require_deduced_type): Likewise.
	* checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit): Likewise.
	* checks/errors/privacy/rust-reachability.cc (ReachabilityVisitor::visit): Likewise.
	* checks/errors/privacy/rust-visibility-resolver.cc (VisibilityResolver::visit): Likewise.
	* checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
	* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise.
	* checks/lints/rust-lint-marklive.cc (MarkLive::go): Likewise.
	* checks/lints/rust-lint-unused-var.cc (unused_var_walk_fn): Likewise.
	* expand/rust-macro-builtins.cc (try_expand_single_string_literal): Likewise.
	(try_expand_many_expr): Likewise.
	(parse_single_string_literal): Likewise.
	(MacroBuiltin::assert_handler): Likewise.
	(MacroBuiltin::file_handler): Likewise.
	(MacroBuiltin::column_handler): Likewise.
	(MacroBuiltin::concat_handler): Likewise.
	(MacroBuiltin::env_handler): Likewise.
	(MacroBuiltin::line_handler): Likewise.
	* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
	(ASTLoweringBase::handle_doc_item_attribute): Likewise.
	* hir/rust-hir-dump.cc (Dump::visit): Likewise.
	* hir/tree/rust-hir-full-test.cc (ConstGenericParam::accept_vis): Likewise.
	* lex/rust-lex.cc (Lexer::parse_utf8_escape): Likewise.
	(Lexer::parse_string): Likewise.
	(Lexer::parse_char_or_lifetime): Likewise.
	* lex/rust-lex.h: Likewise.
	* metadata/rust-export-metadata.cc: Likewise.
	* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
	* resolve/rust-ast-resolve-type.cc (ResolveType::visit): Likewise.
	(ResolveTypeToCanonicalPath::visit): Likewise.
	* resolve/rust-ast-verify-assignee.h: Likewise.
	* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit): Likewise.
	* typecheck/rust-hir-type-check-expr.h: Likewise.
	* typecheck/rust-hir-type-check-item.h: Likewise.
	* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): Likewise.
	* typecheck/rust-tyty-rules.h: Likewise.
	* util/rust-attributes.cc (AttributeChecker::visit): Likewise.
---
 gcc/rust/backend/rust-compile-type.cc         |   8 +-
 gcc/rust/backend/rust-constexpr.cc            |   6 +-
 gcc/rust/backend/rust-tree.cc                 |  38 +-
 .../errors/privacy/rust-privacy-reporter.cc   |  58 +--
 .../errors/privacy/rust-reachability.cc       |   4 +-
 .../privacy/rust-visibility-resolver.cc       |   8 +-
 gcc/rust/checks/errors/rust-const-checker.cc  | 132 +++----
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 142 +++----
 gcc/rust/checks/lints/rust-lint-marklive.cc   |   2 +-
 gcc/rust/checks/lints/rust-lint-unused-var.cc |   2 +-
 gcc/rust/expand/rust-macro-builtins.cc        |  20 +-
 gcc/rust/hir/rust-ast-lower-base.cc           | 352 +++++++++---------
 gcc/rust/hir/rust-hir-dump.cc                 |   4 +-
 gcc/rust/hir/tree/rust-hir-full-test.cc       |   2 +-
 gcc/rust/lex/rust-lex.cc                      |   6 +-
 gcc/rust/lex/rust-lex.h                       |   2 +-
 gcc/rust/metadata/rust-export-metadata.cc     |  24 +-
 gcc/rust/resolve/rust-ast-resolve-expr.cc     |   6 +-
 gcc/rust/resolve/rust-ast-resolve-type.cc     |   6 +-
 gcc/rust/resolve/rust-ast-verify-assignee.h   |   8 +-
 gcc/rust/resolve/rust-early-name-resolver.cc  | 120 +++---
 gcc/rust/typecheck/rust-hir-type-check-expr.h |  32 +-
 gcc/rust/typecheck/rust-hir-type-check-item.h |   4 +-
 .../typecheck/rust-hir-type-check-pattern.cc  |  10 +-
 gcc/rust/typecheck/rust-tyty-rules.h          |  48 +--
 gcc/rust/util/rust-attributes.cc              | 312 ++++++++--------
 26 files changed, 661 insertions(+), 695 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index c8e1d3b4036..a1db6ade9fb 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -428,7 +428,7 @@ TyTyResolveCompile::visit (const TyTy::SliceType &type)
 }
 
 void
-TyTyResolveCompile::visit (const TyTy::BoolType &type)
+TyTyResolveCompile::visit (const TyTy::BoolType &)
 {
   translated
     = ctx->get_backend ()->named_type ("bool",
@@ -532,7 +532,7 @@ TyTyResolveCompile::visit (const TyTy::FloatType &type)
 }
 
 void
-TyTyResolveCompile::visit (const TyTy::USizeType &type)
+TyTyResolveCompile::visit (const TyTy::USizeType &)
 {
   translated = ctx->get_backend ()->named_type (
     "usize",
@@ -542,7 +542,7 @@ TyTyResolveCompile::visit (const TyTy::USizeType &type)
 }
 
 void
-TyTyResolveCompile::visit (const TyTy::ISizeType &type)
+TyTyResolveCompile::visit (const TyTy::ISizeType &)
 {
   translated = ctx->get_backend ()->named_type (
     "isize",
@@ -552,7 +552,7 @@ TyTyResolveCompile::visit (const TyTy::ISizeType &type)
 }
 
 void
-TyTyResolveCompile::visit (const TyTy::CharType &type)
+TyTyResolveCompile::visit (const TyTy::CharType &)
 {
   translated
     = ctx->get_backend ()->named_type ("char",
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 23d940d04ce..912d73b5d7c 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -3996,8 +3996,7 @@ constexpr_fn_retval (const constexpr_ctx *ctx, tree body)
 // return an aggregate constant.  If UNSHARE_P, return an unshared
 // copy of the initializer.
 static tree
-constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p,
-		  bool unshare_p)
+constant_value_1 (tree decl, bool, bool, bool unshare_p)
 {
   while (TREE_CODE (decl) == CONST_DECL)
     {
@@ -6478,8 +6477,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 /* Like maybe_constant_init but first fully instantiate the argument.  */
 
 tree
-fold_non_dependent_init (tree t,
-			 tsubst_flags_t complain /*=tf_warning_or_error*/,
+fold_non_dependent_init (tree t, tsubst_flags_t /*=tf_warning_or_error*/,
 			 bool manifestly_const_eval /*=false*/,
 			 tree object /* = NULL_TREE */)
 {
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index d2d170c23f1..8243d4cf5c6 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -2060,11 +2060,7 @@ rs_tree_equal (tree t1, tree t2)
 
 /* TRUE iff TYPE is publicly & uniquely derived from PARENT.  */
 
-bool
-publicly_uniquely_derived_p (tree parent, tree type)
-{
-  return false;
-}
+bool publicly_uniquely_derived_p (tree, tree) { return false; }
 
 // forked from gcc/cp/typeck.cc comp_except_types
 
@@ -3344,11 +3340,7 @@ release_tree_vector (vec<tree, va_gc> *vec)
 
 /* As above, but also check value-dependence of the expression as a whole.  */
 
-bool
-instantiation_dependent_expression_p (tree expression)
-{
-  return false;
-}
+bool instantiation_dependent_expression_p (tree) { return false; }
 
 // forked from gcc/cp/cvt.cc cp_get_callee
 
@@ -3398,11 +3390,7 @@ scalarish_type_p (const_tree t)
    constructors are deleted.  This function implements the ABI notion of
    non-trivial copy, which has diverged from the one in the standard.  */
 
-bool
-type_has_nontrivial_copy_init (const_tree type)
-{
-  return false;
-}
+bool type_has_nontrivial_copy_init (const_tree) { return false; }
 
 // forked from gcc/cp/tree.cc build_local_temp
 
@@ -3425,11 +3413,7 @@ build_local_temp (tree type)
 /* Returns true iff DECL is a capture proxy for a normal capture
    (i.e. without explicit initializer).  */
 
-bool
-is_normal_capture_proxy (tree decl)
-{
-  return false;
-}
+bool is_normal_capture_proxy (tree) { return false; }
 
 // forked from gcc/cp/c-common.cc reject_gcc_builtin
 
@@ -3694,7 +3678,7 @@ char_type_p (tree type)
    lvalue for the function template specialization.  */
 
 tree
-resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
+resolve_nondeduced_context (tree orig_expr, tsubst_flags_t)
 {
   return orig_expr;
 }
@@ -3973,21 +3957,13 @@ decl_constant_var_p (tree decl)
 /* Returns true iff DECL is a variable or function declared with an auto type
    that has not yet been deduced to a real type.  */
 
-bool
-undeduced_auto_decl (tree decl)
-{
-  return false;
-}
+bool undeduced_auto_decl (tree) { return false; }
 
 // forked from gcc/cp/decl.cc require_deduced_type
 
 /* Complain if DECL has an undeduced return type.  */
 
-bool
-require_deduced_type (tree decl, tsubst_flags_t complain)
-{
-  return true;
-}
+bool require_deduced_type (tree, tsubst_flags_t) { return true; }
 
 /* Return the location of a tree passed to %+ formats.  */
 
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index a126e7b4462..7417f31b510 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -226,7 +226,7 @@ PrivacyReporter::visit (HIR::PathInExpression &path)
 }
 
 void
-PrivacyReporter::visit (HIR::TypePathSegmentFunction &segment)
+PrivacyReporter::visit (HIR::TypePathSegmentFunction &)
 {
   // FIXME: Do we need to do anything for this?
 }
@@ -253,7 +253,7 @@ PrivacyReporter::visit (HIR::QualifiedPathInType &path)
 }
 
 void
-PrivacyReporter::visit (HIR::LiteralExpr &expr)
+PrivacyReporter::visit (HIR::LiteralExpr &)
 {
   // Literals cannot contain any sort of privacy violation
 }
@@ -371,13 +371,13 @@ PrivacyReporter::visit (HIR::TupleIndexExpr &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::StructExprStruct &expr)
+PrivacyReporter::visit (HIR::StructExprStruct &)
 {
   // FIXME: We need to check the visibility of the type it refers to here
 }
 
 void
-PrivacyReporter::visit (HIR::StructExprFieldIdentifier &field)
+PrivacyReporter::visit (HIR::StructExprFieldIdentifier &)
 {}
 
 void
@@ -426,7 +426,7 @@ PrivacyReporter::visit (HIR::FieldAccessExpr &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::ClosureExpr &expr)
+PrivacyReporter::visit (HIR::ClosureExpr &)
 {
   // Not handled yet
 }
@@ -443,7 +443,7 @@ PrivacyReporter::visit (HIR::BlockExpr &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::ContinueExpr &expr)
+PrivacyReporter::visit (HIR::ContinueExpr &)
 {}
 
 void
@@ -474,7 +474,7 @@ PrivacyReporter::visit (HIR::RangeToExpr &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::RangeFullExpr &expr)
+PrivacyReporter::visit (HIR::RangeFullExpr &)
 {}
 
 void
@@ -485,7 +485,7 @@ PrivacyReporter::visit (HIR::RangeFromToInclExpr &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::RangeToInclExpr &expr)
+PrivacyReporter::visit (HIR::RangeToInclExpr &)
 {
   // Not handled yet
 }
@@ -564,14 +564,14 @@ PrivacyReporter::visit (HIR::IfExprConseqIfLet &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::IfLetExpr &expr)
+PrivacyReporter::visit (HIR::IfLetExpr &)
 {
   // TODO: We need to visit the if_let_expr
   // TODO: We need to visit the block as well
 }
 
 void
-PrivacyReporter::visit (HIR::IfLetExprConseqElse &expr)
+PrivacyReporter::visit (HIR::IfLetExprConseqElse &)
 {
   // TODO: We need to visit the if_let_expr
   // TODO: We need to visit the if_block as well
@@ -579,7 +579,7 @@ PrivacyReporter::visit (HIR::IfLetExprConseqElse &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::IfLetExprConseqIf &expr)
+PrivacyReporter::visit (HIR::IfLetExprConseqIf &)
 {
   // TODO: We need to visit the if_let_expr
   // TODO: We need to visit the if_block as well
@@ -587,7 +587,7 @@ PrivacyReporter::visit (HIR::IfLetExprConseqIf &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::IfLetExprConseqIfLet &expr)
+PrivacyReporter::visit (HIR::IfLetExprConseqIfLet &)
 {
   // TODO: We need to visit the if_let_expr
   // TODO: We need to visit the if_block as well
@@ -601,13 +601,13 @@ PrivacyReporter::visit (HIR::MatchExpr &expr)
 }
 
 void
-PrivacyReporter::visit (HIR::AwaitExpr &expr)
+PrivacyReporter::visit (HIR::AwaitExpr &)
 {
   // Not handled yet
 }
 
 void
-PrivacyReporter::visit (HIR::AsyncBlockExpr &expr)
+PrivacyReporter::visit (HIR::AsyncBlockExpr &)
 {
   // Not handled yet
 }
@@ -628,11 +628,11 @@ PrivacyReporter::visit (HIR::Module &module)
 }
 
 void
-PrivacyReporter::visit (HIR::ExternCrate &crate)
+PrivacyReporter::visit (HIR::ExternCrate &)
 {}
 
 void
-PrivacyReporter::visit (HIR::UseDeclaration &use_decl)
+PrivacyReporter::visit (HIR::UseDeclaration &)
 {
   // FIXME: Is there anything we need to do here?
 }
@@ -647,51 +647,51 @@ PrivacyReporter::visit (HIR::Function &function)
 }
 
 void
-PrivacyReporter::visit (HIR::TypeAlias &type_alias)
+PrivacyReporter::visit (HIR::TypeAlias &)
 {
   // TODO: Check the type here
 }
 
 void
-PrivacyReporter::visit (HIR::StructStruct &struct_item)
+PrivacyReporter::visit (HIR::StructStruct &)
 {
   // TODO: Check the type of all fields
 }
 
 void
-PrivacyReporter::visit (HIR::TupleStruct &tuple_struct)
+PrivacyReporter::visit (HIR::TupleStruct &)
 {
   // TODO: Check the type of all fields
 }
 
 void
-PrivacyReporter::visit (HIR::EnumItem &item)
+PrivacyReporter::visit (HIR::EnumItem &)
 {
   // TODO: Check the type of all variants
 }
 
 void
-PrivacyReporter::visit (HIR::EnumItemTuple &item)
+PrivacyReporter::visit (HIR::EnumItemTuple &)
 {
   // TODO: Check the type
 }
 
 void
-PrivacyReporter::visit (HIR::EnumItemStruct &item)
+PrivacyReporter::visit (HIR::EnumItemStruct &)
 {
   // TODO: Check the type
 }
 
 void
-PrivacyReporter::visit (HIR::EnumItemDiscriminant &item)
+PrivacyReporter::visit (HIR::EnumItemDiscriminant &)
 {}
 
 void
-PrivacyReporter::visit (HIR::Enum &enum_item)
+PrivacyReporter::visit (HIR::Enum &)
 {}
 
 void
-PrivacyReporter::visit (HIR::Union &union_item)
+PrivacyReporter::visit (HIR::Union &)
 {
   // TODO: Check the type
 }
@@ -711,7 +711,7 @@ PrivacyReporter::visit (HIR::StaticItem &static_item)
 }
 
 void
-PrivacyReporter::visit (HIR::Trait &trait)
+PrivacyReporter::visit (HIR::Trait &)
 {
   // FIXME: We need to be an ItemVisitor as well
   // for (auto &item : trait.get_trait_items ())
@@ -726,15 +726,15 @@ PrivacyReporter::visit (HIR::ImplBlock &impl)
 }
 
 void
-PrivacyReporter::visit (HIR::ExternBlock &block)
+PrivacyReporter::visit (HIR::ExternBlock &)
 {
   // FIXME: We need to be an ItemVisitor as well
-  // for (auto &item : block.get_extern_items ())
+  // for (auto &block: block.get_extern_items ())
   //   item->accept_vis (*this);
 }
 
 void
-PrivacyReporter::visit (HIR::EmptyStmt &stmt)
+PrivacyReporter::visit (HIR::EmptyStmt &)
 {}
 
 void
diff --git a/gcc/rust/checks/errors/privacy/rust-reachability.cc b/gcc/rust/checks/errors/privacy/rust-reachability.cc
index d61193ec139..b9a2b363708 100644
--- a/gcc/rust/checks/errors/privacy/rust-reachability.cc
+++ b/gcc/rust/checks/errors/privacy/rust-reachability.cc
@@ -140,7 +140,7 @@ ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
 }
 
 void
-ReachabilityVisitor::visit (HIR::TupleStruct &tuple_struct)
+ReachabilityVisitor::visit (HIR::TupleStruct &)
 {}
 
 void
@@ -227,7 +227,7 @@ ReachabilityVisitor::visit (HIR::ImplBlock &impl)
 }
 
 void
-ReachabilityVisitor::visit (HIR::ExternBlock &block)
+ReachabilityVisitor::visit (HIR::ExternBlock &)
 {}
 
 // FIXME: How can we visit Blocks in the current configuration? Have a full
diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
index c27bf791b28..becb9fd93a7 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
@@ -141,11 +141,11 @@ VisibilityResolver::visit (HIR::Module &mod)
 }
 
 void
-VisibilityResolver::visit (HIR::ExternCrate &crate)
+VisibilityResolver::visit (HIR::ExternCrate &)
 {}
 
 void
-VisibilityResolver::visit (HIR::UseDeclaration &use_decl)
+VisibilityResolver::visit (HIR::UseDeclaration &)
 {}
 
 void
@@ -185,7 +185,7 @@ VisibilityResolver::visit (HIR::Enum &enum_item)
 }
 
 void
-VisibilityResolver::visit (HIR::Union &union_item)
+VisibilityResolver::visit (HIR::Union &)
 {}
 
 void
@@ -238,7 +238,7 @@ VisibilityResolver::visit (HIR::ImplBlock &impl)
 }
 
 void
-VisibilityResolver::visit (HIR::ExternBlock &block)
+VisibilityResolver::visit (HIR::ExternBlock &)
 {}
 
 } // namespace Privacy
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 9161fa1ea2a..576c1b170d6 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -114,43 +114,43 @@ ConstChecker::check_default_const_generics (
 }
 
 void
-ConstChecker::visit (Lifetime &lifetime)
+ConstChecker::visit (Lifetime &)
 {}
 
 void
-ConstChecker::visit (LifetimeParam &lifetime_param)
+ConstChecker::visit (LifetimeParam &)
 {}
 
 void
-ConstChecker::visit (PathInExpression &path)
+ConstChecker::visit (PathInExpression &)
 {}
 
 void
-ConstChecker::visit (TypePathSegment &segment)
+ConstChecker::visit (TypePathSegment &)
 {}
 
 void
-ConstChecker::visit (TypePathSegmentGeneric &segment)
+ConstChecker::visit (TypePathSegmentGeneric &)
 {}
 
 void
-ConstChecker::visit (TypePathSegmentFunction &segment)
+ConstChecker::visit (TypePathSegmentFunction &)
 {}
 
 void
-ConstChecker::visit (TypePath &path)
+ConstChecker::visit (TypePath &)
 {}
 
 void
-ConstChecker::visit (QualifiedPathInExpression &path)
+ConstChecker::visit (QualifiedPathInExpression &)
 {}
 
 void
-ConstChecker::visit (QualifiedPathInType &path)
+ConstChecker::visit (QualifiedPathInType &)
 {}
 
 void
-ConstChecker::visit (LiteralExpr &expr)
+ConstChecker::visit (LiteralExpr &)
 {}
 
 void
@@ -270,11 +270,11 @@ ConstChecker::visit (TupleIndexExpr &expr)
 }
 
 void
-ConstChecker::visit (StructExprStruct &expr)
+ConstChecker::visit (StructExprStruct &)
 {}
 
 void
-ConstChecker::visit (StructExprFieldIdentifier &field)
+ConstChecker::visit (StructExprFieldIdentifier &)
 {}
 
 void
@@ -297,7 +297,7 @@ ConstChecker::visit (StructExprStructFields &expr)
 }
 
 void
-ConstChecker::visit (StructExprStructBase &expr)
+ConstChecker::visit (StructExprStructBase &)
 {}
 
 void
@@ -398,7 +398,7 @@ ConstChecker::visit (BlockExpr &expr)
 }
 
 void
-ConstChecker::visit (ContinueExpr &expr)
+ConstChecker::visit (ContinueExpr &)
 {}
 
 void
@@ -428,7 +428,7 @@ ConstChecker::visit (RangeToExpr &expr)
 }
 
 void
-ConstChecker::visit (RangeFullExpr &expr)
+ConstChecker::visit (RangeFullExpr &)
 {}
 
 void
@@ -439,7 +439,7 @@ ConstChecker::visit (RangeFromToInclExpr &expr)
 }
 
 void
-ConstChecker::visit (RangeToInclExpr &expr)
+ConstChecker::visit (RangeToInclExpr &)
 {
   // FIXME: Visit to_expr
 }
@@ -558,31 +558,31 @@ ConstChecker::visit (MatchExpr &expr)
 }
 
 void
-ConstChecker::visit (AwaitExpr &expr)
+ConstChecker::visit (AwaitExpr &)
 {
   // TODO: Visit expression
 }
 
 void
-ConstChecker::visit (AsyncBlockExpr &expr)
+ConstChecker::visit (AsyncBlockExpr &)
 {
   // TODO: Visit block expression
 }
 
 void
-ConstChecker::visit (TypeParam &param)
+ConstChecker::visit (TypeParam &)
 {}
 
 void
-ConstChecker::visit (ConstGenericParam &param)
+ConstChecker::visit (ConstGenericParam &)
 {}
 
 void
-ConstChecker::visit (LifetimeWhereClauseItem &item)
+ConstChecker::visit (LifetimeWhereClauseItem &)
 {}
 
 void
-ConstChecker::visit (TypeBoundWhereClauseItem &item)
+ConstChecker::visit (TypeBoundWhereClauseItem &)
 {}
 
 void
@@ -593,23 +593,23 @@ ConstChecker::visit (Module &module)
 }
 
 void
-ConstChecker::visit (ExternCrate &crate)
+ConstChecker::visit (ExternCrate &)
 {}
 
 void
-ConstChecker::visit (UseTreeGlob &use_tree)
+ConstChecker::visit (UseTreeGlob &)
 {}
 
 void
-ConstChecker::visit (UseTreeList &use_tree)
+ConstChecker::visit (UseTreeList &)
 {}
 
 void
-ConstChecker::visit (UseTreeRebind &use_tree)
+ConstChecker::visit (UseTreeRebind &)
 {}
 
 void
-ConstChecker::visit (UseDeclaration &use_decl)
+ConstChecker::visit (UseDeclaration &)
 {}
 
 void
@@ -653,15 +653,15 @@ ConstChecker::visit (TupleStruct &tuple_struct)
 }
 
 void
-ConstChecker::visit (EnumItem &enum_item)
+ConstChecker::visit (EnumItem &)
 {}
 
 void
-ConstChecker::visit (EnumItemTuple &item)
+ConstChecker::visit (EnumItemTuple &)
 {}
 
 void
-ConstChecker::visit (EnumItemStruct &item)
+ConstChecker::visit (EnumItemStruct &)
 {}
 
 void
@@ -723,7 +723,7 @@ ConstChecker::visit (TraitItemConst &item)
 }
 
 void
-ConstChecker::visit (TraitItemType &item)
+ConstChecker::visit (TraitItemType &)
 {}
 
 void
@@ -747,11 +747,11 @@ ConstChecker::visit (ImplBlock &impl)
 }
 
 void
-ConstChecker::visit (ExternalStaticItem &item)
+ConstChecker::visit (ExternalStaticItem &)
 {}
 
 void
-ConstChecker::visit (ExternalFunctionItem &item)
+ConstChecker::visit (ExternalFunctionItem &)
 {}
 
 void
@@ -763,87 +763,87 @@ ConstChecker::visit (ExternBlock &block)
 }
 
 void
-ConstChecker::visit (LiteralPattern &pattern)
+ConstChecker::visit (LiteralPattern &)
 {}
 
 void
-ConstChecker::visit (IdentifierPattern &pattern)
+ConstChecker::visit (IdentifierPattern &)
 {}
 
 void
-ConstChecker::visit (WildcardPattern &pattern)
+ConstChecker::visit (WildcardPattern &)
 {}
 
 void
-ConstChecker::visit (RangePatternBoundLiteral &bound)
+ConstChecker::visit (RangePatternBoundLiteral &)
 {}
 
 void
-ConstChecker::visit (RangePatternBoundPath &bound)
+ConstChecker::visit (RangePatternBoundPath &)
 {}
 
 void
-ConstChecker::visit (RangePatternBoundQualPath &bound)
+ConstChecker::visit (RangePatternBoundQualPath &)
 {}
 
 void
-ConstChecker::visit (RangePattern &pattern)
+ConstChecker::visit (RangePattern &)
 {}
 
 void
-ConstChecker::visit (ReferencePattern &pattern)
+ConstChecker::visit (ReferencePattern &)
 {}
 
 void
-ConstChecker::visit (StructPatternFieldTuplePat &field)
+ConstChecker::visit (StructPatternFieldTuplePat &)
 {}
 
 void
-ConstChecker::visit (StructPatternFieldIdentPat &field)
+ConstChecker::visit (StructPatternFieldIdentPat &)
 {}
 
 void
-ConstChecker::visit (StructPatternFieldIdent &field)
+ConstChecker::visit (StructPatternFieldIdent &)
 {}
 
 void
-ConstChecker::visit (StructPattern &pattern)
+ConstChecker::visit (StructPattern &)
 {}
 
 void
-ConstChecker::visit (TupleStructItemsNoRange &tuple_items)
+ConstChecker::visit (TupleStructItemsNoRange &)
 {}
 
 void
-ConstChecker::visit (TupleStructItemsRange &tuple_items)
+ConstChecker::visit (TupleStructItemsRange &)
 {}
 
 void
-ConstChecker::visit (TupleStructPattern &pattern)
+ConstChecker::visit (TupleStructPattern &)
 {}
 
 void
-ConstChecker::visit (TuplePatternItemsMultiple &tuple_items)
+ConstChecker::visit (TuplePatternItemsMultiple &)
 {}
 
 void
-ConstChecker::visit (TuplePatternItemsRanged &tuple_items)
+ConstChecker::visit (TuplePatternItemsRanged &)
 {}
 
 void
-ConstChecker::visit (TuplePattern &pattern)
+ConstChecker::visit (TuplePattern &)
 {}
 
 void
-ConstChecker::visit (GroupedPattern &pattern)
+ConstChecker::visit (GroupedPattern &)
 {}
 
 void
-ConstChecker::visit (SlicePattern &pattern)
+ConstChecker::visit (SlicePattern &)
 {}
 
 void
-ConstChecker::visit (EmptyStmt &stmt)
+ConstChecker::visit (EmptyStmt &)
 {}
 
 void
@@ -866,39 +866,39 @@ ConstChecker::visit (ExprStmtWithBlock &stmt)
 }
 
 void
-ConstChecker::visit (TraitBound &bound)
+ConstChecker::visit (TraitBound &)
 {}
 
 void
-ConstChecker::visit (ImplTraitType &type)
+ConstChecker::visit (ImplTraitType &)
 {}
 
 void
-ConstChecker::visit (TraitObjectType &type)
+ConstChecker::visit (TraitObjectType &)
 {}
 
 void
-ConstChecker::visit (ParenthesisedType &type)
+ConstChecker::visit (ParenthesisedType &)
 {}
 
 void
-ConstChecker::visit (ImplTraitTypeOneBound &type)
+ConstChecker::visit (ImplTraitTypeOneBound &)
 {}
 
 void
-ConstChecker::visit (TupleType &type)
+ConstChecker::visit (TupleType &)
 {}
 
 void
-ConstChecker::visit (NeverType &type)
+ConstChecker::visit (NeverType &)
 {}
 
 void
-ConstChecker::visit (RawPointerType &type)
+ConstChecker::visit (RawPointerType &)
 {}
 
 void
-ConstChecker::visit (ReferenceType &type)
+ConstChecker::visit (ReferenceType &)
 {}
 
 void
@@ -912,15 +912,15 @@ ConstChecker::visit (ArrayType &type)
 }
 
 void
-ConstChecker::visit (SliceType &type)
+ConstChecker::visit (SliceType &)
 {}
 
 void
-ConstChecker::visit (InferredType &type)
+ConstChecker::visit (InferredType &)
 {}
 
 void
-ConstChecker::visit (BareFunctionType &type)
+ConstChecker::visit (BareFunctionType &)
 {}
 
 } // namespace HIR
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 3d534743eeb..94808632c04 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -180,11 +180,11 @@ UnsafeChecker::check_function_call (HirId node_id, Location locus)
 }
 
 void
-UnsafeChecker::visit (Lifetime &lifetime)
+UnsafeChecker::visit (Lifetime &)
 {}
 
 void
-UnsafeChecker::visit (LifetimeParam &lifetime_param)
+UnsafeChecker::visit (LifetimeParam &)
 {}
 
 void
@@ -203,31 +203,31 @@ UnsafeChecker::visit (PathInExpression &path)
 }
 
 void
-UnsafeChecker::visit (TypePathSegment &segment)
+UnsafeChecker::visit (TypePathSegment &)
 {}
 
 void
-UnsafeChecker::visit (TypePathSegmentGeneric &segment)
+UnsafeChecker::visit (TypePathSegmentGeneric &)
 {}
 
 void
-UnsafeChecker::visit (TypePathSegmentFunction &segment)
+UnsafeChecker::visit (TypePathSegmentFunction &)
 {}
 
 void
-UnsafeChecker::visit (TypePath &path)
+UnsafeChecker::visit (TypePath &)
 {}
 
 void
-UnsafeChecker::visit (QualifiedPathInExpression &path)
+UnsafeChecker::visit (QualifiedPathInExpression &)
 {}
 
 void
-UnsafeChecker::visit (QualifiedPathInType &path)
+UnsafeChecker::visit (QualifiedPathInType &)
 {}
 
 void
-UnsafeChecker::visit (LiteralExpr &expr)
+UnsafeChecker::visit (LiteralExpr &)
 {}
 
 void
@@ -349,11 +349,11 @@ UnsafeChecker::visit (TupleIndexExpr &expr)
 }
 
 void
-UnsafeChecker::visit (StructExprStruct &expr)
+UnsafeChecker::visit (StructExprStruct &)
 {}
 
 void
-UnsafeChecker::visit (StructExprFieldIdentifier &field)
+UnsafeChecker::visit (StructExprFieldIdentifier &)
 {}
 
 void
@@ -376,7 +376,7 @@ UnsafeChecker::visit (StructExprStructFields &expr)
 }
 
 void
-UnsafeChecker::visit (StructExprStructBase &expr)
+UnsafeChecker::visit (StructExprStructBase &)
 {}
 
 void
@@ -469,7 +469,7 @@ UnsafeChecker::visit (BlockExpr &expr)
 }
 
 void
-UnsafeChecker::visit (ContinueExpr &expr)
+UnsafeChecker::visit (ContinueExpr &)
 {}
 
 void
@@ -499,7 +499,7 @@ UnsafeChecker::visit (RangeToExpr &expr)
 }
 
 void
-UnsafeChecker::visit (RangeFullExpr &expr)
+UnsafeChecker::visit (RangeFullExpr &)
 {}
 
 void
@@ -633,31 +633,31 @@ UnsafeChecker::visit (MatchExpr &expr)
 }
 
 void
-UnsafeChecker::visit (AwaitExpr &expr)
+UnsafeChecker::visit (AwaitExpr &)
 {
   // TODO: Visit expression
 }
 
 void
-UnsafeChecker::visit (AsyncBlockExpr &expr)
+UnsafeChecker::visit (AsyncBlockExpr &)
 {
   // TODO: Visit block expression
 }
 
 void
-UnsafeChecker::visit (TypeParam &param)
+UnsafeChecker::visit (TypeParam &)
 {}
 
 void
-UnsafeChecker::visit (ConstGenericParam &param)
+UnsafeChecker::visit (ConstGenericParam &)
 {}
 
 void
-UnsafeChecker::visit (LifetimeWhereClauseItem &item)
+UnsafeChecker::visit (LifetimeWhereClauseItem &)
 {}
 
 void
-UnsafeChecker::visit (TypeBoundWhereClauseItem &item)
+UnsafeChecker::visit (TypeBoundWhereClauseItem &)
 {}
 
 void
@@ -668,23 +668,23 @@ UnsafeChecker::visit (Module &module)
 }
 
 void
-UnsafeChecker::visit (ExternCrate &crate)
+UnsafeChecker::visit (ExternCrate &)
 {}
 
 void
-UnsafeChecker::visit (UseTreeGlob &use_tree)
+UnsafeChecker::visit (UseTreeGlob &)
 {}
 
 void
-UnsafeChecker::visit (UseTreeList &use_tree)
+UnsafeChecker::visit (UseTreeList &)
 {}
 
 void
-UnsafeChecker::visit (UseTreeRebind &use_tree)
+UnsafeChecker::visit (UseTreeRebind &)
 {}
 
 void
-UnsafeChecker::visit (UseDeclaration &use_decl)
+UnsafeChecker::visit (UseDeclaration &)
 {}
 
 void
@@ -702,42 +702,42 @@ UnsafeChecker::visit (Function &function)
 }
 
 void
-UnsafeChecker::visit (TypeAlias &type_alias)
+UnsafeChecker::visit (TypeAlias &)
 {
   // FIXME: What do we need to do to handle type aliasing? Is it possible to
   // have unsafe types? Type aliases on unsafe functions?
 }
 
 void
-UnsafeChecker::visit (StructStruct &struct_item)
+UnsafeChecker::visit (StructStruct &)
 {}
 
 void
-UnsafeChecker::visit (TupleStruct &tuple_struct)
+UnsafeChecker::visit (TupleStruct &)
 {}
 
 void
-UnsafeChecker::visit (EnumItem &item)
+UnsafeChecker::visit (EnumItem &)
 {}
 
 void
-UnsafeChecker::visit (EnumItemTuple &item)
+UnsafeChecker::visit (EnumItemTuple &)
 {}
 
 void
-UnsafeChecker::visit (EnumItemStruct &item)
+UnsafeChecker::visit (EnumItemStruct &)
 {}
 
 void
-UnsafeChecker::visit (EnumItemDiscriminant &item)
+UnsafeChecker::visit (EnumItemDiscriminant &)
 {}
 
 void
-UnsafeChecker::visit (Enum &enum_item)
+UnsafeChecker::visit (Enum &)
 {}
 
 void
-UnsafeChecker::visit (Union &union_item)
+UnsafeChecker::visit (Union &)
 {}
 
 void
@@ -767,7 +767,7 @@ UnsafeChecker::visit (TraitItemConst &item)
 }
 
 void
-UnsafeChecker::visit (TraitItemType &item)
+UnsafeChecker::visit (TraitItemType &)
 {}
 
 void
@@ -787,11 +787,11 @@ UnsafeChecker::visit (ImplBlock &impl)
 }
 
 void
-UnsafeChecker::visit (ExternalStaticItem &item)
+UnsafeChecker::visit (ExternalStaticItem &)
 {}
 
 void
-UnsafeChecker::visit (ExternalFunctionItem &item)
+UnsafeChecker::visit (ExternalFunctionItem &)
 {}
 
 void
@@ -803,87 +803,87 @@ UnsafeChecker::visit (ExternBlock &block)
 }
 
 void
-UnsafeChecker::visit (LiteralPattern &pattern)
+UnsafeChecker::visit (LiteralPattern &)
 {}
 
 void
-UnsafeChecker::visit (IdentifierPattern &pattern)
+UnsafeChecker::visit (IdentifierPattern &)
 {}
 
 void
-UnsafeChecker::visit (WildcardPattern &pattern)
+UnsafeChecker::visit (WildcardPattern &)
 {}
 
 void
-UnsafeChecker::visit (RangePatternBoundLiteral &bound)
+UnsafeChecker::visit (RangePatternBoundLiteral &)
 {}
 
 void
-UnsafeChecker::visit (RangePatternBoundPath &bound)
+UnsafeChecker::visit (RangePatternBoundPath &)
 {}
 
 void
-UnsafeChecker::visit (RangePatternBoundQualPath &bound)
+UnsafeChecker::visit (RangePatternBoundQualPath &)
 {}
 
 void
-UnsafeChecker::visit (RangePattern &pattern)
+UnsafeChecker::visit (RangePattern &)
 {}
 
 void
-UnsafeChecker::visit (ReferencePattern &pattern)
+UnsafeChecker::visit (ReferencePattern &)
 {}
 
 void
-UnsafeChecker::visit (StructPatternFieldTuplePat &field)
+UnsafeChecker::visit (StructPatternFieldTuplePat &)
 {}
 
 void
-UnsafeChecker::visit (StructPatternFieldIdentPat &field)
+UnsafeChecker::visit (StructPatternFieldIdentPat &)
 {}
 
 void
-UnsafeChecker::visit (StructPatternFieldIdent &field)
+UnsafeChecker::visit (StructPatternFieldIdent &)
 {}
 
 void
-UnsafeChecker::visit (StructPattern &pattern)
+UnsafeChecker::visit (StructPattern &)
 {}
 
 void
-UnsafeChecker::visit (TupleStructItemsNoRange &tuple_items)
+UnsafeChecker::visit (TupleStructItemsNoRange &)
 {}
 
 void
-UnsafeChecker::visit (TupleStructItemsRange &tuple_items)
+UnsafeChecker::visit (TupleStructItemsRange &)
 {}
 
 void
-UnsafeChecker::visit (TupleStructPattern &pattern)
+UnsafeChecker::visit (TupleStructPattern &)
 {}
 
 void
-UnsafeChecker::visit (TuplePatternItemsMultiple &tuple_items)
+UnsafeChecker::visit (TuplePatternItemsMultiple &)
 {}
 
 void
-UnsafeChecker::visit (TuplePatternItemsRanged &tuple_items)
+UnsafeChecker::visit (TuplePatternItemsRanged &)
 {}
 
 void
-UnsafeChecker::visit (TuplePattern &pattern)
+UnsafeChecker::visit (TuplePattern &)
 {}
 
 void
-UnsafeChecker::visit (GroupedPattern &pattern)
+UnsafeChecker::visit (GroupedPattern &)
 {}
 
 void
-UnsafeChecker::visit (SlicePattern &pattern)
+UnsafeChecker::visit (SlicePattern &)
 {}
 
 void
-UnsafeChecker::visit (EmptyStmt &stmt)
+UnsafeChecker::visit (EmptyStmt &)
 {}
 
 void
@@ -906,55 +906,55 @@ UnsafeChecker::visit (ExprStmtWithBlock &stmt)
 }
 
 void
-UnsafeChecker::visit (TraitBound &bound)
+UnsafeChecker::visit (TraitBound &)
 {}
 
 void
-UnsafeChecker::visit (ImplTraitType &type)
+UnsafeChecker::visit (ImplTraitType &)
 {}
 
 void
-UnsafeChecker::visit (TraitObjectType &type)
+UnsafeChecker::visit (TraitObjectType &)
 {}
 
 void
-UnsafeChecker::visit (ParenthesisedType &type)
+UnsafeChecker::visit (ParenthesisedType &)
 {}
 
 void
-UnsafeChecker::visit (ImplTraitTypeOneBound &type)
+UnsafeChecker::visit (ImplTraitTypeOneBound &)
 {}
 
 void
-UnsafeChecker::visit (TupleType &type)
+UnsafeChecker::visit (TupleType &)
 {}
 
 void
-UnsafeChecker::visit (NeverType &type)
+UnsafeChecker::visit (NeverType &)
 {}
 
 void
-UnsafeChecker::visit (RawPointerType &type)
+UnsafeChecker::visit (RawPointerType &)
 {}
 
 void
-UnsafeChecker::visit (ReferenceType &type)
+UnsafeChecker::visit (ReferenceType &)
 {}
 
 void
-UnsafeChecker::visit (ArrayType &type)
+UnsafeChecker::visit (ArrayType &)
 {}
 
 void
-UnsafeChecker::visit (SliceType &type)
+UnsafeChecker::visit (SliceType &)
 {}
 
 void
-UnsafeChecker::visit (InferredType &type)
+UnsafeChecker::visit (InferredType &)
 {}
 
 void
-UnsafeChecker::visit (BareFunctionType &type)
+UnsafeChecker::visit (BareFunctionType &)
 {}
 
 } // namespace HIR
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc b/gcc/rust/checks/lints/rust-lint-marklive.cc
index c914b549257..63927811149 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -78,7 +78,7 @@ MarkLive::Analysis (HIR::Crate &crate)
 //    visited first time
 // 2. save all the live symbols in liveSymbols
 void
-MarkLive::go (HIR::Crate &crate)
+MarkLive::go (HIR::Crate &)
 {
   while (!worklist.empty ())
     {
diff --git a/gcc/rust/checks/lints/rust-lint-unused-var.cc b/gcc/rust/checks/lints/rust-lint-unused-var.cc
index dff9c269962..ba5ffb9372b 100644
--- a/gcc/rust/checks/lints/rust-lint-unused-var.cc
+++ b/gcc/rust/checks/lints/rust-lint-unused-var.cc
@@ -53,7 +53,7 @@ check_decl (tree *t)
 }
 
 static tree
-unused_var_walk_fn (tree *t, int *walk_subtrees, void *closure)
+unused_var_walk_fn (tree *t, int *, void *)
 {
   switch (TREE_CODE (*t))
     {
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 9bed3ddbe79..11334409fe3 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -99,7 +99,6 @@ try_extract_string_literal_from_fragment (const Location &parent_locus,
 
 static std::unique_ptr<AST::LiteralExpr>
 try_expand_single_string_literal (AST::Expr *input_expr,
-				  const Location &invoc_locus,
 				  MacroExpander *expander)
 {
   auto nodes = try_expand_macro_expression (input_expr, expander);
@@ -116,8 +115,8 @@ try_expand_single_string_literal (AST::Expr *input_expr,
 
 static std::vector<std::unique_ptr<AST::Expr>>
 try_expand_many_expr (Parser<MacroInvocLexer> &parser,
-		      const Location &invoc_locus, const TokenId last_token_id,
-		      MacroExpander *expander, bool &has_error)
+		      const TokenId last_token_id, MacroExpander *expander,
+		      bool &has_error)
 {
   auto restrictions = Rust::ParseRestrictions ();
   // stop parsing when encountered a braces/brackets
@@ -204,8 +203,7 @@ parse_single_string_literal (AST::DelimTokenTree &invoc_token_tree,
       // when the expression does not seem to be a string literal, we then try
       // to parse/expand it as macro to see if it expands to a string literal
       auto expr = parser.parse_expr ();
-      lit_expr
-	= try_expand_single_string_literal (expr.get (), invoc_locus, expander);
+      lit_expr = try_expand_single_string_literal (expr.get (), expander);
     }
 
   parser.skip_token (last_token_id);
@@ -265,7 +263,7 @@ load_file_bytes (const char *filename)
 } // namespace
 
 AST::Fragment
-MacroBuiltin::assert_handler (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::assert_handler (Location, AST::MacroInvocData &)
 {
   rust_debug ("assert!() called");
 
@@ -273,7 +271,7 @@ MacroBuiltin::assert_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 }
 
 AST::Fragment
-MacroBuiltin::file_handler (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::file_handler (Location invoc_locus, AST::MacroInvocData &)
 {
   auto current_file
     = Session::get_instance ().linemap->location_file (invoc_locus);
@@ -283,7 +281,7 @@ MacroBuiltin::file_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 }
 
 AST::Fragment
-MacroBuiltin::column_handler (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::column_handler (Location invoc_locus, AST::MacroInvocData &)
 {
   auto current_column
     = Session::get_instance ().linemap->location_to_column (invoc_locus);
@@ -401,7 +399,7 @@ MacroBuiltin::concat_handler (Location invoc_locus, AST::MacroInvocData &invoc)
   auto last_token_id = macro_end_token (invoc_token_tree, parser);
 
   /* NOTE: concat! could accept no argument, so we don't have any checks here */
-  auto expanded_expr = try_expand_many_expr (parser, invoc_locus, last_token_id,
+  auto expanded_expr = try_expand_many_expr (parser, last_token_id,
 					     invoc.get_expander (), has_error);
   for (auto &expr : expanded_expr)
     {
@@ -451,7 +449,7 @@ MacroBuiltin::env_handler (Location invoc_locus, AST::MacroInvocData &invoc)
   std::unique_ptr<AST::LiteralExpr> lit_expr = nullptr;
   bool has_error = false;
 
-  auto expanded_expr = try_expand_many_expr (parser, invoc_locus, last_token_id,
+  auto expanded_expr = try_expand_many_expr (parser, last_token_id,
 					     invoc.get_expander (), has_error);
   if (has_error)
     return AST::Fragment::create_error ();
@@ -591,7 +589,7 @@ MacroBuiltin::include_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 }
 
 AST::Fragment
-MacroBuiltin::line_handler (Location invoc_locus, AST::MacroInvocData &invoc)
+MacroBuiltin::line_handler (Location invoc_locus, AST::MacroInvocData &)
 {
   auto current_line
     = Session::get_instance ().linemap->location_to_line (invoc_locus);
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index f5402efe066..33795726b2f 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -25,499 +25,499 @@ namespace Rust {
 namespace HIR {
 
 void
-ASTLoweringBase::visit (AST::Token &tok)
+ASTLoweringBase::visit (AST::Token &)
 {}
 void
-ASTLoweringBase::visit (AST::DelimTokenTree &delim_tok_tree)
+ASTLoweringBase::visit (AST::DelimTokenTree &)
 {}
 void
-ASTLoweringBase::visit (AST::AttrInputMetaItemContainer &input)
+ASTLoweringBase::visit (AST::AttrInputMetaItemContainer &)
 {}
-//  void ASTLoweringBase::visit(MetaItem& meta_item) {}
-//  void vsit(Stmt& stmt) {}
-//  void ASTLoweringBase::visit(Expr& expr) {}
+//  void ASTLoweringBase::visit(MetaItemmeta_item) {}
+//  void vsit(Stmtstmt) {}
+//  void ASTLoweringBase::visit(Exprexpr) {}
 void
-ASTLoweringBase::visit (AST::IdentifierExpr &ident_expr)
+ASTLoweringBase::visit (AST::IdentifierExpr &)
 {}
-//  void ASTLoweringBase::visit(Pattern& pattern) {}
-//  void ASTLoweringBase::visit(Type& type) {}
-//  void ASTLoweringBase::visit(TypeParamBound& type_param_bound) {}
+//  void ASTLoweringBase::visit(Patternpattern) {}
+//  void ASTLoweringBase::visit(Typetype) {}
+//  void ASTLoweringBase::visit(TypeParamBoundtype_param_bound) {}
 void
-ASTLoweringBase::visit (AST::Lifetime &lifetime)
+ASTLoweringBase::visit (AST::Lifetime &)
 {}
-//  void ASTLoweringBase::visit(GenericParam& generic_param) {}
+//  void ASTLoweringBase::visit(GenericParamgeneric_param) {}
 void
-ASTLoweringBase::visit (AST::LifetimeParam &lifetime_param)
+ASTLoweringBase::visit (AST::LifetimeParam &)
 {}
 void
-ASTLoweringBase::visit (AST::ConstGenericParam &const_param)
+ASTLoweringBase::visit (AST::ConstGenericParam &)
 {}
-//  void ASTLoweringBase::visit(TraitItem& trait_item) {}
-//  void ASTLoweringBase::visit(InherentImplItem& inherent_impl_item) {}
-//  void ASTLoweringBase::visit(TraitImplItem& trait_impl_item) {}
+//  void ASTLoweringBase::visit(TraitItemtrait_item) {}
+//  void ASTLoweringBase::visit(InherentImplIteminherent_impl_item) {}
+//  void ASTLoweringBase::visit(TraitImplItemtrait_impl_item) {}
 
 // rust-path.h
 void
-ASTLoweringBase::visit (AST::PathInExpression &path)
+ASTLoweringBase::visit (AST::PathInExpression &)
 {}
 void
-ASTLoweringBase::visit (AST::TypePathSegment &segment)
+ASTLoweringBase::visit (AST::TypePathSegment &)
 {}
 void
-ASTLoweringBase::visit (AST::TypePathSegmentGeneric &segment)
+ASTLoweringBase::visit (AST::TypePathSegmentGeneric &)
 {}
 void
-ASTLoweringBase::visit (AST::TypePathSegmentFunction &segment)
+ASTLoweringBase::visit (AST::TypePathSegmentFunction &)
 {}
 void
-ASTLoweringBase::visit (AST::TypePath &path)
+ASTLoweringBase::visit (AST::TypePath &)
 {}
 void
-ASTLoweringBase::visit (AST::QualifiedPathInExpression &path)
+ASTLoweringBase::visit (AST::QualifiedPathInExpression &)
 {}
 void
-ASTLoweringBase::visit (AST::QualifiedPathInType &path)
+ASTLoweringBase::visit (AST::QualifiedPathInType &)
 {}
 
 // rust-expr.h
 void
-ASTLoweringBase::visit (AST::LiteralExpr &expr)
+ASTLoweringBase::visit (AST::LiteralExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::AttrInputLiteral &attr_input)
+ASTLoweringBase::visit (AST::AttrInputLiteral &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaItemLitExpr &meta_item)
+ASTLoweringBase::visit (AST::MetaItemLitExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaItemPathLit &meta_item)
+ASTLoweringBase::visit (AST::MetaItemPathLit &)
 {}
 void
-ASTLoweringBase::visit (AST::BorrowExpr &expr)
+ASTLoweringBase::visit (AST::BorrowExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::DereferenceExpr &expr)
+ASTLoweringBase::visit (AST::DereferenceExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ErrorPropagationExpr &expr)
+ASTLoweringBase::visit (AST::ErrorPropagationExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::NegationExpr &expr)
+ASTLoweringBase::visit (AST::NegationExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ArithmeticOrLogicalExpr &expr)
+ASTLoweringBase::visit (AST::ArithmeticOrLogicalExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ComparisonExpr &expr)
+ASTLoweringBase::visit (AST::ComparisonExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::LazyBooleanExpr &expr)
+ASTLoweringBase::visit (AST::LazyBooleanExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::TypeCastExpr &expr)
+ASTLoweringBase::visit (AST::TypeCastExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::AssignmentExpr &expr)
+ASTLoweringBase::visit (AST::AssignmentExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::CompoundAssignmentExpr &expr)
+ASTLoweringBase::visit (AST::CompoundAssignmentExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::GroupedExpr &expr)
+ASTLoweringBase::visit (AST::GroupedExpr &)
 {}
-//  void ASTLoweringBase::visit(ArrayElems& elems) {}
+//  void ASTLoweringBase::visit(ArrayElemselems) {}
 void
-ASTLoweringBase::visit (AST::ArrayElemsValues &elems)
+ASTLoweringBase::visit (AST::ArrayElemsValues &)
 {}
 void
-ASTLoweringBase::visit (AST::ArrayElemsCopied &elems)
+ASTLoweringBase::visit (AST::ArrayElemsCopied &)
 {}
 void
-ASTLoweringBase::visit (AST::ArrayExpr &expr)
+ASTLoweringBase::visit (AST::ArrayExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ArrayIndexExpr &expr)
+ASTLoweringBase::visit (AST::ArrayIndexExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::TupleExpr &expr)
+ASTLoweringBase::visit (AST::TupleExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::TupleIndexExpr &expr)
+ASTLoweringBase::visit (AST::TupleIndexExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::StructExprStruct &expr)
+ASTLoweringBase::visit (AST::StructExprStruct &)
 {}
-//  void ASTLoweringBase::visit(StructExprField& field) {}
+//  void ASTLoweringBase::visit(StructExprFieldfield) {}
 void
-ASTLoweringBase::visit (AST::StructExprFieldIdentifier &field)
+ASTLoweringBase::visit (AST::StructExprFieldIdentifier &)
 {}
 void
-ASTLoweringBase::visit (AST::StructExprFieldIdentifierValue &field)
+ASTLoweringBase::visit (AST::StructExprFieldIdentifierValue &)
 {}
 void
-ASTLoweringBase::visit (AST::StructExprFieldIndexValue &field)
+ASTLoweringBase::visit (AST::StructExprFieldIndexValue &)
 {}
 void
-ASTLoweringBase::visit (AST::StructExprStructFields &expr)
+ASTLoweringBase::visit (AST::StructExprStructFields &)
 {}
 void
-ASTLoweringBase::visit (AST::StructExprStructBase &expr)
+ASTLoweringBase::visit (AST::StructExprStructBase &)
 {}
 void
-ASTLoweringBase::visit (AST::CallExpr &expr)
+ASTLoweringBase::visit (AST::CallExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::MethodCallExpr &expr)
+ASTLoweringBase::visit (AST::MethodCallExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::FieldAccessExpr &expr)
+ASTLoweringBase::visit (AST::FieldAccessExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ClosureExprInner &expr)
+ASTLoweringBase::visit (AST::ClosureExprInner &)
 {}
 void
-ASTLoweringBase::visit (AST::BlockExpr &expr)
+ASTLoweringBase::visit (AST::BlockExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ClosureExprInnerTyped &expr)
+ASTLoweringBase::visit (AST::ClosureExprInnerTyped &)
 {}
 void
-ASTLoweringBase::visit (AST::ContinueExpr &expr)
+ASTLoweringBase::visit (AST::ContinueExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::BreakExpr &expr)
+ASTLoweringBase::visit (AST::BreakExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::RangeFromToExpr &expr)
+ASTLoweringBase::visit (AST::RangeFromToExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::RangeFromExpr &expr)
+ASTLoweringBase::visit (AST::RangeFromExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::RangeToExpr &expr)
+ASTLoweringBase::visit (AST::RangeToExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::RangeFullExpr &expr)
+ASTLoweringBase::visit (AST::RangeFullExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::RangeFromToInclExpr &expr)
+ASTLoweringBase::visit (AST::RangeFromToInclExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::RangeToInclExpr &expr)
+ASTLoweringBase::visit (AST::RangeToInclExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ReturnExpr &expr)
+ASTLoweringBase::visit (AST::ReturnExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::UnsafeBlockExpr &expr)
+ASTLoweringBase::visit (AST::UnsafeBlockExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::LoopExpr &expr)
+ASTLoweringBase::visit (AST::LoopExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::WhileLoopExpr &expr)
+ASTLoweringBase::visit (AST::WhileLoopExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::WhileLetLoopExpr &expr)
+ASTLoweringBase::visit (AST::WhileLetLoopExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ForLoopExpr &expr)
+ASTLoweringBase::visit (AST::ForLoopExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::IfExpr &expr)
+ASTLoweringBase::visit (AST::IfExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::IfExprConseqElse &expr)
+ASTLoweringBase::visit (AST::IfExprConseqElse &)
 {}
 void
-ASTLoweringBase::visit (AST::IfExprConseqIf &expr)
+ASTLoweringBase::visit (AST::IfExprConseqIf &)
 {}
 void
-ASTLoweringBase::visit (AST::IfExprConseqIfLet &expr)
+ASTLoweringBase::visit (AST::IfExprConseqIfLet &)
 {}
 void
-ASTLoweringBase::visit (AST::IfLetExpr &expr)
+ASTLoweringBase::visit (AST::IfLetExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::IfLetExprConseqElse &expr)
+ASTLoweringBase::visit (AST::IfLetExprConseqElse &)
 {}
 void
-ASTLoweringBase::visit (AST::IfLetExprConseqIf &expr)
+ASTLoweringBase::visit (AST::IfLetExprConseqIf &)
 {}
 void
-ASTLoweringBase::visit (AST::IfLetExprConseqIfLet &expr)
+ASTLoweringBase::visit (AST::IfLetExprConseqIfLet &)
 {}
-//  void ASTLoweringBase::visit(MatchCase& match_case) {}
-// void ASTLoweringBase:: (AST::MatchCaseBlockExpr &match_case) {}
-// void ASTLoweringBase:: (AST::MatchCaseExpr &match_case) {}
+//  void ASTLoweringBase::visit(MatchCasematch_case) {}
+// void ASTLoweringBase:: (AST::MatchCaseBlockExpr &) {}
+// void ASTLoweringBase:: (AST::MatchCaseExpr &) {}
 void
-ASTLoweringBase::visit (AST::MatchExpr &expr)
+ASTLoweringBase::visit (AST::MatchExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::AwaitExpr &expr)
+ASTLoweringBase::visit (AST::AwaitExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::AsyncBlockExpr &expr)
+ASTLoweringBase::visit (AST::AsyncBlockExpr &)
 {}
 
 // rust-item.h
 void
-ASTLoweringBase::visit (AST::TypeParam &param)
+ASTLoweringBase::visit (AST::TypeParam &)
 {}
-//  void ASTLoweringBase::visit(WhereClauseItem& item) {}
+//  void ASTLoweringBase::visit(WhereClauseItemitem) {}
 void
-ASTLoweringBase::visit (AST::LifetimeWhereClauseItem &item)
+ASTLoweringBase::visit (AST::LifetimeWhereClauseItem &)
 {}
 void
-ASTLoweringBase::visit (AST::TypeBoundWhereClauseItem &item)
+ASTLoweringBase::visit (AST::TypeBoundWhereClauseItem &)
 {}
 void
-ASTLoweringBase::visit (AST::Method &method)
+ASTLoweringBase::visit (AST::Method &)
 {}
 void
-ASTLoweringBase::visit (AST::Module &module)
+ASTLoweringBase::visit (AST::Module &)
 {}
 void
-ASTLoweringBase::visit (AST::ExternCrate &crate)
+ASTLoweringBase::visit (AST::ExternCrate &)
 {}
-//  void ASTLoweringBase::visit(UseTree& use_tree) {}
+//  void ASTLoweringBase::visit(UseTreeuse_tree) {}
 void
-ASTLoweringBase::visit (AST::UseTreeGlob &use_tree)
+ASTLoweringBase::visit (AST::UseTreeGlob &)
 {}
 void
-ASTLoweringBase::visit (AST::UseTreeList &use_tree)
+ASTLoweringBase::visit (AST::UseTreeList &)
 {}
 void
-ASTLoweringBase::visit (AST::UseTreeRebind &use_tree)
+ASTLoweringBase::visit (AST::UseTreeRebind &)
 {}
 void
-ASTLoweringBase::visit (AST::UseDeclaration &use_decl)
+ASTLoweringBase::visit (AST::UseDeclaration &)
 {}
 void
-ASTLoweringBase::visit (AST::Function &function)
+ASTLoweringBase::visit (AST::Function &)
 {}
 void
-ASTLoweringBase::visit (AST::TypeAlias &type_alias)
+ASTLoweringBase::visit (AST::TypeAlias &)
 {}
 void
-ASTLoweringBase::visit (AST::StructStruct &struct_item)
+ASTLoweringBase::visit (AST::StructStruct &)
 {}
 void
-ASTLoweringBase::visit (AST::TupleStruct &tuple_struct)
+ASTLoweringBase::visit (AST::TupleStruct &)
 {}
 void
-ASTLoweringBase::visit (AST::EnumItem &item)
+ASTLoweringBase::visit (AST::EnumItem &)
 {}
 void
-ASTLoweringBase::visit (AST::EnumItemTuple &item)
+ASTLoweringBase::visit (AST::EnumItemTuple &)
 {}
 void
-ASTLoweringBase::visit (AST::EnumItemStruct &item)
+ASTLoweringBase::visit (AST::EnumItemStruct &)
 {}
 void
-ASTLoweringBase::visit (AST::EnumItemDiscriminant &item)
+ASTLoweringBase::visit (AST::EnumItemDiscriminant &)
 {}
 void
-ASTLoweringBase::visit (AST::Enum &enum_item)
+ASTLoweringBase::visit (AST::Enum &)
 {}
 void
-ASTLoweringBase::visit (AST::Union &union_item)
+ASTLoweringBase::visit (AST::Union &)
 {}
 void
-ASTLoweringBase::visit (AST::ConstantItem &const_item)
+ASTLoweringBase::visit (AST::ConstantItem &)
 {}
 void
-ASTLoweringBase::visit (AST::StaticItem &static_item)
+ASTLoweringBase::visit (AST::StaticItem &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitItemFunc &item)
+ASTLoweringBase::visit (AST::TraitItemFunc &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitItemMethod &item)
+ASTLoweringBase::visit (AST::TraitItemMethod &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitItemConst &item)
+ASTLoweringBase::visit (AST::TraitItemConst &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitItemType &item)
+ASTLoweringBase::visit (AST::TraitItemType &)
 {}
 void
-ASTLoweringBase::visit (AST::Trait &trait)
+ASTLoweringBase::visit (AST::Trait &)
 {}
 void
-ASTLoweringBase::visit (AST::InherentImpl &impl)
+ASTLoweringBase::visit (AST::InherentImpl &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitImpl &impl)
+ASTLoweringBase::visit (AST::TraitImpl &)
 {}
-//  void ASTLoweringBase::visit(ExternalItem& item) {}
+//  void ASTLoweringBase::visit(ExternalItemitem) {}
 void
-ASTLoweringBase::visit (AST::ExternalStaticItem &item)
+ASTLoweringBase::visit (AST::ExternalStaticItem &)
 {}
 void
-ASTLoweringBase::visit (AST::ExternalFunctionItem &item)
+ASTLoweringBase::visit (AST::ExternalFunctionItem &)
 {}
 void
-ASTLoweringBase::visit (AST::ExternBlock &block)
+ASTLoweringBase::visit (AST::ExternBlock &)
 {}
 
 // rust-macro.h
 void
-ASTLoweringBase::visit (AST::MacroMatchFragment &match)
+ASTLoweringBase::visit (AST::MacroMatchFragment &)
 {}
 void
-ASTLoweringBase::visit (AST::MacroMatchRepetition &match)
+ASTLoweringBase::visit (AST::MacroMatchRepetition &)
 {}
 void
-ASTLoweringBase::visit (AST::MacroMatcher &matcher)
+ASTLoweringBase::visit (AST::MacroMatcher &)
 {}
 void
-ASTLoweringBase::visit (AST::MacroRulesDefinition &rules_def)
+ASTLoweringBase::visit (AST::MacroRulesDefinition &)
 {}
 void
-ASTLoweringBase::visit (AST::MacroInvocation &macro_invoc)
+ASTLoweringBase::visit (AST::MacroInvocation &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaItemPath &meta_item)
+ASTLoweringBase::visit (AST::MetaItemPath &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaItemSeq &meta_item)
+ASTLoweringBase::visit (AST::MetaItemSeq &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaWord &meta_item)
+ASTLoweringBase::visit (AST::MetaWord &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaNameValueStr &meta_item)
+ASTLoweringBase::visit (AST::MetaNameValueStr &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaListPaths &meta_item)
+ASTLoweringBase::visit (AST::MetaListPaths &)
 {}
 void
-ASTLoweringBase::visit (AST::MetaListNameValueStr &meta_item)
+ASTLoweringBase::visit (AST::MetaListNameValueStr &)
 {}
 
 // rust-pattern.h
 void
-ASTLoweringBase::visit (AST::LiteralPattern &pattern)
+ASTLoweringBase::visit (AST::LiteralPattern &)
 {}
 void
-ASTLoweringBase::visit (AST::IdentifierPattern &pattern)
+ASTLoweringBase::visit (AST::IdentifierPattern &)
 {}
 void
-ASTLoweringBase::visit (AST::WildcardPattern &pattern)
+ASTLoweringBase::visit (AST::WildcardPattern &)
 {}
-//  void ASTLoweringBase::visit(RangePatternBound& bound) {}
+//  void ASTLoweringBase::visit(RangePatternBoundbound) {}
 void
-ASTLoweringBase::visit (AST::RangePatternBoundLiteral &bound)
+ASTLoweringBase::visit (AST::RangePatternBoundLiteral &)
 {}
 void
-ASTLoweringBase::visit (AST::RangePatternBoundPath &bound)
+ASTLoweringBase::visit (AST::RangePatternBoundPath &)
 {}
 void
-ASTLoweringBase::visit (AST::RangePatternBoundQualPath &bound)
+ASTLoweringBase::visit (AST::RangePatternBoundQualPath &)
 {}
 void
-ASTLoweringBase::visit (AST::RangePattern &pattern)
+ASTLoweringBase::visit (AST::RangePattern &)
 {}
 void
-ASTLoweringBase::visit (AST::ReferencePattern &pattern)
+ASTLoweringBase::visit (AST::ReferencePattern &)
 {}
-//  void ASTLoweringBase::visit(StructPatternField& field) {}
+//  void ASTLoweringBase::visit(StructPatternFieldfield) {}
 void
-ASTLoweringBase::visit (AST::StructPatternFieldTuplePat &field)
+ASTLoweringBase::visit (AST::StructPatternFieldTuplePat &)
 {}
 void
-ASTLoweringBase::visit (AST::StructPatternFieldIdentPat &field)
+ASTLoweringBase::visit (AST::StructPatternFieldIdentPat &)
 {}
 void
-ASTLoweringBase::visit (AST::StructPatternFieldIdent &field)
+ASTLoweringBase::visit (AST::StructPatternFieldIdent &)
 {}
 void
-ASTLoweringBase::visit (AST::StructPattern &pattern)
+ASTLoweringBase::visit (AST::StructPattern &)
 {}
-//  void ASTLoweringBase::visit(TupleStructItems& tuple_items) {}
+//  void ASTLoweringBase::visit(TupleStructItemstuple_items) {}
 void
-ASTLoweringBase::visit (AST::TupleStructItemsNoRange &tuple_items)
+ASTLoweringBase::visit (AST::TupleStructItemsNoRange &)
 {}
 void
-ASTLoweringBase::visit (AST::TupleStructItemsRange &tuple_items)
+ASTLoweringBase::visit (AST::TupleStructItemsRange &)
 {}
 void
-ASTLoweringBase::visit (AST::TupleStructPattern &pattern)
+ASTLoweringBase::visit (AST::TupleStructPattern &)
 {}
-//  void ASTLoweringBase::visit(TuplePatternItems& tuple_items) {}
+//  void ASTLoweringBase::visit(TuplePatternItemstuple_items) {}
 void
-ASTLoweringBase::visit (AST::TuplePatternItemsMultiple &tuple_items)
+ASTLoweringBase::visit (AST::TuplePatternItemsMultiple &)
 {}
 void
-ASTLoweringBase::visit (AST::TuplePatternItemsRanged &tuple_items)
+ASTLoweringBase::visit (AST::TuplePatternItemsRanged &)
 {}
 void
-ASTLoweringBase::visit (AST::TuplePattern &pattern)
+ASTLoweringBase::visit (AST::TuplePattern &)
 {}
 void
-ASTLoweringBase::visit (AST::GroupedPattern &pattern)
+ASTLoweringBase::visit (AST::GroupedPattern &)
 {}
 void
-ASTLoweringBase::visit (AST::SlicePattern &pattern)
+ASTLoweringBase::visit (AST::SlicePattern &)
 {}
 
 // rust-stmt.h
 void
-ASTLoweringBase::visit (AST::EmptyStmt &stmt)
+ASTLoweringBase::visit (AST::EmptyStmt &)
 {}
 void
-ASTLoweringBase::visit (AST::LetStmt &stmt)
+ASTLoweringBase::visit (AST::LetStmt &)
 {}
 void
-ASTLoweringBase::visit (AST::ExprStmtWithoutBlock &stmt)
+ASTLoweringBase::visit (AST::ExprStmtWithoutBlock &)
 {}
 void
-ASTLoweringBase::visit (AST::ExprStmtWithBlock &stmt)
+ASTLoweringBase::visit (AST::ExprStmtWithBlock &)
 {}
 
 // rust-type.h
 void
-ASTLoweringBase::visit (AST::TraitBound &bound)
+ASTLoweringBase::visit (AST::TraitBound &)
 {}
 void
-ASTLoweringBase::visit (AST::ImplTraitType &type)
+ASTLoweringBase::visit (AST::ImplTraitType &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitObjectType &type)
+ASTLoweringBase::visit (AST::TraitObjectType &)
 {}
 void
-ASTLoweringBase::visit (AST::ParenthesisedType &type)
+ASTLoweringBase::visit (AST::ParenthesisedType &)
 {}
 void
-ASTLoweringBase::visit (AST::ImplTraitTypeOneBound &type)
+ASTLoweringBase::visit (AST::ImplTraitTypeOneBound &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitObjectTypeOneBound &type)
+ASTLoweringBase::visit (AST::TraitObjectTypeOneBound &)
 {}
 void
-ASTLoweringBase::visit (AST::TupleType &type)
+ASTLoweringBase::visit (AST::TupleType &)
 {}
 void
-ASTLoweringBase::visit (AST::NeverType &type)
+ASTLoweringBase::visit (AST::NeverType &)
 {}
 void
-ASTLoweringBase::visit (AST::RawPointerType &type)
+ASTLoweringBase::visit (AST::RawPointerType &)
 {}
 void
-ASTLoweringBase::visit (AST::ReferenceType &type)
+ASTLoweringBase::visit (AST::ReferenceType &)
 {}
 void
-ASTLoweringBase::visit (AST::ArrayType &type)
+ASTLoweringBase::visit (AST::ArrayType &)
 {}
 void
-ASTLoweringBase::visit (AST::SliceType &type)
+ASTLoweringBase::visit (AST::SliceType &)
 {}
 void
-ASTLoweringBase::visit (AST::InferredType &type)
+ASTLoweringBase::visit (AST::InferredType &)
 {}
 void
-ASTLoweringBase::visit (AST::BareFunctionType &type)
+ASTLoweringBase::visit (AST::BareFunctionType &)
 {}
 
 HIR::Lifetime
@@ -742,7 +742,7 @@ ASTLoweringBase::handle_outer_attributes (const ItemWrapper &item)
 }
 
 void
-ASTLoweringBase::handle_doc_item_attribute (const ItemWrapper &item,
+ASTLoweringBase::handle_doc_item_attribute (const ItemWrapper &,
 					    const AST::Attribute &attr)
 {
   auto simple_doc_comment = attr.has_attr_input ()
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 261a36daa05..875e1dd9374 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -200,7 +200,7 @@ void
 Dump::visit (ClosureExpr &)
 {}
 void
-Dump::visit (BlockExpr &block_expr)
+Dump::visit (BlockExpr &)
 {
   stream << "BlockExpr"
 	 << ":"
@@ -324,7 +324,7 @@ void
 Dump::visit (UseDeclaration &)
 {}
 void
-Dump::visit (Function &function)
+Dump::visit (Function &)
 {
   indent++;
   stream << std::string (indent, indent_char);
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index f6e27b9a35f..230b7f72a85 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -5256,7 +5256,7 @@ ConstGenericParam::as_string () const
 }
 
 void
-ConstGenericParam::accept_vis (HIRFullVisitor &vis)
+ConstGenericParam::accept_vis (HIRFullVisitor &)
 {}
 
 } // namespace HIR
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 53c7aecd25b..ac7ced540e6 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -1364,7 +1364,7 @@ Lexer::parse_escape (char opening_char)
 /* Parses an escape (or string continue) in a string or character. Supports
  * unicode escapes. */
 std::tuple<Codepoint, int, bool>
-Lexer::parse_utf8_escape (char opening_char)
+Lexer::parse_utf8_escape ()
 {
   Codepoint output_char;
   int additional_length_offset = 0;
@@ -1964,7 +1964,7 @@ Lexer::parse_string (Location loc)
       if (current_char32.value == '\\')
 	{
 	  // parse escape
-	  auto utf8_escape_pair = parse_utf8_escape ('\'');
+	  auto utf8_escape_pair = parse_utf8_escape ();
 	  current_char32 = std::get<0> (utf8_escape_pair);
 
 	  if (current_char32 == Codepoint (0) && std::get<2> (utf8_escape_pair))
@@ -2365,7 +2365,7 @@ Lexer::parse_char_or_lifetime (Location loc)
   if (current_char32.value == '\\')
     {
       // parse escape
-      auto utf8_escape_pair = parse_utf8_escape ('\'');
+      auto utf8_escape_pair = parse_utf8_escape ();
       current_char32 = std::get<0> (utf8_escape_pair);
       length += std::get<1> (utf8_escape_pair);
 
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index a170e91f2cc..2dd60b365ef 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -109,7 +109,7 @@ private:
   std::pair<std::string, int> parse_in_exponent_part ();
   std::pair<PrimitiveCoreType, int> parse_in_type_suffix ();
   std::tuple<char, int, bool> parse_escape (char opening_char);
-  std::tuple<Codepoint, int, bool> parse_utf8_escape (char opening_char);
+  std::tuple<Codepoint, int, bool> parse_utf8_escape ();
   int parse_partial_string_continue ();
   std::pair<long, int> parse_partial_hex_escape ();
   std::pair<Codepoint, int> parse_partial_unicode_escape ();
diff --git a/gcc/rust/metadata/rust-export-metadata.cc b/gcc/rust/metadata/rust-export-metadata.cc
index 56849323e79..49a7226476d 100644
--- a/gcc/rust/metadata/rust-export-metadata.cc
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -157,18 +157,18 @@ class ExportVisItems : public HIR::HIRVisItemVisitor
 public:
   ExportVisItems (ExportContext &context) : ctx (context) {}
 
-  void visit (HIR::Module &module) override {}
-  void visit (HIR::ExternCrate &crate) override {}
-  void visit (HIR::UseDeclaration &use_decl) override {}
-  void visit (HIR::TypeAlias &type_alias) override {}
-  void visit (HIR::StructStruct &struct_item) override {}
-  void visit (HIR::TupleStruct &tuple_struct) override {}
-  void visit (HIR::Enum &enum_item) override {}
-  void visit (HIR::Union &union_item) override {}
-  void visit (HIR::ConstantItem &const_item) override {}
-  void visit (HIR::StaticItem &static_item) override {}
-  void visit (HIR::ImplBlock &impl) override {}
-  void visit (HIR::ExternBlock &block) override {}
+  void visit (HIR::Module &) override {}
+  void visit (HIR::ExternCrate &) override {}
+  void visit (HIR::UseDeclaration &) override {}
+  void visit (HIR::TypeAlias &) override {}
+  void visit (HIR::StructStruct &) override {}
+  void visit (HIR::TupleStruct &) override {}
+  void visit (HIR::Enum &) override {}
+  void visit (HIR::Union &) override {}
+  void visit (HIR::ConstantItem &) override {}
+  void visit (HIR::StaticItem &) override {}
+  void visit (HIR::ImplBlock &) override {}
+  void visit (HIR::ExternBlock &) override {}
 
   void visit (HIR::Trait &trait) override { ctx.emit_trait (trait); }
 
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 536c828beb4..4dfc0833d91 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -102,7 +102,7 @@ ResolveExpr::visit (AST::AssignmentExpr &expr)
   ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix);
 
   // need to verify the assignee
-  VerifyAsignee::go (expr.get_left_expr ().get (), expr.get_node_id ());
+  VerifyAsignee::go (expr.get_left_expr ().get ());
 }
 
 void
@@ -141,7 +141,7 @@ ResolveExpr::visit (AST::CompoundAssignmentExpr &expr)
   ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix);
 
   // need to verify the assignee
-  VerifyAsignee::go (expr.get_left_expr ().get (), expr.get_node_id ());
+  VerifyAsignee::go (expr.get_left_expr ().get ());
 }
 
 void
@@ -553,7 +553,7 @@ ResolveExpr::visit (AST::RangeToExpr &expr)
 }
 
 void
-ResolveExpr::visit (AST::RangeFullExpr &expr)
+ResolveExpr::visit (AST::RangeFullExpr &)
 {
   // nothing to do
 }
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index e5c712aba07..16d05f3792b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -61,13 +61,13 @@ ResolveType::visit (AST::RawPointerType &type)
 }
 
 void
-ResolveType::visit (AST::InferredType &type)
+ResolveType::visit (AST::InferredType &)
 {
   // FIXME
 }
 
 void
-ResolveType::visit (AST::NeverType &type)
+ResolveType::visit (AST::NeverType &)
 {
   // FIXME
 }
@@ -505,7 +505,7 @@ ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
 }
 
 void
-ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
+ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
 {
   // FIXME is this actually allowed? dyn A+B
   gcc_unreachable ();
diff --git a/gcc/rust/resolve/rust-ast-verify-assignee.h b/gcc/rust/resolve/rust-ast-verify-assignee.h
index e05a2251bb9..8d09c9b6564 100644
--- a/gcc/rust/resolve/rust-ast-verify-assignee.h
+++ b/gcc/rust/resolve/rust-ast-verify-assignee.h
@@ -30,9 +30,9 @@ class VerifyAsignee : public ResolverBase
   using Rust::Resolver::ResolverBase::visit;
 
 public:
-  static bool go (AST::Expr *assignee, NodeId parent)
+  static bool go (AST::Expr *assignee)
   {
-    VerifyAsignee checker (parent);
+    VerifyAsignee checker;
     assignee->accept_vis (checker);
     if (!checker.ok)
       rust_error_at (assignee->get_locus (),
@@ -70,10 +70,10 @@ public:
     expr.get_dereferenced_expr ()->accept_vis (*this);
   }
 
-  void visit (AST::PathInExpression &expr) override { ok = true; }
+  void visit (AST::PathInExpression &) override { ok = true; }
 
 private:
-  VerifyAsignee (NodeId parent) : ResolverBase (), ok (false) {}
+  VerifyAsignee () : ResolverBase (), ok (false) {}
 
   bool ok;
 };
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc
index 6b1f1e9c52f..8100564dc78 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -60,31 +60,31 @@ EarlyNameResolver::resolve_qualified_path_type (AST::QualifiedPathType &path)
 }
 
 void
-EarlyNameResolver::visit (AST::Token &tok)
+EarlyNameResolver::visit (AST::Token &)
 {}
 
 void
-EarlyNameResolver::visit (AST::DelimTokenTree &delim_tok_tree)
+EarlyNameResolver::visit (AST::DelimTokenTree &)
 {}
 
 void
-EarlyNameResolver::visit (AST::AttrInputMetaItemContainer &input)
+EarlyNameResolver::visit (AST::AttrInputMetaItemContainer &)
 {}
 
 void
-EarlyNameResolver::visit (AST::IdentifierExpr &ident_expr)
+EarlyNameResolver::visit (AST::IdentifierExpr &)
 {}
 
 void
-EarlyNameResolver::visit (AST::Lifetime &lifetime)
+EarlyNameResolver::visit (AST::Lifetime &)
 {}
 
 void
-EarlyNameResolver::visit (AST::LifetimeParam &lifetime_param)
+EarlyNameResolver::visit (AST::LifetimeParam &)
 {}
 
 void
-EarlyNameResolver::visit (AST::ConstGenericParam &const_param)
+EarlyNameResolver::visit (AST::ConstGenericParam &)
 {}
 
 // FIXME: ARTHUR: Do we need to perform macro resolution for paths as well?
@@ -98,7 +98,7 @@ EarlyNameResolver::visit (AST::PathInExpression &path)
 }
 
 void
-EarlyNameResolver::visit (AST::TypePathSegment &segment)
+EarlyNameResolver::visit (AST::TypePathSegment &)
 {}
 
 void
@@ -144,19 +144,19 @@ EarlyNameResolver::visit (AST::QualifiedPathInType &path)
 }
 
 void
-EarlyNameResolver::visit (AST::LiteralExpr &expr)
+EarlyNameResolver::visit (AST::LiteralExpr &)
 {}
 
 void
-EarlyNameResolver::visit (AST::AttrInputLiteral &attr_input)
+EarlyNameResolver::visit (AST::AttrInputLiteral &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MetaItemLitExpr &meta_item)
+EarlyNameResolver::visit (AST::MetaItemLitExpr &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MetaItemPathLit &meta_item)
+EarlyNameResolver::visit (AST::MetaItemPathLit &)
 {}
 
 void
@@ -271,11 +271,11 @@ EarlyNameResolver::visit (AST::TupleIndexExpr &expr)
 }
 
 void
-EarlyNameResolver::visit (AST::StructExprStruct &expr)
+EarlyNameResolver::visit (AST::StructExprStruct &)
 {}
 
 void
-EarlyNameResolver::visit (AST::StructExprFieldIdentifier &field)
+EarlyNameResolver::visit (AST::StructExprFieldIdentifier &)
 {}
 
 void
@@ -298,7 +298,7 @@ EarlyNameResolver::visit (AST::StructExprStructFields &expr)
 }
 
 void
-EarlyNameResolver::visit (AST::StructExprStructBase &expr)
+EarlyNameResolver::visit (AST::StructExprStructBase &)
 {}
 
 void
@@ -352,7 +352,7 @@ EarlyNameResolver::visit (AST::ClosureExprInnerTyped &expr)
 }
 
 void
-EarlyNameResolver::visit (AST::ContinueExpr &expr)
+EarlyNameResolver::visit (AST::ContinueExpr &)
 {}
 
 void
@@ -382,7 +382,7 @@ EarlyNameResolver::visit (AST::RangeToExpr &expr)
 }
 
 void
-EarlyNameResolver::visit (AST::RangeFullExpr &expr)
+EarlyNameResolver::visit (AST::RangeFullExpr &)
 {}
 
 void
@@ -539,7 +539,7 @@ EarlyNameResolver::visit (AST::TypeParam &param)
 }
 
 void
-EarlyNameResolver::visit (AST::LifetimeWhereClauseItem &item)
+EarlyNameResolver::visit (AST::LifetimeWhereClauseItem &)
 {}
 
 void
@@ -576,23 +576,23 @@ EarlyNameResolver::visit (AST::Module &module)
 }
 
 void
-EarlyNameResolver::visit (AST::ExternCrate &crate)
+EarlyNameResolver::visit (AST::ExternCrate &)
 {}
 
 void
-EarlyNameResolver::visit (AST::UseTreeGlob &use_tree)
+EarlyNameResolver::visit (AST::UseTreeGlob &)
 {}
 
 void
-EarlyNameResolver::visit (AST::UseTreeList &use_tree)
+EarlyNameResolver::visit (AST::UseTreeList &)
 {}
 
 void
-EarlyNameResolver::visit (AST::UseTreeRebind &use_tree)
+EarlyNameResolver::visit (AST::UseTreeRebind &)
 {}
 
 void
-EarlyNameResolver::visit (AST::UseDeclaration &use_decl)
+EarlyNameResolver::visit (AST::UseDeclaration &)
 {}
 
 void
@@ -632,27 +632,27 @@ EarlyNameResolver::visit (AST::TupleStruct &tuple_struct)
 }
 
 void
-EarlyNameResolver::visit (AST::EnumItem &item)
+EarlyNameResolver::visit (AST::EnumItem &)
 {}
 
 void
-EarlyNameResolver::visit (AST::EnumItemTuple &item)
+EarlyNameResolver::visit (AST::EnumItemTuple &)
 {}
 
 void
-EarlyNameResolver::visit (AST::EnumItemStruct &item)
+EarlyNameResolver::visit (AST::EnumItemStruct &)
 {}
 
 void
-EarlyNameResolver::visit (AST::EnumItemDiscriminant &item)
+EarlyNameResolver::visit (AST::EnumItemDiscriminant &)
 {}
 
 void
-EarlyNameResolver::visit (AST::Enum &enum_item)
+EarlyNameResolver::visit (AST::Enum &)
 {}
 
 void
-EarlyNameResolver::visit (AST::Union &union_item)
+EarlyNameResolver::visit (AST::Union &)
 {}
 
 void
@@ -716,7 +716,7 @@ EarlyNameResolver::visit (AST::TraitItemConst &item)
 }
 
 void
-EarlyNameResolver::visit (AST::TraitItemType &item)
+EarlyNameResolver::visit (AST::TraitItemType &)
 {}
 
 void
@@ -777,15 +777,15 @@ EarlyNameResolver::visit (AST::ExternBlock &block)
 }
 
 void
-EarlyNameResolver::visit (AST::MacroMatchFragment &match)
+EarlyNameResolver::visit (AST::MacroMatchFragment &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MacroMatchRepetition &match)
+EarlyNameResolver::visit (AST::MacroMatchRepetition &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MacroMatcher &matcher)
+EarlyNameResolver::visit (AST::MacroMatcher &)
 {}
 
 void
@@ -853,31 +853,31 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc)
 // FIXME: ARTHUR: Do we need to resolve these as well here?
 
 void
-EarlyNameResolver::visit (AST::MetaItemPath &meta_item)
+EarlyNameResolver::visit (AST::MetaItemPath &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MetaItemSeq &meta_item)
+EarlyNameResolver::visit (AST::MetaItemSeq &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MetaWord &meta_item)
+EarlyNameResolver::visit (AST::MetaWord &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MetaNameValueStr &meta_item)
+EarlyNameResolver::visit (AST::MetaNameValueStr &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MetaListPaths &meta_item)
+EarlyNameResolver::visit (AST::MetaListPaths &)
 {}
 
 void
-EarlyNameResolver::visit (AST::MetaListNameValueStr &meta_item)
+EarlyNameResolver::visit (AST::MetaListNameValueStr &)
 {}
 
 void
-EarlyNameResolver::visit (AST::LiteralPattern &pattern)
+EarlyNameResolver::visit (AST::LiteralPattern &)
 {}
 
 void
@@ -888,19 +888,19 @@ EarlyNameResolver::visit (AST::IdentifierPattern &pattern)
 }
 
 void
-EarlyNameResolver::visit (AST::WildcardPattern &pattern)
+EarlyNameResolver::visit (AST::WildcardPattern &)
 {}
 
 void
-EarlyNameResolver::visit (AST::RangePatternBoundLiteral &bound)
+EarlyNameResolver::visit (AST::RangePatternBoundLiteral &)
 {}
 
 void
-EarlyNameResolver::visit (AST::RangePatternBoundPath &bound)
+EarlyNameResolver::visit (AST::RangePatternBoundPath &)
 {}
 
 void
-EarlyNameResolver::visit (AST::RangePatternBoundQualPath &bound)
+EarlyNameResolver::visit (AST::RangePatternBoundQualPath &)
 {}
 
 void
@@ -929,11 +929,11 @@ EarlyNameResolver::visit (AST::StructPatternFieldIdentPat &field)
 }
 
 void
-EarlyNameResolver::visit (AST::StructPatternFieldIdent &field)
+EarlyNameResolver::visit (AST::StructPatternFieldIdent &)
 {}
 
 void
-EarlyNameResolver::visit (AST::StructPattern &pattern)
+EarlyNameResolver::visit (AST::StructPattern &)
 {}
 
 void
@@ -994,7 +994,7 @@ EarlyNameResolver::visit (AST::SlicePattern &pattern)
 }
 
 void
-EarlyNameResolver::visit (AST::EmptyStmt &stmt)
+EarlyNameResolver::visit (AST::EmptyStmt &)
 {}
 
 void
@@ -1022,55 +1022,55 @@ EarlyNameResolver::visit (AST::ExprStmtWithBlock &stmt)
 }
 
 void
-EarlyNameResolver::visit (AST::TraitBound &bound)
+EarlyNameResolver::visit (AST::TraitBound &)
 {}
 
 void
-EarlyNameResolver::visit (AST::ImplTraitType &type)
+EarlyNameResolver::visit (AST::ImplTraitType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::TraitObjectType &type)
+EarlyNameResolver::visit (AST::TraitObjectType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::ParenthesisedType &type)
+EarlyNameResolver::visit (AST::ParenthesisedType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::ImplTraitTypeOneBound &type)
+EarlyNameResolver::visit (AST::ImplTraitTypeOneBound &)
 {}
 
 void
-EarlyNameResolver::visit (AST::TraitObjectTypeOneBound &type)
+EarlyNameResolver::visit (AST::TraitObjectTypeOneBound &)
 {}
 
 void
-EarlyNameResolver::visit (AST::TupleType &type)
+EarlyNameResolver::visit (AST::TupleType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::NeverType &type)
+EarlyNameResolver::visit (AST::NeverType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::RawPointerType &type)
+EarlyNameResolver::visit (AST::RawPointerType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::ReferenceType &type)
+EarlyNameResolver::visit (AST::ReferenceType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::ArrayType &type)
+EarlyNameResolver::visit (AST::ArrayType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::SliceType &type)
+EarlyNameResolver::visit (AST::SliceType &)
 {}
 
 void
-EarlyNameResolver::visit (AST::InferredType &type)
+EarlyNameResolver::visit (AST::InferredType &)
 {}
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index d800549dea2..796cc65ba66 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -72,27 +72,21 @@ public:
   void visit (HIR::ClosureExpr &expr) override;
 
   // TODO
-  void visit (HIR::ErrorPropagationExpr &expr) override {}
-  void visit (HIR::RangeToInclExpr &expr) override {}
-  void visit (HIR::WhileLetLoopExpr &expr) override {}
-  void visit (HIR::ForLoopExpr &expr) override {}
-  void visit (HIR::IfExprConseqIfLet &expr) override {}
-  void visit (HIR::IfLetExprConseqElse &expr) override {}
-  void visit (HIR::IfLetExprConseqIf &expr) override {}
-  void visit (HIR::IfLetExprConseqIfLet &expr) override {}
-  void visit (HIR::AwaitExpr &expr) override {}
-  void visit (HIR::AsyncBlockExpr &expr) override {}
+  void visit (HIR::ErrorPropagationExpr &) override {}
+  void visit (HIR::RangeToInclExpr &) override {}
+  void visit (HIR::WhileLetLoopExpr &) override {}
+  void visit (HIR::ForLoopExpr &) override {}
+  void visit (HIR::IfExprConseqIfLet &) override {}
+  void visit (HIR::IfLetExprConseqElse &) override {}
+  void visit (HIR::IfLetExprConseqIf &) override {}
+  void visit (HIR::IfLetExprConseqIfLet &) override {}
+  void visit (HIR::AwaitExpr &) override {}
+  void visit (HIR::AsyncBlockExpr &) override {}
 
   // don't need to implement these see rust-hir-type-check-struct-field.h
-  void visit (HIR::StructExprFieldIdentifier &field) override
-  {
-    gcc_unreachable ();
-  }
-  void visit (HIR::StructExprFieldIdentifierValue &field) override
-  {
-    gcc_unreachable ();
-  }
-  void visit (HIR::StructExprFieldIndexValue &field) override
+  void visit (HIR::StructExprFieldIdentifier &) override { gcc_unreachable (); }
+  void visit (HIR::StructExprFieldIndexValue &) override { gcc_unreachable (); }
+  void visit (HIR::StructExprFieldIdentifierValue &) override
   {
     gcc_unreachable ();
   }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 10085c90629..2268fdb6e6c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -48,8 +48,8 @@ public:
   void visit (HIR::Trait &trait_block) override;
 
   // nothing to do
-  void visit (HIR::ExternCrate &crate) override {}
-  void visit (HIR::UseDeclaration &use_decl) override {}
+  void visit (HIR::ExternCrate &) override {}
+  void visit (HIR::UseDeclaration &) override {}
 
 protected:
   std::vector<TyTy::SubstitutionParamMapping>
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 82af7294d69..b017a851b5d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -381,34 +381,34 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern)
 }
 
 void
-TypeCheckPattern::visit (HIR::IdentifierPattern &pattern)
+TypeCheckPattern::visit (HIR::IdentifierPattern &)
 {
   infered = parent;
 }
 
 void
-TypeCheckPattern::visit (HIR::GroupedPattern &pattern)
+TypeCheckPattern::visit (HIR::GroupedPattern &)
 {
   // TODO
   gcc_unreachable ();
 }
 
 void
-TypeCheckPattern::visit (HIR::QualifiedPathInExpression &pattern)
+TypeCheckPattern::visit (HIR::QualifiedPathInExpression &)
 {
   // TODO
   gcc_unreachable ();
 }
 
 void
-TypeCheckPattern::visit (HIR::ReferencePattern &pattern)
+TypeCheckPattern::visit (HIR::ReferencePattern &)
 {
   // TODO
   gcc_unreachable ();
 }
 
 void
-TypeCheckPattern::visit (HIR::SlicePattern &pattern)
+TypeCheckPattern::visit (HIR::SlicePattern &)
 {
   // TODO
   gcc_unreachable ();
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 4b1fe4fd418..cfe269221bd 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -123,53 +123,53 @@ public:
     return resolved;
   }
 
-  virtual void visit (TupleType &type) override {}
+  virtual void visit (TupleType &) override {}
 
-  virtual void visit (ADTType &type) override {}
+  virtual void visit (ADTType &) override {}
 
-  virtual void visit (InferType &type) override {}
+  virtual void visit (InferType &) override {}
 
-  virtual void visit (FnType &type) override {}
+  virtual void visit (FnType &) override {}
 
-  virtual void visit (FnPtr &type) override {}
+  virtual void visit (FnPtr &) override {}
 
-  virtual void visit (ArrayType &type) override {}
+  virtual void visit (ArrayType &) override {}
 
-  virtual void visit (SliceType &type) override {}
+  virtual void visit (SliceType &) override {}
 
-  virtual void visit (BoolType &type) override {}
+  virtual void visit (BoolType &) override {}
 
-  virtual void visit (IntType &type) override {}
+  virtual void visit (IntType &) override {}
 
-  virtual void visit (UintType &type) override {}
+  virtual void visit (UintType &) override {}
 
-  virtual void visit (USizeType &type) override {}
+  virtual void visit (USizeType &) override {}
 
-  virtual void visit (ISizeType &type) override {}
+  virtual void visit (ISizeType &) override {}
 
-  virtual void visit (FloatType &type) override {}
+  virtual void visit (FloatType &) override {}
 
-  virtual void visit (ErrorType &type) override {}
+  virtual void visit (ErrorType &) override {}
 
-  virtual void visit (CharType &type) override {}
+  virtual void visit (CharType &) override {}
 
-  virtual void visit (ReferenceType &type) override {}
+  virtual void visit (ReferenceType &) override {}
 
-  virtual void visit (PointerType &type) override {}
+  virtual void visit (PointerType &) override {}
 
-  virtual void visit (ParamType &type) override {}
+  virtual void visit (ParamType &) override {}
 
-  virtual void visit (StrType &type) override {}
+  virtual void visit (StrType &) override {}
 
-  virtual void visit (NeverType &type) override {}
+  virtual void visit (NeverType &) override {}
 
-  virtual void visit (PlaceholderType &type) override {}
+  virtual void visit (PlaceholderType &) override {}
 
-  virtual void visit (ProjectionType &type) override {}
+  virtual void visit (ProjectionType &) override {}
 
-  virtual void visit (DynamicObjectType &type) override {}
+  virtual void visit (DynamicObjectType &) override {}
 
-  virtual void visit (ClosureType &type) override {}
+  virtual void visit (ClosureType &) override {}
 
 protected:
   BaseRules (BaseType *base)
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 1c85273e541..33f2c932d09 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -210,342 +210,342 @@ AttributeChecker::check_attributes (const AST::AttrVec &attributes)
 }
 
 void
-AttributeChecker::visit (AST::Token &tok)
+AttributeChecker::visit (AST::Token &)
 {}
 
 void
-AttributeChecker::visit (AST::DelimTokenTree &delim_tok_tree)
+AttributeChecker::visit (AST::DelimTokenTree &)
 {}
 
 void
-AttributeChecker::visit (AST::AttrInputMetaItemContainer &input)
+AttributeChecker::visit (AST::AttrInputMetaItemContainer &)
 {}
 
 void
-AttributeChecker::visit (AST::IdentifierExpr &ident_expr)
+AttributeChecker::visit (AST::IdentifierExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::Lifetime &lifetime)
+AttributeChecker::visit (AST::Lifetime &)
 {}
 
 void
-AttributeChecker::visit (AST::LifetimeParam &lifetime_param)
+AttributeChecker::visit (AST::LifetimeParam &)
 {}
 
 void
-AttributeChecker::visit (AST::ConstGenericParam &const_param)
+AttributeChecker::visit (AST::ConstGenericParam &)
 {}
 
 // rust-path.h
 void
-AttributeChecker::visit (AST::PathInExpression &path)
+AttributeChecker::visit (AST::PathInExpression &)
 {}
 
 void
-AttributeChecker::visit (AST::TypePathSegment &segment)
+AttributeChecker::visit (AST::TypePathSegment &)
 {}
 
 void
-AttributeChecker::visit (AST::TypePathSegmentGeneric &segment)
+AttributeChecker::visit (AST::TypePathSegmentGeneric &)
 {}
 
 void
-AttributeChecker::visit (AST::TypePathSegmentFunction &segment)
+AttributeChecker::visit (AST::TypePathSegmentFunction &)
 {}
 
 void
-AttributeChecker::visit (AST::TypePath &path)
+AttributeChecker::visit (AST::TypePath &)
 {}
 
 void
-AttributeChecker::visit (AST::QualifiedPathInExpression &path)
+AttributeChecker::visit (AST::QualifiedPathInExpression &)
 {}
 
 void
-AttributeChecker::visit (AST::QualifiedPathInType &path)
+AttributeChecker::visit (AST::QualifiedPathInType &)
 {}
 
 // rust-expr.h
 void
-AttributeChecker::visit (AST::LiteralExpr &expr)
+AttributeChecker::visit (AST::LiteralExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::AttrInputLiteral &attr_input)
+AttributeChecker::visit (AST::AttrInputLiteral &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaItemLitExpr &meta_item)
+AttributeChecker::visit (AST::MetaItemLitExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaItemPathLit &meta_item)
+AttributeChecker::visit (AST::MetaItemPathLit &)
 {}
 
 void
-AttributeChecker::visit (AST::BorrowExpr &expr)
+AttributeChecker::visit (AST::BorrowExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::DereferenceExpr &expr)
+AttributeChecker::visit (AST::DereferenceExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ErrorPropagationExpr &expr)
+AttributeChecker::visit (AST::ErrorPropagationExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::NegationExpr &expr)
+AttributeChecker::visit (AST::NegationExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ArithmeticOrLogicalExpr &expr)
+AttributeChecker::visit (AST::ArithmeticOrLogicalExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ComparisonExpr &expr)
+AttributeChecker::visit (AST::ComparisonExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::LazyBooleanExpr &expr)
+AttributeChecker::visit (AST::LazyBooleanExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::TypeCastExpr &expr)
+AttributeChecker::visit (AST::TypeCastExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::AssignmentExpr &expr)
+AttributeChecker::visit (AST::AssignmentExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::CompoundAssignmentExpr &expr)
+AttributeChecker::visit (AST::CompoundAssignmentExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::GroupedExpr &expr)
+AttributeChecker::visit (AST::GroupedExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ArrayElemsValues &elems)
+AttributeChecker::visit (AST::ArrayElemsValues &)
 {}
 
 void
-AttributeChecker::visit (AST::ArrayElemsCopied &elems)
+AttributeChecker::visit (AST::ArrayElemsCopied &)
 {}
 
 void
-AttributeChecker::visit (AST::ArrayExpr &expr)
+AttributeChecker::visit (AST::ArrayExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ArrayIndexExpr &expr)
+AttributeChecker::visit (AST::ArrayIndexExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::TupleExpr &expr)
+AttributeChecker::visit (AST::TupleExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::TupleIndexExpr &expr)
+AttributeChecker::visit (AST::TupleIndexExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::StructExprStruct &expr)
+AttributeChecker::visit (AST::StructExprStruct &)
 {}
 
 void
-AttributeChecker::visit (AST::StructExprFieldIdentifier &field)
+AttributeChecker::visit (AST::StructExprFieldIdentifier &)
 {}
 
 void
-AttributeChecker::visit (AST::StructExprFieldIdentifierValue &field)
+AttributeChecker::visit (AST::StructExprFieldIdentifierValue &)
 {}
 
 void
-AttributeChecker::visit (AST::StructExprFieldIndexValue &field)
+AttributeChecker::visit (AST::StructExprFieldIndexValue &)
 {}
 
 void
-AttributeChecker::visit (AST::StructExprStructFields &expr)
+AttributeChecker::visit (AST::StructExprStructFields &)
 {}
 
 void
-AttributeChecker::visit (AST::StructExprStructBase &expr)
+AttributeChecker::visit (AST::StructExprStructBase &)
 {}
 
 void
-AttributeChecker::visit (AST::CallExpr &expr)
+AttributeChecker::visit (AST::CallExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::MethodCallExpr &expr)
+AttributeChecker::visit (AST::MethodCallExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::FieldAccessExpr &expr)
+AttributeChecker::visit (AST::FieldAccessExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ClosureExprInner &expr)
+AttributeChecker::visit (AST::ClosureExprInner &)
 {}
 
 void
-AttributeChecker::visit (AST::BlockExpr &expr)
+AttributeChecker::visit (AST::BlockExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ClosureExprInnerTyped &expr)
+AttributeChecker::visit (AST::ClosureExprInnerTyped &)
 {}
 
 void
-AttributeChecker::visit (AST::ContinueExpr &expr)
+AttributeChecker::visit (AST::ContinueExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::BreakExpr &expr)
+AttributeChecker::visit (AST::BreakExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::RangeFromToExpr &expr)
+AttributeChecker::visit (AST::RangeFromToExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::RangeFromExpr &expr)
+AttributeChecker::visit (AST::RangeFromExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::RangeToExpr &expr)
+AttributeChecker::visit (AST::RangeToExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::RangeFullExpr &expr)
+AttributeChecker::visit (AST::RangeFullExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::RangeFromToInclExpr &expr)
+AttributeChecker::visit (AST::RangeFromToInclExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::RangeToInclExpr &expr)
+AttributeChecker::visit (AST::RangeToInclExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ReturnExpr &expr)
+AttributeChecker::visit (AST::ReturnExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::UnsafeBlockExpr &expr)
+AttributeChecker::visit (AST::UnsafeBlockExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::LoopExpr &expr)
+AttributeChecker::visit (AST::LoopExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::WhileLoopExpr &expr)
+AttributeChecker::visit (AST::WhileLoopExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::WhileLetLoopExpr &expr)
+AttributeChecker::visit (AST::WhileLetLoopExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::ForLoopExpr &expr)
+AttributeChecker::visit (AST::ForLoopExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::IfExpr &expr)
+AttributeChecker::visit (AST::IfExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::IfExprConseqElse &expr)
+AttributeChecker::visit (AST::IfExprConseqElse &)
 {}
 
 void
-AttributeChecker::visit (AST::IfExprConseqIf &expr)
+AttributeChecker::visit (AST::IfExprConseqIf &)
 {}
 
 void
-AttributeChecker::visit (AST::IfExprConseqIfLet &expr)
+AttributeChecker::visit (AST::IfExprConseqIfLet &)
 {}
 
 void
-AttributeChecker::visit (AST::IfLetExpr &expr)
+AttributeChecker::visit (AST::IfLetExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::IfLetExprConseqElse &expr)
+AttributeChecker::visit (AST::IfLetExprConseqElse &)
 {}
 
 void
-AttributeChecker::visit (AST::IfLetExprConseqIf &expr)
+AttributeChecker::visit (AST::IfLetExprConseqIf &)
 {}
 
 void
-AttributeChecker::visit (AST::IfLetExprConseqIfLet &expr)
+AttributeChecker::visit (AST::IfLetExprConseqIfLet &)
 {}
 
 void
-AttributeChecker::visit (AST::MatchExpr &expr)
+AttributeChecker::visit (AST::MatchExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::AwaitExpr &expr)
+AttributeChecker::visit (AST::AwaitExpr &)
 {}
 
 void
-AttributeChecker::visit (AST::AsyncBlockExpr &expr)
+AttributeChecker::visit (AST::AsyncBlockExpr &)
 {}
 
 // rust-item.h
 void
-AttributeChecker::visit (AST::TypeParam &param)
+AttributeChecker::visit (AST::TypeParam &)
 {}
 
 void
-AttributeChecker::visit (AST::LifetimeWhereClauseItem &item)
+AttributeChecker::visit (AST::LifetimeWhereClauseItem &)
 {}
 
 void
-AttributeChecker::visit (AST::TypeBoundWhereClauseItem &item)
+AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
 {}
 
 void
-AttributeChecker::visit (AST::Method &method)
+AttributeChecker::visit (AST::Method &)
 {}
 
 void
-AttributeChecker::visit (AST::Module &module)
+AttributeChecker::visit (AST::Module &)
 {}
 
 void
-AttributeChecker::visit (AST::ExternCrate &crate)
+AttributeChecker::visit (AST::ExternCrate &)
 {}
 
 void
-AttributeChecker::visit (AST::UseTreeGlob &use_tree)
+AttributeChecker::visit (AST::UseTreeGlob &)
 {}
 
 void
-AttributeChecker::visit (AST::UseTreeList &use_tree)
+AttributeChecker::visit (AST::UseTreeList &)
 {}
 
 void
-AttributeChecker::visit (AST::UseTreeRebind &use_tree)
+AttributeChecker::visit (AST::UseTreeRebind &)
 {}
 
 void
-AttributeChecker::visit (AST::UseDeclaration &use_decl)
+AttributeChecker::visit (AST::UseDeclaration &)
 {}
 
 void
-AttributeChecker::visit (AST::Function &function)
+AttributeChecker::visit (AST::Function &)
 {}
 
 void
-AttributeChecker::visit (AST::TypeAlias &type_alias)
+AttributeChecker::visit (AST::TypeAlias &)
 {}
 
 void
@@ -555,287 +555,287 @@ AttributeChecker::visit (AST::StructStruct &struct_item)
 }
 
 void
-AttributeChecker::visit (AST::TupleStruct &tuple_struct)
+AttributeChecker::visit (AST::TupleStruct &)
 {}
 
 void
-AttributeChecker::visit (AST::EnumItem &item)
+AttributeChecker::visit (AST::EnumItem &)
 {}
 
 void
-AttributeChecker::visit (AST::EnumItemTuple &item)
+AttributeChecker::visit (AST::EnumItemTuple &)
 {}
 
 void
-AttributeChecker::visit (AST::EnumItemStruct &item)
+AttributeChecker::visit (AST::EnumItemStruct &)
 {}
 
 void
-AttributeChecker::visit (AST::EnumItemDiscriminant &item)
+AttributeChecker::visit (AST::EnumItemDiscriminant &)
 {}
 
 void
-AttributeChecker::visit (AST::Enum &enum_item)
+AttributeChecker::visit (AST::Enum &)
 {}
 
 void
-AttributeChecker::visit (AST::Union &union_item)
+AttributeChecker::visit (AST::Union &)
 {}
 
 void
-AttributeChecker::visit (AST::ConstantItem &const_item)
+AttributeChecker::visit (AST::ConstantItem &)
 {}
 
 void
-AttributeChecker::visit (AST::StaticItem &static_item)
+AttributeChecker::visit (AST::StaticItem &)
 {}
 
 void
-AttributeChecker::visit (AST::TraitItemFunc &item)
+AttributeChecker::visit (AST::TraitItemFunc &)
 {}
 
 void
-AttributeChecker::visit (AST::TraitItemMethod &item)
+AttributeChecker::visit (AST::TraitItemMethod &)
 {}
 
 void
-AttributeChecker::visit (AST::TraitItemConst &item)
+AttributeChecker::visit (AST::TraitItemConst &)
 {}
 
 void
-AttributeChecker::visit (AST::TraitItemType &item)
+AttributeChecker::visit (AST::TraitItemType &)
 {}
 
 void
-AttributeChecker::visit (AST::Trait &trait)
+AttributeChecker::visit (AST::Trait &)
 {}
 
 void
-AttributeChecker::visit (AST::InherentImpl &impl)
+AttributeChecker::visit (AST::InherentImpl &)
 {}
 
 void
-AttributeChecker::visit (AST::TraitImpl &impl)
+AttributeChecker::visit (AST::TraitImpl &)
 {}
 
 void
-AttributeChecker::visit (AST::ExternalStaticItem &item)
+AttributeChecker::visit (AST::ExternalStaticItem &)
 {}
 
 void
-AttributeChecker::visit (AST::ExternalFunctionItem &item)
+AttributeChecker::visit (AST::ExternalFunctionItem &)
 {}
 
 void
-AttributeChecker::visit (AST::ExternBlock &block)
+AttributeChecker::visit (AST::ExternBlock &)
 {}
 
 // rust-macro.h
 void
-AttributeChecker::visit (AST::MacroMatchFragment &match)
+AttributeChecker::visit (AST::MacroMatchFragment &)
 {}
 
 void
-AttributeChecker::visit (AST::MacroMatchRepetition &match)
+AttributeChecker::visit (AST::MacroMatchRepetition &)
 {}
 
 void
-AttributeChecker::visit (AST::MacroMatcher &matcher)
+AttributeChecker::visit (AST::MacroMatcher &)
 {}
 
 void
-AttributeChecker::visit (AST::MacroRulesDefinition &rules_def)
+AttributeChecker::visit (AST::MacroRulesDefinition &)
 {}
 
 void
-AttributeChecker::visit (AST::MacroInvocation &macro_invoc)
+AttributeChecker::visit (AST::MacroInvocation &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaItemPath &meta_item)
+AttributeChecker::visit (AST::MetaItemPath &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaItemSeq &meta_item)
+AttributeChecker::visit (AST::MetaItemSeq &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaWord &meta_item)
+AttributeChecker::visit (AST::MetaWord &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaNameValueStr &meta_item)
+AttributeChecker::visit (AST::MetaNameValueStr &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaListPaths &meta_item)
+AttributeChecker::visit (AST::MetaListPaths &)
 {}
 
 void
-AttributeChecker::visit (AST::MetaListNameValueStr &meta_item)
+AttributeChecker::visit (AST::MetaListNameValueStr &)
 {}
 
 // rust-pattern.h
 void
-AttributeChecker::visit (AST::LiteralPattern &pattern)
+AttributeChecker::visit (AST::LiteralPattern &)
 {}
 
 void
-AttributeChecker::visit (AST::IdentifierPattern &pattern)
+AttributeChecker::visit (AST::IdentifierPattern &)
 {}
 
 void
-AttributeChecker::visit (AST::WildcardPattern &pattern)
+AttributeChecker::visit (AST::WildcardPattern &)
 {}
 
-// void AttributeChecker::visit(RangePatternBound& bound){}
+// void AttributeChecker::visit(RangePatternBound& ){}
 
 void
-AttributeChecker::visit (AST::RangePatternBoundLiteral &bound)
+AttributeChecker::visit (AST::RangePatternBoundLiteral &)
 {}
 
 void
-AttributeChecker::visit (AST::RangePatternBoundPath &bound)
+AttributeChecker::visit (AST::RangePatternBoundPath &)
 {}
 
 void
-AttributeChecker::visit (AST::RangePatternBoundQualPath &bound)
+AttributeChecker::visit (AST::RangePatternBoundQualPath &)
 {}
 
 void
-AttributeChecker::visit (AST::RangePattern &pattern)
+AttributeChecker::visit (AST::RangePattern &)
 {}
 
 void
-AttributeChecker::visit (AST::ReferencePattern &pattern)
+AttributeChecker::visit (AST::ReferencePattern &)
 {}
 
-// void AttributeChecker::visit(StructPatternField& field){}
+// void AttributeChecker::visit(StructPatternField& ){}
 
 void
-AttributeChecker::visit (AST::StructPatternFieldTuplePat &field)
+AttributeChecker::visit (AST::StructPatternFieldTuplePat &)
 {}
 
 void
-AttributeChecker::visit (AST::StructPatternFieldIdentPat &field)
+AttributeChecker::visit (AST::StructPatternFieldIdentPat &)
 {}
 
 void
-AttributeChecker::visit (AST::StructPatternFieldIdent &field)
+AttributeChecker::visit (AST::StructPatternFieldIdent &)
 {}
 
 void
-AttributeChecker::visit (AST::StructPattern &pattern)
+AttributeChecker::visit (AST::StructPattern &)
 {}
 
-// void AttributeChecker::visit(TupleStructItems& tuple_items){}
+// void AttributeChecker::visit(TupleStructItems& ){}
 
 void
-AttributeChecker::visit (AST::TupleStructItemsNoRange &tuple_items)
+AttributeChecker::visit (AST::TupleStructItemsNoRange &)
 {}
 
 void
-AttributeChecker::visit (AST::TupleStructItemsRange &tuple_items)
+AttributeChecker::visit (AST::TupleStructItemsRange &)
 {}
 
 void
-AttributeChecker::visit (AST::TupleStructPattern &pattern)
+AttributeChecker::visit (AST::TupleStructPattern &)
 {}
 
-// void AttributeChecker::visit(TuplePatternItems& tuple_items){}
+// void AttributeChecker::visit(TuplePatternItems& ){}
 
 void
-AttributeChecker::visit (AST::TuplePatternItemsMultiple &tuple_items)
+AttributeChecker::visit (AST::TuplePatternItemsMultiple &)
 {}
 
 void
-AttributeChecker::visit (AST::TuplePatternItemsRanged &tuple_items)
+AttributeChecker::visit (AST::TuplePatternItemsRanged &)
 {}
 
 void
-AttributeChecker::visit (AST::TuplePattern &pattern)
+AttributeChecker::visit (AST::TuplePattern &)
 {}
 
 void
-AttributeChecker::visit (AST::GroupedPattern &pattern)
+AttributeChecker::visit (AST::GroupedPattern &)
 {}
 
 void
-AttributeChecker::visit (AST::SlicePattern &pattern)
+AttributeChecker::visit (AST::SlicePattern &)
 {}
 
 // rust-stmt.h
 void
-AttributeChecker::visit (AST::EmptyStmt &stmt)
+AttributeChecker::visit (AST::EmptyStmt &)
 {}
 
 void
-AttributeChecker::visit (AST::LetStmt &stmt)
+AttributeChecker::visit (AST::LetStmt &)
 {}
 
 void
-AttributeChecker::visit (AST::ExprStmtWithoutBlock &stmt)
+AttributeChecker::visit (AST::ExprStmtWithoutBlock &)
 {}
 
 void
-AttributeChecker::visit (AST::ExprStmtWithBlock &stmt)
+AttributeChecker::visit (AST::ExprStmtWithBlock &)
 {}
 
 // rust-type.h
 void
-AttributeChecker::visit (AST::TraitBound &bound)
+AttributeChecker::visit (AST::TraitBound &)
 {}
 
 void
-AttributeChecker::visit (AST::ImplTraitType &type)
+AttributeChecker::visit (AST::ImplTraitType &)
 {}
 
 void
-AttributeChecker::visit (AST::TraitObjectType &type)
+AttributeChecker::visit (AST::TraitObjectType &)
 {}
 
 void
-AttributeChecker::visit (AST::ParenthesisedType &type)
+AttributeChecker::visit (AST::ParenthesisedType &)
 {}
 
 void
-AttributeChecker::visit (AST::ImplTraitTypeOneBound &type)
+AttributeChecker::visit (AST::ImplTraitTypeOneBound &)
 {}
 
 void
-AttributeChecker::visit (AST::TraitObjectTypeOneBound &type)
+AttributeChecker::visit (AST::TraitObjectTypeOneBound &)
 {}
 
 void
-AttributeChecker::visit (AST::TupleType &type)
+AttributeChecker::visit (AST::TupleType &)
 {}
 
 void
-AttributeChecker::visit (AST::NeverType &type)
+AttributeChecker::visit (AST::NeverType &)
 {}
 
 void
-AttributeChecker::visit (AST::RawPointerType &type)
+AttributeChecker::visit (AST::RawPointerType &)
 {}
 
 void
-AttributeChecker::visit (AST::ReferenceType &type)
+AttributeChecker::visit (AST::ReferenceType &)
 {}
 
 void
-AttributeChecker::visit (AST::ArrayType &type)
+AttributeChecker::visit (AST::ArrayType &)
 {}
 
 void
-AttributeChecker::visit (AST::SliceType &type)
+AttributeChecker::visit (AST::SliceType &)
 {}
 
 void
-AttributeChecker::visit (AST::InferredType &type)
+AttributeChecker::visit (AST::InferredType &)
 {}
 
 void
-AttributeChecker::visit (AST::BareFunctionType &type)
+AttributeChecker::visit (AST::BareFunctionType &)
 {}
 
 } // namespace Analysis
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 101/103] gccrs: Repair 'gcc/rust/lang.opt' comment
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (99 preceding siblings ...)
  2023-02-21 12:02 ` [committed 100/103] gccrs: Cleanup unused parameters to fix the bootstrap build arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 102/103] gccrs: const evaluator: Remove get_nth_callarg arthur.cohen
  2023-02-21 12:02 ` [committed 103/103] gccrs: add math intrinsics arthur.cohen
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Thomas Schwinge

From: Thomas Schwinge <thomas@codesourcery.com>

... lost in #1527 commit 138a6260124740208b8f3aff2e38617f43b05fe8
"rust: Add -frust-compile-until option".

gcc/rust/ChangeLog:

	* lang.opt: Fix ordering of file.
---
 gcc/rust/lang.opt | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index 40aafaf34d2..aab168334f6 100644
--- a/gcc/rust/lang.opt
+++ b/gcc/rust/lang.opt
@@ -117,6 +117,7 @@ Rust Joined RejectNegative
 
 o
 Rust Joined Separate
+; Documented in common.opt
 
 frust-compile-until=
 Rust Joined RejectNegative Enum(frust_compile_until) Var(flag_rust_compile_until)
@@ -158,7 +159,4 @@ Enum(frust_compile_until) String(compilation) Value(9)
 EnumValue
 Enum(frust_compile_until) String(end) Value(10)
 
-
-; Documented in common.opt
-
 ; This comment is to ensure we retain the blank line above.
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 102/103] gccrs: const evaluator: Remove get_nth_callarg
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (100 preceding siblings ...)
  2023-02-21 12:02 ` [committed 101/103] gccrs: Repair 'gcc/rust/lang.opt' comment arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  2023-02-21 12:02 ` [committed 103/103] gccrs: add math intrinsics arthur.cohen
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Arthur Cohen

From: Arthur Cohen <arthur.cohen@embecosm.com>

We only used one path of the C++ folder's get_nth_callarg function:
CALL_EXPR_ARG. Replace all calls to get_nth_callarg by macro calls to
CALL_EXPR_ARG

gcc/rust/ChangeLog:

	* backend/rust-constexpr.cc (get_nth_callarg): Remove function.
	(rs_bind_parameters_in_call): Use CALL_EXPR_ARG instead.
	(potential_constant_expression_1): Likewise.
---
 gcc/rust/backend/rust-constexpr.cc | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 912d73b5d7c..4e581a3f2cf 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -81,8 +81,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 bool
 potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 				 tsubst_flags_t flags);
-inline tree
-get_nth_callarg (tree t, int n);
 tree
 unshare_constructor (tree t MEM_STAT_DECL);
 void
@@ -3081,7 +3079,7 @@ rs_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
       tree type = parms ? TREE_TYPE (parms) : void_type_node;
       if (parms && DECL_BY_REFERENCE (parms))
 	type = TREE_TYPE (type);
-      x = get_nth_callarg (t, i);
+      x = CALL_EXPR_ARG (t, i);
 
       if (TREE_ADDRESSABLE (type))
 	/* Undo convert_for_arg_passing work here.  */
@@ -4080,17 +4078,6 @@ maybe_constexpr_fn (tree t)
   return (DECL_DECLARED_CONSTEXPR_P (t));
 }
 
-// forked from gcc/cp/constexpr.cc get_nth_callarg
-
-/* We have an expression tree T that represents a call, either CALL_EXPR.
-  Return the Nth argument.  */
-
-inline tree
-get_nth_callarg (tree t, int n)
-{
-  return CALL_EXPR_ARG (t, n);
-}
-
 // forked from gcc/cp/constexpr.cc var_in_maybe_constexpr_fn
 
 /* True if T was declared in a function that might be constexpr: either a
@@ -5808,7 +5795,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 		if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
 		    && !DECL_CONSTRUCTOR_P (fun))
 		  {
-		    tree x = get_nth_callarg (t, 0);
+		    tree x = CALL_EXPR_ARG (t, 0);
 
 		    /* Don't require an immediately constant value, as
 		       constexpr substitution might not use the value.  */
@@ -5837,7 +5824,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 	  }
 	for (; i < nargs; ++i)
 	  {
-	    tree x = get_nth_callarg (t, i);
+	    tree x = CALL_EXPR_ARG (t, i);
 	    /* In a template, reference arguments haven't been converted to
 	       REFERENCE_TYPE and we might not even know if the parameter
 	       is a reference, so accept lvalue constants too.  */
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [committed 103/103] gccrs: add math intrinsics
  2023-02-21 12:00 Rust front-end update arthur.cohen
                   ` (101 preceding siblings ...)
  2023-02-21 12:02 ` [committed 102/103] gccrs: const evaluator: Remove get_nth_callarg arthur.cohen
@ 2023-02-21 12:02 ` arthur.cohen
  102 siblings, 0 replies; 107+ messages in thread
From: arthur.cohen @ 2023-02-21 12:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Raiki Tamura

From: Raiki Tamura <tamaron1203@gmail.com>

gcc/rust/ChangeLog:

	* backend/rust-builtins.cc (BuiltinsContext::setup_math_fns): New functions.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/intrinsics-math.rs: New test.
---
 gcc/rust/backend/rust-builtins.cc             | 122 +++++++++++-
 .../rust/compile/torture/intrinsics-math.rs   | 173 ++++++++++++++++++
 2 files changed, 291 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/torture/intrinsics-math.rs

diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
index 66b3becc47a..0517a9aeaf0 100644
--- a/gcc/rust/backend/rust-builtins.cc
+++ b/gcc/rust/backend/rust-builtins.cc
@@ -59,13 +59,127 @@ BuiltinsContext::setup_overflow_fns ()
 void
 BuiltinsContext::setup_math_fns ()
 {
-  tree math_function_type_f32
+  tree fn_type_f32_to_f32
     = build_function_type_list (float_type_node, float_type_node, NULL_TREE);
+  tree fn_type_f64_to_f64
+    = build_function_type_list (double_type_node, double_type_node, NULL_TREE);
+  tree fn_type_f32_f32_to_f32
+    = build_function_type_list (float_type_node, float_type_node,
+				float_type_node, NULL_TREE);
+  tree fn_type_f64_f64_to_f64
+    = build_function_type_list (double_type_node, double_type_node,
+				double_type_node, NULL_TREE);
+  tree fn_type_f32_i32_to_f32
+    = build_function_type_list (float_type_node, float_type_node,
+				integer_type_node, NULL_TREE);
+  tree fn_type_f64_i32_to_f64
+    = build_function_type_list (double_type_node, double_type_node,
+				integer_type_node, NULL_TREE);
 
-  define_builtin ("sinf32", BUILT_IN_SINF, "__builtin_sinf", "sinf",
-		  math_function_type_f32, builtin_const);
   define_builtin ("sqrtf32", BUILT_IN_SQRTF, "__builtin_sqrtf", "sqrtf",
-		  math_function_type_f32, builtin_const);
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("sqrtf64", BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("powif32", BUILT_IN_POWIF, "__builtin_powif", "powif",
+		  fn_type_f32_i32_to_f32, builtin_const);
+  define_builtin ("powif64", BUILT_IN_POWI, "__builtin_powi", "powi",
+		  fn_type_f64_i32_to_f64, builtin_const);
+
+  define_builtin ("sinf32", BUILT_IN_SINF, "__builtin_sinf", "sinf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("sinf64", BUILT_IN_SIN, "__builtin_sin", "sin",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("cosf32", BUILT_IN_COSF, "__builtin_cosf", "cosf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("cosf64", BUILT_IN_COS, "__builtin_cos", "cos",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("powf32", BUILT_IN_POWF, "__builtin_powf", "powf",
+		  fn_type_f32_f32_to_f32, builtin_const);
+  define_builtin ("powf64", BUILT_IN_POW, "__builtin_pow", "pow",
+		  fn_type_f64_f64_to_f64, builtin_const);
+
+  define_builtin ("expf32", BUILT_IN_EXPF, "__builtin_expf", "expf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("expf64", BUILT_IN_EXP, "__builtin_exp", "exp",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("exp2f32", BUILT_IN_EXP2F, "__builtin_exp2f", "exp2f",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("exp2f64", BUILT_IN_EXP2, "__builtin_exp2", "exp2",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("logf32", BUILT_IN_LOGF, "__builtin_logf", "logf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("logf64", BUILT_IN_LOG, "__builtin_log", "log",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("log10f32", BUILT_IN_LOG10F, "__builtin_log10f", "log10f",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("log10f64", BUILT_IN_LOG10, "__builtin_log10", "log10",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("log2f32", BUILT_IN_LOG2F, "__builtin_log2f", "log2f",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("log2f64", BUILT_IN_LOG2, "__builtin_log2", "log2",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("fmaf32", BUILT_IN_FMAF, "__builtin_fmaf", "fmaf",
+		  fn_type_f32_f32_to_f32, builtin_const);
+  define_builtin ("fmaf64", BUILT_IN_FMA, "__builtin_fma", "fma",
+		  fn_type_f64_f64_to_f64, builtin_const);
+
+  define_builtin ("fabsf32", BUILT_IN_FABSF, "__builtin_fabsf", "fabsf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("fabsf64", BUILT_IN_FABS, "__builtin_fabs", "fabs",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("minnumf32", BUILT_IN_FMINF, "__builtin_fminf", "fminf",
+		  fn_type_f32_f32_to_f32, builtin_const);
+  define_builtin ("minnumf64", BUILT_IN_FMIN, "__builtin_fmin", "fmin",
+		  fn_type_f64_f64_to_f64, builtin_const);
+
+  define_builtin ("maxnumf32", BUILT_IN_FMAXF, "__builtin_fmaxf", "fmaxf",
+		  fn_type_f32_f32_to_f32, builtin_const);
+  define_builtin ("maxnumf64", BUILT_IN_FMAX, "__builtin_fmax", "fmax",
+		  fn_type_f64_f64_to_f64, builtin_const);
+
+  define_builtin ("copysignf32", BUILT_IN_COPYSIGNF, "__builtin_copysignf",
+		  "copysignf", fn_type_f32_f32_to_f32, builtin_const);
+  define_builtin ("copysignf64", BUILT_IN_COPYSIGN, "__builtin_copysign",
+		  "copysign", fn_type_f64_f64_to_f64, builtin_const);
+
+  define_builtin ("floorf32", BUILT_IN_FLOORF, "__builtin_floorf", "floorf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("floorf64", BUILT_IN_FLOOR, "__builtin_floor", "floor",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("ceilf32", BUILT_IN_CEILF, "__builtin_ceilf", "ceilf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("ceilf64", BUILT_IN_CEIL, "__builtin_ceil", "ceil",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("truncf32", BUILT_IN_TRUNCF, "__builtin_truncf", "truncf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("truncf64", BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("rintf32", BUILT_IN_RINTF, "__builtin_rintf", "rintf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("rintf64", BUILT_IN_RINT, "__builtin_rint", "rint",
+		  fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("nearbyintf32", BUILT_IN_NEARBYINTF, "__builtin_nearbyintf",
+		  "nearbyintf", fn_type_f32_to_f32, builtin_const);
+  define_builtin ("nearbyintf64", BUILT_IN_NEARBYINT, "__builtin_nearbyint",
+		  "nearbyint", fn_type_f64_to_f64, builtin_const);
+
+  define_builtin ("roundf32", BUILT_IN_ROUNDF, "__builtin_roundf", "roundf",
+		  fn_type_f32_to_f32, builtin_const);
+  define_builtin ("roundf64", BUILT_IN_ROUND, "__builtin_round", "round",
+		  fn_type_f64_to_f64, builtin_const);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-math.rs b/gcc/testsuite/rust/compile/torture/intrinsics-math.rs
new file mode 100644
index 00000000000..fb329baafdd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-math.rs
@@ -0,0 +1,173 @@
+// { dg-additional-options -fdump-tree-original }
+
+#![feature(intrinsics)]
+extern "rust-intrinsic" {
+    pub fn sqrtf32(x: f32) -> f32;
+    pub fn sqrtf64(x: f64) -> f64;
+
+    pub fn sinf32(x: f32) -> f32;
+    pub fn sinf64(x: f64) -> f64;
+
+    pub fn cosf32(x: f32) -> f32;
+    pub fn cosf64(x: f64) -> f64;
+
+    pub fn powf32(a: f32, x: f32) -> f32;
+    pub fn powf64(a: f64, x: f64) -> f64;
+
+    pub fn expf32(x: f32) -> f32;
+    pub fn expf64(x: f64) -> f64;
+
+    pub fn exp2f32(x: f32) -> f32;
+    pub fn exp2f64(x: f64) -> f64;
+
+    pub fn logf32(x: f32) -> f32;
+    pub fn logf64(x: f64) -> f64;
+
+    pub fn log10f32(x: f32) -> f32;
+    pub fn log10f64(x: f64) -> f64;
+
+    pub fn log2f32(x: f32) -> f32;
+    pub fn log2f64(x: f64) -> f64;
+
+    pub fn fmaf32(a: f32, b: f32, c: f32) -> f32;
+    pub fn fmaf64(a: f64, b: f64, c: f64) -> f64;
+
+    pub fn fabsf32(x: f32) -> f32;
+    pub fn fabsf64(x: f64) -> f64;
+
+    pub fn minnumf32(x: f32, y: f32) -> f32;
+    pub fn minnumf64(x: f64, y: f64) -> f64;
+
+    pub fn maxnumf32(x: f32, y: f32) -> f32;
+    pub fn maxnumf64(x: f64, y: f64) -> f64;
+
+    pub fn copysignf32(x: f32, y: f32) -> f32;
+    pub fn copysignf64(x: f64, y: f64) -> f64;
+
+    pub fn floorf32(x: f32) -> f32;
+    pub fn floorf64(x: f64) -> f64;
+
+    pub fn ceilf32(x: f32) -> f32;
+    pub fn ceilf64(x: f64) -> f64;
+
+    pub fn truncf32(x: f32) -> f32;
+    pub fn truncf64(x: f64) -> f64;
+
+    pub fn rintf32(x: f32) -> f32;
+    pub fn rintf64(x: f64) -> f64;
+
+    pub fn nearbyintf32(x: f32) -> f32;
+    pub fn nearbyintf64(x: f64) -> f64;
+
+    pub fn roundf32(x: f32) -> f32;
+    pub fn roundf64(x: f64) -> f64;
+}
+
+fn main() {
+    unsafe fn foo() {
+        let mut f32;
+        let mut f64;
+
+        f32 = sqrtf32(1f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_sqrtf \(1\.0e\+0\);$} 1 original } }
+        f64 = sqrtf64(2f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_sqrt \(2\.0e\+0\);$} 1 original } }
+
+        f32 = sinf32(39f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_sinf \(3\.9e\+1\);$} 1 original } }
+        f64 = sinf64(40f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_sin \(4\.0e\+1\);$} 1 original } }
+
+        f32 = cosf32(5f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_cosf \(5\.0e\+0\);$} 1 original } }
+        f64 = cosf64(6f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_cos \(6\.0e\+0\);$} 1 original } }
+
+        f32 = powf32(7f32, 8f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_powf \(7\.0e\+0, 8\.0e\+0\);$} 1 original } }
+        f64 = powf64(9f64, 10f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_pow \(9\.0e\+0, 1\.0e\+1\);$} 1 original } }
+
+        f32 = expf32(11f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_expf \(1\.1e\+1\);$} 1 original } }
+        f64 = expf64(12f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_exp \(1\.2e\+1\);$} 1 original } }
+
+        f32 = exp2f32(13f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_expf \(1\.1e\+1\);$} 1 original } }
+        f64 = exp2f64(14f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_exp \(1\.2e\+1\);$} 1 original } }
+
+        f32 = logf32(15f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_logf \(1\.5e\+1\);$} 1 original } }
+        f64 = logf64(16f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_log \(1\.6e\+1\);$} 1 original } }
+
+        f32 = log10f32(17f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_log10f \(1\.7e\+1\);$} 1 original } }
+        f64 = log10f64(18f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_log10 \(1\.8e\+1\);$} 1 original } }
+
+        f32 = log2f32(19f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_log2f \(1\.9e\+1\);$} 1 original } }
+        f64 = log2f64(20f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_log2 \(2\.0e\+1\);$} 1 original } }
+
+        f32 = fmaf32(21f32, 22f32, 23f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_fmaf \(2\.1e\+1, 2\.2e\+1, 2\.3e\+1\);$} 1 original } }
+        f64 = fmaf64(24f64, 25f64, 26f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_fma \(2\.4e\+1, 2\.5e\+1, 2\.6e\+1\);$} 1 original } }
+
+        f32 = fabsf32(27f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_fabsf \(2\.7e\+1\);$} 1 original } }
+        f64 = fabsf64(28f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_fabs \(2\.8e\+1\);$} 1 original } }
+
+        f32 = minnumf32(29f32, 30f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_fminf \(2\.9e\+1, 3\.0e\+1\);$} 1 original } }
+        f64 = minnumf64(31f64, 32f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_fmin \(3\.1e\+1, 3\.2e\+1\);$} 1 original } }
+
+        f32 = maxnumf32(33f32, 34f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_fmaxf \(3\.3e\+1, 3\.4e\+1\);$} 1 original } }
+        f64 = maxnumf64(35f64, 36f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_fmax \(3\.5e\+1, 3\.6e\+1\);$} 1 original } }
+
+        f32 = copysignf32(37f32, 38f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_copysignf \(3\.7e\+1, 3\.8e\+1\);$} 1 original } }
+        f64 = copysignf64(39f64, 40f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_copysign \(3\.9e\+1, 4\.0e\+1\);$} 1 original } }
+
+        f32 = floorf32(41f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_floorf \(4\.1e\+1\);$} 1 original } }
+        f64 = floorf64(42f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_floor \(4\.2e\+1\);$} 1 original } }
+
+        f32 = ceilf32(43f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_ceilf \(4\.3e\+1\);$} 1 original } }
+        f64 = ceilf64(44f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_ceil \(4\.4e\+1\);$} 1 original } }
+
+        f32 = truncf32(45f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_truncf \(4\.5e\+1\);$} 1 original } }
+        f64 = truncf64(46f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_trunc \(4\.6e\+1\);$} 1 original } }
+
+        f32 = rintf32(47f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_rintf \(4\.7e\+1\);$} 1 original } }
+        f64 = rintf64(48f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_rint \(4\.8e\+1\);$} 1 original } }
+
+        f32 = nearbyintf32(49f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_nearbyintf \(4\.9e\+1\);$} 1 original } }
+        f64 = nearbyintf64(50f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_nearbyint \(5\.0e\+1\);$} 1 original } }
+
+        f32 = roundf32(51f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_roundf \(5\.1e\+1\);$} 1 original } }
+        f64 = roundf64(52f64);
+        // { dg-final { scan-tree-dump-times {(?n)f64 = __builtin_round \(5\.2e\+1\);$} 1 original } }
+    }
+
+    unsafe { foo() };
+}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Update copyright years. (was: [committed 003/103] gccrs: dump: Emit visibility when dumping items)
  2023-02-21 12:00 ` [committed 003/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
@ 2023-02-21 12:53   ` Thomas Schwinge
  0 siblings, 0 replies; 107+ messages in thread
From: Thomas Schwinge @ 2023-02-21 12:53 UTC (permalink / raw)
  To: Arthur Cohen, gcc-patches; +Cc: gcc-rust

[-- Attachment #1: Type: text/plain, Size: 938 bytes --]

Hi!

On 2023-02-21T13:00:53+0100, arthur.cohen@embecosm.com wrote:
> --- a/gcc/rust/ast/rust-ast-dump.cc
> +++ b/gcc/rust/ast/rust-ast-dump.cc
> @@ -1,4 +1,4 @@
> -// Copyright (C) 2020-2023 Free Software Foundation, Inc.
> +// Copyright (C) 2020-2022 Free Software Foundation, Inc.

> --- a/gcc/rust/ast/rust-ast-dump.h
> +++ b/gcc/rust/ast/rust-ast-dump.h
> @@ -1,4 +1,4 @@
> -// Copyright (C) 2020-2023 Free Software Foundation, Inc.
> +// Copyright (C) 2020-2022 Free Software Foundation, Inc.

Eh.  ;-)

Pushed to master branch
commit e28c5b33b987374f753b32306b0d3ecf610b64f2
"Update copyright years.", see attached.


Grüße
 Thomas


-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Update-copyright-years.patch --]
[-- Type: text/x-diff, Size: 1210 bytes --]

From e28c5b33b987374f753b32306b0d3ecf610b64f2 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <thomas@codesourcery.com>
Date: Tue, 21 Feb 2023 13:49:42 +0100
Subject: [PATCH] Update copyright years.

... which accidentally had gotten reverted in recent
commit r13-6156-g1e8eb102200902e12c1b00e867e338be0a92c292
"gccrs: dump: Emit visibility when dumping items".
---
 gcc/rust/ast/rust-ast-dump.cc | 2 +-
 gcc/rust/ast/rust-ast-dump.h  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index 131e23ea1801..77e04b972dc0 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+// Copyright (C) 2020-2023 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 4bc322cda988..56918f5fc986 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+// Copyright (C) 2020-2023 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [committed 034/103] gccrs: dump: Emit visibility when dumping items
  2023-02-21 12:01 ` [committed 034/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
@ 2023-02-23  1:01   ` Gerald Pfeifer
  2023-02-23 10:53     ` Arthur Cohen
  0 siblings, 1 reply; 107+ messages in thread
From: Gerald Pfeifer @ 2023-02-23  1:01 UTC (permalink / raw)
  To: Arthur Cohen; +Cc: gcc-patches, gcc-rust

Just noticed this by chance: 

How does this patch constitute a functional change (that matches the 
ChangeLog)? It looks it only adds an empty line to the source code?

Gerald

On Tue, 21 Feb 2023, arthur.cohen@embecosm.com wrote:
> From: Arthur Cohen <arthur.cohen@embecosm.com>
> 
> gcc/rust/ChangeLog:
> 
> 	* ast/rust-ast-dump.cc: Emit visibility when dumping items.
> ---
>  gcc/rust/ast/rust-ast-dump.cc | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
> index fdcd97561bb..b7557bdee0c 100644
> --- a/gcc/rust/ast/rust-ast-dump.cc
> +++ b/gcc/rust/ast/rust-ast-dump.cc
> @@ -835,6 +835,7 @@ void
>  Dump::visit (Function &function)
>  {
>    emit_visibility (function.get_visibility ());
> +
>    stream << "fn " << function.get_function_name ();
>    if (function.has_generics ())
>      emit_generic_params (function.get_generic_params ());


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [committed 034/103] gccrs: dump: Emit visibility when dumping items
  2023-02-23  1:01   ` Gerald Pfeifer
@ 2023-02-23 10:53     ` Arthur Cohen
  0 siblings, 0 replies; 107+ messages in thread
From: Arthur Cohen @ 2023-02-23 10:53 UTC (permalink / raw)
  To: Gerald Pfeifer; +Cc: gcc-patches, gcc-rust


[-- Attachment #1.1.1: Type: text/plain, Size: 1733 bytes --]


On 2/23/23 02:01, Gerald Pfeifer wrote:
> Just noticed this by chance:
> 
> How does this patch constitute a functional change (that matches the
> ChangeLog)? It looks it only adds an empty line to the source code?

Huh. That is weird. Sorry about that!

This range of commits on our AST dump contained commits that did not 
pass the testsuite or bootstrap properly. When trying to get them in 
shape for upstreaming (adding Changelog entries and ensuring that they 
build and pass our tests), I added some of the Changelogs before merging 
invalid commits into valid ones.

I must have made a mistake and should have squashed this commit into 
another one. Sorry about that.

As I mentioned above in the thread, this is the last time that such 
mistakes will happen as we are now enforcing proper Changelogs for all 
commits, and are putting together even more testing.

Kindly,

Arthur

> 
> Gerald
> 
> On Tue, 21 Feb 2023, arthur.cohen@embecosm.com wrote:
>> From: Arthur Cohen <arthur.cohen@embecosm.com>
>>
>> gcc/rust/ChangeLog:
>>
>> 	* ast/rust-ast-dump.cc: Emit visibility when dumping items.
>> ---
>>   gcc/rust/ast/rust-ast-dump.cc | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
>> index fdcd97561bb..b7557bdee0c 100644
>> --- a/gcc/rust/ast/rust-ast-dump.cc
>> +++ b/gcc/rust/ast/rust-ast-dump.cc
>> @@ -835,6 +835,7 @@ void
>>   Dump::visit (Function &function)
>>   {
>>     emit_visibility (function.get_visibility ());
>> +
>>     stream << "fn " << function.get_function_name ();
>>     if (function.has_generics ())
>>       emit_generic_params (function.get_generic_params ());
> 


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3195 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 107+ messages in thread

end of thread, other threads:[~2023-02-23 10:53 UTC | newest]

Thread overview: 107+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-21 12:00 Rust front-end update arthur.cohen
2023-02-21 12:00 ` [committed 001/103] gccrs: Fix missing dead code analysis ICE on local enum definition arthur.cohen
2023-02-21 12:00 ` [committed 002/103] gccrs: visibility: Rename get_public_vis_type -> get_vis_type arthur.cohen
2023-02-21 12:00 ` [committed 003/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
2023-02-21 12:53   ` Update copyright years. (was: [committed 003/103] gccrs: dump: Emit visibility when dumping items) Thomas Schwinge
2023-02-21 12:00 ` [committed 004/103] gccrs: Add catch for recusive type queries arthur.cohen
2023-02-21 12:00 ` [committed 005/103] gccrs: testing: try loop in const function arthur.cohen
2023-02-21 12:00 ` [committed 006/103] gccrs: ast: dump assignment and compound assignment expr arthur.cohen
2023-02-21 12:00 ` [committed 007/103] gccrs: ast: dump If expressions arthur.cohen
2023-02-21 12:00 ` [committed 008/103] gccrs: builtins: Move implementation into source file arthur.cohen
2023-02-21 12:00 ` [committed 009/103] gccrs: Track DefId on ADT variants arthur.cohen
2023-02-21 12:01 ` [committed 010/103] gccrs: Ensure uniqueness on Path probe's arthur.cohen
2023-02-21 12:01 ` [committed 011/103] gccrs: Support looking up super traits for trait items arthur.cohen
2023-02-21 12:01 ` [committed 012/103] gccrs: ast: dump: add emit_generic_params helper arthur.cohen
2023-02-21 12:01 ` [committed 013/103] gccrs: ast: dump: add format_{tuple,struct}_field helpers arthur.cohen
2023-02-21 12:01 ` [committed 014/103] gccrs: ast: dump structs, enums and unions arthur.cohen
2023-02-21 12:01 ` [committed 015/103] gccrs: intrinsics: Add data prefetching intrinsics arthur.cohen
2023-02-21 12:01 ` [committed 016/103] gccrs: fix ICE on missing closing paren arthur.cohen
2023-02-21 12:01 ` [committed 017/103] gccrs: mappings: Add MacroInvocation -> MacroRulesDef mappings arthur.cohen
2023-02-21 12:01 ` [committed 018/103] gccrs: rust-ast-resolve-item: Add note about resolving glob uses arthur.cohen
2023-02-21 12:01 ` [committed 019/103] gccrs: ast: Add accept_vis() method to `GenericArg` arthur.cohen
2023-02-21 12:01 ` [committed 020/103] gccrs: early-name-resolver: Add simple macro name resolution arthur.cohen
2023-02-21 12:01 ` [committed 021/103] gccrs: Support type resolution on super traits on dyn objects arthur.cohen
2023-02-21 12:01 ` [committed 022/103] gccrs: Add mappings for fn_once lang item arthur.cohen
2023-02-21 12:01 ` [committed 023/103] gccrs: Add ABI mappings for rust-call to map to ABI::RUST arthur.cohen
2023-02-21 12:01 ` [committed 024/103] gccrs: Method resolution must support multiple candidates arthur.cohen
2023-02-21 12:01 ` [committed 025/103] gccrs: ast: dump: fix extra newline in block without tail arthur.cohen
2023-02-21 12:01 ` [committed 026/103] gccrs: ast: dump: minor fixups to IfExpr formatting arthur.cohen
2023-02-21 12:01 ` [committed 027/103] gccrs: ast: dump: ComparisonExpr and LazyBooleanExpr arthur.cohen
2023-02-21 12:01 ` [committed 028/103] gccrs: ast: dump: ArrayExpr arthur.cohen
2023-02-21 12:01 ` [committed 029/103] gccrs: ast: dump: various simple Exprs arthur.cohen
2023-02-21 12:01 ` [committed 030/103] gccrs: ast: dump: RangeExprs arthur.cohen
2023-02-21 12:01 ` [committed 031/103] gccrs: Refactor TraitResolver to not require a visitor arthur.cohen
2023-02-21 12:01 ` [committed 032/103] gccrs: ast: dump TypeAlias arthur.cohen
2023-02-21 12:01 ` [committed 033/103] gccrs: Support outer attribute handling on trait items just like normal items arthur.cohen
2023-02-21 12:01 ` [committed 034/103] gccrs: dump: Emit visibility when dumping items arthur.cohen
2023-02-23  1:01   ` Gerald Pfeifer
2023-02-23 10:53     ` Arthur Cohen
2023-02-21 12:01 ` [committed 035/103] gccrs: dump: Dump items within modules arthur.cohen
2023-02-21 12:01 ` [committed 036/103] gccrs: dump: Fix module dumping arthur.cohen
2023-02-21 12:01 ` [committed 037/103] gccrs: ast: Module: unloaded module and inner attributes arthur.cohen
2023-02-21 12:01 ` [committed 038/103] gccrs: dump: Dump macro rules definition arthur.cohen
2023-02-21 12:01 ` [committed 039/103] gccrs: Add check for recursive trait cycles arthur.cohen
2023-02-21 12:01 ` [committed 040/103] gccrs: ast: Refactor ASTFragment -> Fragment class arthur.cohen
2023-02-21 12:01 ` [committed 041/103] gccrs: rust: Replace uses of ASTFragment -> Fragment arthur.cohen
2023-02-21 12:01 ` [committed 042/103] gccrs: ast: Improve Fragment API arthur.cohen
2023-02-21 12:01 ` [committed 043/103] gccrs: Add missing fn_once_output langitem arthur.cohen
2023-02-21 12:01 ` [committed 044/103] gccrs: Refactor expression hir lowering into cc file arthur.cohen
2023-02-21 12:01 ` [committed 045/103] gccrs: Formatting cleanup in HIR lowering pattern arthur.cohen
2023-02-21 12:01 ` [committed 046/103] gccrs: Add name resolution for closures arthur.cohen
2023-02-21 12:01 ` [committed 047/103] gccrs: Refactor method call type checking arthur.cohen
2023-02-21 12:01 ` [committed 048/103] gccrs: Add closures to lints and error checking arthur.cohen
2023-02-21 12:01 ` [committed 049/103] gccrs: Initial Type resolution for closures arthur.cohen
2023-02-21 12:01 ` [committed 050/103] gccrs: Closure support at CallExpr arthur.cohen
2023-02-21 12:01 ` [committed 051/103] gccrs: Add missing name resolution to Function type-path segments arthur.cohen
2023-02-21 12:01 ` [committed 052/103] gccrs: Add missing hir lowering to function " arthur.cohen
2023-02-21 12:01 ` [committed 053/103] gccrs: Add missing type resolution for function type segments arthur.cohen
2023-02-21 12:01 ` [committed 054/103] gccrs: Support Closure calls as generic trait bounds arthur.cohen
2023-02-21 12:01 ` [committed 055/103] gccrs: Implement the inline visitor arthur.cohen
2023-02-21 12:01 ` [committed 056/103] gccrs: rust: Allow gccrs to build on x86_64-apple-darwin with clang/libc++ arthur.cohen
2023-02-21 12:01 ` [committed 057/103] gccrs: builtins: Rename all bang macro handlers arthur.cohen
2023-02-21 12:01 ` [committed 058/103] gccrs: intrinsics: Add `sorry_handler` intrinsic handler arthur.cohen
2023-02-21 12:01 ` [committed 059/103] gccrs: constexpr: Add `rust_sorry_at` in places relying on init values arthur.cohen
2023-02-21 12:01 ` [committed 060/103] gccrs: intrinsics: Add early implementation for atomic_store_{seqcst, relaxed, release} arthur.cohen
2023-02-21 12:01 ` [committed 061/103] gccrs: intrinsics: Add unchecked operation intrinsics arthur.cohen
2023-02-21 12:01 ` [committed 062/103] gccrs: intrinsics: Use lambdas for wrapping_<op> intrinsics arthur.cohen
2023-02-21 12:01 ` [committed 063/103] gccrs: intrinsics: Cleanup error handling around atomic_store_* arthur.cohen
2023-02-21 12:01 ` [committed 064/103] gccrs: intrinsics: Implement atomic_load intrinsics arthur.cohen
2023-02-21 12:01 ` [committed 065/103] gccrs: ast: visitor pattern -> overload syntax compatibility layer arthur.cohen
2023-02-21 12:01 ` [committed 066/103] gccrs: ast: transform helper methods to visits and add methods to simplify repeated patterns arthur.cohen
2023-02-21 12:01 ` [committed 067/103] gccrs: ast: refer correctly to arguments in docs-strings arthur.cohen
2023-02-21 12:01 ` [committed 068/103] gccrs: ast: Dump unit struct arthur.cohen
2023-02-21 12:01 ` [committed 069/103] gccrs: add lang item "phantom_data" arthur.cohen
2023-02-21 12:02 ` [committed 070/103] gccrs: add Location to AST::Visibility arthur.cohen
2023-02-21 12:02 ` [committed 071/103] gccrs: typecheck: Fix overzealous `delete` call arthur.cohen
2023-02-21 12:02 ` [committed 072/103] gccrs: ast: add visit overload for references arthur.cohen
2023-02-21 12:02 ` [committed 073/103] gccrs: ast: Dump where clause and recursively needed nodes arthur.cohen
2023-02-21 12:02 ` [committed 074/103] gccrs: ast: Dump slice type arthur.cohen
2023-02-21 12:02 ` [committed 075/103] gccrs: ast: Dump array type arthur.cohen
2023-02-21 12:02 ` [committed 076/103] gccrs: ast: Dump raw pointer type arthur.cohen
2023-02-21 12:02 ` [committed 077/103] gccrs: ast: Dump never type arthur.cohen
2023-02-21 12:02 ` [committed 078/103] gccrs: ast: Dump tuple type arthur.cohen
2023-02-21 12:02 ` [committed 079/103] gccrs: ast: Dump inferred type arthur.cohen
2023-02-21 12:02 ` [committed 080/103] gccrs: ast: Dump bare function type arthur.cohen
2023-02-21 12:02 ` [committed 081/103] gccrs: ast: Dump impl trait type one bound arthur.cohen
2023-02-21 12:02 ` [committed 082/103] gccrs: ast: Dump impl trait type arthur.cohen
2023-02-21 12:02 ` [committed 083/103] gccrs: ast: Dump trait object type arthur.cohen
2023-02-21 12:02 ` [committed 084/103] gccrs: ast: Dump parenthesised type arthur.cohen
2023-02-21 12:02 ` [committed 085/103] gccrs: ast: Dump trait object type one bound arthur.cohen
2023-02-21 12:02 ` [committed 086/103] gccrs: ast: Dump type param type arthur.cohen
2023-02-21 12:02 ` [committed 087/103] gccrs: ast: Dump generic parameters arthur.cohen
2023-02-21 12:02 ` [committed 088/103] gccrs: ast: Remove unused include in rust-ast-dump.cc arthur.cohen
2023-02-21 12:02 ` [committed 089/103] gccrs: ast: Dump remove /* stmp */ comment to not clutter the dump arthur.cohen
2023-02-21 12:02 ` [committed 090/103] gccrs: ast: Dump no comma after self in fn params if it is the last one arthur.cohen
2023-02-21 12:02 ` [committed 091/103] gccrs: Remove default location. Add visibility location to create_* functions arthur.cohen
2023-02-21 12:02 ` [committed 092/103] gccrs: Improve lexer dump arthur.cohen
2023-02-21 12:02 ` [committed 093/103] gccrs: Get rid of make builtin macro arthur.cohen
2023-02-21 12:02 ` [committed 094/103] gccrs: Refactor name resolver to take a Rib::ItemType arthur.cohen
2023-02-21 12:02 ` [committed 095/103] gccrs: Add closure binding's tracking to name resolution arthur.cohen
2023-02-21 12:02 ` [committed 096/103] gccrs: Add capture tracking to the type info for closures arthur.cohen
2023-02-21 12:02 ` [committed 097/103] gccrs: Add initial support for argument capture of closures arthur.cohen
2023-02-21 12:02 ` [committed 098/103] gccrs: Fix undefined behaviour issues on macos arthur.cohen
2023-02-21 12:02 ` [committed 099/103] gccrs: Skip this debug test case which is failing on the latest mac-os devtools and its only for debug info arthur.cohen
2023-02-21 12:02 ` [committed 100/103] gccrs: Cleanup unused parameters to fix the bootstrap build arthur.cohen
2023-02-21 12:02 ` [committed 101/103] gccrs: Repair 'gcc/rust/lang.opt' comment arthur.cohen
2023-02-21 12:02 ` [committed 102/103] gccrs: const evaluator: Remove get_nth_callarg arthur.cohen
2023-02-21 12:02 ` [committed 103/103] gccrs: add math intrinsics arthur.cohen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).