public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Refactor code to reuse a canonical way to compile functions and constants
@ 2022-06-08 12:05 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:05 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b2aa172ff69591452e3566c105f2a4cd8450eab5

commit b2aa172ff69591452e3566c105f2a4cd8450eab5
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Thu Feb 10 17:08:13 2022 +0000

    Refactor code to reuse a canonical way to compile functions and constants
    
    This is a big cleanup so all paths that compile functions and constants
    end up in the same path so we avoid any duplication in how we actually
    compile a function.

Diff:
---
 gcc/rust/Make-lang.in                         |   2 +
 gcc/rust/backend/rust-compile-base.cc         | 280 ++++++++++++++
 gcc/rust/backend/rust-compile-base.h          |  27 +-
 gcc/rust/backend/rust-compile-expr.cc         |   9 +-
 gcc/rust/backend/rust-compile-extern.h        |   6 -
 gcc/rust/backend/rust-compile-implitem.cc     | 102 ++++++
 gcc/rust/backend/rust-compile-implitem.h      | 504 +-------------------------
 gcc/rust/backend/rust-compile-item.cc         | 202 +++++++++++
 gcc/rust/backend/rust-compile-item.h          | 367 +------------------
 gcc/rust/backend/rust-compile-resolve-path.cc |  10 +-
 gcc/rust/backend/rust-compile-stmt.h          |  28 --
 gcc/rust/backend/rust-compile.cc              | 100 +----
 gcc/rust/hir/tree/rust-hir-item.h             |  16 +-
 gcc/rust/rust-backend.h                       |   4 -
 gcc/rust/rust-gcc.cc                          |  14 -
 15 files changed, 648 insertions(+), 1023 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 660ed235a74..4f762160a54 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -96,6 +96,8 @@ GRS_OBJS = \
     rust/rust-compile-intrinsic.o \
     rust/rust-compile-pattern.o \
     rust/rust-base62.o \
+    rust/rust-compile-item.o \
+    rust/rust-compile-implitem.o \
     rust/rust-compile-expr.o \
     rust/rust-compile-type.o \
     rust/rust-constexpr.o \
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 81598c4dc5b..85d85b907ce 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -17,6 +17,11 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-compile-base.h"
+#include "rust-compile-item.h"
+#include "rust-compile-stmt.h"
+#include "rust-compile-fnparam.h"
+#include "rust-compile-var-decl.h"
+
 #include "fold-const.h"
 #include "stringpool.h"
 
@@ -169,5 +174,280 @@ HIRCompileBase::address_expression (tree expr, Location location)
   return build_fold_addr_expr_loc (location.gcc_location (), expr);
 }
 
+std::vector<Bvariable *>
+HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib,
+					  tree fndecl)
+{
+  std::vector<Bvariable *> locals;
+  rib.iterate_decls ([&] (NodeId n, Location) mutable -> bool {
+    Resolver::Definition d;
+    bool ok = ctx->get_resolver ()->lookup_definition (n, &d);
+    rust_assert (ok);
+
+    HIR::Stmt *decl = nullptr;
+    ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
+    rust_assert (ok);
+
+    // if its a function we extract this out side of this fn context
+    // and it is not a local to this function
+    bool is_item = ctx->get_mappings ()->lookup_hir_item (
+		     decl->get_mappings ().get_crate_num (),
+		     decl->get_mappings ().get_hirid ())
+		   != nullptr;
+    if (is_item)
+      {
+	HIR::Item *item = static_cast<HIR::Item *> (decl);
+	CompileItem::compile (item, ctx);
+	return true;
+      }
+
+    Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
+    locals.push_back (compiled);
+
+    return true;
+  });
+
+  return locals;
+}
+
+void
+HIRCompileBase::compile_function_body (Context *ctx, tree fndecl,
+				       HIR::BlockExpr &function_body,
+				       bool has_return_type)
+{
+  for (auto &s : function_body.get_statements ())
+    {
+      auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
+      if (compiled_expr != nullptr)
+	{
+	  tree compiled_stmt
+	    = ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
+	  ctx->add_statement (compiled_stmt);
+	}
+    }
+
+  if (function_body.has_expr ())
+    {
+      // the previous passes will ensure this is a valid return
+      // or a valid trailing expression
+      tree compiled_expr
+	= CompileExpr::Compile (function_body.expr.get (), ctx);
+
+      if (compiled_expr != nullptr)
+	{
+	  if (has_return_type)
+	    {
+	      std::vector<tree> retstmts;
+	      retstmts.push_back (compiled_expr);
+
+	      auto ret = ctx->get_backend ()->return_statement (
+		fndecl, retstmts,
+		function_body.get_final_expr ()->get_locus ());
+	      ctx->add_statement (ret);
+	    }
+	  else
+	    {
+	      tree final_stmt
+		= ctx->get_backend ()->expression_statement (fndecl,
+							     compiled_expr);
+	      ctx->add_statement (final_stmt);
+	    }
+	}
+    }
+}
+
+tree
+HIRCompileBase::compile_function (
+  Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param,
+  std::vector<HIR::FunctionParam> &function_params,
+  const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
+  AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body,
+  const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype,
+  bool function_has_return)
+{
+  tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+  std::string ir_symbol_name
+    = canonical_path->get () + fntype->subst_as_string ();
+
+  // we don't mangle the main fn since we haven't implemented the main shim
+  bool is_main_fn = fn_name.compare ("main") == 0;
+  std::string asm_name = fn_name;
+  if (!is_main_fn)
+    asm_name = ctx->mangle_item (fntype, *canonical_path);
+
+  unsigned int flags = 0;
+  tree fndecl = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
+					       asm_name, flags, locus);
+  setup_attributes_on_fndecl (fndecl, is_main_fn, !visibility.is_error (),
+			      qualifiers, outer_attrs);
+  setup_abi_options (fndecl, fntype->get_abi ());
+
+  // insert into the context
+  ctx->insert_function_decl (fntype, fndecl);
+
+  // setup the params
+  TyTy::BaseType *tyret = fntype->get_return_type ();
+  std::vector<Bvariable *> param_vars;
+  if (!self_param.is_error ())
+    {
+      rust_assert (fntype->is_method ());
+      TyTy::BaseType *self_tyty_lookup = fntype->get_self_type ();
+
+      tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
+      Bvariable *compiled_self_param
+	= CompileSelfParam::compile (ctx, fndecl, self_param, self_type,
+				     self_param.get_locus ());
+
+      param_vars.push_back (compiled_self_param);
+      ctx->insert_var_decl (self_param.get_mappings ().get_hirid (),
+			    compiled_self_param);
+    }
+
+  // offset from + 1 for the TyTy::FnType being used when this is a method to
+  // skip over Self on the FnType
+  bool is_method = !self_param.is_error ();
+  size_t i = is_method ? 1 : 0;
+  for (auto &referenced_param : function_params)
+    {
+      auto tyty_param = fntype->param_at (i++);
+      auto param_tyty = tyty_param.second;
+      auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
+
+      Location param_locus = referenced_param.get_locus ();
+      Bvariable *compiled_param_var
+	= CompileFnParam::compile (ctx, fndecl, &referenced_param,
+				   compiled_param_type, param_locus);
+
+      param_vars.push_back (compiled_param_var);
+      ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (),
+			    compiled_param_var);
+    }
+
+  if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
+    return error_mark_node;
+
+  // lookup locals
+  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_end_locus ();
+
+  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+						start_location, end_location);
+  ctx->push_block (code_block);
+
+  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, locus,
+						   &ret_var_stmt);
+
+      ctx->add_statement (ret_var_stmt);
+    }
+
+  ctx->push_fn (fndecl, return_address);
+  compile_function_body (ctx, fndecl, *function_body, function_has_return);
+  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
+HIRCompileBase::compile_constant_item (
+  Context *ctx, TyTy::BaseType *resolved_type,
+  const Resolver::CanonicalPath *canonical_path, HIR::Expr *const_value_expr,
+  Location locus)
+{
+  const std::string &ident = canonical_path->get ();
+  tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+  tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
+
+  bool is_block_expr
+    = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block;
+
+  // compile the expression
+  tree folded_expr = error_mark_node;
+  if (!is_block_expr)
+    {
+      tree value = CompileExpr::Compile (const_value_expr, ctx);
+      folded_expr = ConstCtx::fold (value);
+    }
+  else
+    {
+      // in order to compile a block expr we want to reuse as much existing
+      // machineary that we already have. This means the best approach is to
+      // make a _fake_ function with a block so it can hold onto temps then
+      // use our constexpr code to fold it completely or error_mark_node
+      Backend::typed_identifier receiver;
+      tree compiled_fn_type = ctx->get_backend ()->function_type (
+	receiver, {}, {Backend::typed_identifier ("_", const_type, locus)},
+	NULL, locus);
+
+      tree fndecl
+	= ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
+      TREE_READONLY (fndecl) = 1;
+
+      tree enclosing_scope = NULL_TREE;
+      HIR::BlockExpr *function_body
+	= static_cast<HIR::BlockExpr *> (const_value_expr);
+      Location start_location = function_body->get_locus ();
+      Location end_location = function_body->get_end_locus ();
+
+      tree code_block
+	= ctx->get_backend ()->block (fndecl, enclosing_scope, {},
+				      start_location, end_location);
+      ctx->push_block (code_block);
+
+      bool address_is_taken = false;
+      tree ret_var_stmt = NULL_TREE;
+      Bvariable *return_address
+	= ctx->get_backend ()->temporary_variable (fndecl, code_block,
+						   const_type, NULL,
+						   address_is_taken, locus,
+						   &ret_var_stmt);
+
+      ctx->add_statement (ret_var_stmt);
+      ctx->push_fn (fndecl, return_address);
+
+      compile_function_body (ctx, fndecl, *function_body, true);
+      tree bind_tree = ctx->pop_block ();
+
+      gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
+      DECL_SAVED_TREE (fndecl) = bind_tree;
+
+      ctx->pop_fn ();
+
+      // lets fold it into a call expr
+      tree call = build_call_array_loc (locus.gcc_location (), const_type,
+					fndecl, 0, NULL);
+      folded_expr = ConstCtx::fold (call);
+    }
+
+  return ctx->get_backend ()->named_constant_expression (const_type, ident,
+							 folded_expr, locus);
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index ec7535648aa..17e889cd11a 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -35,14 +35,9 @@ protected:
 
   Context *ctx;
 
+protected:
   Context *get_context () { return ctx; }
 
-  void compile_function_body (tree fndecl, HIR::BlockExpr &function_body,
-			      bool has_return_type);
-
-  bool compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
-				 std::vector<Bvariable *> &locals);
-
   tree coercion_site (tree rvalue, TyTy::BaseType *actual,
 		      TyTy::BaseType *expected, Location lvalue_locus,
 		      Location rvalue_locus);
@@ -81,6 +76,26 @@ protected:
   static tree address_expression (tree, Location);
 
   static bool mark_addressable (tree, Location);
+
+  static std::vector<Bvariable *>
+  compile_locals_for_block (Context *ctx, Resolver::Rib &rib, tree fndecl);
+
+  static void compile_function_body (Context *ctx, tree fndecl,
+				     HIR::BlockExpr &function_body,
+				     bool has_return_type);
+
+  static tree compile_function (
+    Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param,
+    std::vector<HIR::FunctionParam> &function_params,
+    const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
+    AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body,
+    const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype,
+    bool function_has_return);
+
+  static tree
+  compile_constant_item (Context *ctx, TyTy::BaseType *resolved_type,
+			 const Resolver::CanonicalPath *canonical_path,
+			 HIR::Expr *const_value_expr, Location locus);
 };
 
 } // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index f65e1fd54c8..ab560e8bf34 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -18,6 +18,7 @@
 
 #include "rust-compile.h"
 #include "rust-compile-item.h"
+#include "rust-compile-implitem.h"
 #include "rust-compile-expr.h"
 #include "rust-compile-struct-field-expr.h"
 #include "rust-hir-trait-resolve.h"
@@ -713,7 +714,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
   tree fn = NULL_TREE;
   if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
     {
-      return ctx->get_backend ()->function_code_expression (fn, expr_locus);
+      return address_expression (fn, expr_locus);
     }
 
   // Now we can try and resolve the address since this might be a forward
@@ -765,8 +766,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
       // contain an implementation we should actually return
       // error_mark_node
 
-      return CompileTraitItem::Compile (receiver,
-					trait_item_ref->get_hir_trait_item (),
+      return CompileTraitItem::Compile (trait_item_ref->get_hir_trait_item (),
 					ctx, fntype, true, expr_locus);
     }
   else
@@ -1343,8 +1343,7 @@ CompileExpr::visit (HIR::IdentifierExpr &expr)
     }
   else if (ctx->lookup_function_decl (ref, &fn))
     {
-      translated
-	= ctx->get_backend ()->function_code_expression (fn, expr.get_locus ());
+      translated = address_expression (fn, expr.get_locus ());
     }
   else if (ctx->lookup_var_decl (ref, &var))
     {
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index 143b240e958..1412e7a42eb 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -21,12 +21,6 @@
 
 #include "rust-compile-base.h"
 #include "rust-compile-intrinsic.h"
-#include "rust-compile-tyty.h"
-#include "rust-compile-implitem.h"
-#include "rust-compile-var-decl.h"
-#include "rust-compile-stmt.h"
-#include "rust-compile-expr.h"
-#include "rust-compile-fnparam.h"
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
new file mode 100644
index 00000000000..8dc18d3c5cc
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -0,0 +1,102 @@
+// 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-compile-implitem.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-fnparam.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+CompileTraitItem::visit (HIR::TraitItemConst &constant)
+{
+  rust_assert (concrete != nullptr);
+  TyTy::BaseType *resolved_type = concrete;
+
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+    constant.get_mappings ().get_crate_num (),
+    constant.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  HIR::Expr *const_value_expr = constant.get_expr ().get ();
+  tree const_expr
+    = compile_constant_item (ctx, resolved_type, canonical_path,
+			     const_value_expr, constant.get_locus ());
+  ctx->push_const (const_expr);
+  ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
+
+  reference = const_expr;
+}
+
+void
+CompileTraitItem::visit (HIR::TraitItemFunc &func)
+{
+  rust_assert (func.has_block_defined ());
+
+  rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+  TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete);
+
+  // items can be forward compiled which means we may not need to invoke this
+  // code. We might also have already compiled this generic function as well.
+  tree lookup = NULL_TREE;
+  if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
+				 fntype->get_id (), fntype))
+    {
+      // has this been added to the list then it must be finished
+      if (ctx->function_completed (lookup))
+	{
+	  tree dummy = NULL_TREE;
+	  if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
+	    {
+	      ctx->insert_function_decl (fntype, lookup);
+	    }
+	  reference = address_expression (lookup, ref_locus);
+	  return;
+	}
+    }
+
+  if (fntype->has_subsititions_defined ())
+    {
+      // override the Hir Lookups for the substituions in this context
+      fntype->override_context ();
+    }
+
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+    func.get_mappings ().get_crate_num (), func.get_mappings ().get_nodeid (),
+    &canonical_path);
+  rust_assert (ok);
+
+  // FIXME
+  HIR::Visibility vis (HIR::Visibility::PublicVisType::NONE,
+		       AST::SimplePath::create_empty ());
+  HIR::TraitFunctionDecl &function = func.get_decl ();
+  tree fndecl
+    = compile_function (ctx, function.get_function_name (),
+			function.get_self (), function.get_function_params (),
+			function.get_qualifiers (), vis,
+			func.get_outer_attrs (), func.get_locus (),
+			func.get_block_expr ().get (), canonical_path, fntype,
+			function.has_return_type ());
+  reference = address_expression (fndecl, ref_locus);
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index 93202767f88..60b7246201d 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -19,19 +19,17 @@
 #ifndef RUST_COMPILE_IMPLITEM_H
 #define RUST_COMPILE_IMPLITEM_H
 
-#include "rust-compile-base.h"
-#include "rust-compile-tyty.h"
-#include "rust-compile-var-decl.h"
-#include "rust-compile-stmt.h"
+#include "rust-compile-item.h"
 #include "rust-compile-expr.h"
 #include "rust-compile-fnparam.h"
 
 namespace Rust {
 namespace Compile {
 
-class CompileInherentImplItem : public HIRCompileBase
+// this is a proxy for HIR::ImplItem's back to use the normel HIR::Item path
+class CompileInherentImplItem : public CompileItem
 {
-  using Rust::Compile::HIRCompileBase::visit;
+  using Rust::Compile::CompileItem::visit;
 
 public:
   static tree Compile (HIR::ImplItem *item, Context *ctx,
@@ -50,265 +48,11 @@ public:
     return compiler.reference;
   }
 
-  void visit (HIR::ConstantItem &constant) override
-  {
-    TyTy::BaseType *resolved_type = nullptr;
-    bool ok
-      = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
-					&resolved_type);
-    rust_assert (ok);
-
-    tree type = TyTyResolveCompile::compile (ctx, resolved_type);
-    tree value = CompileExpr::Compile (constant.get_expr (), ctx);
-
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    ok = ctx->get_mappings ()->lookup_canonical_path (
-      constant.get_mappings ().get_crate_num (),
-      constant.get_mappings ().get_nodeid (), &canonical_path);
-    rust_assert (ok);
-
-    std::string ident = canonical_path->get ();
-    tree const_expr = ctx->get_backend ()->named_constant_expression (
-      type, constant.get_identifier (), value, constant.get_locus ());
-
-    ctx->push_const (const_expr);
-    ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
-
-    reference = const_expr;
-  }
-
-  void visit (HIR::Function &function) override
-  {
-    TyTy::BaseType *fntype_tyty;
-    if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
-					 &fntype_tyty))
-      {
-	rust_fatal_error (function.get_locus (),
-			  "failed to lookup function type");
-	return;
-      }
-
-    rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
-    TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
-    if (fntype->has_subsititions_defined ())
-      {
-	// we cant do anything for this only when it is used and a concrete type
-	// is given
-	if (concrete == nullptr)
-	  return;
-	else
-	  {
-	    rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
-	    fntype = static_cast<TyTy::FnType *> (concrete);
-	  }
-      }
-
-    // items can be forward compiled which means we may not need to invoke this
-    // code. We might also have already compiled this generic function as well.
-    tree lookup = NULL_TREE;
-    if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-				   fntype->get_id (), fntype))
-      {
-	// has this been added to the list then it must be finished
-	if (ctx->function_completed (lookup))
-	  {
-	    tree dummy = NULL_TREE;
-	    if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
-	      {
-		ctx->insert_function_decl (fntype, lookup);
-	      }
-	    reference
-	      = ctx->get_backend ()->function_code_expression (lookup,
-							       ref_locus);
-	    return;
-	  }
-      }
-
-    if (fntype->has_subsititions_defined ())
-      {
-	// override the Hir Lookups for the substituions in this context
-	fntype->override_context ();
-      }
-
-    // convert to the actual function type
-    tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    bool ok = ctx->get_mappings ()->lookup_canonical_path (
-      function.get_mappings ().get_crate_num (),
-      function.get_mappings ().get_nodeid (), &canonical_path);
-    rust_assert (ok);
-
-    std::string ir_symbol_name
-      = canonical_path->get () + fntype->subst_as_string ();
-    std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
-
-    unsigned int flags = 0;
-    tree fndecl
-      = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
-				       asm_name, flags, function.get_locus ());
-    setup_attributes_on_fndecl (fndecl, false, function.has_visibility (),
-				function.get_qualifiers (),
-				function.get_outer_attrs ());
-    ctx->insert_function_decl (fntype, fndecl);
-
-    // setup the params
-    TyTy::BaseType *tyret = fntype->get_return_type ();
-    std::vector<Bvariable *> param_vars;
-
-    if (function.is_method ())
-      {
-	// insert self
-	TyTy::BaseType *self_tyty_lookup = nullptr;
-	if (!ctx->get_tyctx ()->lookup_type (
-	      function.get_self_param ().get_mappings ().get_hirid (),
-	      &self_tyty_lookup))
-	  {
-	    rust_error_at (function.get_self_param ().get_locus (),
-			   "failed to lookup self param type");
-	    return;
-	  }
-
-	tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
-	if (self_type == nullptr)
-	  {
-	    rust_error_at (function.get_self_param ().get_locus (),
-			   "failed to compile self param type");
-	    return;
-	  }
-
-	Bvariable *compiled_self_param
-	  = CompileSelfParam::compile (ctx, fndecl, function.get_self_param (),
-				       self_type,
-				       function.get_self_param ().get_locus ());
-	if (compiled_self_param == nullptr)
-	  {
-	    rust_error_at (function.get_self_param ().get_locus (),
-			   "failed to compile self param variable");
-	    return;
-	  }
-
-	param_vars.push_back (compiled_self_param);
-	ctx->insert_var_decl (
-	  function.get_self_param ().get_mappings ().get_hirid (),
-	  compiled_self_param);
-      }
-
-    // offset from + 1 for the TyTy::FnType being used when this is a method to
-    // skip over Self on the FnType
-    size_t i = function.is_method () ? 1 : 0;
-    for (auto referenced_param : function.get_function_params ())
-      {
-	auto tyty_param = fntype->param_at (i);
-	auto param_tyty = tyty_param.second;
-
-	auto compiled_param_type
-	  = TyTyResolveCompile::compile (ctx, param_tyty);
-	if (compiled_param_type == nullptr)
-	  {
-	    rust_error_at (referenced_param.get_locus (),
-			   "failed to compile parameter type");
-	    return;
-	  }
-
-	Location param_locus
-	  = ctx->get_mappings ()->lookup_location (param_tyty->get_ref ());
-	Bvariable *compiled_param_var
-	  = CompileFnParam::compile (ctx, fndecl, &referenced_param,
-				     compiled_param_type, param_locus);
-	if (compiled_param_var == nullptr)
-	  {
-	    rust_error_at (param_locus, "Failed to compile parameter variable");
-	    return;
-	  }
-
-	param_vars.push_back (compiled_param_var);
-
-	ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (),
-			      compiled_param_var);
-	i++;
-      }
-
-    if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
-      {
-	rust_fatal_error (function.get_locus (),
-			  "failed to setup parameter variables");
-	return;
-      }
-
-    // lookup locals
-    auto block_expr = function.get_definition ().get ();
-    auto body_mappings = block_expr->get_mappings ();
-
-    Resolver::Rib *rib = nullptr;
-    if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
-					      &rib))
-      {
-	rust_fatal_error (function.get_locus (),
-			  "failed to setup locals per block");
-	return;
-      }
-
-    std::vector<Bvariable *> locals;
-    ok = compile_locals_for_block (*rib, fndecl, locals);
-    rust_assert (ok);
-
-    tree enclosing_scope = NULL_TREE;
-    HIR::BlockExpr *function_body = function.get_definition ().get ();
-    Location start_location = function_body->get_locus ();
-    Location end_location = function_body->get_end_locus ();
-
-    tree code_block
-      = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
-				    start_location, end_location);
-    ctx->push_block (code_block);
-
-    Bvariable *return_address = nullptr;
-    if (function.has_function_return_type ())
-      {
-	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,
-	  function.get_locus (), &ret_var_stmt);
-
-	ctx->add_statement (ret_var_stmt);
-      }
-
-    ctx->push_fn (fndecl, return_address);
-
-    compile_function_body (fndecl, *function.get_definition ().get (),
-			   function.has_function_return_type ());
-
-    ctx->pop_block ();
-    auto body = ctx->get_backend ()->block_statement (code_block);
-    if (!ctx->get_backend ()->function_set_body (fndecl, body))
-      {
-	rust_error_at (function.get_locus (), "failed to set body to function");
-	return;
-      }
-
-    ctx->pop_fn ();
-    ctx->push_function (fndecl);
-
-    reference
-      = ctx->get_backend ()->function_code_expression (fndecl, ref_locus);
-  }
-
 private:
   CompileInherentImplItem (Context *ctx, TyTy::BaseType *concrete,
 			   Location ref_locus)
-    : HIRCompileBase (ctx), concrete (concrete),
-      reference (ctx->get_backend ()->error_expression ()),
-      ref_locus (ref_locus)
+    : CompileItem (ctx, concrete, ref_locus)
   {}
-
-  TyTy::BaseType *concrete;
-  tree reference;
-  Location ref_locus;
 };
 
 class CompileTraitItem : public HIRCompileBase
@@ -316,12 +60,11 @@ class CompileTraitItem : public HIRCompileBase
   using Rust::Compile::HIRCompileBase::visit;
 
 public:
-  static tree Compile (const TyTy::BaseType *self, HIR::TraitItem *item,
-		       Context *ctx, TyTy::BaseType *concrete,
-		       bool is_query_mode = false,
+  static tree Compile (HIR::TraitItem *item, Context *ctx,
+		       TyTy::BaseType *concrete, bool is_query_mode = false,
 		       Location ref_locus = Location ())
   {
-    CompileTraitItem compiler (self, ctx, concrete, ref_locus);
+    CompileTraitItem compiler (ctx, concrete, ref_locus);
     item->accept_vis (compiler);
 
     if (is_query_mode
@@ -332,240 +75,17 @@ public:
     return compiler.reference;
   }
 
-  void visit (HIR::TraitItemConst &constant) override
-  {
-    rust_assert (concrete != nullptr);
-    TyTy::BaseType *resolved_type = concrete;
-
-    tree type = TyTyResolveCompile::compile (ctx, resolved_type);
-    tree value = CompileExpr::Compile (constant.get_expr ().get (), ctx);
-
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    bool ok = ctx->get_mappings ()->lookup_canonical_path (
-      constant.get_mappings ().get_crate_num (),
-      constant.get_mappings ().get_nodeid (), &canonical_path);
-    rust_assert (ok);
-
-    std::string ident = canonical_path->get ();
-    tree const_expr = ctx->get_backend ()->named_constant_expression (
-      type, constant.get_name (), value, constant.get_locus ());
-
-    ctx->push_const (const_expr);
-    ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
-
-    reference = const_expr;
-  }
-
-  void visit (HIR::TraitItemFunc &func) override
-  {
-    rust_assert (func.has_block_defined ());
-
-    rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
-    TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete);
-
-    // items can be forward compiled which means we may not need to invoke this
-    // code. We might also have already compiled this generic function as well.
-    tree lookup = NULL_TREE;
-    if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-				   fntype->get_id (), fntype))
-      {
-	// has this been added to the list then it must be finished
-	if (ctx->function_completed (lookup))
-	  {
-	    tree dummy = NULL_TREE;
-	    if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
-	      {
-		ctx->insert_function_decl (fntype, lookup);
-	      }
-	    reference
-	      = ctx->get_backend ()->function_code_expression (lookup,
-							       ref_locus);
-	    return;
-	  }
-      }
-
-    if (fntype->has_subsititions_defined ())
-      {
-	// override the Hir Lookups for the substituions in this context
-	fntype->override_context ();
-      }
-
-    // convert to the actual function type
-    tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-    HIR::TraitFunctionDecl &function = func.get_decl ();
-
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    bool ok = ctx->get_mappings ()->lookup_canonical_path (
-      func.get_mappings ().get_crate_num (), func.get_mappings ().get_nodeid (),
-      &canonical_path);
-    rust_assert (ok);
-
-    std::string fn_identifier = canonical_path->get ();
-    std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
-
-    unsigned int flags = 0;
-    tree fndecl
-      = ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
-				       asm_name, flags, func.get_locus ());
-    setup_attributes_on_fndecl (fndecl, false, false,
-				func.get_decl ().get_qualifiers (),
-				func.get_outer_attrs ());
-    ctx->insert_function_decl (fntype, fndecl);
-
-    // setup the params
-    TyTy::BaseType *tyret = fntype->get_return_type ();
-    std::vector<Bvariable *> param_vars;
-
-    if (function.is_method ())
-      {
-	// insert self
-	TyTy::BaseType *self_tyty_lookup = nullptr;
-	if (!ctx->get_tyctx ()->lookup_type (
-	      function.get_self ().get_mappings ().get_hirid (),
-	      &self_tyty_lookup))
-	  {
-	    rust_error_at (function.get_self ().get_locus (),
-			   "failed to lookup self param type");
-	    return;
-	  }
-
-	tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
-	if (self_type == nullptr)
-	  {
-	    rust_error_at (function.get_self ().get_locus (),
-			   "failed to compile self param type");
-	    return;
-	  }
+  void visit (HIR::TraitItemConst &constant) override;
 
-	Bvariable *compiled_self_param
-	  = CompileSelfParam::compile (ctx, fndecl, function.get_self (),
-				       self_type,
-				       function.get_self ().get_locus ());
-	if (compiled_self_param == nullptr)
-	  {
-	    rust_error_at (function.get_self ().get_locus (),
-			   "failed to compile self param variable");
-	    return;
-	  }
-
-	param_vars.push_back (compiled_self_param);
-	ctx->insert_var_decl (function.get_self ().get_mappings ().get_hirid (),
-			      compiled_self_param);
-      }
-
-    // offset from + 1 for the TyTy::FnType being used when this is a method to
-    // skip over Self on the FnType
-    size_t i = function.is_method () ? 1 : 0;
-    for (auto referenced_param : function.get_function_params ())
-      {
-	auto tyty_param = fntype->param_at (i);
-	auto param_tyty = tyty_param.second;
-
-	auto compiled_param_type
-	  = TyTyResolveCompile::compile (ctx, param_tyty);
-	if (compiled_param_type == nullptr)
-	  {
-	    rust_error_at (referenced_param.get_locus (),
-			   "failed to compile parameter type");
-	    return;
-	  }
-
-	Location param_locus
-	  = ctx->get_mappings ()->lookup_location (param_tyty->get_ref ());
-	Bvariable *compiled_param_var
-	  = CompileFnParam::compile (ctx, fndecl, &referenced_param,
-				     compiled_param_type, param_locus);
-	if (compiled_param_var == nullptr)
-	  {
-	    rust_error_at (param_locus, "Failed to compile parameter variable");
-	    return;
-	  }
-
-	param_vars.push_back (compiled_param_var);
-
-	ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (),
-			      compiled_param_var);
-	i++;
-      }
-
-    if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
-      {
-	rust_fatal_error (func.get_locus (),
-			  "failed to setup parameter variables");
-	return;
-      }
-
-    // lookup locals
-    auto block_expr = func.get_block_expr ().get ();
-    auto body_mappings = block_expr->get_mappings ();
-
-    Resolver::Rib *rib = nullptr;
-    if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
-					      &rib))
-      {
-	rust_fatal_error (func.get_locus (),
-			  "failed to setup locals per block");
-	return;
-      }
-
-    std::vector<Bvariable *> locals;
-    ok = compile_locals_for_block (*rib, fndecl, locals);
-    rust_assert (ok);
-
-    tree enclosing_scope = NULL_TREE;
-    HIR::BlockExpr *function_body = func.get_block_expr ().get ();
-    Location start_location = function_body->get_locus ();
-    Location end_location = function_body->get_end_locus ();
-
-    tree code_block
-      = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
-				    start_location, end_location);
-    ctx->push_block (code_block);
-
-    Bvariable *return_address = nullptr;
-    if (function.has_return_type ())
-      {
-	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,
-	  func.get_locus (), &ret_var_stmt);
-
-	ctx->add_statement (ret_var_stmt);
-      }
-
-    ctx->push_fn (fndecl, return_address);
-
-    compile_function_body (fndecl, *func.get_block_expr ().get (),
-			   function.has_return_type ());
-
-    ctx->pop_block ();
-    auto body = ctx->get_backend ()->block_statement (code_block);
-    if (!ctx->get_backend ()->function_set_body (fndecl, body))
-      {
-	rust_error_at (func.get_locus (), "failed to set body to function");
-	return;
-      }
-
-    ctx->pop_fn ();
-    ctx->push_function (fndecl);
-
-    reference
-      = ctx->get_backend ()->function_code_expression (fndecl, ref_locus);
-  }
+  void visit (HIR::TraitItemFunc &func) override;
 
 private:
-  CompileTraitItem (const TyTy::BaseType *self, Context *ctx,
-		    TyTy::BaseType *concrete, Location ref_locus)
-    : HIRCompileBase (ctx), self (self), concrete (concrete),
+  CompileTraitItem (Context *ctx, TyTy::BaseType *concrete, Location ref_locus)
+    : HIRCompileBase (ctx), concrete (concrete),
       reference (ctx->get_backend ()->error_expression ()),
       ref_locus (ref_locus)
   {}
 
-  const TyTy::BaseType *self;
   TyTy::BaseType *concrete;
   tree reference;
   Location ref_locus;
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
new file mode 100644
index 00000000000..d42cc1ef998
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -0,0 +1,202 @@
+// 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-compile-item.h"
+#include "rust-compile-implitem.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-extern.h"
+#include "rust-constexpr.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+CompileItem::visit (HIR::StaticItem &var)
+{
+  // have we already compiled this?
+  Bvariable *static_decl_ref = nullptr;
+  if (ctx->lookup_var_decl (var.get_mappings ().get_hirid (), &static_decl_ref))
+    {
+      reference
+	= ctx->get_backend ()->var_expression (static_decl_ref, ref_locus);
+      return;
+    }
+
+  TyTy::BaseType *resolved_type = nullptr;
+  bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
+					    &resolved_type);
+  rust_assert (ok);
+
+  tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+  tree value = CompileExpr::Compile (var.get_expr (), ctx);
+
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  ok = ctx->get_mappings ()->lookup_canonical_path (
+    var.get_mappings ().get_crate_num (), var.get_mappings ().get_nodeid (),
+    &canonical_path);
+  rust_assert (ok);
+
+  std::string name = canonical_path->get ();
+  std::string asm_name = ctx->mangle_item (resolved_type, *canonical_path);
+
+  bool is_external = false;
+  bool is_hidden = false;
+  bool in_unique_section = true;
+
+  Bvariable *static_global
+    = ctx->get_backend ()->global_variable (name, asm_name, type, is_external,
+					    is_hidden, in_unique_section,
+					    var.get_locus ());
+  ctx->get_backend ()->global_variable_set_init (static_global, value);
+
+  ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global);
+  ctx->push_var (static_global);
+
+  reference = ctx->get_backend ()->var_expression (static_global, ref_locus);
+}
+
+void
+CompileItem::visit (HIR::ConstantItem &constant)
+{
+  // resolve the type
+  TyTy::BaseType *resolved_type = nullptr;
+  bool ok
+    = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
+				      &resolved_type);
+  rust_assert (ok);
+
+  // canonical path
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  ok = ctx->get_mappings ()->lookup_canonical_path (
+    constant.get_mappings ().get_crate_num (),
+    constant.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  HIR::Expr *const_value_expr = constant.get_expr ();
+  tree const_expr
+    = compile_constant_item (ctx, resolved_type, canonical_path,
+			     const_value_expr, constant.get_locus ());
+
+  ctx->push_const (const_expr);
+  ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
+  reference = const_expr;
+}
+
+void
+CompileItem::visit (HIR::Function &function)
+{
+  TyTy::BaseType *fntype_tyty;
+  if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
+				       &fntype_tyty))
+    {
+      rust_fatal_error (function.get_locus (),
+			"failed to lookup function type");
+      return;
+    }
+
+  rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
+  TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
+  if (fntype->has_subsititions_defined ())
+    {
+      // we cant do anything for this only when it is used and a concrete type
+      // is given
+      if (concrete == nullptr)
+	return;
+      else
+	{
+	  rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+	  fntype = static_cast<TyTy::FnType *> (concrete);
+	}
+    }
+
+  // items can be forward compiled which means we may not need to invoke this
+  // code. We might also have already compiled this generic function as well.
+  tree lookup = NULL_TREE;
+  if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
+				 fntype->get_id (), fntype))
+    {
+      // has this been added to the list then it must be finished
+      if (ctx->function_completed (lookup))
+	{
+	  tree dummy = NULL_TREE;
+	  if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
+	    {
+	      ctx->insert_function_decl (fntype, lookup);
+	    }
+
+	  reference = address_expression (lookup, ref_locus);
+	  return;
+	}
+    }
+
+  if (fntype->has_subsititions_defined ())
+    {
+      // override the Hir Lookups for the substituions in this context
+      fntype->override_context ();
+    }
+
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+    function.get_mappings ().get_crate_num (),
+    function.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  tree fndecl
+    = compile_function (ctx, function.get_function_name (),
+			function.get_self_param (),
+			function.get_function_params (),
+			function.get_qualifiers (), function.get_visibility (),
+			function.get_outer_attrs (), function.get_locus (),
+			function.get_definition ().get (), canonical_path,
+			fntype, function.has_function_return_type ());
+  reference = address_expression (fndecl, ref_locus);
+}
+
+void
+CompileItem::visit (HIR::ImplBlock &impl_block)
+{
+  TyTy::BaseType *self_lookup = nullptr;
+  if (!ctx->get_tyctx ()->lookup_type (
+	impl_block.get_type ()->get_mappings ().get_hirid (), &self_lookup))
+    {
+      rust_error_at (impl_block.get_locus (), "failed to resolve type of impl");
+      return;
+    }
+
+  for (auto &impl_item : impl_block.get_impl_items ())
+    CompileInherentImplItem::Compile (impl_item.get (), ctx);
+}
+
+void
+CompileItem::visit (HIR::ExternBlock &extern_block)
+{
+  for (auto &item : extern_block.get_extern_items ())
+    {
+      CompileExternItem::compile (item.get (), ctx, concrete);
+    }
+}
+
+void
+CompileItem::visit (HIR::Module &module)
+{
+  for (auto &item : module.get_items ())
+    CompileItem::compile (item.get (), ctx);
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 70b54155fad..71f259f0643 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -20,14 +20,6 @@
 #define RUST_COMPILE_ITEM
 
 #include "rust-compile-base.h"
-#include "rust-compile-tyty.h"
-#include "rust-compile-implitem.h"
-#include "rust-compile-var-decl.h"
-#include "rust-compile-stmt.h"
-#include "rust-compile-expr.h"
-#include "rust-compile-fnparam.h"
-#include "rust-compile-extern.h"
-#include "rust-constexpr.h"
 
 namespace Rust {
 namespace Compile {
@@ -54,364 +46,17 @@ public:
     return compiler.reference;
   }
 
-  void visit (HIR::StaticItem &var) override
-  {
-    // have we already compiled this?
-    Bvariable *static_decl_ref = nullptr;
-    if (ctx->lookup_var_decl (var.get_mappings ().get_hirid (),
-			      &static_decl_ref))
-      {
-	reference
-	  = ctx->get_backend ()->var_expression (static_decl_ref, ref_locus);
-	return;
-      }
-
-    TyTy::BaseType *resolved_type = nullptr;
-    bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
-					      &resolved_type);
-    rust_assert (ok);
-
-    tree type = TyTyResolveCompile::compile (ctx, resolved_type);
-    tree value = CompileExpr::Compile (var.get_expr (), ctx);
-
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    ok = ctx->get_mappings ()->lookup_canonical_path (
-      var.get_mappings ().get_crate_num (), var.get_mappings ().get_nodeid (),
-      &canonical_path);
-    rust_assert (ok);
-
-    std::string name = canonical_path->get ();
-    std::string asm_name = ctx->mangle_item (resolved_type, *canonical_path);
-
-    bool is_external = false;
-    bool is_hidden = false;
-    bool in_unique_section = true;
-
-    Bvariable *static_global
-      = ctx->get_backend ()->global_variable (name, asm_name, type, is_external,
-					      is_hidden, in_unique_section,
-					      var.get_locus ());
-    ctx->get_backend ()->global_variable_set_init (static_global, value);
-
-    ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global);
-    ctx->push_var (static_global);
-
-    reference = ctx->get_backend ()->var_expression (static_global, ref_locus);
-  }
-
-  void visit (HIR::ConstantItem &constant) override
-  {
-    // resolve the type
-    TyTy::BaseType *resolved_type = nullptr;
-    bool ok
-      = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
-					&resolved_type);
-    rust_assert (ok);
-
-    // canonical path
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    ok = ctx->get_mappings ()->lookup_canonical_path (
-      constant.get_mappings ().get_crate_num (),
-      constant.get_mappings ().get_nodeid (), &canonical_path);
-    rust_assert (ok);
-    std::string ident = canonical_path->get ();
-
-    // types
-    tree type = TyTyResolveCompile::compile (ctx, resolved_type);
-    tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
-
-    HIR::Expr *const_value_expr = constant.get_expr ();
-    bool is_block_expr
-      = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block;
-
-    // compile the expression
-    tree folded_expr = error_mark_node;
-    if (!is_block_expr)
-      {
-	tree value = CompileExpr::Compile (constant.get_expr (), ctx);
-	folded_expr = ConstCtx::fold (value);
-      }
-    else
-      {
-	// in order to compile a block expr we want to reuse as much existing
-	// machineary that we already have. This means the best approach is to
-	// make a _fake_ function with a block so it can hold onto temps then
-	// use our constexpr code to fold it completely or error_mark_node
-	Backend::typed_identifier receiver;
-	tree compiled_fn_type = ctx->get_backend ()->function_type (
-	  receiver, {},
-	  {Backend::typed_identifier ("_", const_type, constant.get_locus ())},
-	  NULL, constant.get_locus ());
-
-	tree fndecl
-	  = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0,
-					   constant.get_locus ());
-	TREE_READONLY (fndecl) = 1;
-
-	tree enclosing_scope = NULL_TREE;
-	HIR::BlockExpr *function_body
-	  = static_cast<HIR::BlockExpr *> (constant.get_expr ());
-	Location start_location = function_body->get_locus ();
-	Location end_location = function_body->get_end_locus ();
-
-	tree code_block
-	  = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
-					start_location, end_location);
-	ctx->push_block (code_block);
-
-	bool address_is_taken = false;
-	tree ret_var_stmt = NULL_TREE;
-	Bvariable *return_address = ctx->get_backend ()->temporary_variable (
-	  fndecl, code_block, const_type, NULL, address_is_taken,
-	  constant.get_locus (), &ret_var_stmt);
-
-	ctx->add_statement (ret_var_stmt);
-	ctx->push_fn (fndecl, return_address);
-
-	compile_function_body (fndecl, *function_body, true);
-
-	ctx->pop_block ();
-
-	auto body = ctx->get_backend ()->block_statement (code_block);
-	if (!ctx->get_backend ()->function_set_body (fndecl, body))
-	  {
-	    rust_error_at (constant.get_locus (),
-			   "failed to set body to constant function");
-	    return;
-	  }
-
-	ctx->pop_fn ();
-
-	// lets fold it into a call expr
-	tree call = build_call_array_loc (constant.get_locus ().gcc_location (),
-					  const_type, fndecl, 0, NULL);
-	folded_expr = ConstCtx::fold (call);
-      }
-
-    tree const_expr
-      = ctx->get_backend ()->named_constant_expression (const_type, ident,
-							folded_expr,
-							constant.get_locus ());
-
-    ctx->push_const (const_expr);
-    ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
-
-    reference = const_expr;
-  }
-
-  void visit (HIR::Function &function) override
-  {
-    TyTy::BaseType *fntype_tyty;
-    if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
-					 &fntype_tyty))
-      {
-	rust_fatal_error (function.get_locus (),
-			  "failed to lookup function type");
-	return;
-      }
-
-    rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
-    TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
-    if (fntype->has_subsititions_defined ())
-      {
-	// we cant do anything for this only when it is used and a concrete type
-	// is given
-	if (concrete == nullptr)
-	  return;
-	else
-	  {
-	    rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
-	    fntype = static_cast<TyTy::FnType *> (concrete);
-	  }
-      }
-
-    // items can be forward compiled which means we may not need to invoke this
-    // code. We might also have already compiled this generic function as well.
-    tree lookup = NULL_TREE;
-    if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-				   fntype->get_id (), fntype))
-      {
-	// has this been added to the list then it must be finished
-	if (ctx->function_completed (lookup))
-	  {
-	    tree dummy = NULL_TREE;
-	    if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
-	      {
-		ctx->insert_function_decl (fntype, lookup);
-	      }
+  void visit (HIR::StaticItem &var) override;
 
-	    reference
-	      = ctx->get_backend ()->function_code_expression (lookup,
-							       ref_locus);
-	    return;
-	  }
-      }
+  void visit (HIR::ConstantItem &constant) override;
 
-    if (fntype->has_subsititions_defined ())
-      {
-	// override the Hir Lookups for the substituions in this context
-	fntype->override_context ();
-      }
+  void visit (HIR::Function &function) override;
 
-    tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+  void visit (HIR::ImplBlock &impl_block) override;
 
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    bool ok = ctx->get_mappings ()->lookup_canonical_path (
-      function.get_mappings ().get_crate_num (),
-      function.get_mappings ().get_nodeid (), &canonical_path);
-    rust_assert (ok);
+  void visit (HIR::ExternBlock &extern_block) override;
 
-    std::string ir_symbol_name
-      = canonical_path->get () + fntype->subst_as_string ();
-    std::string asm_name = function.get_function_name ();
-
-    // we don't mangle the main fn since we haven't implemented the main shim
-    // yet
-    bool is_main_fn = function.get_function_name ().compare ("main") == 0;
-    if (!is_main_fn)
-      {
-	asm_name = ctx->mangle_item (fntype, *canonical_path);
-      }
-
-    unsigned int flags = 0;
-    tree fndecl
-      = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
-				       asm_name, flags, function.get_locus ());
-    setup_attributes_on_fndecl (fndecl, is_main_fn, function.has_visibility (),
-				function.get_qualifiers (),
-				function.get_outer_attrs ());
-
-    // insert into the context
-    ctx->insert_function_decl (fntype, fndecl);
-
-    // setup the params
-    TyTy::BaseType *tyret = fntype->get_return_type ();
-    std::vector<Bvariable *> param_vars;
-
-    size_t i = 0;
-    for (auto &it : fntype->get_params ())
-      {
-	HIR::FunctionParam &referenced_param
-	  = function.get_function_params ().at (i);
-	auto param_tyty = it.second;
-	auto compiled_param_type
-	  = TyTyResolveCompile::compile (ctx, param_tyty);
-
-	Location param_locus
-	  = ctx->get_mappings ()->lookup_location (param_tyty->get_ref ());
-	Bvariable *compiled_param_var
-	  = CompileFnParam::compile (ctx, fndecl, &referenced_param,
-				     compiled_param_type, param_locus);
-	if (compiled_param_var == nullptr)
-	  {
-	    rust_error_at (param_locus, "failed to compile parameter variable");
-	    return;
-	  }
-
-	param_vars.push_back (compiled_param_var);
-
-	ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (),
-			      compiled_param_var);
-	i++;
-      }
-
-    if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
-      {
-	rust_fatal_error (function.get_locus (),
-			  "failed to setup parameter variables");
-	return;
-      }
-
-    // lookup locals
-    auto block_expr = function.get_definition ().get ();
-    auto body_mappings = block_expr->get_mappings ();
-
-    Resolver::Rib *rib = nullptr;
-    if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
-					      &rib))
-      {
-	rust_fatal_error (function.get_locus (),
-			  "failed to setup locals per block");
-	return;
-      }
-
-    std::vector<Bvariable *> locals;
-    ok = compile_locals_for_block (*rib, fndecl, locals);
-    rust_assert (ok);
-
-    tree enclosing_scope = NULL_TREE;
-    HIR::BlockExpr *function_body = function.get_definition ().get ();
-    Location start_location = function_body->get_locus ();
-    Location end_location = function_body->get_end_locus ();
-
-    tree code_block
-      = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
-				    start_location, end_location);
-    ctx->push_block (code_block);
-
-    Bvariable *return_address = nullptr;
-    if (function.has_function_return_type ())
-      {
-	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,
-	  function.get_locus (), &ret_var_stmt);
-
-	ctx->add_statement (ret_var_stmt);
-      }
-
-    ctx->push_fn (fndecl, return_address);
-
-    compile_function_body (fndecl, *function.get_definition ().get (),
-			   function.has_function_return_type ());
-
-    ctx->pop_block ();
-    auto body = ctx->get_backend ()->block_statement (code_block);
-    if (!ctx->get_backend ()->function_set_body (fndecl, body))
-      {
-	rust_error_at (function.get_locus (), "failed to set body to function");
-	return;
-      }
-
-    ctx->pop_fn ();
-    ctx->push_function (fndecl);
-
-    reference
-      = ctx->get_backend ()->function_code_expression (fndecl, ref_locus);
-  }
-
-  void visit (HIR::ImplBlock &impl_block) override
-  {
-    TyTy::BaseType *self_lookup = nullptr;
-    if (!ctx->get_tyctx ()->lookup_type (
-	  impl_block.get_type ()->get_mappings ().get_hirid (), &self_lookup))
-      {
-	rust_error_at (impl_block.get_locus (),
-		       "failed to resolve type of impl");
-	return;
-      }
-
-    for (auto &impl_item : impl_block.get_impl_items ())
-      CompileInherentImplItem::Compile (impl_item.get (), ctx);
-  }
-
-  void visit (HIR::ExternBlock &extern_block) override
-  {
-    for (auto &item : extern_block.get_extern_items ())
-      {
-	CompileExternItem::compile (item.get (), ctx, concrete);
-      }
-  }
-
-  void visit (HIR::Module &module) override
-  {
-    for (auto &item : module.get_items ())
-      CompileItem::compile (item.get (), ctx);
-  }
+  void visit (HIR::Module &module) override;
 
 protected:
   CompileItem (Context *ctx, TyTy::BaseType *concrete, Location ref_locus)
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index c6240463eae..2ef12320203 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -16,10 +16,10 @@
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-#include "rust-linemap.h"
-#include "rust-backend.h"
 #include "rust-compile-resolve-path.h"
 #include "rust-compile-item.h"
+#include "rust-compile-implitem.h"
+#include "rust-compile-expr.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-hir-path-probe.h"
 
@@ -131,7 +131,7 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
       tree fn = NULL_TREE;
       if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
 	{
-	  return ctx->get_backend ()->function_code_expression (fn, expr_locus);
+	  return address_expression (fn, expr_locus);
 	}
     }
 
@@ -245,8 +245,8 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
 	      associated->setup_associated_types ();
 
 	      return CompileTraitItem::Compile (
-		receiver, trait_item_ref->get_hir_trait_item (), ctx, lookup,
-		true, expr_locus);
+		trait_item_ref->get_hir_trait_item (), ctx, lookup, true,
+		expr_locus);
 	    }
 	  else
 	    {
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index 10f9a52e149..24a2084bae2 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -48,34 +48,6 @@ public:
     translated = CompileExpr::Compile (stmt.get_expr (), ctx);
   }
 
-  void visit (HIR::ConstantItem &constant) override
-  {
-    TyTy::BaseType *resolved_type = nullptr;
-    bool ok
-      = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
-					&resolved_type);
-    rust_assert (ok);
-
-    tree type = TyTyResolveCompile::compile (ctx, resolved_type);
-    tree value = CompileExpr::Compile (constant.get_expr (), ctx);
-
-    const Resolver::CanonicalPath *canonical_path = nullptr;
-    ok = ctx->get_mappings ()->lookup_canonical_path (
-      constant.get_mappings ().get_crate_num (),
-      constant.get_mappings ().get_nodeid (), &canonical_path);
-    rust_assert (ok);
-
-    std::string ident = canonical_path->get ();
-    tree const_expr
-      = ctx->get_backend ()->named_constant_expression (type, ident, value,
-							constant.get_locus ());
-
-    ctx->push_const (const_expr);
-    ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
-
-    translated = const_expr;
-  }
-
   void visit (HIR::LetStmt &stmt) override
   {
     // nothing to do
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 2299ddbb93c..fcbfc05a6c5 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -16,14 +16,16 @@
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-#include "rust-compile.h"
-#include "rust-compile-item.h"
-#include "rust-compile-expr.h"
-#include "rust-compile-struct-field-expr.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-hir-path-probe.h"
 #include "rust-hir-type-bounds.h"
 #include "rust-hir-dot-operator.h"
+#include "rust-compile.h"
+#include "rust-compile-item.h"
+#include "rust-compile-implitem.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-struct-field-expr.h"
+#include "rust-compile-stmt.h"
 
 namespace Rust {
 namespace Compile {
@@ -67,9 +69,8 @@ CompileBlock::visit (HIR::BlockExpr &expr)
       return;
     }
 
-  std::vector<Bvariable *> locals;
-  bool ok = compile_locals_for_block (*rib, fndecl, locals);
-  rust_assert (ok);
+  std::vector<Bvariable *> locals
+    = compile_locals_for_block (ctx, *rib, fndecl);
 
   tree enclosing_scope = ctx->peek_enclosing_scope ();
   tree new_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
@@ -203,87 +204,6 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
 
 // Shared methods in compilation
 
-void
-HIRCompileBase::compile_function_body (tree fndecl,
-				       HIR::BlockExpr &function_body,
-				       bool has_return_type)
-{
-  for (auto &s : function_body.get_statements ())
-    {
-      auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
-      if (compiled_expr != nullptr)
-	{
-	  tree compiled_stmt
-	    = ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
-	  ctx->add_statement (compiled_stmt);
-	}
-    }
-
-  if (function_body.has_expr ())
-    {
-      // the previous passes will ensure this is a valid return
-      // or a valid trailing expression
-      tree compiled_expr
-	= CompileExpr::Compile (function_body.expr.get (), ctx);
-
-      if (compiled_expr != nullptr)
-	{
-	  if (has_return_type)
-	    {
-	      std::vector<tree> retstmts;
-	      retstmts.push_back (compiled_expr);
-
-	      auto ret = ctx->get_backend ()->return_statement (
-		fndecl, retstmts,
-		function_body.get_final_expr ()->get_locus ());
-	      ctx->add_statement (ret);
-	    }
-	  else
-	    {
-	      tree final_stmt
-		= ctx->get_backend ()->expression_statement (fndecl,
-							     compiled_expr);
-	      ctx->add_statement (final_stmt);
-	    }
-	}
-    }
-}
-
-bool
-HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
-					  std::vector<Bvariable *> &locals)
-{
-  rib.iterate_decls ([&] (NodeId n, Location) mutable -> bool {
-    Resolver::Definition d;
-    bool ok = ctx->get_resolver ()->lookup_definition (n, &d);
-    rust_assert (ok);
-
-    HIR::Stmt *decl = nullptr;
-    ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
-    rust_assert (ok);
-
-    // if its a function we extract this out side of this fn context
-    // and it is not a local to this function
-    bool is_item = ctx->get_mappings ()->lookup_hir_item (
-		     decl->get_mappings ().get_crate_num (),
-		     decl->get_mappings ().get_hirid ())
-		   != nullptr;
-    if (is_item)
-      {
-	HIR::Item *item = static_cast<HIR::Item *> (decl);
-	CompileItem::compile (item, ctx);
-	return true;
-      }
-
-    Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
-    locals.push_back (compiled);
-
-    return true;
-  });
-
-  return true;
-}
-
 tree
 HIRCompileBase::coercion_site (tree rvalue, TyTy::BaseType *actual,
 			       TyTy::BaseType *expected, Location lvalue_locus,
@@ -533,8 +453,8 @@ HIRCompileBase::compute_address_for_trait_item (
   rust_assert (trait_item_has_definition);
 
   HIR::TraitItem *trait_item = ref->get_hir_trait_item ();
-  return CompileTraitItem::Compile (root, trait_item, ctx, trait_item_fntype,
-				    true, locus);
+  return CompileTraitItem::Compile (trait_item, ctx, trait_item_fntype, true,
+				    locus);
 }
 
 bool
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 5fdf8060170..d1cb762dce2 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -510,7 +510,6 @@ struct FunctionParam
 {
   std::unique_ptr<Pattern> param_name;
   std::unique_ptr<Type> type;
-
   Location locus;
   Analysis::NodeMapping mappings;
 
@@ -1226,11 +1225,7 @@ public:
 
   bool is_method () const { return !self.is_error (); }
 
-  SelfParam &get_self_param ()
-  {
-    rust_assert (is_method ());
-    return self;
-  }
+  SelfParam &get_self_param () { return self; }
 
 protected:
   /* Use covariance to implement clone function as returning this object
@@ -2242,11 +2237,7 @@ public:
 
   bool is_method () const { return !self.is_error (); }
 
-  SelfParam &get_self ()
-  {
-    rust_assert (is_method ());
-    return self;
-  }
+  SelfParam &get_self () { return self; }
 
   Identifier get_function_name () const { return function_name; }
 
@@ -2341,7 +2332,8 @@ public:
     return TraitItemKind::FUNC;
   }
 
-  AST::AttrVec get_outer_attrs () const { return outer_attrs; }
+  AST::AttrVec &get_outer_attrs () { return outer_attrs; }
+  const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
 
 protected:
   // Clone function implementation as (not pure) virtual method
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index f7a1ac60471..ac856af9756 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -251,10 +251,6 @@ public:
   // Return an expression that converts EXPR to TYPE.
   virtual tree convert_expression (tree type, tree expr, Location) = 0;
 
-  // Create an expression for the address of a function.  This is used to
-  // get the address of the code for a function.
-  virtual tree function_code_expression (tree, Location) = 0;
-
   // Return an expression for the field at INDEX in BSTRUCT.
   virtual tree struct_field_expression (tree bstruct, size_t index, Location)
     = 0;
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 86a4106162c..b648365f253 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -229,8 +229,6 @@ public:
 
   tree convert_expression (tree type, tree expr, Location);
 
-  tree function_code_expression (tree, Location);
-
   tree struct_field_expression (tree, size_t, Location);
 
   tree compound_expression (tree, tree, Location);
@@ -1305,18 +1303,6 @@ Gcc_backend::convert_expression (tree type_tree, tree expr_tree,
   return ret;
 }
 
-// Get the address of a function.
-
-tree
-Gcc_backend::function_code_expression (tree func, Location location)
-{
-  if (func == error_mark_node)
-    return this->error_expression ();
-
-  tree ret = build_fold_addr_expr_loc (location.gcc_location (), func);
-  return ret;
-}
-
 // Return an expression for the field at INDEX in BSTRUCT.
 
 tree


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:05 [gcc/devel/rust/master] Refactor code to reuse a canonical way to compile functions and constants Thomas Schwinge

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).